diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h index 990629de2f1..16a0f6ef2a7 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/Targets/RuntimeDyldMachOARM.h @@ -47,6 +47,18 @@ public: return Addr; } + bool isAddrTargetThumb(unsigned SectionID, uint64_t Offset) { + auto TargetObjAddr = Sections[SectionID].getObjAddress() + Offset; + for (auto &KV : GlobalSymbolTable) { + auto &Entry = KV.second; + auto SymbolObjAddr = + Sections[Entry.getSectionID()].getObjAddress() + Entry.getOffset(); + if (TargetObjAddr == SymbolObjAddr) + return (Entry.getFlags().getTargetFlags() & ARMJITSymbolFlags::Thumb); + } + return false; + } + Expected<int64_t> decodeAddend(const RelocationEntry &RE) const { const SectionEntry &Section = Sections[RE.SectionID]; uint8_t *LocalAddress = Section.getAddressWithOffset(RE.Offset); @@ -161,12 +173,18 @@ public: // the value as being a thumb stub: we don't want to mix it up with an ARM // stub targeting the same function. if (RE.RelType == MachO::ARM_THUMB_RELOC_BR22) - Value.IsStubThumb = TargetIsLocalThumbFunc; + Value.IsStubThumb = true; if (RE.IsPCRel) makeValueAddendPCRel(Value, RelI, (RE.RelType == MachO::ARM_THUMB_RELOC_BR22) ? 4 : 8); + // If this is a non-external branch target check whether Value points to a + // thumb func. + if (!Value.SymbolName && (RelType == MachO::ARM_RELOC_BR24 || + RelType == MachO::ARM_THUMB_RELOC_BR22)) + RE.IsTargetThumbFunc = isAddrTargetThumb(Value.SectionID, Value.Offset); + if (RE.RelType == MachO::ARM_RELOC_BR24 || RE.RelType == MachO::ARM_THUMB_RELOC_BR22) processBranchRelocation(RE, Value, Stubs); |