[lld] 5433a79 - [lld-macho][nfc] Create Relocations.{h,cpp} for relocation-specific code

Jez Ng via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 11 10:28:41 PST 2021


Author: Jez Ng
Date: 2021-03-11T13:28:09-05:00
New Revision: 5433a79176a3dac3158c6db792a5938bdc24b905

URL: https://github.com/llvm/llvm-project/commit/5433a79176a3dac3158c6db792a5938bdc24b905
DIFF: https://github.com/llvm/llvm-project/commit/5433a79176a3dac3158c6db792a5938bdc24b905.diff

LOG: [lld-macho][nfc] Create Relocations.{h,cpp} for relocation-specific code

This more closely mirrors the structure of lld-ELF.

Reviewed By: #lld-macho, thakis

Differential Revision: https://reviews.llvm.org/D98384

Added: 
    lld/MachO/Relocations.cpp
    lld/MachO/Relocations.h

Modified: 
    lld/MachO/Arch/ARM64.cpp
    lld/MachO/Arch/X86_64.cpp
    lld/MachO/CMakeLists.txt
    lld/MachO/InputFiles.cpp
    lld/MachO/InputSection.cpp
    lld/MachO/InputSection.h
    lld/MachO/Target.cpp
    lld/MachO/Target.h
    lld/MachO/Writer.cpp

Removed: 
    


################################################################################
diff  --git a/lld/MachO/Arch/ARM64.cpp b/lld/MachO/Arch/ARM64.cpp
index c14114f5ca64..7419046c8e0b 100644
--- a/lld/MachO/Arch/ARM64.cpp
+++ b/lld/MachO/Arch/ARM64.cpp
@@ -39,7 +39,7 @@ struct ARM64 : TargetInfo {
                             uint64_t entryAddr) const override;
 
   void relaxGotLoad(uint8_t *loc, uint8_t type) const override;
-  const TargetInfo::RelocAttrs &getRelocAttrs(uint8_t type) const override;
+  const RelocAttrs &getRelocAttrs(uint8_t type) const override;
   uint64_t getPageSize() const override { return 16 * 1024; }
 };
 
