This updates GenFw's ELF conversion for AArch64 so that relocation pairs that operate on ADRP/ADD, ADRP/LDR or ADRP/STR instruction combinations are allowed under the following conditions: - the relative alignment to the nearest 4 KB boundary of the target of the relocation must be identical between the ELF and the PE/COFF versions of the binary; - the offset between the relocation target and the symbol it refers to is identical between the ELF and the PE/COFF versions, even if the symbol lives in another section.
These two conditions can be met by using a carefully crafted GNU ld script that reflects the placement logic of GenFw. Note that such binaries need to be loaded at a 4 KB aligned load address. This is a preliminary step towards allowing AArch64 binaries to be built with the standard 'small' C model. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <ard.biesheu...@linaro.org> --- BaseTools/Source/C/GenFw/Elf64Convert.c | 51 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.c b/BaseTools/Source/C/GenFw/Elf64Convert.c index 25b90e2f7b51..2266e487cec7 100644 --- a/BaseTools/Source/C/GenFw/Elf64Convert.c +++ b/BaseTools/Source/C/GenFw/Elf64Convert.c @@ -734,13 +734,33 @@ WriteSections64 ( break; case R_AARCH64_ADR_PREL_PG_HI21: - // TODO : AArch64 'small' memory model. - Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_AARCH64 relocation R_AARCH64_ADR_PREL_PG_HI21.", mInImageName); - break; - case R_AARCH64_ADD_ABS_LO12_NC: - // TODO : AArch64 'small' memory model. - Error (NULL, 0, 3000, "Invalid", "WriteSections64(): %s unsupported ELF EM_AARCH64 relocation R_AARCH64_ADD_ABS_LO12_NC.", mInImageName); + case R_AARCH64_LDST8_ABS_LO12_NC: + case R_AARCH64_LDST16_ABS_LO12_NC: + case R_AARCH64_LDST32_ABS_LO12_NC: + case R_AARCH64_LDST64_ABS_LO12_NC: + case R_AARCH64_LDST128_ABS_LO12_NC: + // + // These are static PC relative relocation pairs that will already have been resolved + // during static linking of the ELF shared object. So no need to do anything here if + // a) the original ELF .text section and the derived PE/COFF .text section are placed at + // the same relative alignment with respect to the nearest 4K aligned boundary; + // b) the section containing the symbol that the relocation pair refers to is at + // the same relative offset in both binaries; + // c) it is guaranteed that the load time alignment of the PE/COFF binary is + // at least 4 KB. + // + // While conditions a) and b) could be met by recalculating the immediates based on + // the actual placement of the PE/COFF sections if their offsets and/or alignments + // deviate, condition c) is a necessary condition that applies universally when + // ADRP based symbol references are used. It thus requires the appropriate 'Align=4K' + // declarations in the platform .FDF. + // + if ((SecOffset % 4096) != (SecShdr->sh_addr % 4096) || + (mCoffSectionsOffset[Sym->st_shndx] - SecOffset) != (SymShdr->sh_addr - SecShdr->sh_addr)) { + // TODO: recalculate the two immediates based on the actual placement + Error (NULL, 0, 3000, "Invalid", "AArch64: ADRP/ADD and ADRP/LDR pairs must retain relative sym offset and relative alignment to 4 KB!."); + } break; // Absolute relocations. @@ -825,13 +845,24 @@ WriteRelocations64 ( break; case R_AARCH64_ADR_PREL_PG_HI21: - // TODO : AArch64 'small' memory model. - Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_AARCH64 relocation R_AARCH64_ADR_PREL_PG_HI21.", mInImageName); break; case R_AARCH64_ADD_ABS_LO12_NC: - // TODO : AArch64 'small' memory model. - Error (NULL, 0, 3000, "Invalid", "WriteRelocations64(): %s unsupported ELF EM_AARCH64 relocation R_AARCH64_ADD_ABS_LO12_NC.", mInImageName); + break; + + case R_AARCH64_LDST8_ABS_LO12_NC: + break; + + case R_AARCH64_LDST16_ABS_LO12_NC: + break; + + case R_AARCH64_LDST32_ABS_LO12_NC: + break; + + case R_AARCH64_LDST64_ABS_LO12_NC: + break; + + case R_AARCH64_LDST128_ABS_LO12_NC: break; case R_AARCH64_ABS64: -- 1.9.1 ------------------------------------------------------------------------------ Monitor 25 network devices or servers for free with OpManager! OpManager is web-based network management software that monitors network devices and physical & virtual servers, alerts via email & sms for fault. Monitor 25 devices for free with no restriction. Download now http://ad.doubleclick.net/ddm/clk/292181274;119417398;o _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel