-
Notifications
You must be signed in to change notification settings - Fork 55
Description
When compiling C++ with clang (at least on 3.9.1), the compiler might not output a relocation for branch targets within the same translation unit/object file.
Example:
00000000000001a4 <_ZN6Player7exeWaitEv>:
1a4: f81e0ff3 str x19, [sp, #-32]!
1a8: a9017bfd stp x29, x30, [sp, #16]
[...]
00000000000008b8 <_ZNK12_GLOBAL__N_113PlayerNrvWait7executeEPN2al11NerveKeeperE>:
8b8: f9400020 ldr x0, [x1]
8bc: 17fffe3a b 1a4 <_ZN6Player7exeWaitEv>
The final branch at 8bc outputs no relocation here:
[...]
0000000000000878 R_AARCH64_ADR_PREL_PG_HI21 .data+0x0000000000000020
000000000000087c R_AARCH64_ADD_ABS_LO12_NC .data+0x0000000000000020
0000000000000884 R_AARCH64_CALL26 _ZN2al8setNerveEPNS_9IUseNerveEPKNS_5NerveE
RELOCATION RECORDS FOR [.text._ZN4sead14SafeStringBaseIcED0Ev]:
[...]
An example file can be found here:
Player.zip
Source: https://github.com/MonsterDruide1/OdysseyDecomp/blob/master/src/Player/Player.cpp
Just put it into a diff on both sides, and check one of the (anonymous namespace):: entries, for example (anonymous namespace)::PlayerNrvWait::execute(al::NerveKeeper*) const. objdiff correctly finds it matching (100%), but displays b $<invalid> for the branch.
A relevant point to start investigation is here:
https://github.com/encounter/objdiff/blob/main/objdiff-core/src/diff/display.rs#L274
In this case, dest = 0x1a4, resolved.symbol.address = 0x8bc, so the u64.checked_sub fails.