ImageTool: Rework PE section emission

This commit is contained in:
Marvin Häuser 2023-04-10 19:49:03 +02:00
parent c497d51928
commit 79ee7f5475

View File

@ -23,7 +23,6 @@ typedef struct {
uint32_t ExtraSectionsSize; uint32_t ExtraSectionsSize;
uint32_t UnsignedFileSize; uint32_t UnsignedFileSize;
uint32_t RelocTableSize; uint32_t RelocTableSize;
uint32_t HiiTableSize;
uint32_t DebugTableSize; uint32_t DebugTableSize;
uint32_t FileAlignment; uint32_t FileAlignment;
} image_tool_pe_emit_context_t; } image_tool_pe_emit_context_t;
@ -150,43 +149,23 @@ EmitPeGetRelocSectionSize (
} }
static static
bool void
EmitPeGetHiiSectionSize (
const image_tool_pe_emit_context_t *Context,
uint32_t *HiiSize
)
{
assert (Context != NULL);
assert (HiiSize != NULL);
return !BaseOverflowAlignUpU32 (
Context->Image->HiiInfo.DataSize,
Context->FileAlignment,
HiiSize
);
}
static
bool
EmitPeGetDebugSectionSize ( EmitPeGetDebugSectionSize (
const image_tool_image_info_t *Image, const image_tool_image_info_t *Image,
uint32_t *DebugSize uint32_t *DebugSize
) )
{ {
uint32_t Size;
assert (Image != NULL); assert (Image != NULL);
assert (DebugSize != NULL); assert (DebugSize != NULL);
*DebugSize = 0; Size = 0;
if (Image->DebugInfo.SymbolsPath != NULL) { if (Image->DebugInfo.SymbolsPath != NULL) {
return !BaseOverflowAlignUpU32 ( Size = sizeof (DebugData) + Image->DebugInfo.SymbolsPathLen + 1;
sizeof (DebugData) + Image->DebugInfo.SymbolsPathLen + 1,
Image->SegmentInfo.SegmentAlignment,
DebugSize
);
} }
return true; *DebugSize = Size;
} }
static static
@ -214,17 +193,7 @@ EmitPeGetExtraSectionsSize (
return false; return false;
} }
Result = EmitPeGetDebugSectionSize (Image, &Context->DebugTableSize); EmitPeGetDebugSectionSize (Image, &Context->DebugTableSize);
if (!Result) {
raise ();
return false;
}
Result = EmitPeGetHiiSectionSize (Context, &Context->HiiTableSize);
if (!Result) {
raise ();
return false;
}
Overflow = BaseOverflowAlignUpU32 ( Overflow = BaseOverflowAlignUpU32 (
Context->RelocTableSize, Context->RelocTableSize,
@ -247,7 +216,7 @@ EmitPeGetExtraSectionsSize (
} }
Overflow = BaseOverflowAlignUpU32 ( Overflow = BaseOverflowAlignUpU32 (
Context->HiiTableSize, Context->Image->HiiInfo.DataSize,
Context->FileAlignment, Context->FileAlignment,
&AlignedHiiTableSize &AlignedHiiTableSize
); );
@ -366,14 +335,16 @@ ToolImageEmitPeExtraSectionHeaders (
{ {
uint32_t SectionHeadersSize; uint32_t SectionHeadersSize;
EFI_IMAGE_SECTION_HEADER *Section; EFI_IMAGE_SECTION_HEADER *Section;
uint32_t SectionOffset;
assert (Context != NULL); assert (Context != NULL);
assert (Buffer != NULL); assert (Buffer != NULL);
assert (BufferSize != NULL); assert (BufferSize != NULL);
SectionHeadersSize = 0; SectionHeadersSize = 0;
SectionOffset = AlignedHeaderSize + Context->SectionsSize;
if (Context->HiiTableSize > 0) { if (Context->Image->HiiInfo.DataSize > 0) {
++Context->PeHdr->CommonHeader.FileHeader.NumberOfSections; ++Context->PeHdr->CommonHeader.FileHeader.NumberOfSections;
assert (sizeof (EFI_IMAGE_SECTION_HEADER) <= *BufferSize); assert (sizeof (EFI_IMAGE_SECTION_HEADER) <= *BufferSize);
@ -381,13 +352,15 @@ ToolImageEmitPeExtraSectionHeaders (
Section = (void *) *Buffer; Section = (void *) *Buffer;
strncpy ((char *)Section->Name, ".rsrc", sizeof (Section->Name)); strncpy ((char *)Section->Name, ".rsrc", sizeof (Section->Name));
Section->SizeOfRawData = Context->HiiTableSize; Section->SizeOfRawData = ALIGN_VALUE (Context->Image->HiiInfo.DataSize, Context->FileAlignment);
Section->VirtualSize = Context->HiiTableSize; Section->VirtualSize = Section->SizeOfRawData;
Section->Characteristics = EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | EFI_IMAGE_SCN_MEM_READ; Section->Characteristics = EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | EFI_IMAGE_SCN_MEM_READ;
Section->PointerToRawData = AlignedHeaderSize + Context->SectionsSize; Section->PointerToRawData = SectionOffset;
Section->VirtualAddress = Section->PointerToRawData; Section->VirtualAddress = Section->PointerToRawData;
Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = Context->HiiTableSize; SectionOffset += Section->SizeOfRawData;
Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].Size = Context->Image->HiiInfo.DataSize;
Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = Section->PointerToRawData; Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress = Section->PointerToRawData;
*BufferSize -= sizeof (EFI_IMAGE_SECTION_HEADER); *BufferSize -= sizeof (EFI_IMAGE_SECTION_HEADER);
@ -404,12 +377,14 @@ ToolImageEmitPeExtraSectionHeaders (
strncpy ((char *)Section->Name, ".reloc", sizeof (Section->Name)); strncpy ((char *)Section->Name, ".reloc", sizeof (Section->Name));
Section->SizeOfRawData = ALIGN_VALUE (Context->RelocTableSize, Context->FileAlignment); Section->SizeOfRawData = ALIGN_VALUE (Context->RelocTableSize, Context->FileAlignment);
Section->VirtualSize = ALIGN_VALUE (Context->RelocTableSize, Context->FileAlignment); Section->VirtualSize = Section->SizeOfRawData;
Section->Characteristics = EFI_IMAGE_SCN_CNT_INITIALIZED_DATA Section->Characteristics = EFI_IMAGE_SCN_CNT_INITIALIZED_DATA
| EFI_IMAGE_SCN_MEM_DISCARDABLE | EFI_IMAGE_SCN_MEM_READ; | EFI_IMAGE_SCN_MEM_DISCARDABLE | EFI_IMAGE_SCN_MEM_READ;
Section->PointerToRawData = AlignedHeaderSize + Context->SectionsSize + Context->HiiTableSize; Section->PointerToRawData = SectionOffset;
Section->VirtualAddress = Section->PointerToRawData; Section->VirtualAddress = Section->PointerToRawData;
SectionOffset += Section->SizeOfRawData;
Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = Context->RelocTableSize; Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = Context->RelocTableSize;
Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Section->PointerToRawData; Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = Section->PointerToRawData;
@ -426,21 +401,24 @@ ToolImageEmitPeExtraSectionHeaders (
Section = (void *) *Buffer; Section = (void *) *Buffer;
strncpy ((char *)Section->Name, ".debug", sizeof (Section->Name)); strncpy ((char *)Section->Name, ".debug", sizeof (Section->Name));
Section->SizeOfRawData = Context->DebugTableSize; Section->SizeOfRawData = ALIGN_VALUE (Context->DebugTableSize, Context->FileAlignment);
Section->VirtualSize = Context->DebugTableSize; Section->VirtualSize = Section->SizeOfRawData;
Section->Characteristics = EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | EFI_IMAGE_SCN_MEM_READ; Section->Characteristics = EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | EFI_IMAGE_SCN_MEM_READ;
Section->PointerToRawData = Context->UnsignedFileSize - Context->DebugTableSize; Section->PointerToRawData = SectionOffset;
Section->VirtualAddress = Section->PointerToRawData; Section->VirtualAddress = Section->PointerToRawData;
SectionOffset += Section->SizeOfRawData;
Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY); Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = Section->PointerToRawData; Context->PeHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress = Section->VirtualAddress;
*BufferSize -= sizeof (EFI_IMAGE_SECTION_HEADER); *BufferSize -= sizeof (EFI_IMAGE_SECTION_HEADER);
*Buffer += sizeof (EFI_IMAGE_SECTION_HEADER); *Buffer += sizeof (EFI_IMAGE_SECTION_HEADER);
SectionHeadersSize += sizeof (EFI_IMAGE_SECTION_HEADER); SectionHeadersSize += sizeof (EFI_IMAGE_SECTION_HEADER);
} }
assert (Context->HdrInfo.ExtraSectionHeadersSize == SectionHeadersSize); assert (SectionHeadersSize == Context->HdrInfo.ExtraSectionHeadersSize);
assert (SectionOffset == Context->UnsignedFileSize);
return true; return true;
} }
@ -768,6 +746,8 @@ ToolImageEmitPeDebugTable (
Data->Nb10.Signature = CODEVIEW_SIGNATURE_NB10; Data->Nb10.Signature = CODEVIEW_SIGNATURE_NB10;
memmove (Data->Name, Image->DebugInfo.SymbolsPath, Image->DebugInfo.SymbolsPathLen + 1); memmove (Data->Name, Image->DebugInfo.SymbolsPath, Image->DebugInfo.SymbolsPathLen + 1);
assert (sizeof (*Data) + Image->DebugInfo.SymbolsPathLen + 1 == Context->DebugTableSize);
*BufferSize -= Context->DebugTableSize; *BufferSize -= Context->DebugTableSize;
*Buffer += Context->DebugTableSize; *Buffer += Context->DebugTableSize;
@ -801,22 +781,21 @@ ToolImageEmitPeHiiTable (
Image = Context->Image; Image = Context->Image;
if (Context->HiiTableSize == 0) { if (Image->HiiInfo.DataSize == 0) {
return true; return true;
} }
Context->PeHdr->SizeOfImage += ALIGN_VALUE (Image->HiiInfo.DataSize, Image->SegmentInfo.SegmentAlignment); Context->PeHdr->SizeOfImage += ALIGN_VALUE (Image->HiiInfo.DataSize, Image->SegmentInfo.SegmentAlignment);
assert (Image->HiiInfo.DataSize <= Context->HiiTableSize); assert (Image->HiiInfo.DataSize <= *BufferSize);
assert (Context->HiiTableSize <= *BufferSize);
memmove (*Buffer, Image->HiiInfo.Data, Image->HiiInfo.DataSize); memmove (*Buffer, Image->HiiInfo.Data, Image->HiiInfo.DataSize);
*BufferSize -= Context->HiiTableSize; *BufferSize -= Image->HiiInfo.DataSize;
*Buffer += Context->HiiTableSize; *Buffer += Image->HiiInfo.DataSize;
HiiTablePadding = ALIGN_VALUE_ADDEND( HiiTablePadding = ALIGN_VALUE_ADDEND(
Context->HiiTableSize, Image->HiiInfo.DataSize,
Context->FileAlignment Context->FileAlignment
); );