[PATCH] D26888: [ELF] - Implemented -N.

Ed Maste via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Nov 28 07:11:31 PST 2016


emaste added a comment.

-N changes a few things:

1. Makes the text and data sections readable and writeable.
2. Does not page align data.
3. Uses the `OMAGIC` magic number, if applicable to the output format.

For FreeBSD we don't care about these per se, but we rely on -N allowing us to generate exceptionally small binaries, such as the 512-byte master boot record (MBR) used for BIOS booting.

For example, consider this trivial program:

  #include <unistd.h>
  void
  _start(void)
  {
          _exit(var_data);
  }

Linking normally with GNU ld we see:

  % cc -nostdlib example.c /usr/lib/libc.a; strip a.out
  % readelf -l a.out                                   
  
  Elf file type is EXEC (Executable file)
  Entry point 0x400120
  There are 4 program headers, starting at offset 64
  
  Program Headers:
    Type           Offset             VirtAddr           PhysAddr
                   FileSiz            MemSiz              Flags  Align
    LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                   0x0000000000000250 0x0000000000000250  R E    200000
    LOAD           0x0000000000000250 0x0000000000600250 0x0000000000600250
                   0x0000000000000010 0x0000000000000018  RW     200000
    GNU_EH_FRAME   0x000000000000018c 0x000000000040018c 0x000000000040018c
                   0x000000000000002c 0x000000000000002c  R      4
    GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                   0x0000000000000000 0x0000000000000000  RW     8
  
   Section to Segment mapping:
    Segment Sections...
     00     .text .eh_frame_hdr .eh_frame 
     01     .data .bss 
     02     .eh_frame_hdr 
     03     

and with -N:

  % cc -Wl,-N -nostdlib example.c /usr/lib/libc.a; strip a.out
  % readelf -l a.out                                          
  
  Elf file type is EXEC (Executable file)
  Entry point 0x4000f0
  There are 3 program headers, starting at offset 64
  
  Program Headers:
    Type           Offset             VirtAddr           PhysAddr
                   FileSiz            MemSiz              Flags  Align
    LOAD           0x00000000000000f0 0x00000000004000f0 0x00000000004000f0
                   0x0000000000000140 0x0000000000000148  RWE    10
    GNU_EH_FRAME   0x000000000000015c 0x000000000040015c 0x000000000040015c
                   0x000000000000002c 0x000000000000002c  R      4
    GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                   0x0000000000000000 0x0000000000000000  RW     8
  
   Section to Segment mapping:
    Segment Sections...
     00     .text .eh_frame_hdr .eh_frame .data .bss 
     01     .eh_frame_hdr 
     02     

Excluding the `eh_frame_hdr` In the first case we have two pages, one RE and one RW, and in the 2ond case with -N we have one RWE page.

In FreeBSD we tried switching to a linker script in r305353 <https://svnweb.freebsd.org/base?view=revision&revision=305353> (FreeBSD review D7409 <https://reviews.freebsd.org/D7409> has some comments). We found LLVM PR 30415 <https://llvm.org/bugs/show_bug.cgi?id=30415> when testing with the linker script + LLD.

The linker script change broke one of the loaders when still using ld.bfd though, and the change was reverted in r307954 <https://svnweb.freebsd.org/base?view=revision&revision=307954>. The linker script change will likely be fixed and reapplied at some point.


https://reviews.llvm.org/D26888





More information about the llvm-commits mailing list