-
Notifications
You must be signed in to change notification settings - Fork 511
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support MIPS64 .o files #493
Conversation
…RF test still shows an error.
…PS_32 has it and sometimes it doesn't. Since all tests pass, I think the field can be removed.
Create an issue in the LLVM bug tracker. Won't be the first time we point fingers at the reference tools. |
Now we don't depend on whether relocations on globals in .o should be performed or not.
@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 What do you think? |
@@ -296,18 +297,17 @@ def _do_apply_relocation(self, stream, reloc, symtab): | |||
# Relocations are represented by "recipes". Each recipe specifies: | |||
# bytesize: The number of bytes to read (and write back) to the section. | |||
# This is the unit of data on which relocation is performed. | |||
# has_addend: Does this relocation have an extra addend? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I understand why you removed has_addend
, can you elaborate more (beyond what the PR description says)? Is this a change that can be discussed separately from your implementation to support MIPS64?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. I removed has_addend
because it was the easiest way I found to make what I needed work.
See commit ec3d215 which is before removing has_addend
. It has this test failing:
❯ venv/bin/python scripts/readelf.py --debug-dump=info test/testfiles_for_readelf/simple_mips_gcc.o.elf
Traceback (most recent call last):
File "scripts/readelf.py", line 1852, in <module>
main()
File "scripts/readelf.py", line 1828, in main
readelf.display_debug_dump(args.debug_dump_what)
File "scripts/readelf.py", line 899, in display_debug_dump
self._init_dwarfinfo()
File "scripts/readelf.py", line 1104, in _init_dwarfinfo
self._dwarfinfo = self.elffile.get_dwarf_info()
File "./elftools/elf/elffile.py", line 277, in get_dwarf_info
relocate_dwarf_sections)
File "./elftools/elf/elffile.py", line 795, in _read_dwarf_section
section_stream, reloc_section)
File "./elftools/elf/relocation.py", line 216, in apply_section_relocations
self._do_apply_relocation(stream, reloc, symtab)
File "./elftools/elf/relocation.py", line 287, in _do_apply_relocation
addend=reloc['r_addend'] if recipe.has_addend else 0)
File "./elftools/elf/relocation.py", line 39, in __getitem__
return self.entry[name]
File "./elftools/construct/lib/container.py", line 35, in __getitem__
return self.__dict__[name]
KeyError: 'r_addend'
This is because I changed ENUM_RELOC_TYPE_MIPS['R_MIPS_32']
to have has_addend=True
. If I change it back to False
, this fails:
❯ venv/bin/python test/run_dwarfdump_tests.py test/testfiles_for_dwarfdump/dwarf_mips64el.o.elf
Test file 'test/testfiles_for_dwarfdump/dwarf_mips64el.o.elf'
.......................FAIL
....for file test/testfiles_for_dwarfdump/dwarf_mips64el.o.elf
....for option "--debug-info"
....Output #1 is llvm-dwarfdump, Output #2 is pyelftools
@@ Mismatch on line #6:
>> dw_at_name [dw_form_strp] ( .debug_str[0x000000dc] = "./dwarf_mips64el.c")<<
>> dw_at_name [dw_form_strp] ( .debug_str[0x00000000] = "gnu c17 12.2.0 -mel -march=mips64r2 -mabi=64 -mllsc -mips64r2 -g -o2 -fpic -fstack-protector-strong -fno-strict-overflow -frandom-seed=kdyy43gwzl --param=ssp-buffer-size=4")<<
([('equal', 0, 61, 0, 61), ('replace', 61, 63, 61, 63), ('equal', 63, 68, 63, 68), ('insert', 68, 68, 68, 78), ('equal', 68, 69, 78, 79), ('replace', 69, 76, 79, 95), ('equal', 76, 82, 95, 101), ('replace', 82, 86, 101, 239), ('equal', 86, 88, 239, 241)])
@@ Output #1 dumped to file: /tmp/out-1-dwarf_mips64el.o.elf---debug-info-l4hdubyk.stdout
@@ Output #2 dumped to file: /tmp/out-2-dwarf_mips64el.o.elf---debug-info-ng5agd0v.stdout
Conclusion: FAIL
I have figured it was OK to remove this field from the recipe, since you can know if there is an r_addend
field from the relocation object.
Anyway, I now created another branch without removing the r_addend
field, which instead uses two recipe dicts instead of one: _RELOCATION_RECIPES_MIPS_RELA
and _RELOCATION_RECIPES_MIPS_REL
. It's here: https://github.com/noamraph/pyelftools/tree/mips64-o-with-has-addend
What do you think? Do you prefer the latter approach?
Thanks!
Noam
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you please send your other branch as a separate PR? It should be easy to create a new PR from a different branch. A PR lets me see the delta/patch of the change much more conveniently than looking at a whole branch
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. Here it is: #495
Closing, since #495 was merged |
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 directorytest/testfiles_for_dwarfdump/dwarf_mips64el
and runnix build
. Copy the fileresult/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 beDW_OP_addr 0x0
, while pyelftools reportsDW_OP_addr 0x4
. I think that pyelftools is right, since it agrees with gcc's objdump. To verify, go totest/testfiles_for_dwarfdump/dwarf_mips64el
and run:You get:
To workaround this, I modified
run_dwarfdump_tests.py
to change the output ofllvm-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 addaddend
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 theR_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