mirror of
https://github.com/acidanthera/audk.git
synced 2025-09-24 18:27:49 +02:00
ImageTool: Prefer ELF PIE over object file relocations
This commit is contained in:
parent
dac1ed6cb9
commit
92bb32130b
@ -8,6 +8,7 @@
|
|||||||
static Elf_Ehdr *mEhdr = NULL;
|
static Elf_Ehdr *mEhdr = NULL;
|
||||||
static Elf_Size mPeAlignment = 0x0;
|
static Elf_Size mPeAlignment = 0x0;
|
||||||
static Elf_Addr mBaseAddress = 0x0;
|
static Elf_Addr mBaseAddress = 0x0;
|
||||||
|
static bool mHasPieRelocs = FALSE;
|
||||||
|
|
||||||
#if defined (_MSC_EXTENSIONS)
|
#if defined (_MSC_EXTENSIONS)
|
||||||
#define EFI_IMAGE_MACHINE_IA32 0x014C
|
#define EFI_IMAGE_MACHINE_IA32 0x014C
|
||||||
@ -228,6 +229,10 @@ ParseElfFile (
|
|||||||
fprintf (stderr, "ImageTool: ELF %d-th section's sh_info is out of range\n", Index);
|
fprintf (stderr, "ImageTool: ELF %d-th section's sh_info is out of range\n", Index);
|
||||||
return RETURN_VOLUME_CORRUPTED;
|
return RETURN_VOLUME_CORRUPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Shdr->sh_info == 0) {
|
||||||
|
mHasPieRelocs = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Shdr->sh_addr < mBaseAddress) {
|
if (Shdr->sh_addr < mBaseAddress) {
|
||||||
@ -268,6 +273,38 @@ ParseElfFile (
|
|||||||
return RETURN_SUCCESS;
|
return RETURN_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
bool
|
||||||
|
ProcessRelocSection (
|
||||||
|
const Elf_Shdr *Shdr
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const Elf_Shdr *SecShdr;
|
||||||
|
//
|
||||||
|
// PIE relocations will target dummy section 0.
|
||||||
|
//
|
||||||
|
if (Shdr->sh_info != 0) {
|
||||||
|
//
|
||||||
|
// If PIE relocations exist, prefer them.
|
||||||
|
//
|
||||||
|
if (mHasPieRelocs) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Only translate relocations targetting sections that are translated.
|
||||||
|
//
|
||||||
|
SecShdr = GetShdrByIndex (Shdr->sh_info);
|
||||||
|
|
||||||
|
if (!IsShdrLoadable (SecShdr)) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
assert (mHasPieRelocs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
RETURN_STATUS
|
RETURN_STATUS
|
||||||
SetRelocs (
|
SetRelocs (
|
||||||
@ -276,14 +313,9 @@ SetRelocs (
|
|||||||
{
|
{
|
||||||
UINT32 Index;
|
UINT32 Index;
|
||||||
const Elf_Shdr *RelShdr;
|
const Elf_Shdr *RelShdr;
|
||||||
const Elf_Shdr *SecShdr;
|
|
||||||
UINTN RelIdx;
|
UINTN RelIdx;
|
||||||
const Elf_Rela *Rel;
|
const Elf_Rela *Rel;
|
||||||
UINT32 RelNum;
|
UINT32 RelNum;
|
||||||
#if defined(EFI_TARGET64)
|
|
||||||
UINT32 Index2;
|
|
||||||
BOOLEAN New;
|
|
||||||
#endif
|
|
||||||
RelNum = 0;
|
RelNum = 0;
|
||||||
|
|
||||||
for (Index = 0; Index < mEhdr->e_shnum; Index++) {
|
for (Index = 0; Index < mEhdr->e_shnum; Index++) {
|
||||||
@ -293,19 +325,9 @@ SetRelocs (
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
if (!ProcessRelocSection (RelShdr)) {
|
||||||
// PIE relocations will target dummy section 0.
|
|
||||||
//
|
|
||||||
if (RelShdr->sh_info != 0) {
|
|
||||||
//
|
|
||||||
// Only translate relocations targetting sections that are translated.
|
|
||||||
//
|
|
||||||
SecShdr = GetShdrByIndex (RelShdr->sh_info);
|
|
||||||
|
|
||||||
if (!IsShdrLoadable (SecShdr)) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += (UINTN)RelShdr->sh_entsize) {
|
for (RelIdx = 0; RelIdx < RelShdr->sh_size; RelIdx += (UINTN)RelShdr->sh_entsize) {
|
||||||
Rel = (Elf_Rela *)((UINT8 *)mEhdr + RelShdr->sh_offset + RelIdx);
|
Rel = (Elf_Rela *)((UINT8 *)mEhdr + RelShdr->sh_offset + RelIdx);
|
||||||
@ -321,28 +343,9 @@ SetRelocs (
|
|||||||
break;
|
break;
|
||||||
case R_X86_64_RELATIVE:
|
case R_X86_64_RELATIVE:
|
||||||
case R_X86_64_64:
|
case R_X86_64_64:
|
||||||
//
|
|
||||||
// If this is a ET_DYN (PIE) executable, we will encounter a dynamic SHT_RELA
|
|
||||||
// section that applies to the entire binary, and which will have its section
|
|
||||||
// index set to #0 (which is a NULL section with the SHF_ALLOC bit cleared).
|
|
||||||
//
|
|
||||||
// This RELA section will contain redundant R_xxx_RELATIVE relocations, one
|
|
||||||
// for every R_xxx_xx64 relocation appearing in the per-section RELA sections.
|
|
||||||
// (i.e., .rela.text and .rela.data) and .got entries' addresses (G + GOT).
|
|
||||||
//
|
|
||||||
New = TRUE;
|
|
||||||
|
|
||||||
for (Index2 = 0; Index2 < RelNum; ++Index2) {
|
|
||||||
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].Type = EFI_IMAGE_REL_BASED_DIR64;
|
||||||
mImageInfo.RelocInfo.Relocs[RelNum].Target = (uint32_t)(Rel->r_offset - mBaseAddress);
|
mImageInfo.RelocInfo.Relocs[RelNum].Target = (uint32_t)(Rel->r_offset - mBaseAddress);
|
||||||
++RelNum;
|
++RelNum;
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case R_X86_64_32:
|
case R_X86_64_32:
|
||||||
@ -404,19 +407,9 @@ SetRelocs (
|
|||||||
break;
|
break;
|
||||||
case R_AARCH64_ABS64:
|
case R_AARCH64_ABS64:
|
||||||
case R_AARCH64_RELATIVE:
|
case R_AARCH64_RELATIVE:
|
||||||
New = TRUE;
|
|
||||||
|
|
||||||
for (Index2 = 0; Index2 < RelNum; ++Index2) {
|
|
||||||
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].Type = EFI_IMAGE_REL_BASED_DIR64;
|
||||||
mImageInfo.RelocInfo.Relocs[RelNum].Target = (uint32_t)(Rel->r_offset - mBaseAddress);
|
mImageInfo.RelocInfo.Relocs[RelNum].Target = (uint32_t)(Rel->r_offset - mBaseAddress);
|
||||||
++RelNum;
|
++RelNum;
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case R_AARCH64_ABS32:
|
case R_AARCH64_ABS32:
|
||||||
@ -540,11 +533,16 @@ CreateIntermediate (
|
|||||||
return RETURN_VOLUME_CORRUPTED;
|
return RETURN_VOLUME_CORRUPTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ProcessRelocSection (Shdr)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for (RIndex = 0; RIndex < Shdr->sh_size; RIndex += (UINTN)Shdr->sh_entsize) {
|
for (RIndex = 0; RIndex < Shdr->sh_size; RIndex += (UINTN)Shdr->sh_entsize) {
|
||||||
Rel = (Elf_Rel *)((UINT8 *)mEhdr + Shdr->sh_offset + RIndex);
|
Rel = (Elf_Rel *)((UINT8 *)mEhdr + Shdr->sh_offset + RIndex);
|
||||||
#if defined(EFI_TARGET64)
|
#if defined(EFI_TARGET64)
|
||||||
if (mEhdr->e_machine == EM_X86_64) {
|
if (mEhdr->e_machine == EM_X86_64) {
|
||||||
if ((ELF_R_TYPE(Rel->r_info) == R_X86_64_64)
|
if ((ELF_R_TYPE(Rel->r_info) == R_X86_64_RELATIVE)
|
||||||
|
|| (ELF_R_TYPE(Rel->r_info) == R_X86_64_64)
|
||||||
|| (ELF_R_TYPE(Rel->r_info) == R_X86_64_32)
|
|| (ELF_R_TYPE(Rel->r_info) == R_X86_64_32)
|
||||||
|| (ELF_R_TYPE(Rel->r_info) == R_X86_64_GOTPCREL)
|
|| (ELF_R_TYPE(Rel->r_info) == R_X86_64_GOTPCREL)
|
||||||
|| (ELF_R_TYPE(Rel->r_info) == R_X86_64_GOTPCRELX)
|
|| (ELF_R_TYPE(Rel->r_info) == R_X86_64_GOTPCRELX)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user