What elf sections are necessary for DR's operation?

26 views
Skip to first unread message

Mohammad Ewais

unread,
May 7, 2022, 2:40:13 PM5/7/22
to DynamoRIO Users
I have a very stripped down binary that basically looks like the following:

Source:
extern "C" void WorkerMain()
{
    // I intend to populate this later
    // Exit
    asm("movq $60, %rax;"
             "movq $0, %rdi;"
             "syscall");
}


I compile it with the following linker script:
ENTRY(WorkerMain);
SECTIONS
{
    . = 0x10000;
    .text : { *(.text) }
    /DISCARD/ : { *(.comment) }
    /DISCARD/ : { *(.note.gnu.build-id) }
    /DISCARD/ : { *(.note.gnu.property) }
}


And using theis compile command:
g++ -T tiny.ld -o tiny tiny.cpp -O2 -fno-pie -fno-pic -nostartfiles -nostdlib -fno-rtti -fno-exceptions -fno-asynchronous-unwind-tables -s -static

I eventually get an elf binary with just the .text section, no other sections at all.  Looking like this when I run `objdump -D tiny`:
tiny:     file format elf64-x86-64

Disassembly of section .text:

0000000000010000 <.text>:
   10000:    f3 0f 1e fa              endbr64
   10004:    48 c7 c0 3c 00 00 00     mov    $0x3c,%rax
   1000b:    48 c7 c7 00 00 00 00     mov    $0x0,%rdi
   10012:    0f 05                    syscall
   10014:    c3                       ret

This binary runs fine (even though it does nothing). No segfaults or anything weird happens. But under DR, using the following command:
/home/mewais/DynamoRIO/bin64/drrun -debug -loglevel 4 -c /home/mewais/DCSim/Debug/libSNEClient.so -- ./tiny
it gives me this error during initialization (before the client is even loaded):
<Application /home/mewais/DCSim/Debug/tiny (528524).  Internal Error: DynamoRIO debug check failure: /home/travis/build/DynamoRIO/dynamorio/core/unix/loader.c:1943 is_elf_so_header(exe_map, 0)
(Error occurred @-1 frags)
version 8.0.0, build 1
-early_inject
0x00007fffd9f5c4d0 0x00007f71701e7095
0x00007fffd9f5c720 0x00007f71703fa8ad
0x00007fffd9f5d7d0 0x00007f71703aa1bd>

Naturally, I am thinking that this severe stripping down of the binary is causing this error in DR, since I have never encountered it before. So, what sections do I need to keep in my ELF binary for DR to work correctly?

Mohammad Ewais

unread,
May 8, 2022, 7:37:10 AM5/8/22
to DynamoRIO Users
For more information, this is the output of `readelf -e ./tiny`:

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x10000
  Start of program headers:          64 (bytes into file)
  Start of section headers:          4136 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         2
  Size of section headers:           64 (bytes)
  Number of section headers:         3
  Section header string table index: 2

Section Headers:
  [Nr] Name              Type            Address          Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            0000000000000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        0000000000010000 001000 000015 00  AX  0   0 16
  [ 2] .shstrtab         STRTAB          0000000000000000 001015 000011 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

Program Headers:
  Type           Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
  LOAD           0x001000 0x0000000000010000 0x0000000000010000 0x000015 0x000015 R E 0x1000
  GNU_STACK      0x000000 0x0000000000000000 0x0000000000000000 0x000000 0x000000 RW  0x10

 Section to Segment mapping:
  Segment Sections...
   00     .text
   01  

Mohammad Ewais

unread,
May 8, 2022, 7:55:20 AM5/8/22
to DynamoRIO Users
Last addition, I managed to get it working by using the same source, but NOT using the linker script.
Essentially using the following command:
g++ -o tiny tiny.cpp -O2 -fno-pie -fno-pic -nostartfiles -nostdlib -fno-rtti -fno-exceptions -fno-asynchronous-unwind-tables -s -static -Wl,--entry=WorkerMain

However, I do need the linker script because I want to specify an address for the text section, like follows:
ENTRY(WorkerMain);
SECTIONS
{
    . = 0x10000;
    .text 0x0000100000000000 : { *(.text) }

    /DISCARD/ : { *(.comment) }
    /DISCARD/ : { *(.note.gnu.build-id) }
    /DISCARD/ : { *(.note.gnu.property) }
}

I tried getting rid of the discard lines, same issue. I also tried getting rid of the text line that I am interested in, still same issue. This prompts me to think that these lines are, in fact, fine. But that I missing something else entirely. What should I add to this linker script to keep DR happy while achieving what I want?

Derek Bruening

unread,
May 8, 2022, 1:29:22 PM5/8/22
to Mohammad Ewais, DynamoRIO Users
I would look at it the other way: what changes does DR need to handle this ELF file, since ideally DR would handle anything that runs without DR.  If you look at the is_elf_so_header() sources they don't require very much and I'm rather surprised that that check would fail on anything: I would start there, walking through in the debugger to see exactly what doesn't match.  We would be happy to take a PR making DR more robust to handling unusual ELF files.

--
You received this message because you are subscribed to the Google Groups "DynamoRIO Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to dynamorio-use...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/dynamorio-users/c7e28dde-32a8-4bea-8e73-2b223ef7a97bn%40googlegroups.com.

Mohammad Ewais

unread,
May 8, 2022, 3:24:48 PM5/8/22
to DynamoRIO Users
That's very interesting. I was imagining there is some well known conditions/requirements.

Sure, I will begin by applying the checks in is_elf_so_header() and see what makes the fail.

Derek Bruening

unread,
May 8, 2022, 5:03:53 PM5/8/22
to Mohammad Ewais, DynamoRIO Users
If the app uses rseq, there are some requirements on conventions being followed on having certain ELF sections due to the near-impossibility of handling that feature otherwise: https://dynamorio.org/page_rseq.html#autotoc_md274.  I would expect most other limitations encountered to be unintentional and fixable.

Mohammad Ewais

unread,
May 10, 2022, 6:13:13 AM5/10/22
to DynamoRIO Users
Hi Derek.

The task was proving tedious for me. The function `is_elf_so_header` was getting called many times before the error arises. That coupled with my "little" knowledge in ELF and its sections and the internals of DR made it very time consuming.
I ended up taking the default linker script of GCC, modifying the address of the .text section in it and using it right away.

Apologies for not being able to help DR with this.
Reply all
Reply to author
Forward
0 new messages