mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-25 14:44:28 +02:00
ImageTool: Rework PeEmit with dynamically-growing buffers
This commit is contained in:
parent
e46d356fc9
commit
ba9aad0b56
@ -382,7 +382,7 @@
|
|||||||
$(OUTPUT_DIR)(+)$(MODULE_NAME).map
|
$(OUTPUT_DIR)(+)$(MODULE_NAME).map
|
||||||
|
|
||||||
<Command.MSFT, Command.INTEL, Command.CLANGPDB>
|
<Command.MSFT, Command.INTEL, Command.CLANGPDB>
|
||||||
ImageTool GenImage -c PE -t $(MODULE_TYPE) -o ${dst} ${src}
|
ImageTool GenImage -c PE -x -t $(MODULE_TYPE) -o ${dst} ${src}
|
||||||
$(CP) ${dst} $(DEBUG_DIR)
|
$(CP) ${dst} $(DEBUG_DIR)
|
||||||
$(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi
|
$(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi
|
||||||
-$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR)
|
-$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR)
|
||||||
@ -392,7 +392,7 @@
|
|||||||
$(CP) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).strip
|
$(CP) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).strip
|
||||||
$(OBJCOPY) $(OBJCOPY_STRIPFLAG) $(DEBUG_DIR)(+)$(MODULE_NAME).strip
|
$(OBJCOPY) $(OBJCOPY_STRIPFLAG) $(DEBUG_DIR)(+)$(MODULE_NAME).strip
|
||||||
|
|
||||||
ImageTool GenImage -c PE -t $(MODULE_TYPE) -o ${dst} $(DEBUG_DIR)(+)$(MODULE_NAME).strip
|
ImageTool GenImage -c PE -x -t $(MODULE_TYPE) -d ${src} -o ${dst} $(DEBUG_DIR)(+)$(MODULE_NAME).strip
|
||||||
|
|
||||||
$(CP) ${dst} $(DEBUG_DIR)
|
$(CP) ${dst} $(DEBUG_DIR)
|
||||||
$(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi
|
$(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi
|
||||||
@ -403,7 +403,7 @@
|
|||||||
"$(MTOC)" -subsystem $(MODULE_TYPE) $(MTOC_FLAGS) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).pecoff
|
"$(MTOC)" -subsystem $(MODULE_TYPE) $(MTOC_FLAGS) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).pecoff
|
||||||
# create symbol file for GDB debug
|
# create symbol file for GDB debug
|
||||||
-$(DSYMUTIL) ${src}
|
-$(DSYMUTIL) ${src}
|
||||||
ImageTool GenImage -c PE -t $(MODULE_TYPE) -o ${dst} $(DEBUG_DIR)(+)$(MODULE_NAME).pecoff
|
ImageTool GenImage -c PE -x -t $(MODULE_TYPE) -o ${dst} $(DEBUG_DIR)(+)$(MODULE_NAME).pecoff
|
||||||
$(CP) ${dst} $(DEBUG_DIR)
|
$(CP) ${dst} $(DEBUG_DIR)
|
||||||
$(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi
|
$(CP) ${dst} $(BIN_DIR)(+)$(MODULE_NAME_GUID).efi
|
||||||
-$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR)
|
-$(CP) $(DEBUG_DIR)(+)*.map $(OUTPUT_DIR)
|
||||||
|
@ -19,9 +19,6 @@ CreateEntry (
|
|||||||
EFI_IMAGE_RESOURCE_DIRECTORY *RDir;
|
EFI_IMAGE_RESOURCE_DIRECTORY *RDir;
|
||||||
EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *Entry;
|
EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *Entry;
|
||||||
|
|
||||||
assert (HiiSectionHeader != NULL);
|
|
||||||
assert (HiiSectionOffset != NULL);
|
|
||||||
|
|
||||||
RDir = (EFI_IMAGE_RESOURCE_DIRECTORY *)(HiiSectionHeader + *HiiSectionOffset);
|
RDir = (EFI_IMAGE_RESOURCE_DIRECTORY *)(HiiSectionHeader + *HiiSectionOffset);
|
||||||
*HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);
|
*HiiSectionOffset += sizeof (EFI_IMAGE_RESOURCE_DIRECTORY);
|
||||||
RDir->NumberOfNamedEntries = 1;
|
RDir->NumberOfNamedEntries = 1;
|
||||||
@ -49,11 +46,6 @@ CreateStringEntry (
|
|||||||
{
|
{
|
||||||
EFI_IMAGE_RESOURCE_DIRECTORY_STRING *RDStr;
|
EFI_IMAGE_RESOURCE_DIRECTORY_STRING *RDStr;
|
||||||
|
|
||||||
assert (Entry != NULL);
|
|
||||||
assert (HiiSectionHeader != NULL);
|
|
||||||
assert (HiiSectionOffset != NULL);
|
|
||||||
assert (String != NULL);
|
|
||||||
|
|
||||||
Entry->u1.s.NameOffset = *HiiSectionOffset;
|
Entry->u1.s.NameOffset = *HiiSectionOffset;
|
||||||
RDStr = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *)(HiiSectionHeader + *HiiSectionOffset);
|
RDStr = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *)(HiiSectionHeader + *HiiSectionOffset);
|
||||||
RDStr->Length = (UINT16)StrLen (String);
|
RDStr->Length = (UINT16)StrLen (String);
|
||||||
@ -78,8 +70,6 @@ InitializeHiiResouceSectionHeader (
|
|||||||
EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *LangRDirEntry;
|
EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *LangRDirEntry;
|
||||||
EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry;
|
EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry;
|
||||||
|
|
||||||
assert (HiiSectionHeader != NULL);
|
|
||||||
|
|
||||||
HiiSectionOffset = 0;
|
HiiSectionOffset = 0;
|
||||||
//
|
//
|
||||||
// Create Type, Name, Language entries
|
// Create Type, Name, Language entries
|
||||||
@ -123,10 +113,6 @@ ConstructHii (
|
|||||||
UINT32 FileSize;
|
UINT32 FileSize;
|
||||||
UINT8 NumberOfFormPackages;
|
UINT8 NumberOfFormPackages;
|
||||||
|
|
||||||
assert (Hii != NULL);
|
|
||||||
assert (HiiGuid != NULL);
|
|
||||||
assert (FileNames != NULL);
|
|
||||||
|
|
||||||
NumberOfFormPackages = 0;
|
NumberOfFormPackages = 0;
|
||||||
|
|
||||||
EndPackage.Length = sizeof (EFI_HII_PACKAGE_HEADER);
|
EndPackage.Length = sizeof (EFI_HII_PACKAGE_HEADER);
|
||||||
@ -173,7 +159,7 @@ ConstructHii (
|
|||||||
|
|
||||||
CopyGuid (&HiiPackageListHeader.PackageListGuid, HiiGuid);
|
CopyGuid (&HiiPackageListHeader.PackageListGuid, HiiGuid);
|
||||||
|
|
||||||
HiiPackageData = calloc (1, HiiPackageListHeader.PackageLength);
|
HiiPackageData = AllocateZeroPool (HiiPackageListHeader.PackageLength);
|
||||||
if (HiiPackageData == NULL) {
|
if (HiiPackageData == NULL) {
|
||||||
return RETURN_OUT_OF_RESOURCES;
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
@ -185,6 +171,7 @@ ConstructHii (
|
|||||||
File = UserReadFile (FileNames[Index], &FileSize);
|
File = UserReadFile (FileNames[Index], &FileSize);
|
||||||
if (File == NULL) {
|
if (File == NULL) {
|
||||||
fprintf (stderr, "ImageTool: Could not open %s: %s\n", FileNames[Index], strerror (errno));
|
fprintf (stderr, "ImageTool: Could not open %s: %s\n", FileNames[Index], strerror (errno));
|
||||||
|
free (HiiPackageData);
|
||||||
return RETURN_ABORTED;
|
return RETURN_ABORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
215
BaseTools/ImageTool/DynamicBuffer.c
Normal file
215
BaseTools/ImageTool/DynamicBuffer.c
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <Base.h>
|
||||||
|
|
||||||
|
#include <Library/BaseOverflowLib.h>
|
||||||
|
|
||||||
|
#include "ImageTool.h"
|
||||||
|
#include "DynamicBuffer.h"
|
||||||
|
|
||||||
|
#define IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH 0x1000
|
||||||
|
|
||||||
|
void
|
||||||
|
ImageToolBufferInit (
|
||||||
|
image_tool_dynamic_buffer *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
memset (Buffer, 0, sizeof (*Buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
uint32_t
|
||||||
|
ImageToolBufferExpand (
|
||||||
|
image_tool_dynamic_buffer *Buffer,
|
||||||
|
uint32_t Size
|
||||||
|
)
|
||||||
|
{
|
||||||
|
bool Overflow;
|
||||||
|
uint32_t NewAllocatedSize;
|
||||||
|
uint8_t *NewMemory;
|
||||||
|
uint32_t Offset;
|
||||||
|
|
||||||
|
assert (Buffer->DataSize <= Buffer->AllocatedSize);
|
||||||
|
assert (IS_ALIGNED (Buffer->AllocatedSize, IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH));
|
||||||
|
|
||||||
|
if (Buffer->AllocatedSize - Buffer->DataSize < Size) {
|
||||||
|
Overflow = BaseOverflowAlignUpU32 (
|
||||||
|
Size,
|
||||||
|
IMAGE_TOOL_DYNAMIC_BUFFER_GROWTH,
|
||||||
|
&NewAllocatedSize
|
||||||
|
);
|
||||||
|
if (Overflow) {
|
||||||
|
DEBUG_RAISE ();
|
||||||
|
return MAX_UINT32;
|
||||||
|
}
|
||||||
|
|
||||||
|
Overflow = BaseOverflowAddU32 (
|
||||||
|
NewAllocatedSize,
|
||||||
|
Buffer->AllocatedSize,
|
||||||
|
&NewAllocatedSize
|
||||||
|
);
|
||||||
|
if (Overflow) {
|
||||||
|
DEBUG_RAISE ();
|
||||||
|
return MAX_UINT32;
|
||||||
|
}
|
||||||
|
|
||||||
|
NewMemory = AllocatePool (NewAllocatedSize);
|
||||||
|
if (NewMemory == NULL) {
|
||||||
|
DEBUG_RAISE ();
|
||||||
|
return MAX_UINT32;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Buffer->Memory != NULL) {
|
||||||
|
memmove (NewMemory, Buffer->Memory, Buffer->DataSize);
|
||||||
|
FreePool (Buffer->Memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (
|
||||||
|
NewMemory + Buffer->DataSize,
|
||||||
|
0,
|
||||||
|
NewAllocatedSize - Buffer->DataSize
|
||||||
|
);
|
||||||
|
|
||||||
|
Buffer->Memory = NewMemory;
|
||||||
|
Buffer->AllocatedSize = NewAllocatedSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
Offset = Buffer->DataSize;
|
||||||
|
Buffer->DataSize += Size;
|
||||||
|
|
||||||
|
return Offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ImageToolBufferRead (
|
||||||
|
void *Data,
|
||||||
|
uint32_t Size,
|
||||||
|
const image_tool_dynamic_buffer *Buffer,
|
||||||
|
uint32_t Offset
|
||||||
|
)
|
||||||
|
{
|
||||||
|
assert (Offset + Size > Offset);
|
||||||
|
assert (Offset + Size <= Buffer->DataSize);
|
||||||
|
|
||||||
|
memmove (Data, &Buffer->Memory[Offset], Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ImageToolBufferWrite (
|
||||||
|
image_tool_dynamic_buffer *Buffer,
|
||||||
|
uint32_t Offset,
|
||||||
|
const void *Data,
|
||||||
|
uint32_t Size
|
||||||
|
)
|
||||||
|
{
|
||||||
|
assert (Offset + Size > Offset);
|
||||||
|
assert (Offset + Size <= Buffer->DataSize);
|
||||||
|
|
||||||
|
memmove (&Buffer->Memory[Offset], Data, Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
ImageToolBufferAppend (
|
||||||
|
image_tool_dynamic_buffer *Buffer,
|
||||||
|
const void *Data,
|
||||||
|
uint32_t Size
|
||||||
|
)
|
||||||
|
{
|
||||||
|
uint32_t Offset;
|
||||||
|
|
||||||
|
Offset = ImageToolBufferExpand (Buffer, Size);
|
||||||
|
if (Offset != MAX_UINT32) {
|
||||||
|
memmove (&Buffer->Memory[Offset], Data, Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
ImageToolBufferAppendReserve (
|
||||||
|
image_tool_dynamic_buffer *Buffer,
|
||||||
|
uint32_t Size
|
||||||
|
)
|
||||||
|
{
|
||||||
|
uint32_t Offset;
|
||||||
|
|
||||||
|
Offset = ImageToolBufferExpand (Buffer, Size);
|
||||||
|
if (Offset != MAX_UINT32) {
|
||||||
|
memset (&Buffer->Memory[Offset], 0, Size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
ImageToolBufferAppendReserveAlign (
|
||||||
|
image_tool_dynamic_buffer *Buffer,
|
||||||
|
uint32_t Alignment
|
||||||
|
)
|
||||||
|
{
|
||||||
|
assert (IS_POW2 (Alignment));
|
||||||
|
|
||||||
|
return ImageToolBufferAppendReserve (
|
||||||
|
Buffer,
|
||||||
|
ALIGN_VALUE_ADDEND (ImageToolBufferGetSize (Buffer), Alignment)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
ImageToolBufferGetPointer (
|
||||||
|
const image_tool_dynamic_buffer *Buffer,
|
||||||
|
uint32_t Offset
|
||||||
|
)
|
||||||
|
{
|
||||||
|
assert (Offset < Buffer->DataSize);
|
||||||
|
|
||||||
|
return &Buffer->Memory[Offset];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
ImageToolBufferGetSize (
|
||||||
|
const image_tool_dynamic_buffer *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return Buffer->DataSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
ImageToolBufferDump (
|
||||||
|
uint32_t *Size,
|
||||||
|
image_tool_dynamic_buffer *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
void *Data;
|
||||||
|
uint32_t DataSize;
|
||||||
|
|
||||||
|
if (Buffer->Memory == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
DataSize = ImageToolBufferGetSize (Buffer);
|
||||||
|
|
||||||
|
Data = AllocateCopyPool (DataSize, Buffer->Memory);
|
||||||
|
if (Data == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*Size = DataSize;
|
||||||
|
|
||||||
|
return Data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ImageToolBufferFree (
|
||||||
|
image_tool_dynamic_buffer *Buffer
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (Buffer->Memory != NULL) {
|
||||||
|
FreePool (Buffer->Memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageToolBufferInit (Buffer);
|
||||||
|
}
|
74
BaseTools/ImageTool/DynamicBuffer.h
Normal file
74
BaseTools/ImageTool/DynamicBuffer.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#ifndef DYNAMIC_BUFFER_H
|
||||||
|
#define DYNAMIC_BUFFER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t AllocatedSize;
|
||||||
|
uint32_t DataSize;
|
||||||
|
uint8_t *Memory;
|
||||||
|
} image_tool_dynamic_buffer;
|
||||||
|
|
||||||
|
void
|
||||||
|
ImageToolBufferInit (
|
||||||
|
image_tool_dynamic_buffer *Buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
ImageToolBufferAppend (
|
||||||
|
image_tool_dynamic_buffer *Buffer,
|
||||||
|
const void *Data,
|
||||||
|
uint32_t Size
|
||||||
|
);
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
ImageToolBufferAppendReserve (
|
||||||
|
image_tool_dynamic_buffer *Buffer,
|
||||||
|
uint32_t Size
|
||||||
|
);
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
ImageToolBufferAppendReserveAlign (
|
||||||
|
image_tool_dynamic_buffer *Buffer,
|
||||||
|
uint32_t Alignment
|
||||||
|
);
|
||||||
|
|
||||||
|
void
|
||||||
|
ImageToolBufferRead (
|
||||||
|
void *Data,
|
||||||
|
uint32_t Size,
|
||||||
|
const image_tool_dynamic_buffer *Buffer,
|
||||||
|
uint32_t Offset
|
||||||
|
);
|
||||||
|
|
||||||
|
void
|
||||||
|
ImageToolBufferWrite (
|
||||||
|
image_tool_dynamic_buffer *Buffer,
|
||||||
|
uint32_t Offset,
|
||||||
|
const void *Data,
|
||||||
|
uint32_t Size
|
||||||
|
);
|
||||||
|
|
||||||
|
void *
|
||||||
|
ImageToolBufferGetPointer (
|
||||||
|
const image_tool_dynamic_buffer *Buffer,
|
||||||
|
uint32_t Offset
|
||||||
|
);
|
||||||
|
|
||||||
|
uint32_t
|
||||||
|
ImageToolBufferGetSize (
|
||||||
|
const image_tool_dynamic_buffer *Buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
void *
|
||||||
|
ImageToolBufferDump (
|
||||||
|
uint32_t *Size,
|
||||||
|
image_tool_dynamic_buffer *Buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
void
|
||||||
|
ImageToolBufferFree (
|
||||||
|
image_tool_dynamic_buffer *Buffer
|
||||||
|
);
|
||||||
|
|
||||||
|
#endif // DYNAMIC_BUFFER_H
|
@ -103,8 +103,6 @@ IsShdrLoadable (
|
|||||||
IN const Elf_Shdr *Shdr
|
IN const Elf_Shdr *Shdr
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
assert (Shdr != NULL);
|
|
||||||
|
|
||||||
return (Shdr->sh_flags & SHF_ALLOC) != 0;
|
return (Shdr->sh_flags & SHF_ALLOC) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -360,7 +358,12 @@ SetRelocs (
|
|||||||
//
|
//
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf (stderr, "ImageTool: Unsupported ELF EM_X86_64 relocation 0x%llx in %s\n", ELF_R_TYPE(Rel->r_info), ImageInfo->DebugInfo.SymbolsPath);
|
fprintf (
|
||||||
|
stderr,
|
||||||
|
"ImageTool: Unsupported ELF EM_X86_64 relocation 0x%llx in %s\n",
|
||||||
|
(unsigned long long)ELF_R_TYPE(Rel->r_info),
|
||||||
|
ImageInfo->DebugInfo.SymbolsPath
|
||||||
|
);
|
||||||
return RETURN_INCOMPATIBLE_VERSION;
|
return RETURN_INCOMPATIBLE_VERSION;
|
||||||
}
|
}
|
||||||
} else if (Ehdr->e_machine == EM_AARCH64) {
|
} else if (Ehdr->e_machine == EM_AARCH64) {
|
||||||
@ -402,7 +405,12 @@ SetRelocs (
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf (stderr, "ImageTool: Unsupported ELF EM_AARCH64 relocation 0x%llx in %s\n", ELF_R_TYPE(Rel->r_info), ImageInfo->DebugInfo.SymbolsPath);
|
fprintf (
|
||||||
|
stderr,
|
||||||
|
"ImageTool: Unsupported ELF EM_AARCH64 relocation 0x%llx in %s\n",
|
||||||
|
(unsigned long long)ELF_R_TYPE(Rel->r_info),
|
||||||
|
ImageInfo->DebugInfo.SymbolsPath
|
||||||
|
);
|
||||||
return RETURN_INCOMPATIBLE_VERSION;
|
return RETURN_INCOMPATIBLE_VERSION;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -571,7 +579,7 @@ CreateIntermediate (
|
|||||||
return RETURN_VOLUME_CORRUPTED;
|
return RETURN_VOLUME_CORRUPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Segments = calloc (1, sizeof (*Segments) * ImageInfo->SegmentInfo.NumSegments);
|
Segments = AllocateZeroPool (sizeof (*Segments) * ImageInfo->SegmentInfo.NumSegments);
|
||||||
if (Segments == NULL) {
|
if (Segments == NULL) {
|
||||||
fprintf (stderr, "ImageTool: Could not allocate memory for Segments\n");
|
fprintf (stderr, "ImageTool: Could not allocate memory for Segments\n");
|
||||||
return RETURN_OUT_OF_RESOURCES;
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
@ -580,7 +588,7 @@ CreateIntermediate (
|
|||||||
ImageInfo->SegmentInfo.Segments = Segments;
|
ImageInfo->SegmentInfo.Segments = Segments;
|
||||||
|
|
||||||
if (NumRelocs != 0) {
|
if (NumRelocs != 0) {
|
||||||
Relocs = calloc (1, sizeof (*Relocs) * NumRelocs);
|
Relocs = AllocateZeroPool (sizeof (*Relocs) * NumRelocs);
|
||||||
if (Relocs == NULL) {
|
if (Relocs == NULL) {
|
||||||
fprintf (stderr, "ImageTool: Could not allocate memory for Relocs\n");
|
fprintf (stderr, "ImageTool: Could not allocate memory for Relocs\n");
|
||||||
return RETURN_OUT_OF_RESOURCES;
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
@ -606,7 +614,7 @@ CreateIntermediate (
|
|||||||
return RETURN_VOLUME_CORRUPTED;
|
return RETURN_VOLUME_CORRUPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Segments[SIndex].Name = calloc (1, strlen (Name) + 1);
|
Segments[SIndex].Name = AllocateZeroPool (strlen (Name) + 1);
|
||||||
if (Segments[SIndex].Name == NULL) {
|
if (Segments[SIndex].Name == NULL) {
|
||||||
fprintf (stderr, "ImageTool: Could not allocate memory for Segment #%d Name\n", Index);
|
fprintf (stderr, "ImageTool: Could not allocate memory for Segment #%d Name\n", Index);
|
||||||
return RETURN_OUT_OF_RESOURCES;
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
@ -620,7 +628,7 @@ CreateIntermediate (
|
|||||||
Segments[SIndex].Write = (Shdr->sh_flags & SHF_WRITE) != 0;
|
Segments[SIndex].Write = (Shdr->sh_flags & SHF_WRITE) != 0;
|
||||||
Segments[SIndex].Execute = (Shdr->sh_flags & SHF_EXECINSTR) != 0;
|
Segments[SIndex].Execute = (Shdr->sh_flags & SHF_EXECINSTR) != 0;
|
||||||
|
|
||||||
Segments[SIndex].Data = calloc (1, Segments[SIndex].ImageSize);
|
Segments[SIndex].Data = AllocateZeroPool (Segments[SIndex].ImageSize);
|
||||||
if (Segments[SIndex].Data == NULL) {
|
if (Segments[SIndex].Data == NULL) {
|
||||||
fprintf (stderr, "ImageTool: Could not allocate memory for Segment #%d Data\n", Index);
|
fprintf (stderr, "ImageTool: Could not allocate memory for Segment #%d Data\n", Index);
|
||||||
return RETURN_OUT_OF_RESOURCES;
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
@ -652,7 +660,6 @@ ScanElf (
|
|||||||
const Elf_Ehdr *Ehdr;
|
const Elf_Ehdr *Ehdr;
|
||||||
Elf_Addr BaseAddress;
|
Elf_Addr BaseAddress;
|
||||||
|
|
||||||
assert (ImageInfo != NULL);
|
|
||||||
assert (File != NULL || FileSize == 0);
|
assert (File != NULL || FileSize == 0);
|
||||||
|
|
||||||
Status = ParseElfFile (&Context, File, FileSize);
|
Status = ParseElfFile (&Context, File, FileSize);
|
||||||
@ -667,7 +674,6 @@ ScanElf (
|
|||||||
|
|
||||||
ImageInfo->HeaderInfo.BaseAddress = BaseAddress;
|
ImageInfo->HeaderInfo.BaseAddress = BaseAddress;
|
||||||
ImageInfo->HeaderInfo.EntryPointAddress = (uint32_t)(Ehdr->e_entry - BaseAddress);
|
ImageInfo->HeaderInfo.EntryPointAddress = (uint32_t)(Ehdr->e_entry - BaseAddress);
|
||||||
ImageInfo->HeaderInfo.IsXip = true;
|
|
||||||
ImageInfo->SegmentInfo.SegmentAlignment = (uint32_t)Context.Alignment;
|
ImageInfo->SegmentInfo.SegmentAlignment = (uint32_t)Context.Alignment;
|
||||||
ImageInfo->RelocInfo.RelocsStripped = false;
|
ImageInfo->RelocInfo.RelocsStripped = false;
|
||||||
|
|
||||||
@ -698,11 +704,11 @@ ScanElf (
|
|||||||
return RETURN_INCOMPATIBLE_VERSION;
|
return RETURN_INCOMPATIBLE_VERSION;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageInfo->DebugInfo.SymbolsPath = malloc (ImageInfo->DebugInfo.SymbolsPathLen + 1);
|
ImageInfo->DebugInfo.SymbolsPath = AllocatePool (ImageInfo->DebugInfo.SymbolsPathLen + 1);
|
||||||
if (ImageInfo->DebugInfo.SymbolsPath == NULL) {
|
if (ImageInfo->DebugInfo.SymbolsPath == NULL) {
|
||||||
fprintf (stderr, "ImageTool: Could not allocate memory for Debug Data\n");
|
fprintf (stderr, "ImageTool: Could not allocate memory for Debug Data\n");
|
||||||
return RETURN_OUT_OF_RESOURCES;
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
};
|
}
|
||||||
|
|
||||||
if (SymbolsPath != NULL) {
|
if (SymbolsPath != NULL) {
|
||||||
memmove (ImageInfo->DebugInfo.SymbolsPath, SymbolsPath, ImageInfo->DebugInfo.SymbolsPathLen + 1);
|
memmove (ImageInfo->DebugInfo.SymbolsPath, SymbolsPath, ImageInfo->DebugInfo.SymbolsPathLen + 1);
|
||||||
|
@ -10,7 +10,7 @@ OBJS = $(PROJECT).o
|
|||||||
OBJS += Image.o UefiImageScan.o PeEmit32.o PeEmit64.o PeEmitCommon.o PeScan.o ElfScan32.o ElfScan64.o ElfScanCommon.o BinEmit.o ImageToolEmit.o
|
OBJS += Image.o UefiImageScan.o PeEmit32.o PeEmit64.o PeEmitCommon.o PeScan.o ElfScan32.o ElfScan64.o ElfScanCommon.o BinEmit.o ImageToolEmit.o
|
||||||
OBJS += UefiImageExtraActionLib.o
|
OBJS += UefiImageExtraActionLib.o
|
||||||
OBJS += PeCoffInit.o PeCoffInfo.o PeCoffLoad.o PeCoffRelocate.o PeCoffHii.o PeCoffDebug.o PeCoffHash.o
|
OBJS += PeCoffInit.o PeCoffInfo.o PeCoffLoad.o PeCoffRelocate.o PeCoffHii.o PeCoffDebug.o PeCoffHash.o
|
||||||
OBJS += PeSupport.o UefiImageLib.o CommonSupport.o
|
OBJS += PeSupport.o UefiImageLib.o CommonSupport.o DynamicBuffer.o
|
||||||
|
|
||||||
WERROR = 1
|
WERROR = 1
|
||||||
DEBUG = 1
|
DEBUG = 1
|
||||||
|
@ -16,22 +16,18 @@ CheckToolImageSegment (
|
|||||||
{
|
{
|
||||||
bool Overflow;
|
bool Overflow;
|
||||||
|
|
||||||
assert (Segment != NULL);
|
|
||||||
assert (PreviousEndAddress != NULL);
|
|
||||||
|
|
||||||
if (!IS_ALIGNED (Segment->ImageSize, SegmentInfo->SegmentAlignment)) {
|
if (!IS_ALIGNED (Segment->ImageSize, SegmentInfo->SegmentAlignment)) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Segment->Write && Segment->Execute) {
|
if (Segment->Write && Segment->Execute) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Expand prior segment
|
|
||||||
if (Segment->ImageAddress != *PreviousEndAddress) {
|
if (Segment->ImageAddress != *PreviousEndAddress) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +37,7 @@ CheckToolImageSegment (
|
|||||||
PreviousEndAddress
|
PreviousEndAddress
|
||||||
);
|
);
|
||||||
if (Overflow) {
|
if (Overflow) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,21 +54,18 @@ CheckToolImageSegmentInfo (
|
|||||||
uint32_t Index;
|
uint32_t Index;
|
||||||
bool Result;
|
bool Result;
|
||||||
|
|
||||||
assert (SegmentInfo != NULL);
|
|
||||||
assert (ImageSize != NULL);
|
|
||||||
|
|
||||||
if (!IS_POW2 (SegmentInfo->SegmentAlignment)) {
|
if (!IS_POW2 (SegmentInfo->SegmentAlignment)) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SegmentInfo->NumSegments == 0) {
|
if (SegmentInfo->NumSegments == 0) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IS_ALIGNED (SegmentInfo->Segments[0].ImageAddress, SegmentInfo->SegmentAlignment)) {
|
if (!IS_ALIGNED (SegmentInfo->Segments[0].ImageAddress, SegmentInfo->SegmentAlignment)) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +77,7 @@ CheckToolImageSegmentInfo (
|
|||||||
ImageSize
|
ImageSize
|
||||||
);
|
);
|
||||||
if (!Result) {
|
if (!Result) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -93,6 +86,32 @@ CheckToolImageSegmentInfo (
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
bool
|
||||||
|
CheckToolImageHeaderInfo (
|
||||||
|
const image_tool_header_info_t *HeaderInfo,
|
||||||
|
const image_tool_segment_info_t *SegmentInfo,
|
||||||
|
uint32_t ImageSize
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (SegmentInfo->Segments[0].ImageAddress > HeaderInfo->EntryPointAddress ||
|
||||||
|
HeaderInfo->EntryPointAddress > ImageSize) {
|
||||||
|
DEBUG_RAISE ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IS_ALIGNED (HeaderInfo->BaseAddress, SegmentInfo->SegmentAlignment)) {
|
||||||
|
DEBUG_RAISE ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (HeaderInfo->BaseAddress + ImageSize < HeaderInfo->BaseAddress) {
|
||||||
|
DEBUG_RAISE ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const image_tool_segment_t *
|
const image_tool_segment_t *
|
||||||
ImageGetSegmentByAddress (
|
ImageGetSegmentByAddress (
|
||||||
uint32_t *Address,
|
uint32_t *Address,
|
||||||
@ -102,9 +121,6 @@ ImageGetSegmentByAddress (
|
|||||||
{
|
{
|
||||||
uint32_t Index;
|
uint32_t Index;
|
||||||
|
|
||||||
assert (Address != NULL);
|
|
||||||
assert (SegmentInfo != NULL);
|
|
||||||
|
|
||||||
for (Index = 0; Index < SegmentInfo->NumSegments; ++Index) {
|
for (Index = 0; Index < SegmentInfo->NumSegments; ++Index) {
|
||||||
if ((SegmentInfo->Segments[Index].ImageAddress <= *Address)
|
if ((SegmentInfo->Segments[Index].ImageAddress <= *Address)
|
||||||
&& (*Address < SegmentInfo->Segments[Index].ImageAddress + SegmentInfo->Segments[Index].ImageSize)) {
|
&& (*Address < SegmentInfo->Segments[Index].ImageAddress + SegmentInfo->Segments[Index].ImageSize)) {
|
||||||
@ -117,22 +133,52 @@ ImageGetSegmentByAddress (
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
ToolImageGetRelocSize (
|
||||||
|
uint8_t Type
|
||||||
|
)
|
||||||
|
{
|
||||||
|
switch (Type) {
|
||||||
|
case EFI_IMAGE_REL_BASED_HIGHLOW:
|
||||||
|
{
|
||||||
|
return sizeof (UINT32);
|
||||||
|
}
|
||||||
|
|
||||||
|
case EFI_IMAGE_REL_BASED_DIR64:
|
||||||
|
{
|
||||||
|
return sizeof (UINT64);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
case EFI_IMAGE_REL_BASED_ARM_MOV32T:
|
||||||
|
{
|
||||||
|
return sizeof (UINT32);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
bool
|
bool
|
||||||
CheckToolImageReloc (
|
CheckToolImageReloc (
|
||||||
const image_tool_image_info_t *Image,
|
const image_tool_image_info_t *Image,
|
||||||
uint32_t ImageSize,
|
const image_tool_reloc_t *Reloc,
|
||||||
const image_tool_reloc_t *Reloc
|
uint8_t RelocSize
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
uint32_t RelocOffset;
|
uint32_t RelocOffset;
|
||||||
uint32_t RemainingSize;
|
uint32_t RemainingSize;
|
||||||
const image_tool_segment_t *Segment;
|
const image_tool_segment_t *Segment;
|
||||||
|
|
||||||
|
#if 0
|
||||||
uint16_t MovHigh;
|
uint16_t MovHigh;
|
||||||
uint16_t MovLow;
|
uint16_t MovLow;
|
||||||
|
#endif
|
||||||
assert (Image != NULL);
|
|
||||||
assert (Reloc != NULL);
|
|
||||||
|
|
||||||
RelocOffset = Reloc->Target;
|
RelocOffset = Reloc->Target;
|
||||||
Segment = ImageGetSegmentByAddress (
|
Segment = ImageGetSegmentByAddress (
|
||||||
@ -141,64 +187,40 @@ CheckToolImageReloc (
|
|||||||
&Image->SegmentInfo
|
&Image->SegmentInfo
|
||||||
);
|
);
|
||||||
if (Segment == NULL) {
|
if (Segment == NULL) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (Reloc->Type) {
|
if (RelocSize > RemainingSize) {
|
||||||
case EFI_IMAGE_REL_BASED_HIGHLOW:
|
DEBUG_RAISE ();
|
||||||
{
|
return false;
|
||||||
if (RemainingSize < sizeof (UINT32)) {
|
}
|
||||||
raise ();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
#if 0
|
||||||
|
if (Reloc->Type == EFI_IMAGE_REL_BASED_ARM_MOV32T) {
|
||||||
|
if (!IS_ALIGNED (Reloc->Target, ALIGNOF (UINT16))) {
|
||||||
|
DEBUG_RAISE ();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
case EFI_IMAGE_REL_BASED_DIR64:
|
MovHigh = *(const uint16_t *)&Segment->Data[RelocOffset];
|
||||||
{
|
MovLow = *(const uint16_t *)&Segment->Data[RelocOffset + 2];
|
||||||
if (RemainingSize < sizeof (UINT64)) {
|
if (((MovHigh & 0xFBF0U) != 0xF200U && (MovHigh & 0xFBF0U) != 0xF2C0U) ||
|
||||||
raise ();
|
(MovLow & 0x8000U) != 0) {
|
||||||
return false;
|
DEBUG_RAISE ();
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case EFI_IMAGE_REL_BASED_ARM_MOV32T:
|
|
||||||
{
|
|
||||||
if (RemainingSize < sizeof (UINT32)) {
|
|
||||||
raise ();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!IS_ALIGNED (Reloc->Target, ALIGNOF (UINT16))) {
|
|
||||||
raise ();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
MovHigh = *(const uint16_t *)&Segment->Data[RelocOffset];
|
|
||||||
MovLow = *(const uint16_t *)&Segment->Data[RelocOffset + 2];
|
|
||||||
if (((MovHigh & 0xFBF0U) != 0xF200U && (MovHigh & 0xFBF0U) != 0xF2C0U) ||
|
|
||||||
(MovLow & 0x8000U) != 0) {
|
|
||||||
raise ();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
raise ();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*if (Segment->Write) {
|
// FIXME: Update drivers?
|
||||||
|
if ((Image->HeaderInfo.Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER ||
|
||||||
|
Image->HeaderInfo.Subsystem == EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER) &&
|
||||||
|
Segment->Write) {
|
||||||
printf("!!! writable reloc at %x !!!\n", Reloc->Target);
|
printf("!!! writable reloc at %x !!!\n", Reloc->Target);
|
||||||
}*/
|
//DEBUG_RAISE ();
|
||||||
|
//return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -206,49 +228,52 @@ CheckToolImageReloc (
|
|||||||
static
|
static
|
||||||
bool
|
bool
|
||||||
CheckToolImageRelocInfo (
|
CheckToolImageRelocInfo (
|
||||||
const image_tool_image_info_t *Image,
|
const image_tool_image_info_t *Image
|
||||||
uint32_t ImageSize
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
const image_tool_reloc_info_t *RelocInfo;
|
const image_tool_reloc_info_t *RelocInfo;
|
||||||
|
uint8_t RelocSize;
|
||||||
|
uint32_t MinRelocTarget;
|
||||||
uint32_t Index;
|
uint32_t Index;
|
||||||
bool Result;
|
bool Result;
|
||||||
|
|
||||||
assert (Image != NULL);
|
|
||||||
|
|
||||||
RelocInfo = &Image->RelocInfo;
|
RelocInfo = &Image->RelocInfo;
|
||||||
|
|
||||||
if (RelocInfo->NumRelocs == 0) {
|
if (RelocInfo->NumRelocs == 0) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RelocInfo->RelocsStripped && (RelocInfo->NumRelocs > 0)) {
|
if (RelocInfo->RelocsStripped) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RelocInfo->NumRelocs > (MAX_UINT32 / sizeof (UINT16))) {
|
if (RelocInfo->NumRelocs > (MAX_UINT32 / sizeof (UINT16))) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result = CheckToolImageReloc (Image, ImageSize, &RelocInfo->Relocs[0]);
|
MinRelocTarget = 0;
|
||||||
if (!Result) {
|
|
||||||
raise ();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Index = 1; Index < RelocInfo->NumRelocs; ++Index) {
|
for (Index = 0; Index < RelocInfo->NumRelocs; ++Index) {
|
||||||
if (RelocInfo->Relocs[Index].Target < RelocInfo->Relocs[Index - 1].Target) {
|
if (RelocInfo->Relocs[Index].Target < MinRelocTarget) {
|
||||||
assert (false);
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result = CheckToolImageReloc (Image, ImageSize, &RelocInfo->Relocs[Index]);
|
RelocSize = ToolImageGetRelocSize (RelocInfo->Relocs[Index].Type);
|
||||||
|
if (RelocSize == 0) {
|
||||||
|
DEBUG_RAISE ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = CheckToolImageReloc (Image, &RelocInfo->Relocs[Index], RelocSize);
|
||||||
if (!Result) {
|
if (!Result) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MinRelocTarget = RelocInfo->Relocs[Index].Target + RelocSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -260,14 +285,9 @@ CheckToolImageDebugInfo (
|
|||||||
const image_tool_debug_info_t *DebugInfo
|
const image_tool_debug_info_t *DebugInfo
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
assert (DebugInfo != NULL);
|
if (DebugInfo->SymbolsPathLen > MAX_UINT8) {
|
||||||
|
DEBUG_RAISE ();
|
||||||
if (DebugInfo->SymbolsPath != NULL) {
|
return false;
|
||||||
// FIXME: UE-only?
|
|
||||||
if (DebugInfo->SymbolsPathLen > MAX_UINT8) {
|
|
||||||
raise ();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -281,23 +301,31 @@ CheckToolImage (
|
|||||||
bool Result;
|
bool Result;
|
||||||
uint32_t ImageSize;
|
uint32_t ImageSize;
|
||||||
|
|
||||||
assert (Image != NULL);
|
|
||||||
|
|
||||||
Result = CheckToolImageSegmentInfo (&Image->SegmentInfo, &ImageSize);
|
Result = CheckToolImageSegmentInfo (&Image->SegmentInfo, &ImageSize);
|
||||||
if (!Result) {
|
if (!Result) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result = CheckToolImageRelocInfo (Image, ImageSize);
|
Result = CheckToolImageHeaderInfo (
|
||||||
|
&Image->HeaderInfo,
|
||||||
|
&Image->SegmentInfo,
|
||||||
|
ImageSize
|
||||||
|
);
|
||||||
if (!Result) {
|
if (!Result) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Result = CheckToolImageRelocInfo (Image);
|
||||||
|
if (!Result) {
|
||||||
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result = CheckToolImageDebugInfo (&Image->DebugInfo);
|
Result = CheckToolImageDebugInfo (&Image->DebugInfo);
|
||||||
if (!Result) {
|
if (!Result) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,10 +344,6 @@ ImageInitUnpaddedSize (
|
|||||||
Segment = &Image->SegmentInfo.Segments[Index];
|
Segment = &Image->SegmentInfo.Segments[Index];
|
||||||
Segment->UnpaddedSize = Segment->ImageSize;
|
Segment->UnpaddedSize = Segment->ImageSize;
|
||||||
|
|
||||||
if (Image->HeaderInfo.IsXip) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (; Segment->UnpaddedSize > 0; --Segment->UnpaddedSize) {
|
for (; Segment->UnpaddedSize > 0; --Segment->UnpaddedSize) {
|
||||||
if (Segment->Data[Segment->UnpaddedSize - 1] != 0) {
|
if (Segment->Data[Segment->UnpaddedSize - 1] != 0) {
|
||||||
break;
|
break;
|
||||||
@ -335,20 +359,33 @@ ToolImageDestruct (
|
|||||||
{
|
{
|
||||||
uint8_t Index;
|
uint8_t Index;
|
||||||
|
|
||||||
assert (Image != NULL);
|
|
||||||
|
|
||||||
if (Image->SegmentInfo.Segments != NULL) {
|
if (Image->SegmentInfo.Segments != NULL) {
|
||||||
for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) {
|
for (Index = 0; Index < Image->SegmentInfo.NumSegments; ++Index) {
|
||||||
free (Image->SegmentInfo.Segments[Index].Name);
|
if (Image->SegmentInfo.Segments[Index].Name != NULL) {
|
||||||
free (Image->SegmentInfo.Segments[Index].Data);
|
FreePool (Image->SegmentInfo.Segments[Index].Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Image->SegmentInfo.Segments[Index].Data != NULL) {
|
||||||
|
FreePool (Image->SegmentInfo.Segments[Index].Data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free (Image->SegmentInfo.Segments);
|
if (Image->SegmentInfo.Segments != NULL) {
|
||||||
|
FreePool (Image->SegmentInfo.Segments);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free (Image->HiiInfo.Data);
|
if (Image->HiiInfo.Data != NULL) {
|
||||||
free (Image->RelocInfo.Relocs);
|
FreePool (Image->HiiInfo.Data);
|
||||||
free (Image->DebugInfo.SymbolsPath);
|
}
|
||||||
|
|
||||||
|
if (Image->RelocInfo.Relocs != NULL) {
|
||||||
|
FreePool (Image->RelocInfo.Relocs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Image->DebugInfo.SymbolsPath != NULL) {
|
||||||
|
FreePool (Image->DebugInfo.SymbolsPath);
|
||||||
|
}
|
||||||
|
|
||||||
memset (Image, 0, sizeof (*Image));
|
memset (Image, 0, sizeof (*Image));
|
||||||
}
|
}
|
||||||
@ -356,9 +393,12 @@ ToolImageDestruct (
|
|||||||
bool
|
bool
|
||||||
ToolImageRelocate (
|
ToolImageRelocate (
|
||||||
image_tool_image_info_t *Image,
|
image_tool_image_info_t *Image,
|
||||||
uint64_t BaseAddress
|
uint64_t BaseAddress,
|
||||||
|
uint32_t IgnorePrefix
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
const image_tool_segment_t *LastSegment;
|
||||||
|
uint32_t ImageSize;
|
||||||
uint64_t Adjust;
|
uint64_t Adjust;
|
||||||
const image_tool_reloc_t *Reloc;
|
const image_tool_reloc_t *Reloc;
|
||||||
uint32_t RelocOffset;
|
uint32_t RelocOffset;
|
||||||
@ -368,10 +408,28 @@ ToolImageRelocate (
|
|||||||
uint32_t RelocTarget32;
|
uint32_t RelocTarget32;
|
||||||
uint64_t RelocTarget64;
|
uint64_t RelocTarget64;
|
||||||
|
|
||||||
|
if (!IS_ALIGNED (BaseAddress, Image->SegmentInfo.SegmentAlignment)) {
|
||||||
|
DEBUG_RAISE ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
Adjust = BaseAddress - Image->HeaderInfo.BaseAddress;
|
Adjust = BaseAddress - Image->HeaderInfo.BaseAddress;
|
||||||
|
|
||||||
if (Adjust == 0) {
|
if (Adjust == 0) {
|
||||||
return TRUE;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
LastSegment = &Image->SegmentInfo.Segments[Image->SegmentInfo.NumSegments - 1];
|
||||||
|
ImageSize = LastSegment->ImageAddress + LastSegment->ImageSize;
|
||||||
|
|
||||||
|
//
|
||||||
|
// When removing the image header prefix, BaseAddress + ImageSize may indeed
|
||||||
|
// overflow. The important part is that the address starting from the first
|
||||||
|
// image segment does not.
|
||||||
|
//
|
||||||
|
if (BaseAddress + ImageSize < BaseAddress + IgnorePrefix) {
|
||||||
|
DEBUG_RAISE ();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Index = 0; Index < Image->RelocInfo.NumRelocs; ++Index) {
|
for (Index = 0; Index < Image->RelocInfo.NumRelocs; ++Index) {
|
||||||
@ -383,10 +441,7 @@ ToolImageRelocate (
|
|||||||
&RemainingSize,
|
&RemainingSize,
|
||||||
&Image->SegmentInfo
|
&Image->SegmentInfo
|
||||||
);
|
);
|
||||||
if (Segment == NULL) {
|
assert (Segment != NULL);
|
||||||
raise ();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (Reloc->Type) {
|
switch (Reloc->Type) {
|
||||||
case EFI_IMAGE_REL_BASED_HIGHLOW:
|
case EFI_IMAGE_REL_BASED_HIGHLOW:
|
||||||
@ -409,6 +464,7 @@ ToolImageRelocate (
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
case EFI_IMAGE_REL_BASED_ARM_MOV32T:
|
case EFI_IMAGE_REL_BASED_ARM_MOV32T:
|
||||||
{
|
{
|
||||||
assert (RemainingSize >= sizeof (UINT32));
|
assert (RemainingSize >= sizeof (UINT32));
|
||||||
@ -417,10 +473,11 @@ ToolImageRelocate (
|
|||||||
PeCoffThumbMovwMovtImmediateFixup (&Segment->Data[RelocOffset], Adjust);
|
PeCoffThumbMovwMovtImmediateFixup (&Segment->Data[RelocOffset], Adjust);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
raise ();
|
assert (false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -494,7 +551,7 @@ ToolImageCompare (
|
|||||||
sizeof (Image1->HeaderInfo)
|
sizeof (Image1->HeaderInfo)
|
||||||
);
|
);
|
||||||
if (CmpResult != 0) {
|
if (CmpResult != 0) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,7 +567,7 @@ ToolImageCompare (
|
|||||||
OFFSET_OF (image_tool_segment_info_t, Segments)
|
OFFSET_OF (image_tool_segment_info_t, Segments)
|
||||||
);
|
);
|
||||||
if (CmpResult != 0) {
|
if (CmpResult != 0) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -521,7 +578,7 @@ ToolImageCompare (
|
|||||||
OFFSET_OF (image_tool_segment_t, Name)
|
OFFSET_OF (image_tool_segment_t, Name)
|
||||||
);
|
);
|
||||||
if (CmpResult != 0) {
|
if (CmpResult != 0) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -538,20 +595,22 @@ ToolImageCompare (
|
|||||||
++NameIndex
|
++NameIndex
|
||||||
) {
|
) {
|
||||||
if (Name1[NameIndex] != Name2[NameIndex]) {
|
if (Name1[NameIndex] != Name2[NameIndex]) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CmpResult = memcmp (
|
if (Image1->SegmentInfo.Segments[SegIndex].ImageSize != 0) {
|
||||||
Image1->SegmentInfo.Segments[SegIndex].Data,
|
CmpResult = memcmp (
|
||||||
Image2->SegmentInfo.Segments[SegIndex].Data,
|
Image1->SegmentInfo.Segments[SegIndex].Data,
|
||||||
Image1->SegmentInfo.Segments[SegIndex].ImageSize
|
Image2->SegmentInfo.Segments[SegIndex].Data,
|
||||||
);
|
Image1->SegmentInfo.Segments[SegIndex].ImageSize
|
||||||
if (CmpResult != 0) {
|
);
|
||||||
raise ();
|
if (CmpResult != 0) {
|
||||||
return false;
|
DEBUG_RAISE ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -565,18 +624,20 @@ ToolImageCompare (
|
|||||||
OFFSET_OF (image_tool_reloc_info_t, Relocs)
|
OFFSET_OF (image_tool_reloc_info_t, Relocs)
|
||||||
);
|
);
|
||||||
if (CmpResult != 0) {
|
if (CmpResult != 0) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CmpResult = memcmp (
|
if (Image1->RelocInfo.NumRelocs != 0) {
|
||||||
Image1->RelocInfo.Relocs,
|
CmpResult = memcmp (
|
||||||
Image2->RelocInfo.Relocs,
|
Image1->RelocInfo.Relocs,
|
||||||
Image1->RelocInfo.NumRelocs * sizeof (*Image1->RelocInfo.Relocs)
|
Image2->RelocInfo.Relocs,
|
||||||
);
|
Image1->RelocInfo.NumRelocs * sizeof (*Image1->RelocInfo.Relocs)
|
||||||
if (CmpResult != 0) {
|
);
|
||||||
raise ();
|
if (CmpResult != 0) {
|
||||||
return false;
|
DEBUG_RAISE ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -589,18 +650,20 @@ ToolImageCompare (
|
|||||||
OFFSET_OF (image_tool_hii_info_t, Data)
|
OFFSET_OF (image_tool_hii_info_t, Data)
|
||||||
);
|
);
|
||||||
if (CmpResult != 0) {
|
if (CmpResult != 0) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CmpResult = memcmp (
|
if (Image1->HiiInfo.DataSize != 0) {
|
||||||
Image1->HiiInfo.Data,
|
CmpResult = memcmp (
|
||||||
Image2->HiiInfo.Data,
|
Image1->HiiInfo.Data,
|
||||||
Image1->HiiInfo.DataSize
|
Image2->HiiInfo.Data,
|
||||||
);
|
Image1->HiiInfo.DataSize
|
||||||
if (CmpResult != 0) {
|
);
|
||||||
raise ();
|
if (CmpResult != 0) {
|
||||||
return false;
|
DEBUG_RAISE ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -613,12 +676,12 @@ ToolImageCompare (
|
|||||||
OFFSET_OF (image_tool_debug_info_t, SymbolsPath)
|
OFFSET_OF (image_tool_debug_info_t, SymbolsPath)
|
||||||
);
|
);
|
||||||
if (CmpResult != 0) {
|
if (CmpResult != 0) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Image1->DebugInfo.SymbolsPath != NULL) != (Image2->DebugInfo.SymbolsPath != NULL)) {
|
if ((Image1->DebugInfo.SymbolsPath != NULL) != (Image2->DebugInfo.SymbolsPath != NULL)) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -628,7 +691,7 @@ ToolImageCompare (
|
|||||||
Image2->DebugInfo.SymbolsPath
|
Image2->DebugInfo.SymbolsPath
|
||||||
);
|
);
|
||||||
if (CmpResult != 0) {
|
if (CmpResult != 0) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -642,7 +705,11 @@ ToolImageStripRelocs (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
Image->RelocInfo.NumRelocs = 0;
|
Image->RelocInfo.NumRelocs = 0;
|
||||||
free (Image->RelocInfo.Relocs);
|
|
||||||
|
if (Image->RelocInfo.Relocs != NULL) {
|
||||||
|
FreePool (Image->RelocInfo.Relocs);
|
||||||
|
}
|
||||||
|
|
||||||
Image->RelocInfo.Relocs = NULL;
|
Image->RelocInfo.Relocs = NULL;
|
||||||
|
|
||||||
Image->RelocInfo.RelocsStripped = TRUE;
|
Image->RelocInfo.RelocsStripped = TRUE;
|
||||||
|
@ -37,10 +37,6 @@ HiiSrc (
|
|||||||
FILE *FilePtr;
|
FILE *FilePtr;
|
||||||
UINT32 Index;
|
UINT32 Index;
|
||||||
|
|
||||||
assert (FileNames != NULL);
|
|
||||||
assert (HiiName != NULL);
|
|
||||||
assert (Guid != NULL);
|
|
||||||
|
|
||||||
Status = AsciiStrToGuid (Guid, &HiiGuid);
|
Status = AsciiStrToGuid (Guid, &HiiGuid);
|
||||||
if (RETURN_ERROR (Status)) {
|
if (RETURN_ERROR (Status)) {
|
||||||
fprintf (stderr, "ImageTool: Invalid GUID - %s\n", Guid);
|
fprintf (stderr, "ImageTool: Invalid GUID - %s\n", Guid);
|
||||||
@ -55,7 +51,7 @@ HiiSrc (
|
|||||||
|
|
||||||
FilePtr = fopen (HiiName, "w");
|
FilePtr = fopen (HiiName, "w");
|
||||||
if (FilePtr == NULL) {
|
if (FilePtr == NULL) {
|
||||||
free (Hii);
|
FreePool (Hii);
|
||||||
return RETURN_NO_MEDIA;
|
return RETURN_NO_MEDIA;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +109,8 @@ HiiSrc (
|
|||||||
" (CONST MODULE_HII_PACKAGE_LIST *)&mModuleHiiPackageList;\n"
|
" (CONST MODULE_HII_PACKAGE_LIST *)&mModuleHiiPackageList;\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
free (Hii);
|
fclose (FilePtr);
|
||||||
|
FreePool (Hii);
|
||||||
|
|
||||||
return RETURN_SUCCESS;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -247,9 +244,6 @@ GetAcpi (
|
|||||||
UINT16 Index;
|
UINT16 Index;
|
||||||
UINT32 FileLength;
|
UINT32 FileLength;
|
||||||
|
|
||||||
assert (PeName != NULL);
|
|
||||||
assert (AcpiName != NULL);
|
|
||||||
|
|
||||||
Pe = UserReadFile (PeName, &PeSize);
|
Pe = UserReadFile (PeName, &PeSize);
|
||||||
if (Pe == NULL) {
|
if (Pe == NULL) {
|
||||||
fprintf (stderr, "ImageTool: Could not open %s: %s\n", PeName, strerror (errno));
|
fprintf (stderr, "ImageTool: Could not open %s: %s\n", PeName, strerror (errno));
|
||||||
@ -353,9 +347,11 @@ RETURN_STATUS
|
|||||||
GenExecutable (
|
GenExecutable (
|
||||||
IN const char *OutputFileName,
|
IN const char *OutputFileName,
|
||||||
IN const char *InputFileName,
|
IN const char *InputFileName,
|
||||||
|
IN const char *SymbolsPath OPTIONAL,
|
||||||
IN const char *FormatName,
|
IN const char *FormatName,
|
||||||
IN const char *TypeName,
|
IN const char *TypeName,
|
||||||
IN const char *BaseAddress,
|
IN const char *BaseAddress,
|
||||||
|
IN bool Xip,
|
||||||
IN bool Strip,
|
IN bool Strip,
|
||||||
IN bool FixedAddress
|
IN bool FixedAddress
|
||||||
)
|
)
|
||||||
@ -402,6 +398,10 @@ GenExecutable (
|
|||||||
return RETURN_ABORTED;
|
return RETURN_ABORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SymbolsPath == NULL) {
|
||||||
|
SymbolsPath = InputFileName;
|
||||||
|
}
|
||||||
|
|
||||||
OutputFile = ToolImageEmit (
|
OutputFile = ToolImageEmit (
|
||||||
&OutputFileSize,
|
&OutputFileSize,
|
||||||
InputFile,
|
InputFile,
|
||||||
@ -410,18 +410,20 @@ GenExecutable (
|
|||||||
Type,
|
Type,
|
||||||
BaseAddress != NULL,
|
BaseAddress != NULL,
|
||||||
NewBaseAddress,
|
NewBaseAddress,
|
||||||
InputFileName,
|
SymbolsPath,
|
||||||
|
Xip,
|
||||||
Strip,
|
Strip,
|
||||||
FixedAddress
|
FixedAddress
|
||||||
);
|
);
|
||||||
|
|
||||||
if (OutputFile == NULL) {
|
if (OutputFile == NULL) {
|
||||||
|
DEBUG_RAISE ();
|
||||||
return RETURN_ABORTED;
|
return RETURN_ABORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
UserWriteFile (OutputFileName, OutputFile, OutputFileSize);
|
UserWriteFile (OutputFileName, OutputFile, OutputFileSize);
|
||||||
|
|
||||||
free (OutputFile);
|
FreePool (OutputFile);
|
||||||
|
|
||||||
return RETURN_SUCCESS;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -432,16 +434,18 @@ int main (int argc, const char *argv[])
|
|||||||
UINT32 NumOfFiles;
|
UINT32 NumOfFiles;
|
||||||
const char *OutputName;
|
const char *OutputName;
|
||||||
const char *InputName;
|
const char *InputName;
|
||||||
|
const char *SymbolsPath;
|
||||||
const char *FormatName;
|
const char *FormatName;
|
||||||
const char *TypeName;
|
const char *TypeName;
|
||||||
const char *BaseAddress;
|
const char *BaseAddress;
|
||||||
|
bool Xip;
|
||||||
bool Strip;
|
bool Strip;
|
||||||
bool FixedAddress;
|
bool FixedAddress;
|
||||||
int ArgIndex;
|
int ArgIndex;
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
fprintf (stderr, "ImageTool: No command is specified\n");
|
fprintf (stderr, "ImageTool: No command is specified\n");
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
@ -452,16 +456,18 @@ int main (int argc, const char *argv[])
|
|||||||
if (strcmp (argv[1], "GenImage") == 0) {
|
if (strcmp (argv[1], "GenImage") == 0) {
|
||||||
if (argc < 5) {
|
if (argc < 5) {
|
||||||
fprintf (stderr, "ImageTool: Command arguments are missing\n");
|
fprintf (stderr, "ImageTool: Command arguments are missing\n");
|
||||||
fprintf (stderr, " Usage: ImageTool GenImage [-c Format] [-t ModuleType] [-b BaseAddress] [-s] [-f] -o OutputFile InputFile\n");
|
fprintf (stderr, " Usage: ImageTool GenImage [-c Format] [-t ModuleType] [-b BaseAddress] [-d SymbolsPath] [-x] [-s] [-f] -o OutputFile InputFile\n");
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
OutputName = NULL;
|
OutputName = NULL;
|
||||||
InputName = NULL;
|
InputName = NULL;
|
||||||
|
SymbolsPath = NULL;
|
||||||
FormatName = NULL;
|
FormatName = NULL;
|
||||||
TypeName = NULL;
|
TypeName = NULL;
|
||||||
BaseAddress = NULL;
|
BaseAddress = NULL;
|
||||||
|
Xip = false;
|
||||||
Strip = false;
|
Strip = false;
|
||||||
FixedAddress = false;
|
FixedAddress = false;
|
||||||
for (ArgIndex = 2; ArgIndex < argc; ++ArgIndex) {
|
for (ArgIndex = 2; ArgIndex < argc; ++ArgIndex) {
|
||||||
@ -497,6 +503,16 @@ int main (int argc, const char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
BaseAddress = argv[ArgIndex];
|
BaseAddress = argv[ArgIndex];
|
||||||
|
} else if (strcmp (argv[ArgIndex], "-d") == 0) {
|
||||||
|
++ArgIndex;
|
||||||
|
if (ArgIndex == argc) {
|
||||||
|
fprintf (stderr, "Must specify an argument to -d\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
SymbolsPath = argv[ArgIndex];
|
||||||
|
} else if (strcmp (argv[ArgIndex], "-x") == 0) {
|
||||||
|
Xip = true;
|
||||||
} else if (strcmp (argv[ArgIndex], "-s") == 0) {
|
} else if (strcmp (argv[ArgIndex], "-s") == 0) {
|
||||||
Strip = true;
|
Strip = true;
|
||||||
} else if (strcmp (argv[ArgIndex], "-f") == 0) {
|
} else if (strcmp (argv[ArgIndex], "-f") == 0) {
|
||||||
@ -524,21 +540,23 @@ int main (int argc, const char *argv[])
|
|||||||
Status = GenExecutable (
|
Status = GenExecutable (
|
||||||
OutputName,
|
OutputName,
|
||||||
InputName,
|
InputName,
|
||||||
|
SymbolsPath,
|
||||||
FormatName,
|
FormatName,
|
||||||
TypeName,
|
TypeName,
|
||||||
BaseAddress,
|
BaseAddress,
|
||||||
|
Xip,
|
||||||
Strip,
|
Strip,
|
||||||
FixedAddress
|
FixedAddress
|
||||||
);
|
);
|
||||||
if (RETURN_ERROR (Status)) {
|
if (RETURN_ERROR (Status)) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if (strcmp (argv[1], "HiiSrc") == 0) {
|
} else if (strcmp (argv[1], "HiiSrc") == 0) {
|
||||||
if (argc < 5 || strcmp (argv[3], "-o") != 0) {
|
if (argc < 5 || strcmp (argv[3], "-o") != 0) {
|
||||||
fprintf (stderr, "ImageTool: Command arguments are missing\n");
|
fprintf (stderr, "ImageTool: Command arguments are missing\n");
|
||||||
fprintf (stderr, " Usage: ImageTool HiiBin GUID -o OutputFile InputFile1 InputFile2 ...\n");
|
fprintf (stderr, " Usage: ImageTool HiiBin GUID -o OutputFile InputFile1 InputFile2 ...\n");
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -546,20 +564,20 @@ int main (int argc, const char *argv[])
|
|||||||
|
|
||||||
Status = HiiSrc (argv[4], argv[2], &argv[5], NumOfFiles);
|
Status = HiiSrc (argv[4], argv[2], &argv[5], NumOfFiles);
|
||||||
if (RETURN_ERROR (Status)) {
|
if (RETURN_ERROR (Status)) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else if (strcmp (argv[1], "GetAcpi") == 0) {
|
} else if (strcmp (argv[1], "GetAcpi") == 0) {
|
||||||
if (argc != 5 || strcmp (argv[2], "-o") != 0) {
|
if (argc != 5 || strcmp (argv[2], "-o") != 0) {
|
||||||
fprintf (stderr, "ImageTool: Command arguments are missing\n");
|
fprintf (stderr, "ImageTool: Command arguments are missing\n");
|
||||||
fprintf (stderr, " Usage: ImageTool GetAcpi -o OutputFile InputFile\n");
|
fprintf (stderr, " Usage: ImageTool GetAcpi -o OutputFile InputFile\n");
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status = GetAcpi (argv[4], argv[3]);
|
Status = GetAcpi (argv[4], argv[3]);
|
||||||
if (RETURN_ERROR (Status)) {
|
if (RETURN_ERROR (Status)) {
|
||||||
raise ();
|
DEBUG_RAISE ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,19 +18,12 @@
|
|||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
#include <Library/BaseMemoryLib.h>
|
#include <Library/BaseMemoryLib.h>
|
||||||
#include <Library/BaseOverflowLib.h>
|
#include <Library/BaseOverflowLib.h>
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
#include <Library/MemoryAllocationLib.h>
|
#include <Library/MemoryAllocationLib.h>
|
||||||
#include <UserFile.h>
|
#include <UserFile.h>
|
||||||
|
|
||||||
#define MAX_PE_ALIGNMENT 0x10000
|
#define MAX_PE_ALIGNMENT 0x10000
|
||||||
|
|
||||||
#define raise() assert(false)
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
EFI_IMAGE_DEBUG_DIRECTORY_ENTRY Dir;
|
|
||||||
EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY Nb10;
|
|
||||||
char Name[];
|
|
||||||
} DebugData;
|
|
||||||
|
|
||||||
#define PAGE(x) ((x) & ~4095U)
|
#define PAGE(x) ((x) & ~4095U)
|
||||||
#define PAGE_OFF(x) ((x) & 4095U)
|
#define PAGE_OFF(x) ((x) & 4095U)
|
||||||
|
|
||||||
@ -39,9 +32,8 @@ typedef struct {
|
|||||||
uint32_t EntryPointAddress;
|
uint32_t EntryPointAddress;
|
||||||
uint16_t Machine;
|
uint16_t Machine;
|
||||||
uint16_t Subsystem;
|
uint16_t Subsystem;
|
||||||
uint8_t IsXip;
|
|
||||||
uint8_t FixedAddress;
|
uint8_t FixedAddress;
|
||||||
uint8_t Reserved[6];
|
uint8_t Reserved[7];
|
||||||
} image_tool_header_info_t;
|
} image_tool_header_info_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -60,7 +52,8 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t SegmentAlignment;
|
uint32_t SegmentAlignment;
|
||||||
uint32_t NumSegments;
|
uint16_t NumSegments;
|
||||||
|
uint8_t Reserved[2];
|
||||||
|
|
||||||
image_tool_segment_t *Segments;
|
image_tool_segment_t *Segments;
|
||||||
} image_tool_segment_info_t;
|
} image_tool_segment_info_t;
|
||||||
@ -117,7 +110,8 @@ ImageInitUnpaddedSize (
|
|||||||
bool
|
bool
|
||||||
ToolImageRelocate (
|
ToolImageRelocate (
|
||||||
image_tool_image_info_t *Image,
|
image_tool_image_info_t *Image,
|
||||||
uint64_t BaseAddress
|
uint64_t BaseAddress,
|
||||||
|
uint32_t IgnorePrefix
|
||||||
);
|
);
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -136,6 +130,11 @@ ToolImageStripRelocs (
|
|||||||
image_tool_image_info_t *Image
|
image_tool_image_info_t *Image
|
||||||
);
|
);
|
||||||
|
|
||||||
|
uint8_t
|
||||||
|
ToolImageGetRelocSize (
|
||||||
|
uint8_t Type
|
||||||
|
);
|
||||||
|
|
||||||
RETURN_STATUS
|
RETURN_STATUS
|
||||||
ToolContextConstructUefiImage (
|
ToolContextConstructUefiImage (
|
||||||
OUT image_tool_image_info_t *Image,
|
OUT image_tool_image_info_t *Image,
|
||||||
@ -153,6 +152,7 @@ void *
|
|||||||
ToolImageEmitPe (
|
ToolImageEmitPe (
|
||||||
image_tool_image_info_t *Image,
|
image_tool_image_info_t *Image,
|
||||||
uint32_t *FileSize,
|
uint32_t *FileSize,
|
||||||
|
bool Xip,
|
||||||
bool Strip
|
bool Strip
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -182,4 +182,11 @@ ConstructHii (
|
|||||||
OUT UINT32 *HiiSize
|
OUT UINT32 *HiiSize
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const image_tool_segment_t *
|
||||||
|
ImageGetSegmentByAddress (
|
||||||
|
uint32_t *Address,
|
||||||
|
uint32_t *RemainingSize,
|
||||||
|
const image_tool_segment_info_t *SegmentInfo
|
||||||
|
);
|
||||||
|
|
||||||
#endif // IMAGE_TOOL_H
|
#endif // IMAGE_TOOL_H
|
||||||
|
@ -33,9 +33,11 @@ ToolContextConstruct (
|
|||||||
File,
|
File,
|
||||||
FileSize
|
FileSize
|
||||||
);
|
);
|
||||||
|
#ifndef IMAGE_TOOL_DISABLE_ELF
|
||||||
if (Status == RETURN_UNSUPPORTED) {
|
if (Status == RETURN_UNSUPPORTED) {
|
||||||
Status = ScanElf (ImageInfo, File, FileSize, SymbolsPath);
|
Status = ScanElf (ImageInfo, File, FileSize, SymbolsPath);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
@ -61,13 +63,13 @@ ValidateOutputFile (
|
|||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
assert (false);
|
assert (Status == RETURN_OUT_OF_RESOURCES);
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result = CheckToolImage (&OutputImageInfo);
|
Result = CheckToolImage (&OutputImageInfo);
|
||||||
if (!Result) {
|
if (!Result) {
|
||||||
raise ();
|
assert (false);
|
||||||
ToolImageDestruct (&OutputImageInfo);
|
ToolImageDestruct (&OutputImageInfo);
|
||||||
return RETURN_UNSUPPORTED;
|
return RETURN_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
@ -94,6 +96,7 @@ ToolImageEmit (
|
|||||||
IN bool Relocate,
|
IN bool Relocate,
|
||||||
IN uint64_t BaseAddress,
|
IN uint64_t BaseAddress,
|
||||||
IN const char *SymbolsPath OPTIONAL,
|
IN const char *SymbolsPath OPTIONAL,
|
||||||
|
IN bool Xip,
|
||||||
IN bool Strip,
|
IN bool Strip,
|
||||||
IN bool FixedAddress
|
IN bool FixedAddress
|
||||||
)
|
)
|
||||||
@ -138,12 +141,13 @@ ToolImageEmit (
|
|||||||
|
|
||||||
Success = CheckToolImage (&ImageInfo);
|
Success = CheckToolImage (&ImageInfo);
|
||||||
if (!Success) {
|
if (!Success) {
|
||||||
|
DEBUG_RAISE ();
|
||||||
ToolImageDestruct (&ImageInfo);
|
ToolImageDestruct (&ImageInfo);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Relocate) {
|
if (Relocate) {
|
||||||
Success = ToolImageRelocate (&ImageInfo, BaseAddress);
|
Success = ToolImageRelocate (&ImageInfo, BaseAddress, 0);
|
||||||
if (!Success) {
|
if (!Success) {
|
||||||
fprintf (stderr, "ImageTool: Failed to relocate input file %s\n", SymbolsPath);
|
fprintf (stderr, "ImageTool: Failed to relocate input file %s\n", SymbolsPath);
|
||||||
ToolImageDestruct (&ImageInfo);
|
ToolImageDestruct (&ImageInfo);
|
||||||
@ -157,17 +161,24 @@ ToolImageEmit (
|
|||||||
|
|
||||||
OutputFile = NULL;
|
OutputFile = NULL;
|
||||||
if (Format == UefiImageFormatPe) {
|
if (Format == UefiImageFormatPe) {
|
||||||
OutputFile = ToolImageEmitPe (&ImageInfo, OutputFileSize, Strip);
|
OutputFile = ToolImageEmitPe (&ImageInfo, OutputFileSize, Xip, Strip);
|
||||||
} else {
|
} else {
|
||||||
assert (false);
|
assert (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (OutputFile == NULL) {
|
||||||
|
DEBUG_RAISE ();
|
||||||
|
ToolImageDestruct (&ImageInfo);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
Status = ValidateOutputFile (OutputFile, *OutputFileSize, &ImageInfo);
|
Status = ValidateOutputFile (OutputFile, *OutputFileSize, &ImageInfo);
|
||||||
|
|
||||||
ToolImageDestruct (&ImageInfo);
|
ToolImageDestruct (&ImageInfo);
|
||||||
|
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
assert (false);
|
assert (Status == RETURN_OUT_OF_RESOURCES);
|
||||||
|
FreePool (OutputFile);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ ToolImageEmit (
|
|||||||
IN bool Relocate,
|
IN bool Relocate,
|
||||||
IN uint64_t BaseAddress,
|
IN uint64_t BaseAddress,
|
||||||
IN const char *SymbolsPath OPTIONAL,
|
IN const char *SymbolsPath OPTIONAL,
|
||||||
|
IN bool Xip,
|
||||||
IN bool Strip,
|
IN bool Strip,
|
||||||
IN bool FixedAddress
|
IN bool FixedAddress
|
||||||
);
|
);
|
||||||
|
@ -20,7 +20,7 @@ PE = $(UDK_PATH)\MdePkg\Library\BasePeCoffLib2
|
|||||||
UA = $(UDK_PATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull
|
UA = $(UDK_PATH)\MdePkg\Library\BaseUefiImageExtraActionLibNull
|
||||||
|
|
||||||
OBJECTS = ImageTool.obj Image.obj PeEmit32.obj PeEmit64.obj PeEmitCommon.obj UefiImageScan.obj PeScan.obj ElfScan32.obj ElfScan64.obj ElfScanCommon.obj BinEmit.obj ImageToolEmit.obj
|
OBJECTS = ImageTool.obj Image.obj PeEmit32.obj PeEmit64.obj PeEmitCommon.obj UefiImageScan.obj PeScan.obj ElfScan32.obj ElfScan64.obj ElfScanCommon.obj BinEmit.obj ImageToolEmit.obj
|
||||||
OBJECTS = $(OBJECTS) {$(OV)}BaseAlignment.obj BaseBitOverflow.obj {$(UA)}UefiImageExtraActionLib.obj
|
OBJECTS = $(OBJECTS) {$(OV)}BaseAlignment.obj BaseBitOverflow.obj {$(UA)}UefiImageExtraActionLib.obj DynamicBuffer.obj
|
||||||
OBJECTS = $(OBJECTS) {$(PE)}PeCoffInit.obj PeCoffInfo.obj PeCoffRelocate.obj PeCoffLoad.obj PeCoffHii.obj PeCoffDebug.obj PeCoffHash.obj
|
OBJECTS = $(OBJECTS) {$(PE)}PeCoffInit.obj PeCoffInfo.obj PeCoffRelocate.obj PeCoffLoad.obj PeCoffHii.obj PeCoffDebug.obj PeCoffHash.obj
|
||||||
|
|
||||||
BASE = $(UDK_PATH)\MdePkg\Library\BaseLib
|
BASE = $(UDK_PATH)\MdePkg\Library\BaseLib
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -9,6 +9,7 @@ void *
|
|||||||
ToolImageEmitPe (
|
ToolImageEmitPe (
|
||||||
image_tool_image_info_t *Image,
|
image_tool_image_info_t *Image,
|
||||||
uint32_t *FileSize,
|
uint32_t *FileSize,
|
||||||
|
bool Xip,
|
||||||
bool Strip
|
bool Strip
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -20,13 +21,13 @@ ToolImageEmitPe (
|
|||||||
case IMAGE_FILE_MACHINE_I386:
|
case IMAGE_FILE_MACHINE_I386:
|
||||||
case IMAGE_FILE_MACHINE_ARMTHUMB_MIXED:
|
case IMAGE_FILE_MACHINE_ARMTHUMB_MIXED:
|
||||||
{
|
{
|
||||||
return ToolImageEmitPe32 (Image, FileSize);
|
return ToolImageEmitPe32 (Image, FileSize, Xip);
|
||||||
}
|
}
|
||||||
|
|
||||||
case IMAGE_FILE_MACHINE_X64:
|
case IMAGE_FILE_MACHINE_X64:
|
||||||
case IMAGE_FILE_MACHINE_ARM64:
|
case IMAGE_FILE_MACHINE_ARM64:
|
||||||
{
|
{
|
||||||
return ToolImageEmitPe64 (Image, FileSize);
|
return ToolImageEmitPe64 (Image, FileSize, Xip);
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -13,13 +13,15 @@
|
|||||||
void *
|
void *
|
||||||
ToolImageEmitPe32 (
|
ToolImageEmitPe32 (
|
||||||
const image_tool_image_info_t *Image,
|
const image_tool_image_info_t *Image,
|
||||||
uint32_t *FileSize
|
uint32_t *FileSize,
|
||||||
|
bool Xip
|
||||||
);
|
);
|
||||||
|
|
||||||
void *
|
void *
|
||||||
ToolImageEmitPe64 (
|
ToolImageEmitPe64 (
|
||||||
const image_tool_image_info_t *Image,
|
const image_tool_image_info_t *Image,
|
||||||
uint32_t *FileSize
|
uint32_t *FileSize,
|
||||||
|
bool Xip
|
||||||
);
|
);
|
||||||
|
|
||||||
#endif // PE_EMIT_COMMON_H
|
#endif // PE_EMIT_COMMON_H
|
||||||
|
@ -6,11 +6,13 @@
|
|||||||
|
|
||||||
#include "ImageTool.h"
|
#include "ImageTool.h"
|
||||||
|
|
||||||
|
#include "PeScan.h"
|
||||||
|
|
||||||
#define PE_COFF_SECT_NAME_RELOC ".reloc\0"
|
#define PE_COFF_SECT_NAME_RELOC ".reloc\0"
|
||||||
#define PE_COFF_SECT_NAME_RESRC ".rsrc\0\0"
|
#define PE_COFF_SECT_NAME_RESRC ".rsrc\0\0"
|
||||||
#define PE_COFF_SECT_NAME_DEBUG ".debug\0"
|
#define PE_COFF_SECT_NAME_DEBUG ".debug\0"
|
||||||
|
|
||||||
bool
|
RETURN_STATUS
|
||||||
ScanPeGetRelocInfo (
|
ScanPeGetRelocInfo (
|
||||||
OUT image_tool_reloc_info_t *RelocInfo,
|
OUT image_tool_reloc_info_t *RelocInfo,
|
||||||
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context
|
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context
|
||||||
@ -29,9 +31,7 @@ ScanPeGetRelocInfo (
|
|||||||
const char *ImageBuffer;
|
const char *ImageBuffer;
|
||||||
UINT16 RelocType;
|
UINT16 RelocType;
|
||||||
UINT16 RelocOffset;
|
UINT16 RelocOffset;
|
||||||
|
uint32_t ToolRelocsSize;
|
||||||
assert (RelocInfo != NULL);
|
|
||||||
assert (Context != NULL);
|
|
||||||
|
|
||||||
// FIXME: PE/COFF context access
|
// FIXME: PE/COFF context access
|
||||||
RelocBlockRva = Context->RelocDirRva;
|
RelocBlockRva = Context->RelocDirRva;
|
||||||
@ -40,13 +40,28 @@ ScanPeGetRelocInfo (
|
|||||||
// Verify the Relocation Directory is not empty.
|
// Verify the Relocation Directory is not empty.
|
||||||
//
|
//
|
||||||
if (RelocDirSize == 0) {
|
if (RelocDirSize == 0) {
|
||||||
return true;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
RelocInfo->Relocs = calloc (RelocDirSize / sizeof (UINT16), sizeof (*RelocInfo->Relocs));
|
STATIC_ASSERT (
|
||||||
|
sizeof (*RelocInfo->Relocs) % sizeof (UINT16) == 0,
|
||||||
|
"The division below is inaccurate."
|
||||||
|
);
|
||||||
|
|
||||||
|
Overflow = BaseOverflowMulU32 (
|
||||||
|
RelocDirSize,
|
||||||
|
sizeof (*RelocInfo->Relocs) / sizeof (UINT16),
|
||||||
|
&ToolRelocsSize
|
||||||
|
);
|
||||||
|
if (Overflow) {
|
||||||
|
DEBUG_RAISE ();
|
||||||
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
|
RelocInfo->Relocs = AllocateZeroPool (ToolRelocsSize);
|
||||||
if (RelocInfo->Relocs == NULL) {
|
if (RelocInfo->Relocs == NULL) {
|
||||||
fprintf (stderr, "ImageTool: Could not allocate memory for Relocs[]\n");
|
fprintf (stderr, "ImageTool: Could not allocate memory for Relocs[]\n");
|
||||||
return false;
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
TopOfRelocDir = RelocBlockRva + RelocDirSize;
|
TopOfRelocDir = RelocBlockRva + RelocDirSize;
|
||||||
@ -65,7 +80,7 @@ ScanPeGetRelocInfo (
|
|||||||
);
|
);
|
||||||
if (Overflow) {
|
if (Overflow) {
|
||||||
fprintf (stderr, "ImageTool: Overflow during TopOfRelocDir calculation\n");
|
fprintf (stderr, "ImageTool: Overflow during TopOfRelocDir calculation\n");
|
||||||
return false;
|
return RETURN_VOLUME_CORRUPTED;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Apply all Base Relocations of the Image.
|
// Apply all Base Relocations of the Image.
|
||||||
@ -83,7 +98,7 @@ ScanPeGetRelocInfo (
|
|||||||
);
|
);
|
||||||
if (Overflow) {
|
if (Overflow) {
|
||||||
fprintf (stderr, "ImageTool: Overflow during SizeOfRelocs calculation\n");
|
fprintf (stderr, "ImageTool: Overflow during SizeOfRelocs calculation\n");
|
||||||
return false;
|
return RETURN_VOLUME_CORRUPTED;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// Verify the Base Relocation Block is in bounds of the Relocation
|
// Verify the Base Relocation Block is in bounds of the Relocation
|
||||||
@ -91,7 +106,7 @@ ScanPeGetRelocInfo (
|
|||||||
//
|
//
|
||||||
if (SizeOfRelocs > RelocBlockRvaMax - RelocBlockRva) {
|
if (SizeOfRelocs > RelocBlockRvaMax - RelocBlockRva) {
|
||||||
fprintf (stderr, "ImageTool: Base Relocation Block is out of bounds of the Relocation Directory\n");
|
fprintf (stderr, "ImageTool: Base Relocation Block is out of bounds of the Relocation Directory\n");
|
||||||
return false;
|
return RETURN_VOLUME_CORRUPTED;
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
// This arithmetic cannot overflow because we know
|
// This arithmetic cannot overflow because we know
|
||||||
@ -113,7 +128,6 @@ ScanPeGetRelocInfo (
|
|||||||
RelocType = IMAGE_RELOC_TYPE (RelocBlock->Relocations[RelocIndex]);
|
RelocType = IMAGE_RELOC_TYPE (RelocBlock->Relocations[RelocIndex]);
|
||||||
RelocOffset = IMAGE_RELOC_OFFSET (RelocBlock->Relocations[RelocIndex]);
|
RelocOffset = IMAGE_RELOC_OFFSET (RelocBlock->Relocations[RelocIndex]);
|
||||||
|
|
||||||
// FIXME: Make separate functions for UE
|
|
||||||
switch (RelocType) {
|
switch (RelocType) {
|
||||||
case EFI_IMAGE_REL_BASED_ABSOLUTE:
|
case EFI_IMAGE_REL_BASED_ABSOLUTE:
|
||||||
continue;
|
continue;
|
||||||
@ -123,7 +137,7 @@ ScanPeGetRelocInfo (
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
fprintf (stderr, "ImageTool: Unknown RelocType = 0x%x\n", RelocType);
|
fprintf (stderr, "ImageTool: Unknown RelocType = 0x%x\n", RelocType);
|
||||||
return false;
|
return RETURN_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
RelocInfo->Relocs[RelocInfo->NumRelocs].Target = RelocBlock->VirtualAddress + RelocOffset;
|
RelocInfo->Relocs[RelocInfo->NumRelocs].Target = RelocBlock->VirtualAddress + RelocOffset;
|
||||||
@ -140,13 +154,13 @@ ScanPeGetRelocInfo (
|
|||||||
//
|
//
|
||||||
if (RelocBlockRva != TopOfRelocDir) {
|
if (RelocBlockRva != TopOfRelocDir) {
|
||||||
fprintf (stderr, "ImageTool: Relocation Directory size does not match the contained data\n");
|
fprintf (stderr, "ImageTool: Relocation Directory size does not match the contained data\n");
|
||||||
return false;
|
return RETURN_VOLUME_CORRUPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
RETURN_STATUS
|
||||||
ScanPeGetSegmentInfo (
|
ScanPeGetSegmentInfo (
|
||||||
OUT image_tool_segment_info_t *SegmentInfo,
|
OUT image_tool_segment_info_t *SegmentInfo,
|
||||||
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context
|
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context
|
||||||
@ -158,15 +172,19 @@ ScanPeGetSegmentInfo (
|
|||||||
const char *ImageBuffer;
|
const char *ImageBuffer;
|
||||||
uint32_t Index;
|
uint32_t Index;
|
||||||
|
|
||||||
assert (SegmentInfo != NULL);
|
|
||||||
assert (Context != NULL);
|
|
||||||
|
|
||||||
NumSections = PeCoffGetSectionTable (Context, &Section);
|
NumSections = PeCoffGetSectionTable (Context, &Section);
|
||||||
|
|
||||||
SegmentInfo->Segments = calloc (NumSections, sizeof (*SegmentInfo->Segments));
|
STATIC_ASSERT (
|
||||||
|
sizeof (*SegmentInfo->Segments) <= sizeof (*Section),
|
||||||
|
"The multiplication below may overflow."
|
||||||
|
);
|
||||||
|
|
||||||
|
SegmentInfo->Segments = AllocateZeroPool (
|
||||||
|
NumSections * sizeof (*SegmentInfo->Segments)
|
||||||
|
);
|
||||||
if (SegmentInfo->Segments == NULL) {
|
if (SegmentInfo->Segments == NULL) {
|
||||||
fprintf (stderr, "ImageTool: Could not allocate memory for Segments[]\n");
|
fprintf (stderr, "ImageTool: Could not allocate memory for Segments[]\n");
|
||||||
return false;
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageBuffer = (char *)PeCoffLoaderGetImageAddress (Context);
|
ImageBuffer = (char *)PeCoffLoaderGetImageAddress (Context);
|
||||||
@ -184,112 +202,35 @@ ScanPeGetSegmentInfo (
|
|||||||
&& memcmp (Section->Name, PE_COFF_SECT_NAME_RELOC, sizeof (Section->Name)) != 0
|
&& memcmp (Section->Name, PE_COFF_SECT_NAME_RELOC, sizeof (Section->Name)) != 0
|
||||||
&& memcmp (Section->Name, PE_COFF_SECT_NAME_RESRC, sizeof (Section->Name)) != 0
|
&& memcmp (Section->Name, PE_COFF_SECT_NAME_RESRC, sizeof (Section->Name)) != 0
|
||||||
&& memcmp (Section->Name, PE_COFF_SECT_NAME_DEBUG, sizeof (Section->Name)) != 0) {
|
&& memcmp (Section->Name, PE_COFF_SECT_NAME_DEBUG, sizeof (Section->Name)) != 0) {
|
||||||
ImageSegment->Name = calloc (1, sizeof (Section->Name));
|
ImageSegment->Name = AllocateCopyPool (
|
||||||
|
sizeof (Section->Name),
|
||||||
|
Section->Name
|
||||||
|
);
|
||||||
if (ImageSegment->Name == NULL) {
|
if (ImageSegment->Name == NULL) {
|
||||||
fprintf (stderr, "ImageTool: Could not allocate memory for Segment Name\n");
|
fprintf (stderr, "ImageTool: Could not allocate memory for Segment Name\n");
|
||||||
return false;
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
memmove (ImageSegment->Name, Section->Name, sizeof (Section->Name));
|
|
||||||
|
|
||||||
ImageSegment->ImageAddress = Section->VirtualAddress;
|
ImageSegment->ImageAddress = Section->VirtualAddress;
|
||||||
ImageSegment->ImageSize = ALIGN_VALUE (Section->VirtualSize, SegmentInfo->SegmentAlignment);
|
ImageSegment->ImageSize = ALIGN_VALUE (Section->VirtualSize, SegmentInfo->SegmentAlignment);
|
||||||
ImageSegment->Read = (Section->Characteristics & EFI_IMAGE_SCN_MEM_READ) != 0;
|
ImageSegment->Read = (Section->Characteristics & EFI_IMAGE_SCN_MEM_READ) != 0;
|
||||||
ImageSegment->Write = (Section->Characteristics & EFI_IMAGE_SCN_MEM_WRITE) != 0;
|
ImageSegment->Write = (Section->Characteristics & EFI_IMAGE_SCN_MEM_WRITE) != 0;
|
||||||
ImageSegment->Execute = (Section->Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) != 0;
|
ImageSegment->Execute = (Section->Characteristics & EFI_IMAGE_SCN_MEM_EXECUTE) != 0;
|
||||||
|
|
||||||
ImageSegment->Data = malloc (ImageSegment->ImageSize);
|
ImageSegment->Data = AllocateCopyPool (
|
||||||
|
ImageSegment->ImageSize,
|
||||||
|
ImageBuffer + Section->VirtualAddress
|
||||||
|
);
|
||||||
if (ImageSegment->Data == NULL) {
|
if (ImageSegment->Data == NULL) {
|
||||||
fprintf (stderr, "ImageTool: Could not allocate memory for Segment Data\n");
|
fprintf (stderr, "ImageTool: Could not allocate memory for Segment Data\n");
|
||||||
free (ImageSegment->Name);
|
FreePool (ImageSegment->Name);
|
||||||
return false;
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
memmove (
|
|
||||||
ImageSegment->Data,
|
|
||||||
ImageBuffer + Section->VirtualAddress,
|
|
||||||
ImageSegment->ImageSize
|
|
||||||
);
|
|
||||||
|
|
||||||
++SegmentInfo->NumSegments;
|
++SegmentInfo->NumSegments;
|
||||||
++ImageSegment;
|
++ImageSegment;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return RETURN_SUCCESS;
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ScanPeGetDebugInfo (
|
|
||||||
OUT image_tool_debug_info_t *DebugInfo,
|
|
||||||
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context
|
|
||||||
)
|
|
||||||
{
|
|
||||||
const CHAR8 *PdbPath;
|
|
||||||
UINT32 PdbPathSize;
|
|
||||||
RETURN_STATUS Status;
|
|
||||||
|
|
||||||
assert (DebugInfo != NULL);
|
|
||||||
assert (Context != NULL);
|
|
||||||
|
|
||||||
Status = PeCoffGetPdbPath (Context, &PdbPath, &PdbPathSize);
|
|
||||||
if (Status == RETURN_NOT_FOUND) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (RETURN_ERROR (Status)) {
|
|
||||||
fprintf (stderr, "ImageTool: Could not get PdbPath\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DebugInfo->SymbolsPath = malloc (PdbPathSize);
|
|
||||||
if (DebugInfo->SymbolsPath == NULL) {
|
|
||||||
fprintf (stderr, "ImageTool: Could not allocate memory for SymbolsPath\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
memmove (DebugInfo->SymbolsPath, PdbPath, PdbPathSize);
|
|
||||||
|
|
||||||
assert (PdbPathSize >= 1);
|
|
||||||
assert (DebugInfo->SymbolsPath[PdbPathSize - 1] == '\0');
|
|
||||||
|
|
||||||
DebugInfo->SymbolsPathLen = PdbPathSize - 1;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
ScanPeGetHiiInfo (
|
|
||||||
OUT image_tool_hii_info_t *HiiInfo,
|
|
||||||
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context
|
|
||||||
)
|
|
||||||
{
|
|
||||||
UINT32 HiiRva;
|
|
||||||
UINT32 HiiSize;
|
|
||||||
RETURN_STATUS Status;
|
|
||||||
const char *ImageBuffer;
|
|
||||||
|
|
||||||
assert (HiiInfo != NULL);
|
|
||||||
assert (Context != NULL);
|
|
||||||
|
|
||||||
Status = PeCoffGetHiiDataRva (Context, &HiiRva, &HiiSize);
|
|
||||||
if (Status == RETURN_NOT_FOUND) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (RETURN_ERROR (Status)) {
|
|
||||||
fprintf (stderr, "ImageTool: Could not get HiiRva\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
HiiInfo->Data = calloc (1, HiiSize);
|
|
||||||
if (HiiInfo->Data == NULL) {
|
|
||||||
fprintf (stderr, "ImageTool: Could not allocate memory for HiiInfo Data\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageBuffer = (char *)PeCoffLoaderGetImageAddress (Context);
|
|
||||||
|
|
||||||
memmove (HiiInfo->Data, ImageBuffer + HiiRva, HiiSize);
|
|
||||||
HiiInfo->DataSize = HiiSize;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
@ -8,13 +8,13 @@
|
|||||||
|
|
||||||
#include "ImageTool.h"
|
#include "ImageTool.h"
|
||||||
|
|
||||||
bool
|
RETURN_STATUS
|
||||||
ScanPeGetRelocInfo (
|
ScanPeGetRelocInfo (
|
||||||
OUT image_tool_reloc_info_t *RelocInfo,
|
OUT image_tool_reloc_info_t *RelocInfo,
|
||||||
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context
|
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context
|
||||||
);
|
);
|
||||||
|
|
||||||
bool
|
RETURN_STATUS
|
||||||
ScanPeGetSegmentInfo (
|
ScanPeGetSegmentInfo (
|
||||||
OUT image_tool_segment_info_t *SegmentInfo,
|
OUT image_tool_segment_info_t *SegmentInfo,
|
||||||
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context
|
IN PE_COFF_LOADER_IMAGE_CONTEXT *Context
|
||||||
|
@ -25,8 +25,6 @@ ScanUefiImageGetHeaderInfo (
|
|||||||
HeaderInfo->EntryPointAddress = UefiImageGetEntryPointAddress (Context);
|
HeaderInfo->EntryPointAddress = UefiImageGetEntryPointAddress (Context);
|
||||||
HeaderInfo->Machine = UefiImageGetMachine (Context);
|
HeaderInfo->Machine = UefiImageGetMachine (Context);
|
||||||
HeaderInfo->Subsystem = UefiImageGetSubsystem (Context);
|
HeaderInfo->Subsystem = UefiImageGetSubsystem (Context);
|
||||||
// FIXME:
|
|
||||||
HeaderInfo->IsXip = true;
|
|
||||||
|
|
||||||
Status = UefiImageGetFixedAddress (Context, &Address);
|
Status = UefiImageGetFixedAddress (Context, &Address);
|
||||||
if (!RETURN_ERROR (Status)) {
|
if (!RETURN_ERROR (Status)) {
|
||||||
@ -47,7 +45,7 @@ ScanUefiImageGetHeaderInfo (
|
|||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
bool
|
RETURN_STATUS
|
||||||
ScanUefiImageGetRelocInfo (
|
ScanUefiImageGetRelocInfo (
|
||||||
OUT image_tool_reloc_info_t *RelocInfo,
|
OUT image_tool_reloc_info_t *RelocInfo,
|
||||||
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||||
@ -55,9 +53,6 @@ ScanUefiImageGetRelocInfo (
|
|||||||
{
|
{
|
||||||
UINT8 FormatIndex;
|
UINT8 FormatIndex;
|
||||||
|
|
||||||
assert (RelocInfo != NULL);
|
|
||||||
assert (Context != NULL);
|
|
||||||
|
|
||||||
FormatIndex = UefiImageGetFormat (Context);
|
FormatIndex = UefiImageGetFormat (Context);
|
||||||
|
|
||||||
RelocInfo->RelocsStripped = UefiImageGetRelocsStripped (Context);
|
RelocInfo->RelocsStripped = UefiImageGetRelocsStripped (Context);
|
||||||
@ -71,11 +66,11 @@ ScanUefiImageGetRelocInfo (
|
|||||||
"ImageTool: Unsupported UefiImage format %u\n",
|
"ImageTool: Unsupported UefiImage format %u\n",
|
||||||
FormatIndex
|
FormatIndex
|
||||||
);
|
);
|
||||||
return false;
|
return RETURN_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
bool
|
RETURN_STATUS
|
||||||
ScanUefiImageGetSegmentInfo (
|
ScanUefiImageGetSegmentInfo (
|
||||||
OUT image_tool_segment_info_t *SegmentInfo,
|
OUT image_tool_segment_info_t *SegmentInfo,
|
||||||
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||||
@ -83,9 +78,6 @@ ScanUefiImageGetSegmentInfo (
|
|||||||
{
|
{
|
||||||
UINT8 FormatIndex;
|
UINT8 FormatIndex;
|
||||||
|
|
||||||
assert (SegmentInfo != NULL);
|
|
||||||
assert (Context != NULL);
|
|
||||||
|
|
||||||
FormatIndex = UefiImageGetFormat (Context);
|
FormatIndex = UefiImageGetFormat (Context);
|
||||||
|
|
||||||
SegmentInfo->SegmentAlignment = UefiImageGetSegmentAlignment (Context);
|
SegmentInfo->SegmentAlignment = UefiImageGetSegmentAlignment (Context);
|
||||||
@ -99,10 +91,10 @@ ScanUefiImageGetSegmentInfo (
|
|||||||
"ImageTool: Unsupported UefiImage format %u\n",
|
"ImageTool: Unsupported UefiImage format %u\n",
|
||||||
FormatIndex
|
FormatIndex
|
||||||
);
|
);
|
||||||
return false;
|
return RETURN_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
RETURN_STATUS
|
||||||
ScanUefiImageGetDebugInfo (
|
ScanUefiImageGetDebugInfo (
|
||||||
OUT image_tool_debug_info_t *DebugInfo,
|
OUT image_tool_debug_info_t *DebugInfo,
|
||||||
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||||
@ -112,35 +104,31 @@ ScanUefiImageGetDebugInfo (
|
|||||||
const CHAR8 *SymbolsPath;
|
const CHAR8 *SymbolsPath;
|
||||||
UINT32 SymbolsPathSize;
|
UINT32 SymbolsPathSize;
|
||||||
|
|
||||||
assert (DebugInfo != NULL);
|
|
||||||
assert (Context != NULL);
|
|
||||||
|
|
||||||
Status = UefiImageGetSymbolsPath (Context, &SymbolsPath, &SymbolsPathSize);
|
Status = UefiImageGetSymbolsPath (Context, &SymbolsPath, &SymbolsPathSize);
|
||||||
if (Status == RETURN_NOT_FOUND) {
|
if (Status == RETURN_NOT_FOUND || Status == RETURN_UNSUPPORTED) {
|
||||||
return true;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
if (RETURN_ERROR (Status)) {
|
if (RETURN_ERROR (Status)) {
|
||||||
fprintf (stderr, "ImageTool: Could not get SymbolsPath\n");
|
fprintf (stderr, "ImageTool: Could not get SymbolsPath\n");
|
||||||
return false;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert (SymbolsPathSize >= 1);
|
assert (SymbolsPathSize >= 1);
|
||||||
|
|
||||||
DebugInfo->SymbolsPath = malloc (SymbolsPathSize + 1);
|
DebugInfo->SymbolsPath = AllocateCopyPool (SymbolsPathSize, SymbolsPath);
|
||||||
if (DebugInfo->SymbolsPath == NULL) {
|
if (DebugInfo->SymbolsPath == NULL) {
|
||||||
fprintf (stderr, "ImageTool: Could not allocate memory for SymbolsPath\n");
|
fprintf (stderr, "ImageTool: Could not allocate memory for SymbolsPath\n");
|
||||||
return false;
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
|
|
||||||
memmove (DebugInfo->SymbolsPath, SymbolsPath, SymbolsPathSize);
|
|
||||||
assert (DebugInfo->SymbolsPath[SymbolsPathSize - 1] == '\0');
|
assert (DebugInfo->SymbolsPath[SymbolsPathSize - 1] == '\0');
|
||||||
|
|
||||||
DebugInfo->SymbolsPathLen = SymbolsPathSize - 1;
|
DebugInfo->SymbolsPathLen = SymbolsPathSize - 1;
|
||||||
|
|
||||||
return true;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
RETURN_STATUS
|
||||||
ScanUefiImageGetHiiInfo (
|
ScanUefiImageGetHiiInfo (
|
||||||
OUT image_tool_hii_info_t *HiiInfo,
|
OUT image_tool_hii_info_t *HiiInfo,
|
||||||
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
IN UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context
|
||||||
@ -151,30 +139,26 @@ ScanUefiImageGetHiiInfo (
|
|||||||
UINT32 HiiSize;
|
UINT32 HiiSize;
|
||||||
const char *ImageBuffer;
|
const char *ImageBuffer;
|
||||||
|
|
||||||
assert (HiiInfo != NULL);
|
|
||||||
assert (Context != NULL);
|
|
||||||
|
|
||||||
Status = UefiImageGetHiiDataRva (Context, &HiiRva, &HiiSize);
|
Status = UefiImageGetHiiDataRva (Context, &HiiRva, &HiiSize);
|
||||||
if (Status == RETURN_NOT_FOUND) {
|
if (Status == RETURN_NOT_FOUND) {
|
||||||
return true;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
if (RETURN_ERROR (Status)) {
|
if (RETURN_ERROR (Status)) {
|
||||||
fprintf (stderr, "ImageTool: Malformed HII data\n");
|
fprintf (stderr, "ImageTool: Malformed HII data\n");
|
||||||
return false;
|
return Status;
|
||||||
}
|
|
||||||
|
|
||||||
HiiInfo->Data = malloc (HiiSize);
|
|
||||||
if (HiiInfo->Data == NULL) {
|
|
||||||
fprintf (stderr, "ImageTool: Could not allocate memory for HiiInfo Data\n");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageBuffer = (char *)UefiImageLoaderGetImageAddress (Context);
|
ImageBuffer = (char *)UefiImageLoaderGetImageAddress (Context);
|
||||||
|
|
||||||
memmove (HiiInfo->Data, ImageBuffer + HiiRva, HiiSize);
|
HiiInfo->Data = AllocateCopyPool (HiiSize, ImageBuffer + HiiRva);
|
||||||
|
if (HiiInfo->Data == NULL) {
|
||||||
|
fprintf (stderr, "ImageTool: Could not allocate memory for HiiInfo Data\n");
|
||||||
|
return RETURN_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
|
||||||
HiiInfo->DataSize = HiiSize;
|
HiiInfo->DataSize = HiiSize;
|
||||||
|
|
||||||
return true;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
RETURN_STATUS
|
RETURN_STATUS
|
||||||
@ -194,7 +178,6 @@ ToolContextConstructUefiImage (
|
|||||||
void *Destination;
|
void *Destination;
|
||||||
bool Success;
|
bool Success;
|
||||||
|
|
||||||
assert (Image != NULL);
|
|
||||||
assert (File != NULL || FileSize == 0);
|
assert (File != NULL || FileSize == 0);
|
||||||
|
|
||||||
if (FileSize > MAX_UINT32) {
|
if (FileSize > MAX_UINT32) {
|
||||||
@ -229,7 +212,7 @@ ToolContextConstructUefiImage (
|
|||||||
if (RETURN_ERROR (Status)) {
|
if (RETURN_ERROR (Status)) {
|
||||||
fprintf (stderr, "ImageTool: Could not Load Image\n");
|
fprintf (stderr, "ImageTool: Could not Load Image\n");
|
||||||
FreeAlignedPages (Destination, DestinationPages);
|
FreeAlignedPages (Destination, DestinationPages);
|
||||||
return RETURN_VOLUME_CORRUPTED;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset (Image, 0, sizeof (*Image));
|
memset (Image, 0, sizeof (*Image));
|
||||||
@ -237,36 +220,41 @@ ToolContextConstructUefiImage (
|
|||||||
Success = ScanUefiImageGetHeaderInfo (&Image->HeaderInfo, &Context);
|
Success = ScanUefiImageGetHeaderInfo (&Image->HeaderInfo, &Context);
|
||||||
if (!Success) {
|
if (!Success) {
|
||||||
fprintf (stderr, "ImageTool: Could not retrieve header info\n");
|
fprintf (stderr, "ImageTool: Could not retrieve header info\n");
|
||||||
|
ToolImageDestruct (Image);
|
||||||
FreeAlignedPages (Destination, DestinationPages);
|
FreeAlignedPages (Destination, DestinationPages);
|
||||||
return RETURN_VOLUME_CORRUPTED;
|
return RETURN_VOLUME_CORRUPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Success = ScanUefiImageGetSegmentInfo (&Image->SegmentInfo, &Context);
|
Status = ScanUefiImageGetSegmentInfo (&Image->SegmentInfo, &Context);
|
||||||
if (!Success) {
|
if (RETURN_ERROR (Status)) {
|
||||||
fprintf (stderr, "ImageTool: Could not retrieve segment info\n");
|
fprintf (stderr, "ImageTool: Could not retrieve segment info\n");
|
||||||
|
ToolImageDestruct (Image);
|
||||||
FreeAlignedPages (Destination, DestinationPages);
|
FreeAlignedPages (Destination, DestinationPages);
|
||||||
return RETURN_VOLUME_CORRUPTED;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Success = ScanUefiImageGetRelocInfo (&Image->RelocInfo, &Context);
|
Status = ScanUefiImageGetRelocInfo (&Image->RelocInfo, &Context);
|
||||||
if (!Success) {
|
if (RETURN_ERROR (Status)) {
|
||||||
fprintf (stderr, "ImageTool: Could not retrieve reloc info\n");
|
fprintf (stderr, "ImageTool: Could not retrieve reloc info\n");
|
||||||
|
ToolImageDestruct (Image);
|
||||||
FreeAlignedPages (Destination, DestinationPages);
|
FreeAlignedPages (Destination, DestinationPages);
|
||||||
return RETURN_VOLUME_CORRUPTED;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Success = ScanUefiImageGetHiiInfo (&Image->HiiInfo, &Context);
|
Status = ScanUefiImageGetHiiInfo (&Image->HiiInfo, &Context);
|
||||||
if (!Success) {
|
if (RETURN_ERROR (Status)) {
|
||||||
fprintf (stderr, "ImageTool: Could not retrieve HII info\n");
|
fprintf (stderr, "ImageTool: Could not retrieve HII info\n");
|
||||||
|
ToolImageDestruct (Image);
|
||||||
FreeAlignedPages (Destination, DestinationPages);
|
FreeAlignedPages (Destination, DestinationPages);
|
||||||
return RETURN_VOLUME_CORRUPTED;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Success = ScanUefiImageGetDebugInfo (&Image->DebugInfo, &Context);
|
Status = ScanUefiImageGetDebugInfo (&Image->DebugInfo, &Context);
|
||||||
if (!Success) {
|
if (RETURN_ERROR (Status)) {
|
||||||
fprintf (stderr, "ImageTool: Could not retrieve debug info\n");
|
fprintf (stderr, "ImageTool: Could not retrieve debug info\n");
|
||||||
|
ToolImageDestruct (Image);
|
||||||
FreeAlignedPages (Destination, DestinationPages);
|
FreeAlignedPages (Destination, DestinationPages);
|
||||||
return RETURN_VOLUME_CORRUPTED;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeAlignedPages (Destination, DestinationPages);
|
FreeAlignedPages (Destination, DestinationPages);
|
||||||
|
@ -42,6 +42,7 @@ OBJECTS += \
|
|||||||
$(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmit64.o \
|
$(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmit64.o \
|
||||||
$(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmitCommon.o \
|
$(EDK2_OBJPATH)/BaseTools/ImageTool/PeEmitCommon.o \
|
||||||
$(EDK2_OBJPATH)/BaseTools/ImageTool/BinEmit.o \
|
$(EDK2_OBJPATH)/BaseTools/ImageTool/BinEmit.o \
|
||||||
|
$(EDK2_OBJPATH)/BaseTools/ImageTool/DynamicBuffer.o \
|
||||||
$(EDK2_OBJPATH)/OpenCorePkg/User/Library/UserFile.o
|
$(EDK2_OBJPATH)/OpenCorePkg/User/Library/UserFile.o
|
||||||
|
|
||||||
OBJECTS += \
|
OBJECTS += \
|
||||||
|
@ -42,6 +42,7 @@ OBJECTS = $(OBJECTS) \
|
|||||||
$(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmit64.obj \
|
$(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmit64.obj \
|
||||||
$(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmitCommon.obj \
|
$(EDK2_OBJPATH)\BaseTools\ImageTool\PeEmitCommon.obj \
|
||||||
$(EDK2_OBJPATH)\BaseTools\ImageTool\BinEmit.obj \
|
$(EDK2_OBJPATH)\BaseTools\ImageTool\BinEmit.obj \
|
||||||
|
$(EDK2_OBJPATH)\BaseTools\ImageTool\DynamicBuffer.obj \
|
||||||
$(EDK2_OBJPATH)\OpenCorePkg\User\Library\UserFile.obj
|
$(EDK2_OBJPATH)\OpenCorePkg\User\Library\UserFile.obj
|
||||||
|
|
||||||
OBJECTS = $(OBJECTS) \
|
OBJECTS = $(OBJECTS) \
|
||||||
|
@ -3741,6 +3741,7 @@ Returns:
|
|||||||
true,
|
true,
|
||||||
NewBaseAddress,
|
NewBaseAddress,
|
||||||
NULL,
|
NULL,
|
||||||
|
TRUE,
|
||||||
Strip,
|
Strip,
|
||||||
FALSE
|
FALSE
|
||||||
);
|
);
|
||||||
|
@ -1456,6 +1456,7 @@ Returns:
|
|||||||
true,
|
true,
|
||||||
NewBaseAddress,
|
NewBaseAddress,
|
||||||
NULL,
|
NULL,
|
||||||
|
TRUE,
|
||||||
FALSE,
|
FALSE,
|
||||||
TRUE
|
TRUE
|
||||||
);
|
);
|
||||||
|
@ -95,6 +95,7 @@ class DataSection (DataSectionClassObject):
|
|||||||
GenFdsGlobalVariable.GenerateFirmwareImage(
|
GenFdsGlobalVariable.GenerateFirmwareImage(
|
||||||
StrippedFile,
|
StrippedFile,
|
||||||
GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict),
|
GenFdsGlobalVariable.MacroExtend(self.SectFileName, Dict),
|
||||||
|
Xip=True,
|
||||||
Strip=True,
|
Strip=True,
|
||||||
IsMakefile = IsMakefile
|
IsMakefile = IsMakefile
|
||||||
)
|
)
|
||||||
|
@ -290,6 +290,7 @@ class EfiSection (EfiSectionClassObject):
|
|||||||
GenFdsGlobalVariable.GenerateFirmwareImage(
|
GenFdsGlobalVariable.GenerateFirmwareImage(
|
||||||
StrippedFile,
|
StrippedFile,
|
||||||
File,
|
File,
|
||||||
|
Xip=True,
|
||||||
Strip=True,
|
Strip=True,
|
||||||
IsMakefile = IsMakefile
|
IsMakefile = IsMakefile
|
||||||
)
|
)
|
||||||
|
@ -793,6 +793,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
|
|||||||
GenFdsGlobalVariable.GenerateFirmwareImage(
|
GenFdsGlobalVariable.GenerateFirmwareImage(
|
||||||
StrippedFile,
|
StrippedFile,
|
||||||
File,
|
File,
|
||||||
|
Xip=True,
|
||||||
Strip=True,
|
Strip=True,
|
||||||
IsMakefile=IsMakefile
|
IsMakefile=IsMakefile
|
||||||
)
|
)
|
||||||
@ -827,6 +828,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
|
|||||||
GenFdsGlobalVariable.GenerateFirmwareImage(
|
GenFdsGlobalVariable.GenerateFirmwareImage(
|
||||||
StrippedFile,
|
StrippedFile,
|
||||||
GenSecInputFile,
|
GenSecInputFile,
|
||||||
|
Xip=True,
|
||||||
Strip=True,
|
Strip=True,
|
||||||
IsMakefile=IsMakefile
|
IsMakefile=IsMakefile
|
||||||
)
|
)
|
||||||
|
@ -607,7 +607,7 @@ class GenFdsGlobalVariable:
|
|||||||
GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV")
|
GenFdsGlobalVariable.CallExternalTool(Cmd, "Failed to generate FV")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def GenerateFirmwareImage(Output, Input, Format="Auto", Strip=False, IsMakefile=False):
|
def GenerateFirmwareImage(Output, Input, Format="Auto", Xip=False, Strip=False, IsMakefile=False):
|
||||||
if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:
|
if not GenFdsGlobalVariable.NeedsUpdate(Output, Input) and not IsMakefile:
|
||||||
return
|
return
|
||||||
GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
|
GenFdsGlobalVariable.DebugLogger(EdkLogger.DEBUG_5, "%s needs update because of newer %s" % (Output, Input))
|
||||||
@ -615,6 +615,8 @@ class GenFdsGlobalVariable:
|
|||||||
Cmd = ["ImageTool GenImage"]
|
Cmd = ["ImageTool GenImage"]
|
||||||
if Format != "Auto":
|
if Format != "Auto":
|
||||||
Cmd += ("-c", Format)
|
Cmd += ("-c", Format)
|
||||||
|
if Xip:
|
||||||
|
Cmd.append("-x")
|
||||||
if Strip:
|
if Strip:
|
||||||
Cmd.append("-s")
|
Cmd.append("-s")
|
||||||
Cmd += ("-o", Output, Input)
|
Cmd += ("-o", Output, Input)
|
||||||
|
@ -642,7 +642,7 @@ class ModuleReport(object):
|
|||||||
if os.path.isfile(DefaultEFIfile):
|
if os.path.isfile(DefaultEFIfile):
|
||||||
Tempfile = os.path.join(OutputDir, self.ModuleName + "_hash.tmp")
|
Tempfile = os.path.join(OutputDir, self.ModuleName + "_hash.tmp")
|
||||||
# rebase the efi image since its base address may not zero
|
# rebase the efi image since its base address may not zero
|
||||||
cmd = ["ImageTool GenImage -b 0 -o", Tempfile, DefaultEFIfile]
|
cmd = ["ImageTool GenImage -x -b 0 -o", Tempfile, DefaultEFIfile]
|
||||||
try:
|
try:
|
||||||
PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
PopenObject = subprocess.Popen(' '.join(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
||||||
except Exception as X:
|
except Exception as X:
|
||||||
|
@ -1542,16 +1542,16 @@ class Build():
|
|||||||
#
|
#
|
||||||
# Update Image to new BaseAddress by ImageTool tool
|
# Update Image to new BaseAddress by ImageTool tool
|
||||||
#
|
#
|
||||||
LaunchCommand(["ImageTool", "GenImage", "-b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.OutputDir)
|
LaunchCommand(["ImageTool", "GenImage", "-x", "-b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.OutputDir)
|
||||||
LaunchCommand(["ImageTool", "GenImage", "-b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.DebugDir)
|
LaunchCommand(["ImageTool", "GenImage", "-x", "-b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.DebugDir)
|
||||||
## for SMM module in SMRAM, the SMRAM will be allocated from base to top.
|
## for SMM module in SMRAM, the SMRAM will be allocated from base to top.
|
||||||
else:
|
else:
|
||||||
BaseAddress = AlignUp(BaseAddress, ModuleInfo.Image.SectionAlignment)
|
BaseAddress = AlignUp(BaseAddress, ModuleInfo.Image.SectionAlignment)
|
||||||
#
|
#
|
||||||
# Set new address to the section header only for SMM driver.
|
# Set new address to the section header only for SMM driver.
|
||||||
#
|
#
|
||||||
LaunchCommand(["ImageTool", "GenImage", "-f -b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.OutputDir)
|
LaunchCommand(["ImageTool", "GenImage", "-x", "-f -b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.OutputDir)
|
||||||
LaunchCommand(["ImageTool", "GenImage", "-f -b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.DebugDir)
|
LaunchCommand(["ImageTool", "GenImage", "-x", "-f -b", str(BaseAddress), "-o", ModuleOutputImage, ModuleOutputImage], ModuleInfo.DebugDir)
|
||||||
#
|
#
|
||||||
# Collect function address from Map file
|
# Collect function address from Map file
|
||||||
#
|
#
|
||||||
|
@ -96,10 +96,10 @@ UefiImageLoaderGetRuntimeContextSizePe (
|
|||||||
|
|
||||||
RETURN_STATUS
|
RETURN_STATUS
|
||||||
UefiImageRelocateImagePe (
|
UefiImageRelocateImagePe (
|
||||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
|
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
|
||||||
IN UINT64 BaseAddress,
|
IN UINT64 BaseAddress,
|
||||||
OUT UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL,
|
OUT VOID *RuntimeContext OPTIONAL,
|
||||||
IN UINT32 RuntimeContextSize
|
IN UINT32 RuntimeContextSize
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return PeCoffRelocateImage (
|
return PeCoffRelocateImage (
|
||||||
|
@ -71,10 +71,10 @@ RETURN_STATUS
|
|||||||
typedef
|
typedef
|
||||||
RETURN_STATUS
|
RETURN_STATUS
|
||||||
(*UEFI_IMAGE_RELOCARE_IMAGE) (
|
(*UEFI_IMAGE_RELOCARE_IMAGE) (
|
||||||
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
|
IN OUT UEFI_IMAGE_LOADER_IMAGE_CONTEXT *Context,
|
||||||
IN UINT64 BaseAddress,
|
IN UINT64 BaseAddress,
|
||||||
OUT UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *RuntimeContext OPTIONAL,
|
OUT VOID *RuntimeContext OPTIONAL,
|
||||||
IN UINT32 RuntimeContextSize
|
IN UINT32 RuntimeContextSize
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef
|
typedef
|
||||||
|
@ -285,12 +285,16 @@ UefiImageRelocateImage (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
RETURN_STATUS Status;
|
RETURN_STATUS Status;
|
||||||
|
VOID *FormatContext;
|
||||||
|
UINT32 FormatContextSize;
|
||||||
|
|
||||||
|
FormatContext = RuntimeContext;
|
||||||
|
FormatContextSize = RuntimeContextSize;
|
||||||
if (RuntimeContext != NULL) {
|
if (RuntimeContext != NULL) {
|
||||||
*(UINT64 *)RuntimeContext = Context->FormatIndex;
|
*(UINT64 *)RuntimeContext = Context->FormatIndex;
|
||||||
RuntimeContext = (UEFI_IMAGE_LOADER_RUNTIME_CONTEXT *)((UINT64 *)RuntimeContext + 1);
|
FormatContext = (VOID *)((UINT64 *)RuntimeContext + 1);
|
||||||
ASSERT (RuntimeContextSize >= 8);
|
ASSERT (FormatContextSize >= 8);
|
||||||
RuntimeContextSize -= 8;
|
FormatContextSize -= 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
UEFI_IMAGE_EXEC (
|
UEFI_IMAGE_EXEC (
|
||||||
@ -299,8 +303,8 @@ UefiImageRelocateImage (
|
|||||||
RelocateImage,
|
RelocateImage,
|
||||||
Context,
|
Context,
|
||||||
BaseAddress,
|
BaseAddress,
|
||||||
RuntimeContext,
|
FormatContext,
|
||||||
RuntimeContextSize
|
FormatContextSize
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!RETURN_ERROR (Status)) {
|
if (!RETURN_ERROR (Status)) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user