Tests fail because Mimick fails to inject the mock in the right place. ELF support first checks for the fn_vv symbol in the .rela.dyn section and only goes look for it in the .rela.plt section if it fails the first lookup. I can see the mmk_test executable shows two relocations for that symbol, one in each table.
Relocation section '.rela.dyn' at offset 0x1670 contains 24 entries:
Offset Info Type Sym. Value Sym. Name + Addend
...
000000022f60 000900000401 R_AARCH64_GLOB_DA 0000000000000000 fn_vv + 0
...
000000022f78 000c00000401 R_AARCH64_GLOB_DA 0000000000000000 fn_ii + 0
000000022f80 000d00000401 R_AARCH64_GLOB_DA 0000000000000000 fn_ii_va + 0
...
Relocation section '.rela.plt' at offset 0x18b0 contains 18 entries:
Offset Info Type Sym. Value Sym. Name + Addend
...
000000023020 000900000402 R_AARCH64_JUMP_SL 0000000000000000 fn_vv + 0
000000023030 000c00000402 R_AARCH64_JUMP_SL 0000000000000000 fn_ii + 0
000000023038 000d00000402 R_AARCH64_JUMP_SL 0000000000000000 fn_ii_va + 0
...
Stepping through machine code, I can see Mimick puts the mock trampoline in the GOT but trampolines in code use the PLT's GOT.
Discussion
I failed to find a concise and complete explanation out there as to why two relocations are showing in my aarch64 box. My recollection so far is that, in the most general case, a dynamic ELF executable needs both an R_<ARCH>_JUMP_SLOT relocation in the .rela.plt section for lazy binding of an external callable symbol and an R_<ARCH>_GLOB_DAT relocation in the .rela.dyn section when/if the address of an external callable symbol is requested (i.e. the function pointer). And while some linkers may perform an optimization and deduplicate this information, they are not bound to do so.
@Snaipe does that sound reasonable? I can see plt_get_offsets() is capable of returning multiple offsets. Did you intend to support such cases?
System details
aarch64
cmake
3.16.3gcc
9.3.0ld
2.34Bug report
Tests fail because Mimick fails to inject the mock in the right place. ELF support first checks for the
fn_vv
symbol in the.rela.dyn
section and only goes look for it in the.rela.plt
section if it fails the first lookup. I can see themmk_test
executable shows two relocations for that symbol, one in each table.Stepping through machine code, I can see
Mimick
puts the mock trampoline in the GOT but trampolines in code use the PLT's GOT.Discussion
I failed to find a concise and complete explanation out there as to why two relocations are showing in my
aarch64
box. My recollection so far is that, in the most general case, a dynamic ELF executable needs both anR_<ARCH>_JUMP_SLOT
relocation in the.rela.plt
section for lazy binding of an external callable symbol and anR_<ARCH>_GLOB_DAT
relocation in the.rela.dyn
section when/if the address of an external callable symbol is requested (i.e. the function pointer). And while some linkers may perform an optimization and deduplicate this information, they are not bound to do so.@Snaipe does that sound reasonable? I can see
plt_get_offsets()
is capable of returning multiple offsets. Did you intend to support such cases?