0

I'm trying to extract the original source code from an ELF with debug symbols.

$ sed -n "14,16p" main.c
    for (int p=start;p<end;p++)
        if (isPrime(p))
            printf("%d\n",p);

I want the "closest", preceeding source line from a given address:

$ gcc -g -O0 main.c -o main
$ objdump -D -S main > main.asm
$ sed -n "451,457p" main.asm
        if (isPrime(p))
 6ba:   8b 45 f4                mov    -0xc(%rbp),%eax
 6bd:   89 c7                   mov    %eax,%edi
 6bf:   e8 86 ff ff ff          callq  64a <isPrime>
 6c4:   85 c0                   test   %eax,%eax
 6c6:   74 16                   je     6de <main+0x49>
            printf("%d\n",p);

So given the 0x6bf call instruction, I would like to extract if (isPrime(p)).

This seems possible since objdump does it (right?)

OrenIshShalom
  • 5,974
  • 9
  • 37
  • 87

2 Answers2

2

I'm trying to extract the original source code from an ELF with debug symbols.

That's impossible: the ELF with debug symbols contains no original source code.

What you appear to be after is source code location, i.e. file and line. Armed with file name, line number, and the original source, you can trivially print that line.

To recover file/line info, you could use addr2line -e main 0x6bf.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
0

It turns out that it can be quite easily done with pyelftools:

import elftools
from elftools.elf.elffile import ELFFile as ELF

def addr_2_line(ELFname: str, addr: int) -> int:
    with open(ELFname, "rb") as fl:
        elf = ELF(fl)
        dwarf_info = elf.get_dwarf_info()
        for cu in dwarf_info.iter_CUs():
            line = 1
            for entry in dwarf_info.line_program_for_CU(cu).get_entries():
                if entry.state:
                    if addr > entry.state.address:
                        line = entry.state.line
                    else:
                        return line
address = addr_2_line("main", 0x6bf)
print(f"src code[ 0x6bf ] = {address}")

When I run it it indeed gives the desired line:

src code[ 0x6bf ] = 15

It is probably worth checking if no adjustments are needed when there are more than just one compilation unit (cu)

OrenIshShalom
  • 5,974
  • 9
  • 37
  • 87