Skip to content
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

Implement diffing relocations within data sections #154

Merged
merged 9 commits into from
Jan 18, 2025

Conversation

LagoLunatic
Copy link
Contributor

Because objdiff does not link the base object, and it only compares the raw bytes of data sections with each other, any differing relocations inside data will not show as a diff in the current version of objdiff. This can make them difficult to fix. And for objects that can't be linked and have their hash checked due to other reasons like regalloc or weak function ordering, it can be nearly impossible to even know when these issues exist in the first place, which can result in objects that appear equivalent but have nonequivalent relocations.

Some common cases where this can happen include*:

  • Arrays of function pointers
  • PTMF literals
  • Jump tables used by switch statements

To help avoid this issue, this PR implements diffing for relocations in data.


In the data diff view, bytes that contain relocations that don't match will show highlighted as different, even though the bytes themselves (00) are the same:
image

Hovering over a row that contains at least one relocation will show all relocations in that row on that side (both matching and nonmatching relocations):
image
Which specific byte the user hovered over can't be detected, so multiple relocations in a single line will be shown together (hopefully this isn't too confusing).

You can also right click a reloc to copy its target symbol name:
image


In the symbol listing view, paired symbols that don't have matching relocations with their counterpart will show less than 100%:
image
Specifically, each byte containing a relocation will be counted twice for the percentage: once for if the value of the unlinked byte itself matches, and a second time for if the relocation matches.

The section's overall match percent will look at the entire section, not each individual symbol. This means that the section may show less than 100% even when each individual symbol's relocations match 100% when the symbols are out of order in the section, such as weak vtables:
image


When vtables are not out of order, but instead there are weak stripped vtables in the middle of the section, the diff looks a bit weird:
image
It shows a bunch of diffs here because the vtables are shifted, and so its diffing the stripped vtables with the unstripped vtables (this is a result of objdiff showing the entire section at once in the data diff view).
But I don't think this is a big deal as it doesn't show any diffs when you go back to the symbol list view, this is the same object:
image


I've only tested this for PPC architecture. In theory it should work on other architectures too, as I added arch-specific code to detect how many bytes each relocation takes up, but I'm not sure.

(*Specific examples of these issues that were found and fixed while testing this PR can be seen here zeldaret/tww@8e44641 and here zeldaret/tp@2189777)

@encounter encounter merged commit a4fdb61 into encounter:main Jan 18, 2025
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants