This is an archive of the discontinued LLVM Phabricator instance.

[ORC] Add a utility for adding missing "self" relocations to a Symbol
ClosedPublic

Authored by benlangmuir on Nov 2 2021, 11:30 AM.

Details

Summary

If a tool wants to introduce new indirections via stubs at link-time in
ORC, it can cause fidelity issues around the address of the function if
some references to the function do not have relocations. This is known
to happen inside the body of the function itself on x86_64 for example,
where a PC-relative address is formed, but without a relocation.

_foo:
  leaq -7(%rip), %rax ## form pointer to '_foo' without relocation

_bar:
  leaq (%rip), %rax ##  uses X86_64_RELOC_SIGNED to '_foo'

The consequence of introducing a stub for such a function at link time
is that if it forms a pointer to itself without relocation, it will not
have the same value as a pointer from outside the function. If the
function pointer is used as a key, this can cause problems.

This utility provides best-effort support for adding such missing
relocations using MCDisassembler and MCInstrAnalysis to identify the
problematic instructions. Currently it is only implemented for x86_64.

Note: the related issue with call/jump instructions is not handled
here, only forming function pointers.

rdar://83514317

Diff Detail

Event Timeline

benlangmuir created this revision.Nov 2 2021, 11:30 AM
benlangmuir requested review of this revision.Nov 2 2021, 11:30 AM
Herald added a project: Restricted Project. · View Herald TranscriptNov 2 2021, 11:30 AM
benlangmuir added inline comments.Nov 2 2021, 11:37 AM
llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
447

I wasn't sure if it was worth zeroing out the existing addend in the instruction stream - it would seem to be "nice" to zero it out to ensure we're depending on the relocation instead of the original addend, but it seems to get overwritten completely when we perform the fixup anyway and the contents of the block need to be copied and made mutable to make any changes.

lhames accepted this revision.Nov 4 2021, 1:18 PM

We should fix MC to emit the missing relocations, but we'll have a lot of legacy objects to deal with -- this is a great solution for those.

LGTM.

llvm/lib/ExecutionEngine/Orc/IndirectionUtils.cpp
447

We've never formalized this as a policy but in practice JITLink relocations always overwrite all operand bits, so it should be safe to leave the existing ones in there. I think leaving the bits as-is is the right trade-off.

llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
412–413

My knee-jerk reaction was "what happens if there are multiple memory operands", but we've already got evaluateMemoryOperandAddress above so there's some precedent for assuming one memory operand.

This revision is now accepted and ready to land.Nov 4 2021, 1:18 PM