@@ -52,8 +52,8 @@ struct ARM64 : TargetInfo {
 // are weird -- it results in the value of the GOT slot being written, instead
 // of the address. Let's not support it unless we find a real-world use case.
 
-const TargetInfo::RelocAttrs &ARM64::getRelocAttrs(uint8_t type) const {
-  static const std::array<TargetInfo::RelocAttrs, 11> relocAttrsArray{{
+const RelocAttrs &ARM64::getRelocAttrs(uint8_t type) const {
+  static const std::array<RelocAttrs, 11> relocAttrsArray{{
 #define B(x) RelocAttrBits::x
       {"UNSIGNED", B(UNSIGNED) | B(ABSOLUTE) | B(EXTERN) | B(LOCAL) |
                        B(DYSYM8) | B(BYTE4) | B(BYTE8)},
@@ -73,7 +73,7 @@ const TargetInfo::RelocAttrs &ARM64::getRelocAttrs(uint8_t type) const {
   }};
   assert(type < relocAttrsArray.size() && "invalid relocation type");
   if (type >= relocAttrsArray.size())
-    return TargetInfo::invalidRelocAttrs;
+    return invalidRelocAttrs;
   return relocAttrsArray[type];
 }
 

diff  --git a/lld/MachO/Arch/X86_64.cpp b/lld/MachO/Arch/X86_64.cpp
index e7624b5e5558..112e2f214050 100644
--- a/lld/MachO/Arch/X86_64.cpp
+++ b/lld/MachO/Arch/X86_64.cpp
@@ -36,14 +36,14 @@ struct X86_64 : TargetInfo {
                             uint64_t entryAddr) const override;
 
   void relaxGotLoad(uint8_t *loc, uint8_t type) const override;
-  const TargetInfo::RelocAttrs &getRelocAttrs(uint8_t type) const override;
+  const RelocAttrs &getRelocAttrs(uint8_t type) const override;
   uint64_t getPageSize() const override { return 4 * 1024; }
 };
 
 } // namespace
 
-const TargetInfo::RelocAttrs &X86_64::getRelocAttrs(uint8_t type) const {
-  static const std::array<TargetInfo::RelocAttrs, 10> relocAttrsArray{{
+const RelocAttrs &X86_64::getRelocAttrs(uint8_t type) const {
+  static const std::array<RelocAttrs, 10> relocAttrsArray{{
 #define B(x) RelocAttrBits::x
       {"UNSIGNED", B(UNSIGNED) | B(ABSOLUTE) | B(EXTERN) | B(LOCAL) |
                        B(DYSYM8) | B(BYTE4) | B(BYTE8)},
@@ -60,7 +60,7 @@ const TargetInfo::RelocAttrs &X86_64::getRelocAttrs(uint8_t type) const {
   }};
   assert(type < relocAttrsArray.size() && "invalid relocation type");
   if (type >= relocAttrsArray.size())
-    return TargetInfo::invalidRelocAttrs;
+    return invalidRelocAttrs;
   return relocAttrsArray[type];
 }
 

diff  --git a/lld/MachO/CMakeLists.txt b/lld/MachO/CMakeLists.txt
index 7eeec910724d..8eb3371580b7 100644
--- a/lld/MachO/CMakeLists.txt
+++ b/lld/MachO/CMakeLists.txt
@@ -19,6 +19,7 @@ add_lld_library(lldMachO2
   ObjC.cpp
   OutputSection.cpp
   OutputSegment.cpp
+  Relocations.cpp
   SymbolTable.cpp
   Symbols.cpp
   SyntheticSections.cpp

diff  --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp
index 1f73e893c2c7..5ec0bf611c84 100644
--- a/lld/MachO/InputFiles.cpp
+++ b/lld/MachO/InputFiles.cpp
@@ -203,7 +203,7 @@ static InputSection *findContainingSubsection(SubsectionMap &map,
 
 static bool validateRelocationInfo(InputFile *file, const section_64 &sec,
                                    relocation_info rel) {
-  const TargetInfo::RelocAttrs &relocAttrs = target->getRelocAttrs(rel.r_type);
+  const RelocAttrs &relocAttrs = target->getRelocAttrs(rel.r_type);
   bool valid = true;
   auto message = [relocAttrs, file, sec, rel, &valid](const Twine &diagnostic) {
     valid = false;

diff  --git a/lld/MachO/InputSection.cpp b/lld/MachO/InputSection.cpp
index 18c2543ddf6c..a54d83618bb0 100644
--- a/lld/MachO/InputSection.cpp
+++ b/lld/MachO/InputSection.cpp
@@ -36,7 +36,7 @@ uint64_t InputSection::getVA() const { return parent->addr + outSecOff; }
 
 static uint64_t resolveSymbolVA(uint8_t *loc, const lld::macho::Symbol &sym,
                                 uint8_t type) {
-  const TargetInfo::RelocAttrs &relocAttrs = target->getRelocAttrs(type);
+  const RelocAttrs &relocAttrs = target->getRelocAttrs(type);
   if (relocAttrs.hasAttr(RelocAttrBits::BRANCH)) {
     if (sym.isInStubs())
       return in.stubs->addr + sym.stubsIndex * target->stubSize;

diff  --git a/lld/MachO/InputSection.h b/lld/MachO/InputSection.h
index 249f55cc27bc..c83a547b932f 100644
--- a/lld/MachO/InputSection.h
+++ b/lld/MachO/InputSection.h
@@ -9,9 +9,10 @@
 #ifndef LLD_MACHO_INPUT_SECTION_H
 #define LLD_MACHO_INPUT_SECTION_H
 
+#include "Relocations.h"
+
 #include "lld/Common/LLVM.h"
 #include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/PointerUnion.h"
 #include "llvm/BinaryFormat/MachO.h"
 
 namespace lld {
@@ -23,19 +24,6 @@ class OutputSection;
 class Symbol;
 class Defined;
 
-struct Reloc {
-  uint8_t type = llvm::MachO::GENERIC_RELOC_INVALID;
-  bool pcrel = false;
-  uint8_t length = 0;
-  // The offset from the start of the subsection that this relocation belongs
-  // to.
-  uint32_t offset = 0;
-  // Adding this offset to the address of the referent symbol or subsection
-  // gives the destination that this relocation refers to.
-  uint64_t addend = 0;
-  llvm::PointerUnion<Symbol *, InputSection *> referent = nullptr;
-};
-
 class InputSection {
 public:
   virtual ~InputSection() = default;

diff  --git a/lld/MachO/Relocations.cpp b/lld/MachO/Relocations.cpp
new file mode 100644
index 000000000000..a60dbb21ff9e
--- /dev/null
+++ b/lld/MachO/Relocations.cpp
@@ -0,0 +1,42 @@
+//===- Relocations.cpp ----------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Relocations.h"
+#include "Symbols.h"
+#include "SyntheticSections.h"
+#include "Target.h"
+
+#include "lld/Common/ErrorHandler.h"
+
+using namespace llvm;
+using namespace lld;
+using namespace lld::macho;
+
+bool macho::validateSymbolRelocation(const Symbol *sym,
+                                     const InputSection *isec, const Reloc &r) {
+  const RelocAttrs &relocAttrs = target->getRelocAttrs(r.type);
+  bool valid = true;
+  auto message = [relocAttrs, sym, isec, &valid](const Twine &diagnostic) {
+    valid = false;
+    return (relocAttrs.name + " relocation " + diagnostic + " for `" +
+            sym->getName() + "' in " + toString(isec))
+        .str();
+  };
+
+  if (relocAttrs.hasAttr(RelocAttrBits::TLV) != sym->isTlv())
+    error(message(Twine("requires that variable ") +
+                  (sym->isTlv() ? "not " : "") + "be thread-local"));
+  if (relocAttrs.hasAttr(RelocAttrBits::DYSYM8) && isa<DylibSymbol>(sym) &&
+      r.length != 3)
+    error(message("has width " + std::to_string(1 << r.length) +
+                  " bytes, but must be 8 bytes"));
+
+  return valid;
+}
+
+const RelocAttrs macho::invalidRelocAttrs{"INVALID", RelocAttrBits::_0};

diff  --git a/lld/MachO/Relocations.h b/lld/MachO/Relocations.h
new file mode 100644
index 000000000000..21a27aba14ac
--- /dev/null
+++ b/lld/MachO/Relocations.h
@@ -0,0 +1,74 @@
+//===- Relocations.h --------------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_MACHO_RELOCATIONS_H
+#define LLD_MACHO_RELOCATIONS_H
+
+#include "llvm/ADT/BitmaskEnum.h"
+#include "llvm/ADT/PointerUnion.h"
+#include "llvm/BinaryFormat/MachO.h"
+
+#include <cstddef>
+#include <cstdint>
+
+namespace lld {
+namespace macho {
+LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
+
+class Symbol;
+class InputSection;
+
+enum class RelocAttrBits {
+  _0 = 0,              // invalid
+  PCREL = 1 << 0,      // Value is PC-relative offset
+  ABSOLUTE = 1 << 1,   // Value is an absolute address or fixed offset
+  BYTE4 = 1 << 2,      // 4 byte datum
+  BYTE8 = 1 << 3,      // 8 byte datum
+  EXTERN = 1 << 4,     // Can have an external symbol
+  LOCAL = 1 << 5,      // Can have a local symbol
+  ADDEND = 1 << 6,     // *_ADDEND paired prefix reloc
+  SUBTRAHEND = 1 << 7, // *_SUBTRACTOR paired prefix reloc
+  BRANCH = 1 << 8,     // Value is branch target
+  GOT = 1 << 9,        // References a symbol in the Global Offset Table
+  TLV = 1 << 10,       // References a thread-local symbol
+  DYSYM8 = 1 << 11,    // Requires DySym width to be 8 bytes
+  LOAD = 1 << 12,      // Relaxable indirect load
+  POINTER = 1 << 13,   // Non-relaxable indirect load (pointer is taken)
+  UNSIGNED = 1 << 14,  // *_UNSIGNED relocs
+  LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ (1 << 15) - 1),
+};
+// Note: SUBTRACTOR always pairs with UNSIGNED (a delta between two symbols).
+
+struct RelocAttrs {
+  llvm::StringRef name;
+  RelocAttrBits bits;
+  bool hasAttr(RelocAttrBits b) const { return (bits & b) == b; }
+};
+
+struct Reloc {
+  uint8_t type = llvm::MachO::GENERIC_RELOC_INVALID;
+  bool pcrel = false;
+  uint8_t length = 0;
+  // The offset from the start of the subsection that this relocation belongs
+  // to.
+  uint32_t offset = 0;
+  // Adding this offset to the address of the referent symbol or subsection
+  // gives the destination that this relocation refers to.
+  uint64_t addend = 0;
+  llvm::PointerUnion<Symbol *, InputSection *> referent = nullptr;
+};
+
+bool validateSymbolRelocation(const Symbol *, const InputSection *,
+                              const Reloc &);
+
+extern const RelocAttrs invalidRelocAttrs;
+
+} // namespace macho
+} // namespace lld
+
+#endif

diff  --git a/lld/MachO/Target.cpp b/lld/MachO/Target.cpp
index a37d1f76ae31..0f70776a507f 100644
--- a/lld/MachO/Target.cpp
+++ b/lld/MachO/Target.cpp
@@ -7,40 +7,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "Target.h"
-#include "InputSection.h"
-#include "Symbols.h"
-#include "SyntheticSections.h"
 
-#include "lld/Common/ErrorHandler.h"
-
-using namespace llvm;
 using namespace lld;
 using namespace lld::macho;
 
-const TargetInfo::RelocAttrs TargetInfo::invalidRelocAttrs{"INVALID",
-                                                           RelocAttrBits::_0};
-
-bool TargetInfo::validateSymbolRelocation(const Symbol *sym,
-                                          const InputSection *isec,
-                                          const Reloc &r) {
-  const RelocAttrs &relocAttrs = getRelocAttrs(r.type);
-  bool valid = true;
-  auto message = [relocAttrs, sym, isec, &valid](const Twine &diagnostic) {
-    valid = false;
-    return (relocAttrs.name + " relocation " + diagnostic + " for `" +
-            sym->getName() + "' in " + toString(isec))
-        .str();
-  };
-
-  if (relocAttrs.hasAttr(RelocAttrBits::TLV) != sym->isTlv())
-    error(message(Twine("requires that variable ") +
-                  (sym->isTlv() ? "not " : "") + "be thread-local"));
-  if (relocAttrs.hasAttr(RelocAttrBits::DYSYM8) && isa<DylibSymbol>(sym) &&
-      r.length != 3)
-    error(message("has width " + std::to_string(1 << r.length) +
-                  " bytes, but must be 8 bytes"));
-
-  return valid;
-}
-
 TargetInfo *macho::target = nullptr;

diff  --git a/lld/MachO/Target.h b/lld/MachO/Target.h
index 4ad833fae43a..2563bc1e987d 100644
--- a/lld/MachO/Target.h
+++ b/lld/MachO/Target.h
@@ -9,6 +9,8 @@
 #ifndef LLD_MACHO_TARGET_H
 #define LLD_MACHO_TARGET_H
 
+#include "Relocations.h"
+
 #include "llvm/ADT/BitmaskEnum.h"
 #include "llvm/BinaryFormat/MachO.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -23,7 +25,6 @@ LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
 class Symbol;
 class DylibSymbol;
 class InputSection;
-struct Reloc;
 
 enum : uint64_t {
   // We are currently only supporting 64-bit targets since macOS and iOS are
@@ -33,36 +34,8 @@ enum : uint64_t {
   MaxAlignmentPowerOf2 = 32,
 };
 
-enum class RelocAttrBits {
-  _0 = 0,              // invalid
-  PCREL = 1 << 0,      // Value is PC-relative offset
-  ABSOLUTE = 1 << 1,   // Value is an absolute address or fixed offset
-  BYTE4 = 1 << 2,      // 4 byte datum
-  BYTE8 = 1 << 3,      // 8 byte datum
-  EXTERN = 1 << 4,     // Can have an external symbol
-  LOCAL = 1 << 5,      // Can have a local symbol
-  ADDEND = 1 << 6,     // *_ADDEND paired prefix reloc
-  SUBTRAHEND = 1 << 7, // *_SUBTRACTOR paired prefix reloc
-  BRANCH = 1 << 8,     // Value is branch target
-  GOT = 1 << 9,        // References a symbol in the Global Offset Table
-  TLV = 1 << 10,       // References a thread-local symbol
-  DYSYM8 = 1 << 11,    // Requires DySym width to be 8 bytes
-  LOAD = 1 << 12,      // Relaxable indirect load
-  POINTER = 1 << 13,   // Non-relaxable indirect load (pointer is taken)
-  UNSIGNED = 1 << 14,  // *_UNSIGNED relocs
-  LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue*/ (1 << 15) - 1),
-};
-// Note: SUBTRACTOR always pairs with UNSIGNED (a delta between two symbols).
-
 class TargetInfo {
 public:
-  struct RelocAttrs {
-    llvm::StringRef name;
-    RelocAttrBits bits;
-    bool hasAttr(RelocAttrBits b) const { return (bits & b) == b; }
-  };
-  static const RelocAttrs invalidRelocAttrs;
-
   virtual ~TargetInfo() = default;
 
   // Validate the relocation structure and get its addend.
@@ -97,8 +70,6 @@ class TargetInfo {
   bool validateRelocationInfo(llvm::MemoryBufferRef,
                               const llvm::MachO::section_64 &sec,
                               llvm::MachO::relocation_info);
-  bool validateSymbolRelocation(const Symbol *, const InputSection *isec,
-                                const Reloc &);
   void prepareSymbolRelocation(Symbol *, const InputSection *, const Reloc &);
 
   uint32_t cpuType;

diff  --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 78245f5d5f7e..dbf20742358d 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -444,7 +444,7 @@ class LCCodeSignature : public LoadCommand {
 
 static void prepareSymbolRelocation(lld::macho::Symbol *sym,
                                     const InputSection *isec, const Reloc &r) {
-  const TargetInfo::RelocAttrs &relocAttrs = target->getRelocAttrs(r.type);
+  const RelocAttrs &relocAttrs = target->getRelocAttrs(r.type);
 
   if (relocAttrs.hasAttr(RelocAttrBits::BRANCH)) {
     prepareBranchTarget(sym);
@@ -484,8 +484,7 @@ void Writer::scanRelocations() {
         if (auto *undefined = dyn_cast<Undefined>(sym))
           treatUndefinedSymbol(*undefined);
         // treatUndefinedSymbol() can replace sym with a DylibSymbol; re-check.
-        if (!isa<Undefined>(sym) &&
-            target->validateSymbolRelocation(sym, isec, r))
+        if (!isa<Undefined>(sym) && validateSymbolRelocation(sym, isec, r))
           prepareSymbolRelocation(sym, isec, r);
       } else {
         assert(r.referent.is<InputSection *>());


        


More information about the llvm-commits mailing list