[mach-o] update __eh_frame handling for Nick's suggestions
authorTim Northover <tnorthover@apple.com>
Thu, 16 Oct 2014 20:52:18 +0000 (20:52 +0000)
committerTim Northover <tnorthover@apple.com>
Thu, 16 Oct 2014 20:52:18 +0000 (20:52 +0000)
First, add a comment to support more variation in FDE formats. Second, refactor
fde -> function handling into a separate function living in the ArchHandler.

llvm-svn: 219959

lld/lib/ReaderWriter/MachO/ArchHandler.cpp
lld/lib/ReaderWriter/MachO/ArchHandler.h
lld/lib/ReaderWriter/MachO/CompactUnwindPass.cpp
lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp

index 3fa1fb3b91fe5e9af4d0e03c8b573917351cb890..3ccb17120647beec57e36b0ebdd1c6be86775ba0 100644 (file)
@@ -153,6 +153,18 @@ bool ArchHandler::isDwarfCIE(bool swap, const DefinedAtom *atom) {
   return read32(swap, *(uint32_t *)(atom->rawContent().data() + idOffset)) == 0;
 }
 
+const Atom *ArchHandler::fdeTargetFunction(const DefinedAtom *fde) {
+  for (auto ref : *fde) {
+    if (ref->kindNamespace() == Reference::KindNamespace::mach_o &&
+        ref->kindValue() == unwindRefToFunctionKind()) {
+      assert(ref->kindArch() == kindArch() && "unexpected Reference arch");
+      return ref->target();
+    }
+  }
+
+  return nullptr;
+}
+
 } // namespace mach_o
 } // namespace lld
 
index f4e7bf7a69120b9080f1d111f60e99a5887bf69a..9613f7a29bcb9813411c8ed7846e67df3a360f61 100644 (file)
@@ -88,6 +88,8 @@ public:
   /// __eh_frame.
   virtual Reference::KindValue unwindRefToEhFrameKind() = 0;
 
+  virtual const Atom *fdeTargetFunction(const DefinedAtom *fde);
+
   /// Used by normalizedFromAtoms() to know where to generated rebasing and 
   /// binding info in final executables.
   virtual bool isPointer(const Reference &) = 0;
index 59fb3195f8dfcb2feb507c7b3fc217f9ab24abd0..77bd3e9bc432cbd254755362bd3648e68cbf0111 100644 (file)
@@ -411,18 +411,13 @@ private:
   collectDwarfFrameEntries(std::unique_ptr<MutableFile> &mergedFile,
                            std::map<const Atom *, const Atom *> &dwarfFrames) {
     for (const DefinedAtom *ehFrameAtom : mergedFile->defined()) {
-      if (ehFrameAtom->contentType() != DefinedAtom::typeCFI ||
-          ArchHandler::isDwarfCIE(_swap, ehFrameAtom))
+      if (ehFrameAtom->contentType() != DefinedAtom::typeCFI)
+        continue;
+      if (ArchHandler::isDwarfCIE(_swap, ehFrameAtom))
         continue;
 
-      DefinedAtom::reference_iterator ref = ehFrameAtom->begin();
-      for (; ref != ehFrameAtom->end(); ++ref)
-        if (ref->kindNamespace() == Reference::KindNamespace::mach_o &&
-            ref->kindArch() == _archHandler.kindArch() &&
-            ref->kindValue() == _archHandler.unwindRefToFunctionKind()) {
-          dwarfFrames.insert(std::make_pair(ref->target(), ehFrameAtom));
-          break;
-        }
+      if (const Atom *function = _archHandler.fdeTargetFunction(ehFrameAtom))
+        dwarfFrames[function] = ehFrameAtom;
     }
   }
 
index d52af892b94ee474cb15dc4be39f521fdd12e72f..d0536904bac77c4f43ac0d538cefdb66bf98b85c 100644 (file)
@@ -677,7 +677,9 @@ std::error_code addEHFrameReferences(const NormalizedFile &normalizedFile,
                        addend, handler.kindArch());
 
     // Linker needs to fixup reference from the FDE to the function it's
-    // describing.
+    // describing. FIXME: there are actually different ways to do this, and the
+    // particular method used is specified in the CIE's augmentation fields
+    // (hopefully)
     uint64_t rangeFieldInFDE = cieFieldInFDE + sizeof(uint32_t);
 
     int64_t functionFromFDE = readSPtr(is64, swap, frameData + rangeFieldInFDE);