From b4bcef368160651ce8631398eb06cd716113c949 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marvin=20Ha=CC=88user?= <8659494+mhaeuser@users.noreply.github.com> Date: Sat, 15 Apr 2023 13:44:23 +0200 Subject: [PATCH] ImageTool: Properly handle ELF base address --- BaseTools/ImageTool/ElfScan.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/BaseTools/ImageTool/ElfScan.c b/BaseTools/ImageTool/ElfScan.c index 2810b08b96..622a2d8966 100644 --- a/BaseTools/ImageTool/ElfScan.c +++ b/BaseTools/ImageTool/ElfScan.c @@ -7,6 +7,7 @@ static Elf_Ehdr *mEhdr = NULL; static Elf_Size mPeAlignment = 0x0; +static Elf_Addr mBaseAddress = 0x0; #if defined (_MSC_EXTENSIONS) #define EFI_IMAGE_MACHINE_IA32 0x014C @@ -218,6 +219,7 @@ ParseElfFile ( // // Check section headers // + mBaseAddress = ~(Elf_Addr)0; for (Index = 0; Index < mEhdr->e_shnum; ++Index) { Offset = (UINTN)mEhdr->e_shoff + Index * mEhdr->e_shentsize; @@ -245,6 +247,10 @@ ParseElfFile ( return RETURN_VOLUME_CORRUPTED; } + if (Shdr->sh_addr < mBaseAddress) { + mBaseAddress = Shdr->sh_addr; + } + if (Shdr->sh_addralign <= mPeAlignment) { continue; } @@ -329,14 +335,14 @@ SetRelocs ( New = TRUE; for (Index2 = 0; Index2 < RelNum; ++Index2) { - if (((uint32_t)Rel->r_offset) == mImageInfo.RelocInfo.Relocs[Index2].Target) { + if (((uint32_t)Rel->r_offset) == mBaseAddress + mImageInfo.RelocInfo.Relocs[Index2].Target) { New = FALSE; } } if (New) { mImageInfo.RelocInfo.Relocs[RelNum].Type = EFI_IMAGE_REL_BASED_DIR64; - mImageInfo.RelocInfo.Relocs[RelNum].Target = (uint32_t)Rel->r_offset; + mImageInfo.RelocInfo.Relocs[RelNum].Target = (uint32_t)(Rel->r_offset - mBaseAddress); ++RelNum; } @@ -344,7 +350,7 @@ SetRelocs ( case R_X86_64_32: mImageInfo.RelocInfo.Relocs[RelNum].Type = EFI_IMAGE_REL_BASED_HIGHLOW; - mImageInfo.RelocInfo.Relocs[RelNum].Target = (uint32_t)Rel->r_offset; + mImageInfo.RelocInfo.Relocs[RelNum].Target = (uint32_t)(Rel->r_offset - mBaseAddress); ++RelNum; break; @@ -403,14 +409,14 @@ SetRelocs ( New = TRUE; for (Index2 = 0; Index2 < RelNum; ++Index2) { - if (((uint32_t)Rel->r_offset) == mImageInfo.RelocInfo.Relocs[Index2].Target) { + if (((uint32_t)Rel->r_offset) == mBaseAddress + mImageInfo.RelocInfo.Relocs[Index2].Target) { New = FALSE; } } if (New) { mImageInfo.RelocInfo.Relocs[RelNum].Type = EFI_IMAGE_REL_BASED_DIR64; - mImageInfo.RelocInfo.Relocs[RelNum].Target = (uint32_t)Rel->r_offset; + mImageInfo.RelocInfo.Relocs[RelNum].Target = (uint32_t)(Rel->r_offset - mBaseAddress); ++RelNum; } @@ -418,7 +424,7 @@ SetRelocs ( case R_AARCH64_ABS32: mImageInfo.RelocInfo.Relocs[RelNum].Type = EFI_IMAGE_REL_BASED_HIGHLOW; - mImageInfo.RelocInfo.Relocs[RelNum].Target = (uint32_t)Rel->r_offset; + mImageInfo.RelocInfo.Relocs[RelNum].Target = (uint32_t)(Rel->r_offset - mBaseAddress); ++RelNum; break; @@ -435,7 +441,7 @@ SetRelocs ( case R_386_32: mImageInfo.RelocInfo.Relocs[RelNum].Type = EFI_IMAGE_REL_BASED_HIGHLOW; - mImageInfo.RelocInfo.Relocs[RelNum].Target = Rel->r_offset; + mImageInfo.RelocInfo.Relocs[RelNum].Target = (Rel->r_offset - mBaseAddress); ++RelNum; break; @@ -488,7 +494,7 @@ SetRelocs ( case R_ARM_ABS32: mImageInfo.RelocInfo.Relocs[RelNum].Type = EFI_IMAGE_REL_BASED_HIGHLOW; - mImageInfo.RelocInfo.Relocs[RelNum].Target = Rel->r_offset; + mImageInfo.RelocInfo.Relocs[RelNum].Target = (Rel->r_offset - mBaseAddress); ++RelNum; break; @@ -620,7 +626,7 @@ CreateIntermediate ( memcpy (Segments[SIndex].Data, (UINT8 *)mEhdr + Shdr->sh_offset, (size_t)Shdr->sh_size); - Segments[SIndex].ImageAddress = Shdr->sh_addr; + Segments[SIndex].ImageAddress = Shdr->sh_addr - mBaseAddress; Segments[SIndex].ImageSize = Segments[SIndex].DataSize; Segments[SIndex].Read = true; Segments[SIndex].Write = false; @@ -654,7 +660,7 @@ CreateIntermediate ( memcpy (Segments[SIndex].Data, (UINT8 *)mEhdr + Shdr->sh_offset, (size_t)Shdr->sh_size); } - Segments[SIndex].ImageAddress = Shdr->sh_addr; + Segments[SIndex].ImageAddress = Shdr->sh_addr - mBaseAddress; Segments[SIndex].ImageSize = Segments[SIndex].DataSize; Segments[SIndex].Read = true; Segments[SIndex].Write = true; @@ -673,7 +679,7 @@ CreateIntermediate ( if (Shdr->sh_type == SHT_PROGBITS) { memcpy (mImageInfo.HiiInfo.Data, (UINT8 *)mEhdr + Shdr->sh_offset, (size_t)Shdr->sh_size); - SetHiiResourceHeader (mImageInfo.HiiInfo.Data, (UINT32)Shdr->sh_addr); + SetHiiResourceHeader (mImageInfo.HiiInfo.Data, (UINT32)(Shdr->sh_addr - mBaseAddress)); } } else if ((Shdr->sh_flags & SHF_ALLOC) != 0) { fprintf (stderr, "ImageTool: Unknown SHF_ALLOC Section %d\n", SIndex); @@ -704,8 +710,8 @@ ScanElf ( memset (&mImageInfo, 0, sizeof (mImageInfo)); - mImageInfo.HeaderInfo.BaseAddress = 0; - mImageInfo.HeaderInfo.EntryPointAddress = (uint32_t)mEhdr->e_entry; + mImageInfo.HeaderInfo.BaseAddress = mBaseAddress; + mImageInfo.HeaderInfo.EntryPointAddress = (uint32_t)(mEhdr->e_entry - mBaseAddress); mImageInfo.HeaderInfo.IsXip = true; mImageInfo.SegmentInfo.SegmentAlignment = (uint32_t)mPeAlignment; mImageInfo.RelocInfo.RelocsStripped = false;