eliben / pyelftools

Parsing ELF and DWARF in Python
Other
1.99k stars 508 forks source link

Support MIPS64 .o files #493

Closed noamraph closed 1 year ago

noamraph commented 1 year ago

I added support for parsing mips64 .o files.

Testing

I'll start from the testing. I added a file test/testfiles_for_dwarfdump/dwarf_mips64el.o.elf.

I created this file using a "nix flake". To generate this file, install nix, enable flakes by running echo "experimental-features = nix-command flakes" > ~/.config/nix/nix.conf, go to the directory test/testfiles_for_dwarfdump/dwarf_mips64el and run nix build. Copy the file result/dwarf_mips64el.o into ../dwarf_mips64el.o.elf.

Annoyingly, I had to mess with the test. llvm-dwarfdump doesn't perform a relocation, and reports a location experssion to be DW_OP_addr 0x0, while pyelftools reports DW_OP_addr 0x4. I think that pyelftools is right, since it agrees with gcc's objdump. To verify, go to test/testfiles_for_dwarfdump/dwarf_mips64el and run:

nix develop -c bash -c 'mips64el-unknown-linux-gnuabi64-objdump --dwarf=info ../dwarf_mips64el.o.elf'

You get:

../dwarf_mips64el.o.elf:     file format elf64-tradlittlemips

Contents of the .debug_info section:
...
 <1><1e>: Abbrev Number: 1 (DW_TAG_variable)
...
    <28>   DW_AT_location    : 9 byte block: 3 4 0 0 0 0 0 0 0  (DW_OP_addr: 4)
...

To workaround this, I modified run_dwarfdump_tests.py to change the output of llvm-dwarfdump for this specific input.

Code

I added support for the R_MIPS_64 relocation type, in its simple form, where it defines just one relocation. I raised ELFRelocationError if it defines more than one relocation (as it can).

I changed _reloc_calc_sym_plus_value to add addend to its result. The test fails without it, and I think that if an addend is defined, it should always be added.

I removed the _RELOCATION_RECIPE_TYPE.has_addend field. The reason is that the R_MIPS_32 relocation sometimes has an addend and sometimes doesn't. This simplifies the code, and all tests pass, so I hope it's OK.

What do you think?

Thanks a lot for pyelftools! It helps me a lot! Noam

sevaa commented 1 year ago

Create an issue in the LLVM bug tracker. Won't be the first time we point fingers at the reference tools.

noamraph commented 1 year ago

@sevaa after thinking about it, I think that there is no clear answer on whether relocations on globals should be performed when analyzing the .o file. The reason is that the relocated address (0x4 in this case) is still not the real address that the global would be in.

So I updated the example .o file to only include locals.

I now had to make a smaller change to run_dwarfdump_test.py: in one place, llvm-dwarfdump showed (0x0000000000000000 ".text") and pyelftools showed just (0x0000000000000000) (which I think makes sense). So I added a replacement from the first string to the other.

What do you think?

eliben commented 1 year ago

Closing, since #495 was merged