Hi Heinrich,

Thanks for the suggestions.

I will continue investigating, if there is another way to build PE32+ ARM (v6kz) binaries.

I am not aware of any currently working configuration other than the one through GNU-EFI (aarch64 is not an option for me).

Nonetheless, this patch isn't about me trying to run an EFI binary, it's about U-Boot.

U-Boot uses GNU-EFI files for building the test applications. And does so by using bad linker scripts, that weren't present in that form in GNU-EFI to begin with.

This means that _relocate is fundamentally broken without this patch on U-Boot.

If this patch isn't applied, the checks in Makefile (looking at the target checkarmreloc) create a false sense,
that such binaries (that contain relocations) would work.

It's true, that none of the generated binaries contain relocations and thereby no issues are visible currently, nonetheless, once they would be introduced, the behavior would cause confusion.

Greetings,
Patrick


Am 06.11.22 um 22:37 schrieb Heinrich Schuchardt:
Am 6. November 2022 18:03:09 MEZ schrieb Patrick Zacharias 
<littlefighte...@web.de>:
Hi Heinrich,

Thanks for the information, I'll make sure to use it for future contributions.

I encountered this issue, while building a custom EFI application using Rust by 
linking
the following files:

./arch/arm/lib/reloc_arm_efi.c
./arch/arm/lib/crt0_arm_efi.S
./arch/arm/lib/elf_arm_efi.lds
The U-Boot files are only used for building test applications for U-Boot. They 
are not usable for building generic applications which may require relocations.

If your application have different requirements, please create files in your 
own repository and adjust them to your needs.

When building rust UEFI applications consider using the aarch64-unknown-uefi 
target and the r_efi crate. That target has been promoted to tier 2 recently. 
See https://github.com/rust-lang/compiler-team/issues/555

Probably you need a nightly build of the compiler to use it.

Best regards

Heinrich

As well as the custom application built as a library, that exports "efi_main".

Thus, the relocations were caused by the "write_fmt" functions that Rust 
provides.
I encountered it, when concatenating two strings.
format!("Test {}", "Test2");

The relocation was not applied and therefor lead to a crash.

>From my understanding these relocations are ELF relocations and are therefor 
applied by the _relocate function (inside the built application)
and not by the EFI loader. This is why I assumed, that it's fine for these 
relocations to reside in the data section.

I noticed, that in the _relocate function in ./arch/arm/lib/reloc_arm_efi.c, 
that the case R_ARM_RELATIVE was never entered,
even though the generated shared object included them.
I then looked at the EFI header file (crt0_arm_efi.S) and noticed, that it 
specifies only up to _edata to be loaded.

I concluded that _edata needs to be extended to include the ELF relocations as 
well.

After I decided to place it after the relocations, I noticed, that _edata is 
already specified at the same (new position) in gnu-efi.
This reaffirmed me to contribute the patch as it currently is.

I assumed, that on x86, that the linker treats the ELF relocations (.rela.*) as 
if it was part of the data section.
>From my understanding the EFI relocations are in .reloc while the ELF 
relocations are in .rela.*.
I might be mistaken, however.

Greetings,
Patrick

Am 06.11.22 um 10:20 schrieb Heinrich Schuchardt:
On 10/31/22 21:01, Patrick Zacharias wrote:
Prior to this commit, the relocations would not get loaded by the efi
loader.

This lead to none of the relocations being applied.

Signed-off-by: Fighter19 <1475802+fighte...@users.noreply.github.com>
Thanks Patrick for your contribution.

You can use scripts/get_maintainer.pl to determine to whom a patch
should be sent.

Where did you actually see relocations?
Which code is not position independent?

---
   arch/arm/lib/elf_aarch64_efi.lds | 2 +-
   arch/arm/lib/elf_arm_efi.lds     | 2 +-
   2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm/lib/elf_aarch64_efi.lds
b/arch/arm/lib/elf_aarch64_efi.lds
index c0604dad46..1982864d17 100644
--- a/arch/arm/lib/elf_aarch64_efi.lds
+++ b/arch/arm/lib/elf_aarch64_efi.lds
@@ -46,12 +46,12 @@ SECTIONS
           *(COMMON)
           . = ALIGN(512);
           _bss_end = .;
-        _edata = .;
       }
       .rela.dyn : { *(.rela.dyn) }
       .rela.plt : { *(.rela.plt) }
       .rela.got : { *(.rela.got) }
       .rela.data : { *(.rela.data) *(.rela.data*) }
+    _edata = .;
       _data_size = . - _etext;

       . = ALIGN(4096);
diff --git a/arch/arm/lib/elf_arm_efi.lds b/arch/arm/lib/elf_arm_efi.lds
index 767ebda635..c1b58a8033 100644
--- a/arch/arm/lib/elf_arm_efi.lds
+++ b/arch/arm/lib/elf_arm_efi.lds
@@ -46,12 +46,12 @@ SECTIONS
           *(COMMON)
           . = ALIGN(512);
           _bss_end = .;
-        _edata = .;
       }
       .rel.dyn : { *(.rel.dyn) }
       .rel.plt : { *(.rel.plt) }
       .rel.got : { *(.rel.got) }
       .rel.data : { *(.rel.data) *(.rel.data*) }
+    _edata = .;
Relocations (if they exist) should be in the .reloc section, not in the
.data section.

If we want to create a .reloc section, we have to change
arch/arm/lib/crt0_*_efi.S too. Furthermore the relocation section must
be pointed to by field BaseRelocationTable of the Optional Header Data
Directories (see PE-COFF specification).

Please, consider the other UEFI architectures (x86 and RISC-V) too.

Best regards

Heinrich

       _data_size = . - _etext;

       /DISCARD/ : {


Reply via email to