Bug 232922

Summary: elfcopy make corrupt binary on armv7
Product: Base System Reporter: HIROKI MORI <yamori813>
Component: armAssignee: freebsd-arm mailing list <freebsd-arm>
Status: New ---    
Severity: Affects Only Me CC: emaste, mmel
Priority: ---    
Version: CURRENT   
Hardware: arm   
OS: Any   

Description HIROKI MORI 2018-11-03 02:12:05 UTC
I try pcDuino(Allwinner A10) by ZRouter build system.

I do cross build for armv7 kernel on FreeBSD 10.4R amd64.

I do convert ELF kernel to binary then u-boot image.

I found FreeBSD elfcopy(objcopy) bug at armv7.

elfcopy make corrupt file by -O binary.

I seem data section is wrong position at elfcopy. 

This is files.

https://www.dropbox.com/s/xtw7jlc5kpiyd91/armv7kernel.tar.xz?dl=0

Pcduino_Lite_kernel - original elf file

Pcduino_Lite_kernel.elfcopy.ng - corrupt file by FreeBSD elfcopy
 
Pcduino_Lite_kernel.objcopy.ok - good file by binutil objcopy
Comment 1 Ed Maste freebsd_committer 2018-11-03 18:27:36 UTC
Program headers from Pcduino_Lite_kernel:

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0xc0200034 0xc0200034 0x00120 0x00120 R   0x4
  INTERP         0x26b624 0xc046b624 0xc046b624 0x0000d 0x0000d R   0x1
      [Requesting program interpreter: /red/herring]
  LOAD           0x000000 0xc0200000 0xc0200000 0x2c6838 0x2c6838 R E 0x1000
  LOAD           0x2c6840 0xc04c7840 0xc04c7840 0x340f8 0x847c0 RW  0x4000
  DYNAMIC        0x2fa8f0 0xc04fb8f0 0xc04fb8f0 0x00048 0x00048 RW  0x4
  GNU_RELRO      0x2fa8f0 0xc04fb8f0 0xc04fb8f0 0x00048 0x00048 R   0x1
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0
  NOTE           0x261468 0xc0461468 0xc0461468 0x00024 0x00024 R   0x4
  ARM_EXIDX      0x2b76a8 0xc04b76a8 0xc04b76a8 0x0f190 0x0f190 R   0x4

From readelf -x .data Pcduino_Lite_kernel:
Hex dump of section '.data':
  0xc04c7840 00c054c0 24000000 00000000 e9f85434 ..T.$.........T4
  0xc04c7850 210244c0 00000000 00008001 02000000 !.D.............
  0xc04c7860 303d2ac0 48784cc0 00008001 ffffff0f 0=*.HxL.........

From .objcopy.ok:
002c66c0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
002c66d0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
...
002c76c0  00 c0 54 c0 24 00 00 00  00 00 00 00 e9 f8 54 34  |..T.$.........T4|
002c76d0  21 02 44 c0 00 00 00 00  00 00 80 01 02 00 00 00  |!.D.............|
002c76e0  30 3d 2a c0 48 78 4c c0  00 00 80 01 ff ff ff 0f  |0=*.HxL.........|

From .objcopy.ng:
002c66c0  00 c0 54 c0 24 00 00 00  00 00 00 00 e9 f8 54 34  |..T.$.........T4|
002c66d0  21 02 44 c0 00 00 00 00  00 00 80 01 02 00 00 00  |!.D.............|
002c66e0  30 3d 2a c0 48 78 4c c0  00 00 80 01 ff ff ff 0f  |0=*.HxL.........|

The .data section is mislocated by 0x1000.
Comment 2 Michal Meloun freebsd_committer 2019-02-07 09:01:19 UTC
elftoolchain objcopy incorrectly uses segment offset to determine final segment offset in produced binary file:
https://svnweb.freebsd.org/base/head/contrib/elftoolchain/elfcopy/binary.c?revision=333063&view=markup#l114

but binutils objcopy (correctly) uses lma for same purpose:
https://svnweb.freebsd.org/base/head/contrib/binutils/bfd/binary.c?revision=218822&view=markup#l265

For me, this is a clear bug. sh_offset should be changed to sh_addr in 
create_binary() function.