summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay Ni <ray.ni@intel.com>2021-06-29 10:43:58 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2021-06-30 07:12:54 +0000
commit939ed3a59223f516e5168577ba61ee3baf98eeea (patch)
tree748dbfc6ae830ba5273a91657891d20bb3ed9fb6
parent580b11201ed001f9533c6782ec87d430b1736040 (diff)
downloadedk2-939ed3a59223f516e5168577ba61ee3baf98eeea.zip
edk2-939ed3a59223f516e5168577ba61ee3baf98eeea.tar.gz
edk2-939ed3a59223f516e5168577ba61ee3baf98eeea.tar.bz2
UefiPayloadPkg/PayloadLoader: Fix bug in locating relocation section
Per ELF spec, the DT_REL/DT_RELA tag in dynamic section stores the virtual address of the relocation section. But today's code logic treats it as the section offset and finds the relocation section whose offset equals to DT_REL/DT_RELA. The logic can work when the section offset equals to the section virtual address. But when the ELF is generated from the link script that reserves a sizeof(pe_header) in the file beginning, the section offset doesn't equal to section virtual address. Such logic can not find the relocation section. The patch fixes this bug. Signed-off-by: Ray Ni <ray.ni@intel.com> Cc: Maurice Ma <maurice.ma@intel.com> Reviewed-by: Guo Dong <guo.dong@intel.com> Cc: Benjamin You <benjamin.you@intel.com>
-rw-r--r--UefiPayloadPkg/PayloadLoaderPeim/ElfLib/Elf32Lib.c22
-rw-r--r--UefiPayloadPkg/PayloadLoaderPeim/ElfLib/Elf64Lib.c22
2 files changed, 30 insertions, 14 deletions
diff --git a/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/Elf32Lib.c b/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/Elf32Lib.c
index 3fa100c..dd27d3c 100644
--- a/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/Elf32Lib.c
+++ b/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/Elf32Lib.c
@@ -206,7 +206,7 @@ RelocateElf32Dynamic (
Elf32_Shdr *DynShdr;
Elf32_Shdr *RelShdr;
Elf32_Dyn *Dyn;
- UINT32 RelaOffset;
+ UINT32 RelaAddress;
UINT32 RelaCount;
UINT32 RelaSize;
UINT32 RelaEntrySize;
@@ -246,7 +246,7 @@ RelocateElf32Dynamic (
//
// 2. Locate the relocation section from the dynamic section.
//
- RelaOffset = MAX_UINT32;
+ RelaAddress = MAX_UINT32;
RelaSize = 0;
RelaCount = 0;
RelaEntrySize = 0;
@@ -265,8 +265,8 @@ RelocateElf32Dynamic (
// based on the original file value and the memory base address.
// For consistency, files do not contain relocation entries to ``correct'' addresses in the dynamic structure.
//
- RelaOffset = Dyn->d_un.d_ptr - (UINT32) (UINTN) ElfCt->PreferredImageAddress;
- RelaType = (Dyn->d_tag == DT_RELA) ? SHT_RELA: SHT_REL;
+ RelaAddress = Dyn->d_un.d_ptr;
+ RelaType = (Dyn->d_tag == DT_RELA) ? SHT_RELA: SHT_REL;
break;
case DT_RELACOUNT:
case DT_RELCOUNT:
@@ -285,7 +285,7 @@ RelocateElf32Dynamic (
}
}
- if (RelaOffset == MAX_UINT64) {
+ if (RelaAddress == MAX_UINT64) {
ASSERT (RelaCount == 0);
ASSERT (RelaEntrySize == 0);
ASSERT (RelaSize == 0);
@@ -298,8 +298,16 @@ RelocateElf32Dynamic (
//
// Verify the existence of the relocation section.
//
- RelShdr = GetElf32SectionByRange (ElfCt->FileBase, RelaOffset, RelaSize);
- ASSERT (RelShdr != NULL);
+ RelShdr = NULL;
+ for (Index = 0; Index < ElfCt->ShNum; Index++) {
+ RelShdr = GetElf32SectionByIndex (ElfCt->FileBase, Index);
+ ASSERT (RelShdr != NULL);
+ if ((RelShdr->sh_addr == RelaAddress) && (RelShdr->sh_size == RelaSize)) {
+ break;
+ }
+ RelShdr = NULL;
+ }
+
if (RelShdr == NULL) {
return EFI_UNSUPPORTED;
}
diff --git a/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/Elf64Lib.c b/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/Elf64Lib.c
index e364807..3f4f129 100644
--- a/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/Elf64Lib.c
+++ b/UefiPayloadPkg/PayloadLoaderPeim/ElfLib/Elf64Lib.c
@@ -215,7 +215,7 @@ RelocateElf64Dynamic (
Elf64_Shdr *DynShdr;
Elf64_Shdr *RelShdr;
Elf64_Dyn *Dyn;
- UINT64 RelaOffset;
+ UINT64 RelaAddress;
UINT64 RelaCount;
UINT64 RelaSize;
UINT64 RelaEntrySize;
@@ -255,7 +255,7 @@ RelocateElf64Dynamic (
//
// 2. Locate the relocation section from the dynamic section.
//
- RelaOffset = MAX_UINT64;
+ RelaAddress = MAX_UINT64;
RelaSize = 0;
RelaCount = 0;
RelaEntrySize = 0;
@@ -274,8 +274,8 @@ RelocateElf64Dynamic (
// based on the original file value and the memory base address.
// For consistency, files do not contain relocation entries to ``correct'' addresses in the dynamic structure.
//
- RelaOffset = Dyn->d_un.d_ptr - (UINTN) ElfCt->PreferredImageAddress;
- RelaType = (Dyn->d_tag == DT_RELA) ? SHT_RELA: SHT_REL;
+ RelaAddress = Dyn->d_un.d_ptr;
+ RelaType = (Dyn->d_tag == DT_RELA) ? SHT_RELA: SHT_REL;
break;
case DT_RELACOUNT:
case DT_RELCOUNT:
@@ -294,7 +294,7 @@ RelocateElf64Dynamic (
}
}
- if (RelaOffset == MAX_UINT64) {
+ if (RelaAddress == MAX_UINT64) {
ASSERT (RelaCount == 0);
ASSERT (RelaEntrySize == 0);
ASSERT (RelaSize == 0);
@@ -307,8 +307,16 @@ RelocateElf64Dynamic (
//
// Verify the existence of the relocation section.
//
- RelShdr = GetElf64SectionByRange (ElfCt->FileBase, RelaOffset, RelaSize);
- ASSERT (RelShdr != NULL);
+ RelShdr = NULL;
+ for (Index = 0; Index < ElfCt->ShNum; Index++) {
+ RelShdr = GetElf64SectionByIndex (ElfCt->FileBase, Index);
+ ASSERT (RelShdr != NULL);
+ if ((RelShdr->sh_addr == RelaAddress) && (RelShdr->sh_size == RelaSize)) {
+ break;
+ }
+ RelShdr = NULL;
+ }
+
if (RelShdr == NULL) {
return EFI_UNSUPPORTED;
}