diff options
Diffstat (limited to 'contrib/llvm-project/lld/MachO/Arch/ARM.cpp')
-rw-r--r-- | contrib/llvm-project/lld/MachO/Arch/ARM.cpp | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/contrib/llvm-project/lld/MachO/Arch/ARM.cpp b/contrib/llvm-project/lld/MachO/Arch/ARM.cpp index 7de0837fcf38..fd215ed99b59 100644 --- a/contrib/llvm-project/lld/MachO/Arch/ARM.cpp +++ b/contrib/llvm-project/lld/MachO/Arch/ARM.cpp @@ -40,6 +40,9 @@ struct ARM : TargetInfo { void relaxGotLoad(uint8_t *loc, uint8_t type) const override; const RelocAttrs &getRelocAttrs(uint8_t type) const override; uint64_t getPageSize() const override { return 4 * 1024; } + + void handleDtraceReloc(const Symbol *sym, const Reloc &r, + uint8_t *loc) const override; }; } // namespace @@ -170,3 +173,36 @@ TargetInfo *macho::createARMTargetInfo(uint32_t cpuSubtype) { static ARM t(cpuSubtype); return &t; } + +void ARM::handleDtraceReloc(const Symbol *sym, const Reloc &r, + uint8_t *loc) const { + if (config->outputType == MH_OBJECT) + return; + + switch (r.type) { + case ARM_RELOC_BR24: + if (sym->getName().startswith("___dtrace_probe")) { + // change call site to a NOP + write32le(loc, 0xE1A00000); + } else if (sym->getName().startswith("___dtrace_isenabled")) { + // change call site to 'eor r0, r0, r0' + write32le(loc, 0xE0200000); + } else { + error("Unrecognized dtrace symbol prefix: " + toString(*sym)); + } + break; + case ARM_THUMB_RELOC_BR22: + if (sym->getName().startswith("___dtrace_probe")) { + // change 32-bit blx call site to two thumb NOPs + write32le(loc, 0x46C046C0); + } else if (sym->getName().startswith("___dtrace_isenabled")) { + // change 32-bit blx call site to 'nop', 'eor r0, r0' + write32le(loc, 0x46C04040); + } else { + error("Unrecognized dtrace symbol prefix: " + toString(*sym)); + } + break; + default: + llvm_unreachable("Unsupported dtrace relocation type for ARM"); + } +} |