diff --git a/llvm/test/tools/llvm-objcopy/MachO/arm64-relocs.s b/llvm/test/tools/llvm-objcopy/MachO/arm64-relocs.s new file mode 100644 --- /dev/null +++ b/llvm/test/tools/llvm-objcopy/MachO/arm64-relocs.s @@ -0,0 +1,16 @@ +# REQUIRES: aarch64-registered-target + +# RUN: llvm-mc -filetype=obj -triple=arm64-apple-darwin %s -o %t +# RUN: llvm-objcopy %t %t.copy +# RUN: cmp %t %t.copy + +.text +.globl _foo, _bar +_foo: + ## ARM64_RELOC_ADDEND and ARM64_RELOC_BRANCH26 + bl _bar + 123 + +_bar: + ret + +.subsections_via_symbols diff --git a/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp b/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp --- a/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp +++ b/llvm/tools/llvm-objcopy/MachO/MachOReader.cpp @@ -94,6 +94,7 @@ S.Content = StringRef(reinterpret_cast(Data->data()), Data->size()); + const uint32_t CPUType = MachOObj.getHeader().cputype; S.Relocations.reserve(S.NReloc); for (auto RI = MachOObj.section_rel_begin(SecRef->getRawDataRefImpl()), RE = MachOObj.section_rel_end(SecRef->getRawDataRefImpl()); @@ -102,6 +103,10 @@ R.Symbol = nullptr; // We'll fill this field later. R.Info = MachOObj.getRelocation(RI->getRawDataRefImpl()); R.Scattered = MachOObj.isRelocationScattered(R.Info); + unsigned Type = MachOObj.getAnyRelocationType(R.Info); + // TODO Support CPU_TYPE_ARM. + R.IsAddend = !R.Scattered && (CPUType == MachO::CPU_TYPE_ARM64 && + Type == MachO::ARM64_RELOC_ADDEND); R.Extern = !R.Scattered && MachOObj.getPlainRelocationExternal(R.Info); S.Relocations.push_back(R); } @@ -222,7 +227,7 @@ for (LoadCommand &LC : O.LoadCommands) for (std::unique_ptr
&Sec : LC.Sections) for (auto &Reloc : Sec->Relocations) - if (!Reloc.Scattered) { + if (!Reloc.Scattered && !Reloc.IsAddend) { const uint32_t SymbolNum = Reloc.getPlainRelocationSymbolNum(MachOObj.isLittleEndian()); if (Reloc.Extern) { diff --git a/llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp b/llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp --- a/llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp +++ b/llvm/tools/llvm-objcopy/MachO/MachOWriter.cpp @@ -261,7 +261,7 @@ Sec->Content.size()); for (size_t Index = 0; Index < Sec->Relocations.size(); ++Index) { RelocationInfo RelocInfo = Sec->Relocations[Index]; - if (!RelocInfo.Scattered) { + if (!RelocInfo.Scattered && !RelocInfo.IsAddend) { const uint32_t SymbolNum = RelocInfo.Extern ? (*RelocInfo.Symbol)->Index : (*RelocInfo.Sec)->Index; diff --git a/llvm/tools/llvm-objcopy/MachO/Object.h b/llvm/tools/llvm-objcopy/MachO/Object.h --- a/llvm/tools/llvm-objcopy/MachO/Object.h +++ b/llvm/tools/llvm-objcopy/MachO/Object.h @@ -180,6 +180,9 @@ Optional Sec; // True if Info is a scattered_relocation_info. bool Scattered; + // True if the type is an ADDEND. r_symbolnum holds the addend instead of a + // symbol index. + bool IsAddend; // True if the r_symbolnum points to a section number (i.e. r_extern=0). bool Extern; MachO::any_relocation_info Info;