[PATCH] D145555: [obj2yaml] Emit ProgramHeader.Offset

Job Noorman via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Mar 8 01:05:50 PST 2023


jobnoorman created this revision.
jobnoorman added reviewers: MaskRay, labath, rupprecht, grimar.
Herald added subscribers: pmatos, pengfei, emaste.
Herald added a project: All.
jobnoorman requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Currently, obj2yaml doesn't emit the offset of program headers, leaving it to yaml2obj to calculate offsets based on `FirstSec` and `LastSec`. This causes an obj2yaml->yaml2obj round trip to often produce an ELF file that is not equivalent to the original, especially since it seems common to have program headers at offset 0 whose first section starts at a higher address. Besides being non-equivalent, the produced ELF files also do not seem to work propery and readelf complains about them.

Taking a simple hello world program in C, compiled using either GCC or Clang, the original ELF file has the following program headers (only showing some relevant ones):

  Program Headers:
    Type           Offset             VirtAddr           PhysAddr
                   FileSiz            MemSiz              Flags  Align
    PHDR           0x0000000000000040 0x0000000000000040 0x0000000000000040
                   0x00000000000002d8 0x00000000000002d8  R      0x8
    INTERP         0x0000000000000318 0x0000000000000318 0x0000000000000318
                   0x000000000000001c 0x000000000000001c  R      0x1
        [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
    LOAD           0x0000000000000000 0x0000000000000000 0x0000000000000000
                   0x0000000000000630 0x0000000000000630  R      0x1000
    LOAD           0x0000000000001000 0x0000000000001000 0x0000000000001000
                   0x0000000000000161 0x0000000000000161  R E    0x1000
  ...
  
   Section to Segment mapping:
    Segment Sections...
     00
     01     .interp
     02     .interp .note.gnu.property .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt
     03     .init .plt .text .fini
  ...

While this is the result of an obj2yaml->yaml2obj round trip:

  Program Headers:
    Type           Offset             VirtAddr           PhysAddr
                   FileSiz            MemSiz              Flags  Align
    PHDR           0x0000000000000000 0x0000000000000040 0x0000000000000040
                   0x0000000000000000 0x0000000000000000  R      0x8
  readelf: Error: the PHDR segment is not covered by a LOAD segment
    INTERP         0x0000000000000318 0x0000000000000318 0x0000000000000318
                   0x000000000000001c 0x000000000000001c  R      0x1
        [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
    LOAD           0x0000000000000318 0x0000000000000000 0x0000000000000000
                   0x0000000000000318 0x0000000000000318  R      0x1000
    LOAD           0x0000000000001000 0x0000000000001000 0x0000000000001000
                   0x0000000000000161 0x0000000000000161  R E    0x1000
  ...
  
   Section to Segment mapping:
    Segment Sections...
     00
     01     .interp
     02
     03     .init .plt .text .fini
  ...

Note that the offset of segment 2 changed from 0x0 to 0x318. This has two effects:

- readelf complains "Error: the PHDR segment is not covered by a LOAD segment" since PHDR was originally covered by segment 2 but not anymore;
- Segment 2 effectively became empty according to the section to segment mapping.

I addition to these, the output doesn't correctly execute anymore, crashing with a "SIGSEGV (Address boundary error)".

This patch fixes the difference in program header layout after a round trip by explicitly emitting offsets.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D145555

Files:
  llvm/test/Object/obj2yaml.test
  llvm/test/tools/obj2yaml/ELF/program-headers.yaml
  llvm/tools/obj2yaml/elf2yaml.cpp

-------------- next part --------------
A non-text attachment was scrubbed...
Name: D145555.503253.patch
Type: text/x-patch
Size: 6578 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230308/f7cecae5/attachment.bin>


More information about the llvm-commits mailing list