Bug 235391 - armv7: kernel.bin produced by buildkernel is corrupted.
Summary: armv7: kernel.bin produced by buildkernel is corrupted.
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: arm (show other bugs)
Version: CURRENT
Hardware: arm Any
: --- Affects Some People
Assignee: freebsd-arm mailing list
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-02-01 15:14 UTC by Michal Meloun
Modified: 2019-02-07 08:38 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Michal Meloun freebsd_committer 2019-02-01 15:14:30 UTC
Actually, ld.lld changed many years lasting status quo - file layout of loadable sections in ELF file no longer correspond to in memory layout [1]. 

Unfortunately,  elftoolchain objcopy uses for generating kernel.bin images doesn't handle this well and produces invalid binary files. The generated binary follows ELF file layout, not a requested memory one.

This changed ld.lld behavior also means that we cannot load kernel to memory and simply jump to start address to run it. Imo, many kernel developers use
this technique in early stage of porting kernel to new HW.

And I just noticed this, alignment of second load section looks very strange, I pretty sure that this is not a right output.

[1]
kernel generated by ld.lld:
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0xc0000034 0xc0000034 0x00120 0x00120 R   0x4
  INTERP         0x730e6c 0xc0730e6c 0xc0730e6c 0x0000d 0x0000d R   0x1
      [Requesting program interpreter: /red/herring]
  LOAD           0x000000 0xc0000000 0xc0000000 0x7f3804 0x7f3804 R E 0x1000
  LOAD           0x7f3840 0xc07f4840 0xc07f4840 0xcf848 0x2f37c0 RW  0x4000
  DYNAMIC        0x8c3040 0xc08c4040 0xc08c4040 0x00048 0x00048 RW  0x4
  GNU_RELRO      0x8c3040 0xc08c4040 0xc08c4040 0x00048 0x00048 R   0x1
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0
  NOTE           0x7c102c 0xc07c102c 0xc07c102c 0x00024 0x00024 R   0x4
  ARM_EXIDX      0x7d6774 0xc07d6774 0xc07d6774 0x1d090 0x1d090 R   0x4


exactly same (from identical objects) kernel generated by ld.bfd:
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  ARM_EXIDX      0x7b7f10 0xc07b7f10 0xc07b7f10 0x1d3b0 0x1d3b0 R   0x4
  PHDR           0x000034 0xc0000034 0xc0000034 0x000c0 0x000c0 R E 0x4
  INTERP         0x72d188 0xc072d188 0xc072d188 0x0000d 0x0000d R   0x1
      [Requesting program interpreter: /red/herring]
  LOAD           0x000000 0xc0000000 0xc0000000 0x8a5b0c 0xac8000 RWE 0x8000
  DYNAMIC        0x8a5aa4 0xc08a5aa4 0xc08a5aa4 0x00068 0x00068 RW  0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4
Comment 1 Michal Meloun freebsd_committer 2019-02-07 08:38:13 UTC
This problem is caused by the folowing statement in ldscript.arm:

  /* Adjust the address for the data segment.  We want to adjust up to
     the same address within the page on the next page up.  */
  . = ALIGN(0x1000) + (. & (0x1000 - 1)) ; 
  .data    :

I'm unable to decode meaning or purpose of this calculation (is not it equivalent to pure . = . + 0x1000 ?) but changing it to more obvious: 
  . = ALIGN(0x1000);
restores right behavior (ELF file layout is in sync with memory layout).
So, whats now?

The elfcopy problem is already reported in PR232922, I will continue there.

readelf dump after alignment change (for kernel linked by ld.lld):
Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0xc0000034 0xc0000034 0x00120 0x00120 R   0x4
  INTERP         0x7312ec 0xc07312ec 0xc07312ec 0x0000d 0x0000d R   0x1
      [Requesting program interpreter: /red/herring]
  LOAD           0x000000 0xc0000000 0xc0000000 0x7f3cb0 0x7f3cb0 R E 0x1000
  LOAD           0x7f4000 0xc07f4000 0xc07f4000 0xcf848 0x2f0000 RW  0x4000
  DYNAMIC        0x8c3800 0xc08c3800 0xc08c3800 0x00048 0x00048 RW  0x4
  GNU_RELRO      0x8c3800 0xc08c3800 0xc08c3800 0x00048 0x00048 R   0x1
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RW  0
  NOTE           0x7c14dc 0xc07c14dc 0xc07c14dc 0x00024 0x00024 R   0x4
  ARM_EXIDX      0x7d6c18 0xc07d6c18 0xc07d6c18 0x1d098 0x1d098 R   0x4