Bug 26218 - Invalid coff/pe arm machine type creating EFI binary
Summary: Invalid coff/pe arm machine type creating EFI binary
Status: ASSIGNED
Alias: None
Product: binutils
Classification: Unclassified
Component: binutils (show other bugs)
Version: 2.38 (HEAD)
: P2 normal
Target Milestone: ---
Assignee: Tamar Christina
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-07-08 18:05 UTC by Alexander von Gluck IV
Modified: 2021-10-29 08:47 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2020-07-09 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alexander von Gluck IV 2020-07-08 18:05:03 UTC
objcopy creates invalid ARM EFI bootloaders.


objcopy -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela -j .reloc -j .dynstr -j .debug* --output-target=pei-arm-little --subsystem=efi-app $(2) $(1)


  Offset to PE: 0x80
  Machine type: 0x0a00, Unknown machine type
  PointerToSymbolTable should be 0.
  NumberOfSymbols should be 0.
  Characteristics: 0x0105
   * Relocation information was stripped from the file.
   * COFF line numbers were stripped from the file.
   * The computer supports 32-bit words.
  Wrong OHS Magic 0x742e
  Image type: (crash in EFI analyzer tool)


This invalid machine type seems to come from here:

http://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=include/coff/arm.h;h=93ce49c1d05114b7d4b1cdb588fd8a1f4f0e68e;hb=HEAD#l78

(include/coff/arm.h line 78)

78 #define ARMMAGIC 0xa00 /* I just made this up */

ARMMAGIC gets references multiple places, with sketchy WINCE ifdef's surrounding ARMPEMAGIC (which is "more sane")

http://sourceware.org/git/?p=binutils-gdb.git;a=blob;f=bfd/coffcode.h;h=0910f918d13bf46394e3d3f3da4055fd2aa7a79;hb=HEAD#l2754
Comment 1 Nick Clifton 2020-07-09 09:50:09 UTC
Hi Alexander,

> objcopy -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela
> -j .reloc -j .dynstr -j .debug* --output-target=pei-arm-little
> --subsystem=efi-app $(2) $(1)

Does this work if you replace pei-arm-little with pei-arm-wince-little ?

>   Wrong OHS Magic 0x742e

What is the correct OHS Magic value ?

Cheers
  Nick
Comment 2 Alexander von Gluck IV 2020-07-09 15:49:36 UTC
Hi!

So, my toolchain doesn't have pei-arm-wince-little support, so not an easy test. (I can work on building a toolchain with pei-arm-wince-little, but it will take a bit of time)  I'll report back here.


The efi_analyzer tool i'm running is here:
https://github.com/xypron/efi_analyzer/blob/master/efianalyze.c


Essentially, it seems like arm pe objects have a unix/coff focus which never really existed after 2000 when this was written. I don't think there are really any valid unix/coff arm targets, so this default behaviour really doesn't even make sense.

This is why things like gnu-efi do "fake" pe headers:
https://sourceforge.net/p/gnu-efi/code/ci/master/tree/gnuefi/crt0-efi-arm.S

The alternative is moving over to clang/ld.lld since they support this stuff pretty well natively.
https://dvdhrm.github.io/2019/01/31/goodbye-gnuefi/


It might make sense for the ARM folks (Linaro) to take a look at this one if they're still around.

Both of these are ideal for improved ARM adoption:

* "easier to generate correct" EFI bootloaders + u-boot now supporting UEFI
* "easier to generate correct" EFI bootloaders + edk2 now supporting ARM UEFI
Comment 3 Tamar Christina 2021-06-30 12:14:48 UTC
(In reply to Nick Clifton from comment #1)
> Hi Alexander,
> 
> > objcopy -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel -j .rela
> > -j .reloc -j .dynstr -j .debug* --output-target=pei-arm-little
> > --subsystem=efi-app $(2) $(1)
> 
> Does this work if you replace pei-arm-little with pei-arm-wince-little ?
> 
> >   Wrong OHS Magic 0x742e
> 
> What is the correct OHS Magic value ?
> 
> Cheers
>   Nick

Looks like binutils already contains the right magic values

#define	ARMPEMAGIC	0x1c0
#define	THUMBPEMAGIC	0x1c2

But the problem is how do we change the default target's magic value..
If we just change it I believe we break objdump and the linker's ability to recognize the format.

perhaps expose it as a different format?
Comment 4 Nick Clifton 2021-06-30 14:12:39 UTC
(In reply to Tamar Christina from comment #3)

> #define	ARMPEMAGIC	0x1c0
> 
> But the problem is how do we change the default target's magic value..
> If we just change it I believe we break objdump and the linker's ability to
> recognize the format.
> 
> perhaps expose it as a different format?

Probably a new target configuration.  Something like arm-efi ?

It looks like the ARM_WINCE code is currently redundant - I could not find it #defined anywhere - but maybe we need to resurrect it ?
Comment 5 Tamar Christina 2021-06-30 14:20:04 UTC
(In reply to Nick Clifton from comment #4)
> (In reply to Tamar Christina from comment #3)
> 
> > #define	ARMPEMAGIC	0x1c0
> > 
> > But the problem is how do we change the default target's magic value..
> > If we just change it I believe we break objdump and the linker's ability to
> > recognize the format.
> > 
> > perhaps expose it as a different format?
> 
> Probably a new target configuration.  Something like arm-efi ?
> 
> It looks like the ARM_WINCE code is currently redundant - I could not find
> it #defined anywhere - but maybe we need to resurrect it ?

It's set in bfd/config.bfd when defining the targets

  arm-wince-pe | arm-*-wince | arm*-*-mingw32ce* | arm*-*-cegcc*)
    targ_defvec=arm_pe_wince_le_vec
    targ_selvecs="arm_pe_wince_le_vec arm_pe_wince_be_vec arm_pei_wince_le_vec arm_pei_wince_be_vec"
    targ_underscore=no
    targ_cflags="-DARM_WINCE -DARM_COFF_BUGFIX"
    ;;

It must be working since otherwise any WINCE devices (which afaik are still used in some old windows embedded devices) would have the loader reject the binaries as unknown.