Timmmm
Timmmm

Reputation: 97008

How to use `llvm-symbolizer --filter-markup`?

llvm-symbolizer has a useful looking --filter-markup feature that supposedly will let you pipe a file through it containing markup like {{pc:0x20000}} and it will convert that to a symbol, file and line number.

However there are basically no instructions on how to use this. Yes there's that long manual page but it's mostly just a description of the markup; there are no instructions on how to actually use it.

I tried the obvious thing:

❯ echo '{{{data:0x2000155e}}}' | llvm-symbolizer --filter-markup --obj=foo.elf
error: no mmap covers address
{{{data:0x2000155e}}}
        ^
[[[data:0x2000155e]]]

However it turns out this is not right. As far as I can tell it can't just read an ELF file. You need to manually tell it about loaded modules like this:

{{{module:1:foo:elf:ca97eacb6dd63797cec37aea1b33abff}}}
{{{mmap:0x0000000020000000:0x0000000020000000:load:1:rwx:0x0}}}

I'm not sure about the mmap line yet. I haven't got that far because it already gives this error:

error: could not find build ID 'CA97EACB6DD63797CEC37AEA1B33ABFF'
[[[ELF module #0x1 "foo"; BuildID=ca97eacb6dd63797cec37aea1b33abff [0x20000000-0x3fffffff](rwx)]]]

That build ID is correct:

❯ readelf -n foo.elf

Displaying notes found in: .note.gnu.build-id
  Owner                Data size        Description
  GNU                  0x00000010       NT_GNU_BUILD_ID (unique build ID bitstring)
    Build ID: ca97eacb6dd63797cec37aea1b33abff

Side note: to get a build ID (you don't get one by default) you need -Wl,--build-id and also make sure you save the relevant section as loadable PROGBITS in your linker script:

  .note.gnu.build-id :
  {
    KEEP(*(.note.gnu.build-id))
  } 

I don't know why it needs to be loadable but it doesn't work with (NOLOAD).

Anyway I read the source code and it seems like llvm-symbolizer tries to load the ELF from some kind of build ID database?? I did try --debug-file-path . too but I think it's expecting the ELF to be in some hashed filename or something.

Where is the documentation for this stuff? Why can't I just use --obj=foo.elf. If I don't use --filter-markup then --obj=foo.elf works fine:

❯ llvm-symbolizer --obj=foo.elf 0x20000000
_start
/home/...../../common/crt.S:18:0

I only have a single statically linked ELF, so I don't need any fancy debug info databases. This also doesn't require me to manually specify mmap entries...

Upvotes: 0

Views: 26

Answers (0)

Related Questions