[lld] r212239 - [mach-o] add parsing of x86 relocations

Nick Kledzik kledzik at apple.com
Wed Jul 2 16:52:22 PDT 2014


Author: kledzik
Date: Wed Jul  2 18:52:22 2014
New Revision: 212239

URL: http://llvm.org/viewvc/llvm-project?rev=212239&view=rev
Log:
[mach-o] add parsing of x86 relocations

Added:
    lld/trunk/test/mach-o/parse-relocs-x86.yaml
Modified:
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
    lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.cpp
    lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.h
    lld/trunk/test/mach-o/parse-cfstring32.yaml
    lld/trunk/test/mach-o/parse-non-lazy-pointers.yaml

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h?rev=212239&r1=212238&r2=212239&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryUtils.h Wed Jul  2 18:52:22 2014
@@ -182,6 +182,9 @@ inline void swapStruct(llvm::MachO::nlis
 
 
 
+inline uint16_t read16(bool swap, uint16_t value) {
+    return (swap ? getSwappedBytes(value) : value);
+}
 
 inline uint32_t read32(bool swap, uint32_t value) {
     return (swap ? getSwappedBytes(value) : value);

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp?rev=212239&r1=212238&r2=212239&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp Wed Jul  2 18:52:22 2014
@@ -438,10 +438,25 @@ std::error_code convertRelocs(const Sect
     if (sectIndex > normalizedFile.sections.size())
       return make_dynamic_error_code(Twine("out of range section "
                                      "index (") + Twine(sectIndex) + ")");
-    const Section &sect = normalizedFile.sections[sectIndex-1];
+    const Section *sect = nullptr;
+    if (sectIndex == 0) {
+      for (const Section &s : normalizedFile.sections) {
+        uint64_t sAddr = s.address;
+        if ((sAddr <= addr) && (addr < sAddr+s.content.size())) {
+          sect = &s;
+          break;
+        }
+      }
+      if (!sect) {
+        return make_dynamic_error_code(Twine("address (" + Twine(addr)
+                                           + ") is not in any section"));
+      }
+    } else {
+      sect = &normalizedFile.sections[sectIndex-1];
+    }
     uint32_t offsetInTarget;
-    uint64_t offsetInSect = addr - sect.address;
-    *atom = file.findAtomCoveringAddress(sect, offsetInSect, &offsetInTarget);
+    uint64_t offsetInSect = addr - sect->address;
+    *atom = file.findAtomCoveringAddress(*sect, offsetInSect, &offsetInTarget);
     *addend = offsetInTarget;
     return std::error_code();
   };
@@ -534,7 +549,7 @@ std::error_code convertRelocs(const Sect
          + " (r_address=" + Twine::utohexstr(reloc.offset)
          + ", r_type=" + Twine(reloc.type)
          + ", r_extern=" + Twine(reloc.isExtern)
-         + ", r_length=" + Twine(reloc.length)
+         + ", r_length=" + Twine((int)reloc.length)
          + ", r_pcrel=" + Twine(reloc.pcRel)
          + (!reloc.scattered ? (Twine(", r_symbolnum=") + Twine(reloc.symbol))
                              : (Twine(", r_scattered=1, r_value=")
@@ -542,7 +557,17 @@ std::error_code convertRelocs(const Sect
          + ")" );
     } else {
       // Instantiate an lld::Reference object and add to its atom.
-      inAtom->addReference(offsetInAtom, kind, target, addend);
+      Reference::KindArch arch = Reference::KindArch::all;
+      switch (normalizedFile.arch ) {
+      case lld::MachOLinkingContext::arch_x86_64:
+        arch = Reference::KindArch::x86_64;
+        break;
+      case lld::MachOLinkingContext::arch_x86:
+        arch = Reference::KindArch::x86;
+        break;
+      }
+      
+      inAtom->addReference(offsetInAtom, kind, target, addend, arch);
     }
   }
   return std::error_code();
@@ -580,7 +605,8 @@ normalizedObjectToAtoms(const Normalized
   }
 
   // TEMP BEGIN: until all KindHandlers switched to new interface.
-  if (normalizedFile.arch != lld::MachOLinkingContext::arch_x86_64)
+  if ((normalizedFile.arch != lld::MachOLinkingContext::arch_x86_64) &&
+      (normalizedFile.arch != lld::MachOLinkingContext::arch_x86))
     return std::unique_ptr<File>(std::move(file));
   // TEMP END
 

Modified: lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.cpp?rev=212239&r1=212238&r2=212239&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.cpp Wed Jul  2 18:52:22 2014
@@ -76,6 +76,23 @@ KindHandler::RelocPattern KindHandler::r
   return result;
 }
 
+int16_t KindHandler::readS16(bool swap, const uint8_t *addr) {
+  return read16(swap, *reinterpret_cast<const uint16_t*>(addr));
+}
+
+int32_t KindHandler::readS32(bool swap, const uint8_t *addr) {
+  return read32(swap, *reinterpret_cast<const uint32_t*>(addr));
+}
+
+uint32_t KindHandler::readU32(bool swap, const uint8_t *addr) {
+  return read32(swap, *reinterpret_cast<const uint32_t*>(addr));
+}
+
+int64_t KindHandler::readS64(bool swap, const uint8_t *addr) {
+  return read64(swap, *reinterpret_cast<const uint64_t*>(addr));
+}
+
+
 bool KindHandler::isPairedReloc(const Relocation &reloc) {
   llvm_unreachable("abstract");
 }
@@ -87,13 +104,13 @@ KindHandler::getReferenceInfo(const Relo
                                     uint64_t fixupAddress, bool swap,
                                     FindAtomBySectionAndAddress atomFromAddress,
                                     FindAtomBySymbolIndex atomFromSymbolIndex,
-                                    Reference::KindValue *kind, 
-                                    const lld::Atom **target, 
+                                    Reference::KindValue *kind,
+                                    const lld::Atom **target,
                                     Reference::Addend *addend) {
   llvm_unreachable("abstract");
 }
 
-std::error_code 
+std::error_code
 KindHandler::getPairReferenceInfo(const normalized::Relocation &reloc1,
                            const normalized::Relocation &reloc2,
                            const DefinedAtom *inAtom,
@@ -101,8 +118,8 @@ KindHandler::getPairReferenceInfo(const
                            uint64_t fixupAddress, bool swap,
                            FindAtomBySectionAndAddress atomFromAddress,
                            FindAtomBySymbolIndex atomFromSymbolIndex,
-                           Reference::KindValue *kind, 
-                           const lld::Atom **target, 
+                           Reference::KindValue *kind,
+                           const lld::Atom **target,
                            Reference::Addend *addend) {
   llvm_unreachable("abstract");
 }
@@ -169,13 +186,6 @@ bool KindHandler_x86_64::isPairedReloc(c
   return (reloc.type == X86_64_RELOC_SUBTRACTOR);
 }
 
-static int32_t readS32(bool swap, const uint8_t *addr) {
-  return read32(swap, *reinterpret_cast<const uint32_t*>(addr));
-}
-
-static int64_t readS64(bool swap, const uint8_t *addr) {
-  return read64(swap, *reinterpret_cast<const uint64_t*>(addr));
-}
 
 Reference::KindValue 
 KindHandler_x86_64::kindFromReloc(const Relocation &reloc) {
@@ -400,29 +410,166 @@ KindHandler_x86::~KindHandler_x86() {
 }
 
 const Registry::KindStrings KindHandler_x86::kindStrings[] = {
-  LLD_KIND_STRING_ENTRY(LLD_X86_RELOC_BRANCH32),
-  LLD_KIND_STRING_ENTRY(LLD_X86_RELOC_ABS32),
-  LLD_KIND_STRING_ENTRY(LLD_X86_RELOC_FUNC_REL32),
-  LLD_KIND_STRING_ENTRY(LLD_X86_RELOC_POINTER32),
-  LLD_KIND_STRING_ENTRY(LLD_X86_RELOC_LAZY_TARGET),
-  LLD_KIND_STRING_ENTRY(LLD_X86_RELOC_LAZY_IMMEDIATE),
+  LLD_KIND_STRING_ENTRY(invalid),
+  LLD_KIND_STRING_ENTRY(branch32),
+  LLD_KIND_STRING_ENTRY(branch16),
+  LLD_KIND_STRING_ENTRY(abs32),
+  LLD_KIND_STRING_ENTRY(funcRel32),
+  LLD_KIND_STRING_ENTRY(pointer32),
+  LLD_KIND_STRING_ENTRY(delta32),
+  LLD_KIND_STRING_ENTRY(lazyPointer),
+  LLD_KIND_STRING_ENTRY(lazyImmediateLocation),
   LLD_KIND_STRING_END
 };
 
 bool KindHandler_x86::isCallSite(const Reference &ref) {
-  return (ref.kindValue() == LLD_X86_RELOC_BRANCH32);
+  return (ref.kindValue() == branch32);
 }
 
 bool KindHandler_x86::isPointer(const Reference &ref) {
-  return (ref.kindValue() == LLD_X86_RELOC_POINTER32);
+  return (ref.kindValue() == pointer32);
 }
 
 bool KindHandler_x86::isLazyImmediate(const Reference &ref) {
-  return (ref.kindValue() == LLD_X86_RELOC_LAZY_TARGET);
+  return (ref.kindValue() == lazyImmediateLocation);
 }
 
 bool KindHandler_x86::isLazyTarget(const Reference &ref) {
-  return (ref.kindValue() == LLD_X86_RELOC_LAZY_TARGET);
+  return (ref.kindValue() == lazyPointer);
+}
+
+
+bool KindHandler_x86::isPairedReloc(const Relocation &reloc) {
+  if (!reloc.scattered)
+    return false;
+  return (reloc.type == GENERIC_RELOC_LOCAL_SECTDIFF) || 
+         (reloc.type == GENERIC_RELOC_SECTDIFF);
+}
+
+
+std::error_code
+KindHandler_x86::getReferenceInfo(const Relocation &reloc,
+                                  const DefinedAtom *inAtom,
+                                  uint32_t offsetInAtom,
+                                  uint64_t fixupAddress, bool swap,
+                                  FindAtomBySectionAndAddress atomFromAddress,
+                                  FindAtomBySymbolIndex atomFromSymbolIndex,
+                                  Reference::KindValue *kind,
+                                  const lld::Atom **target,
+                                  Reference::Addend *addend) {
+  typedef std::error_code E;
+  DefinedAtom::ContentPermissions perms;
+  const uint8_t *fixupContent = &inAtom->rawContent()[offsetInAtom];
+  uint64_t targetAddress;
+  switch (relocPattern(reloc)) {
+  case GENERIC_RELOC_VANILLA | rPcRel | rExtern | rLength4:
+    // ex: call _foo (and _foo undefined)
+    *kind = branch32;
+    if (E ec = atomFromSymbolIndex(reloc.symbol, target))
+      return ec;
+    *addend = fixupAddress + 4 + readS32(swap, fixupContent);
+    break;
+  case GENERIC_RELOC_VANILLA | rPcRel  | rLength4:
+    // ex: call _foo (and _foo defined)
+    *kind = branch32;
+    targetAddress = fixupAddress + 4 + readS32(swap, fixupContent);
+    return atomFromAddress(reloc.symbol, targetAddress, target, addend);
+    break;
+  case GENERIC_RELOC_VANILLA | rPcRel | rExtern | rLength2:
+    // ex: callw _foo (and _foo undefined)
+    *kind = branch16;
+    if (E ec = atomFromSymbolIndex(reloc.symbol, target))
+      return ec;
+    *addend = fixupAddress + 2 + readS16(swap, fixupContent);
+    break;
+  case GENERIC_RELOC_VANILLA | rPcRel  | rLength2:
+    // ex: callw _foo (and _foo defined)
+    *kind = branch16;
+    targetAddress = fixupAddress + 2 + readS16(swap, fixupContent);
+    return atomFromAddress(reloc.symbol, targetAddress, target, addend);
+    break;
+  case GENERIC_RELOC_VANILLA  | rExtern | rLength4:
+    // ex: movl	_foo, %eax   (and _foo undefined)
+    // ex: .long _foo        (and _foo undefined)
+    perms = inAtom->permissions();
+    *kind = ((perms & DefinedAtom::permR_X) == DefinedAtom::permR_X)
+                                                            ? abs32 : pointer32;
+    if (E ec = atomFromSymbolIndex(reloc.symbol, target))
+      return ec;
+    *addend = readU32(swap, fixupContent);
+    break;
+  case GENERIC_RELOC_VANILLA  | rLength4:
+    // ex: movl	_foo, %eax   (and _foo defined)
+    // ex: .long _foo        (and _foo defined)
+    perms = inAtom->permissions();
+    *kind = ((perms & DefinedAtom::permR_X) == DefinedAtom::permR_X)
+                                                            ? abs32 : pointer32;
+    targetAddress = readU32(swap, fixupContent);
+    return atomFromAddress(reloc.symbol, targetAddress, target, addend);
+    break;
+  default:
+    return make_dynamic_error_code(Twine("unsupported i386 relocation type"));
+  }
+  return std::error_code();
+}
+
+
+std::error_code
+KindHandler_x86::getPairReferenceInfo(const normalized::Relocation &reloc1,
+                                     const normalized::Relocation &reloc2,
+                                     const DefinedAtom *inAtom,
+                                     uint32_t offsetInAtom,
+                                     uint64_t fixupAddress, bool swap,
+                                     FindAtomBySectionAndAddress atomFromAddr,
+                                     FindAtomBySymbolIndex atomFromSymbolIndex,
+                                     Reference::KindValue *kind,
+                                     const lld::Atom **target,
+                                     Reference::Addend *addend) {
+  const uint8_t *fixupContent = &inAtom->rawContent()[offsetInAtom];
+  std::error_code ec;
+  DefinedAtom::ContentPermissions perms = inAtom->permissions();
+  uint32_t fromAddress;
+  uint32_t toAddress;
+  uint32_t value;
+  const lld::Atom *fromTarget;
+  Reference::Addend offsetInTo;
+  Reference::Addend offsetInFrom;
+  switch(relocPattern(reloc1) << 16 | relocPattern(reloc2)) {
+  case ((GENERIC_RELOC_SECTDIFF       | rScattered | rLength4) << 16 |
+         GENERIC_RELOC_PAIR           | rScattered | rLength4):
+  case ((GENERIC_RELOC_LOCAL_SECTDIFF | rScattered | rLength4) << 16 |
+         GENERIC_RELOC_PAIR           | rScattered | rLength4):
+    toAddress = reloc1.value;
+    fromAddress = reloc2.value;
+    value = readS32(swap, fixupContent);
+    ec = atomFromAddr(0, toAddress, target, &offsetInTo);
+    if (ec)
+      return ec;
+    ec = atomFromAddr(0, fromAddress, &fromTarget, &offsetInFrom);
+    if (ec)
+      return ec;
+    if (fromTarget != inAtom)
+      return make_dynamic_error_code(Twine("SECTDIFF relocation where "
+                                     "subtrahend label is not in atom"));
+    *kind = ((perms & DefinedAtom::permR_X) == DefinedAtom::permR_X)
+                                                          ? funcRel32 : delta32;
+    if (*kind == funcRel32) {
+      // SECTDIFF relocations are used in i386 codegen where the function
+      // prolog does a CALL to the next instruction which POPs the return
+      // address into EBX which becomes the pic-base register.  The POP 
+      // instruction is label the used for the subtrahend in expressions.
+      // The funcRel32 kind represents the 32-bit delta to some symbol from
+      // the start of the function (atom) containing the funcRel32.
+      uint32_t ta = fromAddress + value - toAddress;
+      *addend = ta - offsetInFrom;
+    } else {
+      *addend= fromAddress + value - toAddress;
+    }
+    return std::error_code();
+    break;
+  default:
+    return make_dynamic_error_code(Twine("unsupported i386 relocation type"));
+  }
 }
 
 void KindHandler_x86::applyFixup(Reference::KindNamespace ns,

Modified: lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.h?rev=212239&r1=212238&r2=212239&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ReferenceKinds.h Wed Jul  2 18:52:22 2014
@@ -125,7 +125,11 @@ protected:
     rLength8   = 0x0300
   };
   static RelocPattern relocPattern(const normalized::Relocation &reloc);
-  
+
+  static int16_t  readS16(bool swap, const uint8_t *addr);
+  static int32_t  readS32(bool swap, const uint8_t *addr);
+  static uint32_t readU32(bool swap, const uint8_t *addr);
+  static int64_t  readS64(bool swap, const uint8_t *addr);  
 };
 
 
@@ -216,12 +220,61 @@ public:
   bool isPointer(const Reference &) override;
   bool isLazyImmediate(const Reference &) override;
   bool isLazyTarget(const Reference &) override;
-  virtual void applyFixup(Reference::KindNamespace ns, Reference::KindArch arch,
+  bool isPairedReloc(const normalized::Relocation &) override;
+  std::error_code getReferenceInfo(const normalized::Relocation &reloc,
+                                   const DefinedAtom *inAtom,
+                                   uint32_t offsetInAtom,
+                                   uint64_t fixupAddress, bool swap,
+                                   FindAtomBySectionAndAddress atomFromAddress,
+                                   FindAtomBySymbolIndex atomFromSymbolIndex,
+                                   Reference::KindValue *kind,
+                                   const lld::Atom **target,
+                                   Reference::Addend *addend) override;
+  std::error_code
+      getPairReferenceInfo(const normalized::Relocation &reloc1,
+                           const normalized::Relocation &reloc2,
+                           const DefinedAtom *inAtom,
+                           uint32_t offsetInAtom,
+                           uint64_t fixupAddress, bool swap,
+                           FindAtomBySectionAndAddress atomFromAddress,
+                           FindAtomBySymbolIndex atomFromSymbolIndex,
+                           Reference::KindValue *kind,
+                           const lld::Atom **target,
+                           Reference::Addend *addend) override;
+
+  void applyFixup(Reference::KindNamespace ns, Reference::KindArch arch,
                           Reference::KindValue kindValue, uint64_t addend,
                           uint8_t *location, uint64_t fixupAddress,
                           uint64_t targetAddress) override;
+
+private:
+  friend class X86LazyPointerAtom;
+  friend class X86StubHelperAtom;
+  friend class X86StubAtom;
+  friend class X86StubHelperCommonAtom;
+  friend class X86NonLazyPointerAtom;
+
+  enum : Reference::KindValue {
+    invalid,               /// for error condition
+
+    // Kinds found in mach-o .o files:
+    branch32,              /// ex: call _foo
+    branch16,              /// ex: callw _foo
+    abs32,                 /// ex: movl _foo, %eax
+    funcRel32,             /// ex: movl _foo-L1(%eax), %eax
+    pointer32,             /// ex: .long _foo
+    delta32,               /// ex: .long _foo - .
+
+    // Kinds introduced by Passes:
+    lazyPointer,           /// Location contains a lazy pointer.
+    lazyImmediateLocation, /// Location contains immediate value used in stub.
+  };
+
+
 };
 
+
+
 class KindHandler_arm : public KindHandler {
 public:
   static const Registry::KindStrings kindStrings[];

Modified: lld/trunk/test/mach-o/parse-cfstring32.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/parse-cfstring32.yaml?rev=212239&r1=212238&r2=212239&view=diff
==============================================================================
--- lld/trunk/test/mach-o/parse-cfstring32.yaml (original)
+++ lld/trunk/test/mach-o/parse-cfstring32.yaml Wed Jul  2 18:52:22 2014
@@ -39,7 +39,7 @@ sections:
         length:          2
         pc-rel:          false
         extern:          true
-        symbol:          1
+        symbol:          0
       - offset:          0x00000008
         type:            GENERIC_RELOC_VANILLA
         length:          2
@@ -51,7 +51,7 @@ sections:
         length:          2
         pc-rel:          false
         extern:          true
-        symbol:          1
+        symbol:          0
 undefined-symbols:
   - name:            ___CFConstantStringClassReference
     type:            N_UNDF
@@ -60,19 +60,35 @@ undefined-symbols:
 ...
 
 # CHECK: defined-atoms:
-# CHECK:  - scope:           hidden
+# CHECK:  - ref-name:        [[STR1:L[L0-9]+]]
+# CHECK:    scope:           hidden
 # CHECK:    type:            c-string
 # CHECK:    content:         [ 68, 65, 6C, 6C, 6F, 00 ]
 # CHECK:    merge:           by-content
-# CHECK:  - scope:           hidden
+# CHECK:  - ref-name:        [[STR2:L[L0-9]+]]
+# CHECK:    scope:           hidden
 # CHECK:    type:            c-string
 # CHECK:    content:         [ 74, 68, 65, 72, 65, 00 ]
 # CHECK:    merge:           by-content
 # CHECK:  - scope:           hidden
 # CHECK:    type:            cfstring
 # CHECK:    merge:           by-content
+# CHECK:    references:
+# CHECK:        - kind:            pointer32
+# CHECK:          offset:          0
+# CHECK:          target:          ___CFConstantStringClassReference
+# CHECK:        - kind:            pointer32
+# CHECK:          offset:          8
+# CHECK:          target:          [[STR1]]
 # CHECK:  - scope:           hidden
 # CHECK:    type:            cfstring
 # CHECK:    merge:           by-content
+# CHECK:    references:
+# CHECK:        - kind:            pointer32
+# CHECK:          offset:          0
+# CHECK:          target:          ___CFConstantStringClassReference
+# CHECK:        - kind:            pointer32
+# CHECK:          offset:          8
+# CHECK:          target:          [[STR2]]
 # CHECK:undefined-atoms:
 # CHECK:  - name:            ___CFConstantStringClassReference

Modified: lld/trunk/test/mach-o/parse-non-lazy-pointers.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/parse-non-lazy-pointers.yaml?rev=212239&r1=212238&r2=212239&view=diff
==============================================================================
--- lld/trunk/test/mach-o/parse-non-lazy-pointers.yaml (original)
+++ lld/trunk/test/mach-o/parse-non-lazy-pointers.yaml Wed Jul  2 18:52:22 2014
@@ -71,11 +71,13 @@ undefined-symbols:
 
 
 # CHECK:defined-atoms:
-# CHECK:  - scope:           hidden
+# CHECK:  - ref-name:        [[GOT1:L[L0-9]+]]
+# CHECK:    scope:           hidden
 # CHECK:    type:            got
 # CHECK:    content:         [ 00, 00, 00, 00 ]
 # CHECK:    merge:           by-content
-# CHECK:  - scope:           hidden
+# CHECK:  - ref-name:        [[GOT2:L[L0-9]+]]
+# CHECK:    scope:           hidden
 # CHECK:    type:            got
 # CHECK:    content:         [ 00, 00, 00, 00 ]
 # CHECK:    merge:           by-content
@@ -83,6 +85,13 @@ undefined-symbols:
 # CHECK:    scope:           global
 # CHECK:    content:         [ 55, 89, E5, E8, 00, 00, 00, 00, 59, 8D, 81, 14,
 # CHECK:                       00, 00, 00, 8D, 81, 18, 00, 00, 00, 5D, C3 ]
+# CHECK:     references:
+# CHECK:       - kind:            funcRel32
+# CHECK:         offset:          11
+# CHECK:         target:          [[GOT1]]
+# CHECK:       - kind:            funcRel32
+# CHECK:         offset:          17
+# CHECK:         target:          [[GOT2]]
 # CHECK:  - name:            _foo
 # CHECK:    content:         [ 55, 89, E5, 5D, C3 ]
 

Added: lld/trunk/test/mach-o/parse-relocs-x86.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/parse-relocs-x86.yaml?rev=212239&view=auto
==============================================================================
--- lld/trunk/test/mach-o/parse-relocs-x86.yaml (added)
+++ lld/trunk/test/mach-o/parse-relocs-x86.yaml Wed Jul  2 18:52:22 2014
@@ -0,0 +1,190 @@
+# RUN: lld -flavor darwin -arch i386 -r -print_atoms %s -o %t  | FileCheck %s
+#
+# Test parsing of x86 relocations.
+#
+#  .text
+#
+#_test:
+#  	call _undef
+#  	call _undef+2
+#   callw _undef
+#L1:
+#  	movl	_undef, %eax
+#   movl	_x, %eax
+#  	movl	_x-L1(%eax), %eax
+#  	movl	_x+4-L1(%eax), %eax
+#
+#  .data
+#_x: 
+#  .long _undef
+#  .long _test - .
+#  .long _test+3 - .
+#
+
+--- !mach-o
+arch:            x86
+file-type:       MH_OBJECT
+flags:           [  ]
+OS:              unknown
+sections:        
+  - segment:         __TEXT
+    section:         __text
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+    address:         0x0000000000000000
+    content:         [ 0xE8, 0xFB, 0xFF, 0xFF, 0xFF, 0xE8, 0xF8, 0xFF, 
+                       0xFF, 0xFF, 0x66, 0xE8, 0xF2, 0xFF, 0xA1, 0x00, 
+                       0x00, 0x00, 0x00, 0xA1, 0x24, 0x00, 0x00, 0x00, 
+                       0x8B, 0x80, 0x16, 0x00, 0x00, 0x00, 0x8B, 0x80, 
+                       0x1A, 0x00, 0x00, 0x00 ]
+    relocations:     
+      - offset:          0x00000020
+        scattered:       true
+        type:            GENERIC_RELOC_LOCAL_SECTDIFF
+        length:          2
+        pc-rel:          false
+        value:           0x00000024
+      - offset:          0x00000000
+        scattered:       true
+        type:            GENERIC_RELOC_PAIR
+        length:          2
+        pc-rel:          false
+        value:           0x0000000E
+      - offset:          0x0000001A
+        scattered:       true
+        type:            GENERIC_RELOC_LOCAL_SECTDIFF
+        length:          2
+        pc-rel:          false
+        value:           0x00000024
+      - offset:          0x00000000
+        scattered:       true
+        type:            GENERIC_RELOC_PAIR
+        length:          2
+        pc-rel:          false
+        value:           0x0000000E
+      - offset:          0x00000014
+        type:            GENERIC_RELOC_VANILLA
+        length:          2
+        pc-rel:          false
+        extern:          false
+        symbol:          2
+      - offset:          0x0000000F
+        type:            GENERIC_RELOC_VANILLA
+        length:          2
+        pc-rel:          false
+        extern:          true
+        symbol:          2
+      - offset:          0x0000000C
+        type:            GENERIC_RELOC_VANILLA
+        length:          1
+        pc-rel:          true
+        extern:          true
+        symbol:          2
+      - offset:          0x00000006
+        type:            GENERIC_RELOC_VANILLA
+        length:          2
+        pc-rel:          true
+        extern:          true
+        symbol:          2
+      - offset:          0x00000001
+        type:            GENERIC_RELOC_VANILLA
+        length:          2
+        pc-rel:          true
+        extern:          true
+        symbol:          2
+  - segment:         __DATA
+    section:         __data
+    type:            S_REGULAR
+    attributes:      [  ]
+    address:         0x0000000000000024
+    content:         [ 0x00, 0x00, 0x00, 0x00, 0xD8, 0xFF, 0xFF, 0xFF, 
+                       0xD7, 0xFF, 0xFF, 0xFF ]
+    relocations:     
+      - offset:          0x00000008
+        scattered:       true
+        type:            GENERIC_RELOC_LOCAL_SECTDIFF
+        length:          2
+        pc-rel:          false
+        value:           0x00000000
+      - offset:          0x00000000
+        scattered:       true
+        type:            GENERIC_RELOC_PAIR
+        length:          2
+        pc-rel:          false
+        value:           0x0000002C
+      - offset:          0x00000004
+        scattered:       true
+        type:            GENERIC_RELOC_LOCAL_SECTDIFF
+        length:          2
+        pc-rel:          false
+        value:           0x00000000
+      - offset:          0x00000000
+        scattered:       true
+        type:            GENERIC_RELOC_PAIR
+        length:          2
+        pc-rel:          false
+        value:           0x00000028
+      - offset:          0x00000000
+        type:            GENERIC_RELOC_VANILLA
+        length:          2
+        pc-rel:          false
+        extern:          true
+        symbol:          2
+local-symbols:   
+  - name:            _test
+    type:            N_SECT
+    sect:            1
+    value:           0x0000000000000000
+  - name:            _x
+    type:            N_SECT
+    sect:            2
+    value:           0x0000000000000024
+undefined-symbols: 
+  - name:            _undef
+    type:            N_UNDF
+    scope:           [ N_EXT ]
+    value:           0x0000000000000000
+...
+
+# CHECK: defined-atoms:
+# CHECK:   - name:            _x
+# CHECK:     type:            data
+# CHECK:     references:
+# CHECK:       - kind:            pointer32
+# CHECK:         offset:          0
+# CHECK:         target:          _undef
+# CHECK:       - kind:            delta32
+# CHECK:         offset:          4
+# CHECK:         target:          _test
+# CHECK:       - kind:            delta32
+# CHECK:         offset:          8
+# CHECK:         target:          _test
+# CHECK:         addend:          3
+# CHECK:  - name:            _test
+# CHECK:    references:
+# CHECK:      - kind:            branch32
+# CHECK:        offset:          1
+# CHECK:        target:          _undef
+# CHECK-NOT:    addend:
+# CHECK:      - kind:            branch32
+# CHECK:        offset:          6
+# CHECK:        target:          _undef
+# CHECK:        addend:          2
+# CHECK:      - kind:            branch16
+# CHECK:        offset:          12
+# CHECK:        target:          _undef
+# CHECK:      - kind:            abs32
+# CHECK:        offset:          15
+# CHECK:        target:          _undef
+# CHECK:      - kind:            abs32
+# CHECK:        offset:          20
+# CHECK:        target:          _x
+# CHECK:      - kind:            funcRel32
+# CHECK:        offset:          26
+# CHECK:        target:          _x
+# CHECK:        addend:          -14
+# CHECK:      - kind:            funcRel32
+# CHECK:        offset:          32
+# CHECK:        target:          _x
+# CHECK:        addend:          -10
+





More information about the llvm-commits mailing list