[lld] r276935 - [lld][MachO] Re-apply r276921 with fix - initialize strings for debug string

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Wed Jul 27 15:55:31 PDT 2016


Author: lhames
Date: Wed Jul 27 17:55:30 2016
New Revision: 276935

URL: http://llvm.org/viewvc/llvm-project?rev=276935&view=rev
Log:
[lld][MachO] Re-apply r276921 with fix - initialize strings for debug string
copies.


Added:
    lld/trunk/lib/ReaderWriter/MachO/DebugInfo.h
    lld/trunk/test/mach-o/debug-syms.yaml
Modified:
    lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
    lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt
    lld/trunk/lib/ReaderWriter/MachO/File.h
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
    lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp

Modified: lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp?rev=276935&r1=276934&r2=276935&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp Wed Jul 27 17:55:30 2016
@@ -463,7 +463,10 @@ ArchHandler_x86_64::getPairReferenceInfo
       return ec;
     uint64_t encodedAddend = (int64_t)*(const little64_t *)fixupContent;
     if (inAtom == fromTarget) {
-      *kind = delta64;
+      if (inAtom->contentType() == DefinedAtom::typeCFI)
+        *kind = unwindFDEToFunction;
+      else
+        *kind = delta64;
       *addend = encodedAddend + offsetInAtom;
     } else if (inAtom == *target) {
       *kind = negDelta64;

Modified: lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt?rev=276935&r1=276934&r2=276935&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt (original)
+++ lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt Wed Jul 27 17:55:30 2016
@@ -21,6 +21,7 @@ add_lld_library(lldMachO
   LINK_LIBS
     lldCore
     lldYAML
+    LLVMDebugInfoDWARF
     LLVMObject
     LLVMSupport
     ${PTHREAD_LIB}

Added: lld/trunk/lib/ReaderWriter/MachO/DebugInfo.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/DebugInfo.h?rev=276935&view=auto
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/DebugInfo.h (added)
+++ lld/trunk/lib/ReaderWriter/MachO/DebugInfo.h Wed Jul 27 17:55:30 2016
@@ -0,0 +1,310 @@
+//===- lib/ReaderWriter/MachO/File.h ----------------------------*- C++ -*-===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_READER_WRITER_MACHO_DEBUGINFO_H
+#define LLD_READER_WRITER_MACHO_DEBUGINFO_H
+
+#include "lld/Core/Atom.h"
+#include <vector>
+
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+
+namespace lld {
+namespace mach_o {
+
+class DebugInfo {
+public:
+  enum class Kind {
+    Dwarf,
+    Stabs
+  };
+
+  Kind kind() const { return _kind; }
+
+  void setAllocator(std::unique_ptr<llvm::BumpPtrAllocator> allocator) {
+    _allocator = std::move(allocator);
+  }
+
+protected:
+  DebugInfo(Kind kind) : _kind(kind) {}
+
+private:
+  std::unique_ptr<llvm::BumpPtrAllocator> _allocator;
+  Kind _kind;
+};
+
+struct TranslationUnitSource {
+  StringRef name;
+  StringRef path;
+};
+
+class DwarfDebugInfo : public DebugInfo {
+public:
+  DwarfDebugInfo(TranslationUnitSource tu)
+    : DebugInfo(Kind::Dwarf), _tu(std::move(tu)) {}
+
+  static inline bool classof(const DebugInfo *di) {
+    return di->kind() == Kind::Dwarf;
+  }
+
+  const TranslationUnitSource &translationUnitSource() const { return _tu; }
+
+private:
+  TranslationUnitSource _tu;
+};
+
+struct Stab {
+  Stab(const Atom* atom, uint8_t type, uint8_t other, uint16_t desc,
+       uint32_t value, StringRef str)
+    : atom(atom), type(type), other(other), desc(desc), value(value),
+      str(str) {}
+
+  const class Atom*   atom;
+  uint8_t             type;
+  uint8_t             other;
+  uint16_t            desc;
+  uint32_t            value;
+  StringRef           str;
+};
+
+inline raw_ostream& operator<<(raw_ostream &os, Stab &s) {
+  os << "Stab -- atom: " << llvm::format("%p", s.atom) << ", type: " << (uint32_t)s.type
+     << ", other: " << (uint32_t)s.other << ", desc: " << s.desc << ", value: " << s.value
+     << ", str: '" << s.str << "'";
+  return os;
+}
+
+class StabsDebugInfo : public DebugInfo {
+public:
+
+  typedef std::vector<Stab> StabsList;
+
+  StabsDebugInfo(StabsList stabs)
+    : DebugInfo(Kind::Stabs), _stabs(std::move(stabs)) {}
+
+  static inline bool classof(const DebugInfo *di) {
+    return di->kind() == Kind::Stabs;
+  }
+
+  const StabsList& stabs() const { return _stabs; }
+
+public:
+  StabsList _stabs;
+};
+
+} // end namespace mach_o
+} // end namespace lld
+
+#endif // LLD_READER_WRITER_MACHO_DEBUGINFO_H
+//===- lib/ReaderWriter/MachO/File.h ----------------------------*- C++ -*-===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_READER_WRITER_MACHO_DEBUGINFO_H
+#define LLD_READER_WRITER_MACHO_DEBUGINFO_H
+
+#include "lld/Core/Atom.h"
+#include <vector>
+
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+
+namespace lld {
+namespace mach_o {
+
+class DebugInfo {
+public:
+  enum class Kind {
+    Dwarf,
+    Stabs
+  };
+
+  Kind kind() const { return _kind; }
+
+protected:
+  DebugInfo(Kind kind) : _kind(kind) {}
+
+private:
+  Kind _kind;
+};
+
+
+struct TranslationUnitSource {
+  StringRef name;
+  StringRef path;
+};
+
+class DwarfDebugInfo : public DebugInfo {
+public:
+  DwarfDebugInfo(TranslationUnitSource tu)
+    : DebugInfo(Kind::Dwarf), _tu(std::move(tu)) {}
+
+  static inline bool classof(const DebugInfo *di) {
+    return di->kind() == Kind::Dwarf;
+  }
+
+  const TranslationUnitSource &translationUnitSource() const { return _tu; }
+
+private:
+  TranslationUnitSource _tu;
+};
+
+struct Stab {
+  Stab(const Atom* atom, uint8_t type, uint8_t other, uint16_t desc,
+       uint32_t value, StringRef str)
+    : atom(atom), type(type), other(other), desc(desc), value(value),
+      str(str) {}
+
+  const class Atom*   atom;
+  uint8_t             type;
+  uint8_t             other;
+  uint16_t            desc;
+  uint32_t            value;
+  StringRef           str;
+};
+
+inline raw_ostream& operator<<(raw_ostream &os, Stab &s) {
+  os << "Stab -- atom: " << llvm::format("%p", s.atom) << ", type: " << (uint32_t)s.type
+     << ", other: " << (uint32_t)s.other << ", desc: " << s.desc << ", value: " << s.value
+     << ", str: '" << s.str << "'";
+  return os;
+}
+
+class StabsDebugInfo : public DebugInfo {
+public:
+
+  typedef std::vector<Stab> StabsList;
+
+  StabsDebugInfo(StabsList stabs)
+    : DebugInfo(Kind::Stabs), _stabs(std::move(stabs)) {}
+
+  static inline bool classof(const DebugInfo *di) {
+    return di->kind() == Kind::Stabs;
+  }
+
+  const StabsList& stabs() const { return _stabs; }
+
+public:
+  StabsList _stabs;
+};
+
+} // end namespace mach_o
+} // end namespace lld
+
+#endif // LLD_READER_WRITER_MACHO_DEBUGINFO_H
+//===- lib/ReaderWriter/MachO/File.h ----------------------------*- C++ -*-===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_READER_WRITER_MACHO_DEBUGINFO_H
+#define LLD_READER_WRITER_MACHO_DEBUGINFO_H
+
+#include "lld/Core/Atom.h"
+#include <vector>
+
+#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
+
+
+namespace lld {
+namespace mach_o {
+
+class DebugInfo {
+public:
+  enum class Kind {
+    Dwarf,
+    Stabs
+  };
+
+  Kind kind() const { return _kind; }
+
+protected:
+  DebugInfo(Kind kind) : _kind(kind) {}
+
+private:
+  Kind _kind;
+};
+
+
+struct TranslationUnitSource {
+  StringRef name;
+  StringRef path;
+};
+
+class DwarfDebugInfo : public DebugInfo {
+public:
+  DwarfDebugInfo(TranslationUnitSource tu)
+    : DebugInfo(Kind::Dwarf), _tu(std::move(tu)) {}
+
+  static inline bool classof(const DebugInfo *di) {
+    return di->kind() == Kind::Dwarf;
+  }
+
+  const TranslationUnitSource &translationUnitSource() const { return _tu; }
+
+private:
+  TranslationUnitSource _tu;
+};
+
+struct Stab {
+  Stab(const Atom* atom, uint8_t type, uint8_t other, uint16_t desc,
+       uint32_t value, StringRef str)
+    : atom(atom), type(type), other(other), desc(desc), value(value),
+      str(str) {}
+
+  const class Atom*   atom;
+  uint8_t             type;
+  uint8_t             other;
+  uint16_t            desc;
+  uint32_t            value;
+  StringRef           str;
+};
+
+inline raw_ostream& operator<<(raw_ostream &os, Stab &s) {
+  os << "Stab -- atom: " << llvm::format("%p", s.atom) << ", type: " << (uint32_t)s.type
+     << ", other: " << (uint32_t)s.other << ", desc: " << s.desc << ", value: " << s.value
+     << ", str: '" << s.str << "'";
+  return os;
+}
+
+class StabsDebugInfo : public DebugInfo {
+public:
+
+  typedef std::vector<Stab> StabsList;
+
+  StabsDebugInfo(StabsList stabs)
+    : DebugInfo(Kind::Stabs), _stabs(std::move(stabs)) {}
+
+  static inline bool classof(const DebugInfo *di) {
+    return di->kind() == Kind::Stabs;
+  }
+
+  const StabsList& stabs() const { return _stabs; }
+
+public:
+  StabsList _stabs;
+};
+
+} // end namespace mach_o
+} // end namespace lld
+
+#endif // LLD_READER_WRITER_MACHO_DEBUGINFO_H

Modified: lld/trunk/lib/ReaderWriter/MachO/File.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/File.h?rev=276935&r1=276934&r2=276935&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/File.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/File.h Wed Jul 27 17:55:30 2016
@@ -11,11 +11,13 @@
 #define LLD_READER_WRITER_MACHO_FILE_H
 
 #include "Atoms.h"
+#include "DebugInfo.h"
 #include "MachONormalizedFile.h"
 #include "lld/Core/SharedLibraryFile.h"
 #include "lld/Core/Simple.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringMap.h"
+#include "llvm/Support/Format.h"
 #include <unordered_map>
 
 namespace lld {
@@ -25,11 +27,15 @@ using lld::mach_o::normalized::Section;
 
 class MachOFile : public SimpleFile {
 public:
+
+  /// Real file constructor - for on-disk files.
   MachOFile(std::unique_ptr<MemoryBuffer> mb, MachOLinkingContext *ctx)
     : SimpleFile(mb->getBufferIdentifier(), File::kindMachObject),
       _mb(std::move(mb)), _ctx(ctx) {}
 
-  MachOFile(StringRef path) : SimpleFile(path, File::kindMachObject) {}
+  /// Dummy file constructor - for virtual files.
+  MachOFile(StringRef path)
+    : SimpleFile(path, File::kindMachObject) {}
 
   void addDefinedAtom(StringRef name, Atom::Scope scope,
                       DefinedAtom::ContentType type, DefinedAtom::Merge merge,
@@ -225,6 +231,13 @@ public:
     return F->kind() == File::kindMachObject;
   }
 
+  void setDebugInfo(std::unique_ptr<DebugInfo> debugInfo) {
+    _debugInfo = std::move(debugInfo);
+  }
+
+  DebugInfo* debugInfo() const { return _debugInfo.get(); }
+  std::unique_ptr<DebugInfo> takeDebugInfo() { return std::move(_debugInfo); }
+
 protected:
   std::error_code doParse() override {
     // Convert binary file to normalized mach-o.
@@ -265,6 +278,7 @@ private:
       MachOLinkingContext::objc_unknown;
   uint32_t                       _swiftVersion = 0;
   normalized::FileFlags        _flags = llvm::MachO::MH_SUBSECTIONS_VIA_SYMBOLS;
+  std::unique_ptr<DebugInfo>   _debugInfo;
 };
 
 class MachODylibFile : public SharedLibraryFile {

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h?rev=276935&r1=276934&r2=276935&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h Wed Jul 27 17:55:30 2016
@@ -42,6 +42,7 @@
 #ifndef LLD_READER_WRITER_MACHO_NORMALIZE_FILE_H
 #define LLD_READER_WRITER_MACHO_NORMALIZE_FILE_H
 
+#include "DebugInfo.h"
 #include "lld/Core/Error.h"
 #include "lld/Core/LLVM.h"
 #include "lld/ReaderWriter/MachOLinkingContext.h"
@@ -91,8 +92,22 @@ struct Relocation {
   bool                isExtern;
   Hex32               value;
   uint32_t            symbol;
+
+#ifndef NDEBUG
+  raw_ostream& operator<<(raw_ostream &OS) const {
+    dump(OS);
+    return OS;
+  }
+
+  void dump(raw_ostream &OS = llvm::dbgs()) const;
+#endif
 };
 
+inline raw_ostream& operator<<(raw_ostream &OS, const Relocation &R) {
+  R.dump(OS);
+  return OS;
+}
+
 /// A typedef so that YAML I/O can treat this vector as a sequence.
 typedef std::vector<Relocation> Relocations;
 
@@ -226,7 +241,6 @@ struct DataInCode {
   DataRegionType  kind;
 };
 
-
 /// A typedef so that YAML I/O can encode/decode mach_header.flags.
 LLVM_YAML_STRONG_TYPEDEF(uint32_t, FileFlags)
 
@@ -242,6 +256,7 @@ struct NormalizedFile {
   std::vector<Symbol>         localSymbols;
   std::vector<Symbol>         globalSymbols;
   std::vector<Symbol>         undefinedSymbols;
+  std::vector<Symbol>         stabsSymbols;
 
   // Maps to load commands with no LINKEDIT content (final linked images only).
   std::vector<DependentDylib> dependentDylibs;

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp?rev=276935&r1=276934&r2=276935&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp Wed Jul 27 17:55:30 2016
@@ -390,12 +390,14 @@ readBinary(std::unique_ptr<MemoryBuffer>
           if (sin->n_strx > strSize)
             return true;
           sout.name  = &strings[sin->n_strx];
-          sout.type  = (NListType)(sin->n_type & N_TYPE);
+          sout.type = static_cast<NListType>(sin->n_type & (N_STAB|N_TYPE));
           sout.scope = (sin->n_type & (N_PEXT|N_EXT));
           sout.sect  = sin->n_sect;
           sout.desc  = sin->n_desc;
           sout.value = sin->n_value;
-          if (sout.type == N_UNDF)
+          if (sin->n_type & N_STAB)
+            f->stabsSymbols.push_back(sout);
+          else if (sout.type == N_UNDF)
             f->undefinedSymbols.push_back(sout);
           else if (sin->n_type & N_EXT)
             f->globalSymbols.push_back(sout);
@@ -429,6 +431,8 @@ readBinary(std::unique_ptr<MemoryBuffer>
             f->undefinedSymbols.push_back(sout);
           else if (sout.scope == (SymbolScope)N_EXT)
             f->globalSymbols.push_back(sout);
+          else if (sin->n_type & N_STAB)
+            f->stabsSymbols.push_back(sout);
           else
             f->localSymbols.push_back(sout);
         }
@@ -535,7 +539,7 @@ public:
   loadFile(std::unique_ptr<MemoryBuffer> mb,
            const Registry &registry) const override {
     std::unique_ptr<File> ret =
-        llvm::make_unique<MachOFile>(std::move(mb), &_ctx);
+      llvm::make_unique<MachOFile>(std::move(mb), &_ctx);
     return std::move(ret);
   }
 

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp?rev=276935&r1=276934&r2=276935&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp Wed Jul 27 17:55:30 2016
@@ -789,8 +789,8 @@ llvm::Error MachOFileLayout::writeLoadCo
     st->cmd     = LC_SYMTAB;
     st->cmdsize = sizeof(symtab_command);
     st->symoff  = _startOfSymbols;
-    st->nsyms   = _file.localSymbols.size() + _file.globalSymbols.size()
-                                            + _file.undefinedSymbols.size();
+    st->nsyms   = _file.stabsSymbols.size() + _file.localSymbols.size() +
+                  _file.globalSymbols.size() + _file.undefinedSymbols.size();
     st->stroff  = _startOfSymbolStrings;
     st->strsize = _endOfSymbolStrings - _startOfSymbolStrings;
     if (_swap)
@@ -876,8 +876,8 @@ llvm::Error MachOFileLayout::writeLoadCo
     st->cmd     = LC_SYMTAB;
     st->cmdsize = sizeof(symtab_command);
     st->symoff  = _startOfSymbols;
-    st->nsyms   = _file.localSymbols.size() + _file.globalSymbols.size()
-                                            + _file.undefinedSymbols.size();
+    st->nsyms   = _file.stabsSymbols.size() + _file.localSymbols.size() +
+                  _file.globalSymbols.size() + _file.undefinedSymbols.size();
     st->stroff  = _startOfSymbolStrings;
     st->strsize = _endOfSymbolStrings - _startOfSymbolStrings;
     if (_swap)
@@ -890,7 +890,8 @@ llvm::Error MachOFileLayout::writeLoadCo
       dst->cmd            = LC_DYSYMTAB;
       dst->cmdsize        = sizeof(dysymtab_command);
       dst->ilocalsym      = _symbolTableLocalsStartIndex;
-      dst->nlocalsym      = _file.localSymbols.size();
+      dst->nlocalsym      = _file.stabsSymbols.size() +
+                            _file.localSymbols.size();
       dst->iextdefsym     = _symbolTableGlobalsStartIndex;
       dst->nextdefsym     = _file.globalSymbols.size();
       dst->iundefsym      = _symbolTableUndefinesStartIndex;
@@ -1102,6 +1103,7 @@ void MachOFileLayout::writeSymbolTable()
   uint32_t symOffset = _startOfSymbols;
   uint32_t strOffset = _startOfSymbolStrings;
   _buffer[strOffset++] = '\0'; // Reserve n_strx offset of zero to mean no name.
+  appendSymbols(_file.stabsSymbols, symOffset, strOffset);
   appendSymbols(_file.localSymbols, symOffset, strOffset);
   appendSymbols(_file.globalSymbols, symOffset, strOffset);
   appendSymbols(_file.undefinedSymbols, symOffset, strOffset);
@@ -1414,10 +1416,14 @@ void MachOFileLayout::buildExportTrie()
 void MachOFileLayout::computeSymbolTableSizes() {
   // MachO symbol tables have three ranges: locals, globals, and undefines
   const size_t nlistSize = (_is64 ? sizeof(nlist_64) : sizeof(nlist));
-  _symbolTableSize = nlistSize * (_file.localSymbols.size()
+  _symbolTableSize = nlistSize * (_file.stabsSymbols.size()
+                                + _file.localSymbols.size()
                                 + _file.globalSymbols.size()
                                 + _file.undefinedSymbols.size());
   _symbolStringPoolSize = 1; // Always reserve 1-byte for the empty string.
+  for (const Symbol &sym : _file.stabsSymbols) {
+    _symbolStringPoolSize += (sym.name.size()+1);
+  }
   for (const Symbol &sym : _file.localSymbols) {
     _symbolStringPoolSize += (sym.name.size()+1);
   }
@@ -1428,7 +1434,8 @@ void MachOFileLayout::computeSymbolTable
     _symbolStringPoolSize += (sym.name.size()+1);
   }
   _symbolTableLocalsStartIndex = 0;
-  _symbolTableGlobalsStartIndex = _file.localSymbols.size();
+  _symbolTableGlobalsStartIndex = _file.stabsSymbols.size() +
+                                  _file.localSymbols.size();
   _symbolTableUndefinesStartIndex = _symbolTableGlobalsStartIndex
                                     + _file.globalSymbols.size();
 

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp?rev=276935&r1=276934&r2=276935&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Wed Jul 27 17:55:30 2016
@@ -22,6 +22,7 @@
 
 #include "MachONormalizedFile.h"
 #include "ArchHandler.h"
+#include "DebugInfo.h"
 #include "MachONormalizedFileBinaryUtils.h"
 #include "lld/Core/Error.h"
 #include "lld/Core/LLVM.h"
@@ -34,6 +35,7 @@
 #include "llvm/Support/MachO.h"
 #include <map>
 #include <system_error>
+#include <unordered_set>
 
 using llvm::StringRef;
 using llvm::isa;
@@ -120,6 +122,7 @@ public:
   void      copySectionInfo(NormalizedFile &file);
   void      updateSectionInfo(NormalizedFile &file);
   void      buildAtomToAddressMap();
+  llvm::Error synthesizeDebugNotes(NormalizedFile &file);
   llvm::Error addSymbols(const lld::File &atomFile, NormalizedFile &file);
   void      addIndirectSymbols(const lld::File &atomFile, NormalizedFile &file);
   void      addRebaseAndBindingInfo(const lld::File &, NormalizedFile &file);
@@ -201,6 +204,7 @@ private:
   bool                          _allSourceFilesHaveMinVersions = true;
   LoadCommandType               _minVersionCommandType = (LoadCommandType)0;
   uint32_t                      _minVersion = 0;
+  std::vector<lld::mach_o::Stab> _stabs;
 };
 
 Util::~Util() {
@@ -785,6 +789,156 @@ void Util::buildAtomToAddressMap() {
   }
 }
 
+llvm::Error Util::synthesizeDebugNotes(NormalizedFile &file) {
+
+  // Bail out early if we don't need to generate a debug map.
+  if (_ctx.debugInfoMode() == MachOLinkingContext::DebugInfoMode::noDebugMap)
+    return llvm::Error::success();
+
+  std::vector<const DefinedAtom*> atomsNeedingDebugNotes;
+  std::set<const mach_o::MachOFile*> filesWithStabs;
+  bool objFileHasDwarf = false;
+  const File *objFile = nullptr;
+
+  for (SectionInfo *sect : _sectionInfos) {
+    for (const AtomInfo &info : sect->atomsAndOffsets) {
+      if (const DefinedAtom *atom = dyn_cast<DefinedAtom>(info.atom)) {
+
+        // FIXME: No stabs/debug-notes for symbols that wouldn't be in the
+        //        symbol table.
+        // FIXME: No stabs/debug-notes for kernel dtrace probes.
+
+        if (atom->contentType() == DefinedAtom::typeCFI ||
+            atom->contentType() == DefinedAtom::typeCString)
+          continue;
+
+        // Whenever we encounter a new file, update the 'objfileHasDwarf' flag.
+        if (&info.atom->file() != objFile) {
+          objFileHasDwarf = false;
+          if (const mach_o::MachOFile *atomFile =
+              dyn_cast<mach_o::MachOFile>(&info.atom->file())) {
+            if (atomFile->debugInfo()) {
+              if (isa<mach_o::DwarfDebugInfo>(atomFile->debugInfo()))
+                objFileHasDwarf = true;
+              else if (isa<mach_o::StabsDebugInfo>(atomFile->debugInfo()))
+                filesWithStabs.insert(atomFile);
+            }
+          }
+        }
+
+        // If this atom is from a file that needs dwarf, add it to the list.
+        if (objFileHasDwarf)
+          atomsNeedingDebugNotes.push_back(info.atom);
+      }
+    }
+  }
+
+  // Sort atoms needing debug notes by file ordinal, then atom ordinal.
+  std::sort(atomsNeedingDebugNotes.begin(), atomsNeedingDebugNotes.end(),
+            [](const DefinedAtom *lhs, const DefinedAtom *rhs) {
+              if (lhs->file().ordinal() != rhs->file().ordinal())
+                return (lhs->file().ordinal() < rhs->file().ordinal());
+              return (lhs->ordinal() < rhs->ordinal());
+            });
+
+  // FIXME: Handle <rdar://problem/17689030>: Add -add_ast_path option to \
+  //        linker which add N_AST stab entry to output
+  // See OutputFile::synthesizeDebugNotes in ObjectFile.cpp in ld64.
+
+  StringRef oldFileName = "";
+  StringRef oldDirPath = "";
+  bool wroteStartSO = false;
+  std::unordered_set<std::string> seenFiles;
+  for (const DefinedAtom *atom : atomsNeedingDebugNotes) {
+    const auto &atomFile = cast<mach_o::MachOFile>(atom->file());
+    assert(dyn_cast_or_null<lld::mach_o::DwarfDebugInfo>(atomFile.debugInfo())
+           && "file for atom needing debug notes does not contain dwarf");
+    auto &dwarf = cast<lld::mach_o::DwarfDebugInfo>(*atomFile.debugInfo());
+
+    auto &tu = dwarf.translationUnitSource();
+    StringRef newFileName = tu.name;
+    StringRef newDirPath = tu.path;
+
+    // Add an SO whenever the TU source file changes.
+    if (newFileName != oldFileName || newDirPath != oldDirPath) {
+      // Translation unit change, emit ending SO
+      if (oldFileName != "")
+        _stabs.push_back(mach_o::Stab(nullptr, N_SO, 1, 0, 0, ""));
+
+      oldFileName = newFileName;
+      oldDirPath = newDirPath;
+
+      // If newDirPath doesn't end with a '/' we need to add one:
+      if (newDirPath.back() != '/') {
+        std::string *p = file.ownedAllocations.Allocate<std::string>();
+        new (p) std::string();
+        *p = (newDirPath + "/").str();
+        newDirPath = *p;
+      }
+
+      // New translation unit, emit start SOs:
+      _stabs.push_back(mach_o::Stab(nullptr, N_SO, 0, 0, 0, newDirPath));
+      _stabs.push_back(mach_o::Stab(nullptr, N_SO, 0, 0, 0, newFileName));
+
+      // Synthesize OSO for start of file.
+      std::string *fullPath = file.ownedAllocations.Allocate<std::string>();
+      new (fullPath) std::string();
+      {
+        SmallString<1024> pathBuf(atomFile.path());
+        if (auto EC = llvm::sys::fs::make_absolute(pathBuf))
+          return llvm::errorCodeToError(EC);
+        *fullPath = pathBuf.str();
+      }
+
+      // Get mod time.
+      uint32_t modTime = 0;
+      llvm::sys::fs::file_status stat;
+      if (!llvm::sys::fs::status(*fullPath, stat))
+        if (llvm::sys::fs::exists(stat))
+          modTime = stat.getLastModificationTime().toEpochTime();
+
+      _stabs.push_back(mach_o::Stab(nullptr, N_OSO, _ctx.getCPUSubType(), 1,
+                                    modTime, *fullPath));
+      // <rdar://problem/6337329> linker should put cpusubtype in n_sect field
+      // of nlist entry for N_OSO debug note entries.
+      wroteStartSO = true;
+    }
+
+    if (atom->contentType() == DefinedAtom::typeCode) {
+      // Synthesize BNSYM and start FUN stabs.
+      _stabs.push_back(mach_o::Stab(atom, N_BNSYM, 1, 0, 0, ""));
+      _stabs.push_back(mach_o::Stab(atom, N_FUN, 1, 0, 0, atom->name()));
+      // Synthesize any SOL stabs needed
+      // FIXME: add SOL stabs.
+      _stabs.push_back(mach_o::Stab(nullptr, N_FUN, 0, 0,
+                                    atom->rawContent().size(), ""));
+      _stabs.push_back(mach_o::Stab(nullptr, N_ENSYM, 1, 0,
+                                    atom->rawContent().size(), ""));
+    } else {
+      if (atom->scope() == Atom::scopeTranslationUnit)
+        _stabs.push_back(mach_o::Stab(atom, N_STSYM, 1, 0, 0, atom->name()));
+      else
+        _stabs.push_back(mach_o::Stab(nullptr, N_GSYM, 1, 0, 0, atom->name()));
+    }
+  }
+
+  // Emit ending SO if necessary.
+  if (wroteStartSO)
+    _stabs.push_back(mach_o::Stab(nullptr, N_SO, 1, 0, 0, ""));
+
+  // Copy any stabs from .o file.
+  for (const auto *objFile : filesWithStabs) {
+    const auto &stabsList =
+      cast<mach_o::StabsDebugInfo>(objFile->debugInfo())->stabs();
+    for (auto &stab : stabsList) {
+      // FIXME: Drop stabs whose atoms have been dead-stripped.
+      _stabs.push_back(stab);
+    }
+  }
+
+  return llvm::Error::success();
+}
+
 uint16_t Util::descBits(const DefinedAtom* atom) {
   uint16_t desc = 0;
   switch (atom->merge()) {
@@ -868,10 +1022,27 @@ llvm::Error Util::getSymbolTableRegion(c
   llvm_unreachable("atom->scope() unknown enum value");
 }
 
+
+
 llvm::Error Util::addSymbols(const lld::File &atomFile,
                              NormalizedFile &file) {
   bool rMode = (_ctx.outputMachOType() == llvm::MachO::MH_OBJECT);
-  // Mach-O symbol table has three regions: locals, globals, undefs.
+  // Mach-O symbol table has four regions: stabs, locals, globals, undefs.
+
+  // Add all stabs.
+  for (auto &stab : _stabs) {
+    Symbol sym;
+    sym.type = static_cast<NListType>(stab.type);
+    sym.scope = 0;
+    sym.sect = stab.other;
+    sym.desc = stab.desc;
+    if (stab.atom)
+      sym.value = _atomToAddress[stab.atom];
+    else
+      sym.value = stab.value;
+    sym.name = stab.str;
+    file.stabsSymbols.push_back(sym);
+  }
 
   // Add all local (non-global) symbols in address order
   std::vector<AtomAndIndex> globals;
@@ -1404,6 +1575,8 @@ normalizedFromAtoms(const lld::File &ato
   util.copySectionInfo(normFile);
   util.assignAddressesToSections(normFile);
   util.buildAtomToAddressMap();
+  if (auto err = util.synthesizeDebugNotes(normFile))
+    return std::move(err);
   util.updateSectionInfo(normFile);
   util.copySectionContent(normFile);
   if (auto ec = util.addSymbols(atomFile, normFile)) {

Modified: lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp?rev=276935&r1=276934&r2=276935&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp (original)
+++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp Wed Jul 27 17:55:30 2016
@@ -27,7 +27,11 @@
 #include "MachONormalizedFileBinaryUtils.h"
 #include "lld/Core/Error.h"
 #include "lld/Core/LLVM.h"
+#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
+#include "llvm/Support/DataExtractor.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/Dwarf.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/Format.h"
 #include "llvm/Support/MachO.h"
 #include "llvm/Support/LEB128.h"
@@ -499,7 +503,7 @@ const Section* findSectionCoveringAddres
 
 const MachODefinedAtom *
 findAtomCoveringAddress(const NormalizedFile &normalizedFile, MachOFile &file,
-                        uint64_t addr, Reference::Addend *addend) {
+                        uint64_t addr, Reference::Addend &addend) {
   const Section *sect = nullptr;
   sect = findSectionCoveringAddress(normalizedFile, addr);
   if (!sect)
@@ -509,7 +513,7 @@ findAtomCoveringAddress(const Normalized
   uint64_t offsetInSect = addr - sect->address;
   auto atom =
       file.findAtomCoveringAddress(*sect, offsetInSect, &offsetInTarget);
-  *addend = offsetInTarget;
+  addend = offsetInTarget;
   return atom;
 }
 
@@ -548,19 +552,23 @@ llvm::Error convertRelocs(const Section
                            -> llvm::Error {
     // Find symbol from index.
     const Symbol *sym = nullptr;
+    uint32_t numStabs  = normalizedFile.stabsSymbols.size();
     uint32_t numLocal  = normalizedFile.localSymbols.size();
     uint32_t numGlobal = normalizedFile.globalSymbols.size();
     uint32_t numUndef  = normalizedFile.undefinedSymbols.size();
-    if (symbolIndex < numLocal) {
-      sym = &normalizedFile.localSymbols[symbolIndex];
-    } else if (symbolIndex < numLocal+numGlobal) {
-      sym = &normalizedFile.globalSymbols[symbolIndex-numLocal];
-    } else if (symbolIndex < numLocal+numGlobal+numUndef) {
-      sym = &normalizedFile.undefinedSymbols[symbolIndex-numLocal-numGlobal];
+    assert(symbolIndex >= numStabs && "Searched for stab via atomBySymbol?");
+    if (symbolIndex < numStabs+numLocal) {
+      sym = &normalizedFile.localSymbols[symbolIndex-numStabs];
+    } else if (symbolIndex < numStabs+numLocal+numGlobal) {
+      sym = &normalizedFile.globalSymbols[symbolIndex-numStabs-numLocal];
+    } else if (symbolIndex < numStabs+numLocal+numGlobal+numUndef) {
+      sym = &normalizedFile.undefinedSymbols[symbolIndex-numStabs-numLocal-
+                                             numGlobal];
     } else {
       return llvm::make_error<GenericError>(Twine("symbol index (")
                                      + Twine(symbolIndex) + ") out of range");
     }
+
     // Find atom from symbol.
     if ((sym->type & N_TYPE) == N_SECT) {
       if (sym->sect > normalizedFile.sections.size())
@@ -685,6 +693,297 @@ bool isDebugInfoSection(const Section &s
   return section.segmentName.equals("__DWARF");
 }
 
+static const Atom* findDefinedAtomByName(MachOFile &file, Twine name) {
+  std::string strName = name.str();
+  for (auto *atom : file.defined())
+    if (atom->name() == strName)
+      return atom;
+  return nullptr;
+}
+
+static StringRef copyDebugString(StringRef str, BumpPtrAllocator &alloc) {
+  std::string *strCopy = alloc.Allocate<std::string>();
+  new (strCopy) std::string();
+  *strCopy = str;
+  return *strCopy;
+}
+
+llvm::Error parseStabs(MachOFile &file,
+                       const NormalizedFile &normalizedFile,
+                       bool copyRefs) {
+
+  if (normalizedFile.stabsSymbols.empty())
+    return llvm::Error::success();
+
+  // FIXME: Kill this off when we can move to sane yaml parsing.
+  std::unique_ptr<BumpPtrAllocator> allocator;
+  if (copyRefs)
+    allocator = llvm::make_unique<BumpPtrAllocator>();
+
+  enum { start, inBeginEnd } state = start;
+
+  const Atom *currentAtom = nullptr;
+  uint64_t currentAtomAddress = 0;
+  StabsDebugInfo::StabsList stabsList;
+  for (const auto &stabSym : normalizedFile.stabsSymbols) {
+    Stab stab(nullptr, stabSym.type, stabSym.sect, stabSym.desc,
+              stabSym.value, stabSym.name);
+    switch (state) {
+    case start:
+      switch (static_cast<StabType>(stabSym.type)) {
+      case N_BNSYM:
+        state = inBeginEnd;
+        currentAtomAddress = stabSym.value;
+        Reference::Addend addend;
+        currentAtom = findAtomCoveringAddress(normalizedFile, file,
+                                              currentAtomAddress, addend);
+        if (addend != 0)
+          return llvm::make_error<GenericError>(
+                   "Non-zero addend for BNSYM '" + stabSym.name + "' in " +
+                   file.path());
+        if (currentAtom)
+          stab.atom = currentAtom;
+        else {
+          // FIXME: ld64 just issues a warning here - should we match that?
+          return llvm::make_error<GenericError>(
+                   "can't find atom for stabs BNSYM at " +
+                   Twine::utohexstr(stabSym.value) + " in " + file.path());
+        }
+        break;
+      case N_SO:
+      case N_OSO:
+        // Not associated with an atom, just copy.
+        if (copyRefs)
+          stab.str = copyDebugString(stabSym.name, *allocator);
+        else
+          stab.str = stabSym.name;
+        break;
+      case N_GSYM: {
+        auto colonIdx = stabSym.name.find(':');
+        if (colonIdx != StringRef::npos) {
+          StringRef name = stabSym.name.substr(0, colonIdx);
+          currentAtom = findDefinedAtomByName(file, "_" + name);
+          stab.atom = currentAtom;
+          if (copyRefs)
+            stab.str = copyDebugString(stabSym.name, *allocator);
+          else
+            stab.str = stabSym.name;
+        } else {
+          currentAtom = findDefinedAtomByName(file, stabSym.name);
+          stab.atom = currentAtom;
+          if (copyRefs)
+            stab.str = copyDebugString(stabSym.name, *allocator);
+          else
+            stab.str = stabSym.name;
+        }
+        if (stab.atom == nullptr)
+          return llvm::make_error<GenericError>(
+                   "can't find atom for N_GSYM stabs" + stabSym.name +
+                   " in " + file.path());
+        break;
+      }
+      case N_FUN:
+        return llvm::make_error<GenericError>(
+                 "old-style N_FUN stab '" + stabSym.name + "' unsupported");
+      default:
+        return llvm::make_error<GenericError>(
+                 "unrecognized stab symbol '" + stabSym.name + "'");
+      }
+      break;
+    case inBeginEnd:
+      stab.atom = currentAtom;
+      switch (static_cast<StabType>(stabSym.type)) {
+      case N_ENSYM:
+        state = start;
+        currentAtom = nullptr;
+        break;
+      case N_FUN:
+        // Just copy the string.
+        if (copyRefs)
+          stab.str = copyDebugString(stabSym.name, *allocator);
+        else
+          stab.str = stabSym.name;
+        break;
+      default:
+        return llvm::make_error<GenericError>(
+                 "unrecognized stab symbol '" + stabSym.name + "'");
+      }
+    }
+    llvm::dbgs() << "Adding to stabsList: " << stab << "\n";
+    stabsList.push_back(stab);
+  }
+
+  file.setDebugInfo(llvm::make_unique<StabsDebugInfo>(std::move(stabsList)));
+
+  // FIXME: Kill this off when we fix YAML memory ownership.
+  file.debugInfo()->setAllocator(std::move(allocator));
+
+  return llvm::Error::success();
+}
+
+static llvm::DataExtractor
+dataExtractorFromSection(const NormalizedFile &normalizedFile,
+                         const Section &S) {
+  const bool is64 = MachOLinkingContext::is64Bit(normalizedFile.arch);
+  const bool isBig = MachOLinkingContext::isBigEndian(normalizedFile.arch);
+  StringRef SecData(reinterpret_cast<const char*>(S.content.data()),
+                    S.content.size());
+  return llvm::DataExtractor(SecData, !isBig, is64 ? 8 : 4);
+}
+
+// FIXME: Cribbed from llvm-dwp -- should share "lightweight CU DIE
+//        inspection" code if possible.
+static uint32_t getCUAbbrevOffset(llvm::DataExtractor abbrevData,
+                                  uint64_t abbrCode) {
+  uint64_t curCode;
+  uint32_t offset = 0;
+  while ((curCode = abbrevData.getULEB128(&offset)) != abbrCode) {
+    // Tag
+    abbrevData.getULEB128(&offset);
+    // DW_CHILDREN
+    abbrevData.getU8(&offset);
+    // Attributes
+    while (abbrevData.getULEB128(&offset) | abbrevData.getULEB128(&offset))
+      ;
+  }
+  return offset;
+}
+
+// FIXME: Cribbed from llvm-dwp -- should share "lightweight CU DIE
+//        inspection" code if possible.
+static Expected<const char *>
+getIndexedString(const NormalizedFile &normalizedFile,
+                 uint32_t form, llvm::DataExtractor infoData,
+                 uint32_t &infoOffset, const Section &stringsSection) {
+  if (form == llvm::dwarf::DW_FORM_string)
+   return infoData.getCStr(&infoOffset);
+  if (form != llvm::dwarf::DW_FORM_strp)
+    return llvm::make_error<GenericError>(
+        "string field encoded without DW_FORM_strp");
+  uint32_t stringOffset = infoData.getU32(&infoOffset);
+  llvm::DataExtractor stringsData =
+    dataExtractorFromSection(normalizedFile, stringsSection);
+  return stringsData.getCStr(&stringOffset);
+}
+
+// FIXME: Cribbed from llvm-dwp -- should share "lightweight CU DIE
+//        inspection" code if possible.
+static llvm::Expected<TranslationUnitSource>
+readCompUnit(const NormalizedFile &normalizedFile,
+             const Section &info,
+             const Section &abbrev,
+             const Section &strings,
+             StringRef path) {
+  // FIXME: Cribbed from llvm-dwp -- should share "lightweight CU DIE
+  //        inspection" code if possible.
+  uint32_t offset = 0;
+  auto infoData = dataExtractorFromSection(normalizedFile, info);
+  uint32_t length = infoData.getU32(&offset);
+  if (length == 0xffffffff)
+    infoData.getU64(&offset);
+  else if (length > 0xffffff00)
+    return llvm::make_error<GenericError>("Malformed DWARF in " + path);
+
+  uint16_t version = infoData.getU16(&offset);
+
+  if (version < 2 || version > 4)
+    return llvm::make_error<GenericError>("Unsupported DWARF version in " +
+                                          path);
+
+  infoData.getU32(&offset); // Abbrev offset (should be zero)
+  uint8_t addrSize = infoData.getU8(&offset);
+
+  uint32_t abbrCode = infoData.getULEB128(&offset);
+  auto abbrevData = dataExtractorFromSection(normalizedFile, abbrev);
+  uint32_t abbrevOffset = getCUAbbrevOffset(abbrevData, abbrCode);
+  uint64_t tag = abbrevData.getULEB128(&abbrevOffset);
+  if (tag != llvm::dwarf::DW_TAG_compile_unit)
+    return llvm::make_error<GenericError>("top level DIE is not a compile unit");
+  // DW_CHILDREN
+  abbrevData.getU8(&abbrevOffset);
+  uint32_t name;
+  uint32_t form;
+  TranslationUnitSource tu;
+  while ((name = abbrevData.getULEB128(&abbrevOffset)) |
+             (form = abbrevData.getULEB128(&abbrevOffset)) &&
+         (name != 0 || form != 0)) {
+    switch (name) {
+    case llvm::dwarf::DW_AT_name: {
+      if (auto eName = getIndexedString(normalizedFile, form, infoData, offset,
+                                        strings))
+          tu.name = *eName;
+      else
+        return eName.takeError();
+      break;
+    }
+    case llvm::dwarf::DW_AT_comp_dir: {
+      if (auto eName = getIndexedString(normalizedFile, form, infoData, offset,
+                                        strings))
+        tu.path = *eName;
+      else
+        return eName.takeError();
+      break;
+    }
+    default:
+      llvm::DWARFFormValue::skipValue(form, infoData, &offset, version,
+                                      addrSize);
+    }
+  }
+  return tu;
+}
+
+llvm::Error parseDebugInfo(MachOFile &file,
+                           const NormalizedFile &normalizedFile, bool copyRefs) {
+
+  // Find the interesting debug info sections.
+  const Section *debugInfo = nullptr;
+  const Section *debugAbbrev = nullptr;
+  const Section *debugStrings = nullptr;
+
+  for (auto &s : normalizedFile.sections) {
+    if (s.segmentName == "__DWARF") {
+      if (s.sectionName == "__debug_info")
+        debugInfo = &s;
+      else if (s.sectionName == "__debug_abbrev")
+        debugAbbrev = &s;
+      else if (s.sectionName == "__debug_str")
+        debugStrings = &s;
+    }
+  }
+
+  if (!debugInfo)
+    return parseStabs(file, normalizedFile, copyRefs);
+
+  if (debugInfo->content.size() == 0)
+    return llvm::Error::success();
+
+  if (debugInfo->content.size() < 12)
+    return llvm::make_error<GenericError>("Malformed __debug_info section in " +
+                                          file.path() + ": too small");
+
+  if (!debugAbbrev)
+    return llvm::make_error<GenericError>("Missing __dwarf_abbrev section in " +
+                                          file.path());
+
+  if (auto tuOrErr = readCompUnit(normalizedFile, *debugInfo, *debugAbbrev,
+                                  *debugStrings, file.path())) {
+    // FIXME: Kill of allocator and code under 'copyRefs' when we fix YAML
+    //        memory ownership.
+    std::unique_ptr<BumpPtrAllocator> allocator;
+    if (copyRefs) {
+      allocator = llvm::make_unique<BumpPtrAllocator>();
+      tuOrErr->name = copyDebugString(tuOrErr->name, *allocator);
+      tuOrErr->path = copyDebugString(tuOrErr->path, *allocator);
+    }
+    file.setDebugInfo(llvm::make_unique<DwarfDebugInfo>(std::move(*tuOrErr)));
+    if (copyRefs)
+      file.debugInfo()->setAllocator(std::move(allocator));
+  } else
+    return tuOrErr.takeError();
+
+  return llvm::Error::success();
+}
+
 static int64_t readSPtr(bool is64, bool isBig, const uint8_t *addr) {
   if (is64)
     return read64(addr, isBig);
@@ -853,7 +1152,7 @@ static llvm::Error processCIE(const Norm
       const MachODefinedAtom *func = nullptr;
       Reference::Addend addend;
       func = findAtomCoveringAddress(normalizedFile, file, funcAddress,
-                                     &addend);
+                                     addend);
       atom->addReference(Reference::KindNamespace::mach_o, handler.kindArch(),
                          handler.unwindRefToPersonalityFunctionKind(),
                          PersonalityFunctionField, func, addend);
@@ -936,7 +1235,7 @@ static llvm::Error processFDE(const Norm
     }
     Reference::Addend addend;
     auto *target = findAtomCoveringAddress(normalizedFile, file,
-                                           targetAddress, &addend);
+                                           targetAddress, addend);
     atom->addReference(Reference::KindNamespace::mach_o, handler.kindArch(),
                        refKind, refAddress, target, addend);
 
@@ -1095,7 +1394,6 @@ llvm::Error parseObjCImageInfo(const Sec
   return llvm::Error();
 }
 
-
 /// Converts normalized mach-o file into an lld::File and lld::Atoms.
 llvm::Expected<std::unique_ptr<lld::File>>
 objectToAtoms(const NormalizedFile &normalizedFile, StringRef path,
@@ -1136,10 +1434,11 @@ normalizedObjectToAtoms(MachOFile *file,
   // Create atoms from each section.
   for (auto &sect : normalizedFile.sections) {
     DEBUG(llvm::dbgs() << "Creating atoms: "; sect.dump());
+
+    // If this is a debug-info section parse it specially.
     if (isDebugInfoSection(sect))
       continue;
 
-
     // If the file contains an objc_image_info struct, then we should parse the
     // ObjC flags and Swift version.
     if (isObjCImageInfo(sect)) {
@@ -1248,6 +1547,10 @@ normalizedObjectToAtoms(MachOFile *file,
   for (const DefinedAtom* defAtom : file->defined()) {
     reinterpret_cast<const SimpleDefinedAtom*>(defAtom)->sortReferences();
   }
+
+  if (auto err = parseDebugInfo(*file, normalizedFile, copyRefs))
+    return err;
+
   return llvm::Error();
 }
 
@@ -1325,6 +1628,13 @@ normalizedToAtoms(const NormalizedFile &
 }
 
 #ifndef NDEBUG
+void Relocation::dump(llvm::raw_ostream &OS) const {
+  OS << "Relocation (offset=" << llvm::format_hex(offset, 8, true)
+     << ", scatered=" << scattered << ", type=" << type << ", length=" << length
+     << ", pcrel=" << pcRel << ", isExtern=" << isExtern << ", value="
+     << llvm::format_hex(value, 8, true) << ", symbol=" << symbol << ")\n";
+}
+
 void Section::dump(llvm::raw_ostream &OS) const {
   OS << "Section (\"" << segmentName << ", " << sectionName << "\"";
   OS << ", addr: " << llvm::format_hex(address, 16, true);

Added: lld/trunk/test/mach-o/debug-syms.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/mach-o/debug-syms.yaml?rev=276935&view=auto
==============================================================================
--- lld/trunk/test/mach-o/debug-syms.yaml (added)
+++ lld/trunk/test/mach-o/debug-syms.yaml Wed Jul 27 17:55:30 2016
@@ -0,0 +1,249 @@
+# RUN: lld -flavor darwin -arch x86_64 -o %t %s -lSystem && \
+# RUN:   llvm-nm -no-sort -debug-syms %t | FileCheck %s
+
+# CHECK:      0000000000000000 - 00 0000    SO /Users/lhames/Projects/lld/lld-svn-tot/scratch/
+# CHECK-NEXT: 0000000000000000 - 00 0000    SO hw.c
+# CHECK-NEXT:    {{[0-9a-f]+}} - 03 0001   OSO {{.*}}/test/mach-o/debug-syms.yaml
+# CHECK-NEXT: 0000000100000fa0 - 01 0000 BNSYM 
+# CHECK-NEXT: 0000000100000fa0 - 01 0000   FUN _main
+# CHECK-NEXT: 0000000000000016 - 00 0000   FUN 
+# CHECK-NEXT: 0000000000000016 - 01 0000 ENSYM 
+# CHECK-NEXT: 0000000000000000 - 01 0000    SO 
+
+--- !mach-o
+arch:            x86_64
+file-type:       MH_OBJECT
+flags:           [ MH_SUBSECTIONS_VIA_SYMBOLS ]
+compat-version:  0.0
+current-version: 0.0
+has-UUID:        false
+OS:              unknown
+min-os-version-kind: LC_VERSION_MIN_MACOSX
+sections:        
+  - segment:         __TEXT
+    section:         __text
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_PURE_INSTRUCTIONS, S_ATTR_SOME_INSTRUCTIONS ]
+    alignment:       16
+    address:         0x0000000000000000
+    content:         [ 0x55, 0x48, 0x89, 0xE5, 0x31, 0xC0, 0xC7, 0x45, 
+                       0xFC, 0x00, 0x00, 0x00, 0x00, 0x89, 0x7D, 0xF8, 
+                       0x48, 0x89, 0x75, 0xF0, 0x5D, 0xC3 ]
+  - segment:         __DWARF
+    section:         __debug_str
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_DEBUG ]
+    address:         0x0000000000000016
+    content:         [ 0x41, 0x70, 0x70, 0x6C, 0x65, 0x20, 0x4C, 0x4C, 
+                       0x56, 0x4D, 0x20, 0x76, 0x65, 0x72, 0x73, 0x69, 
+                       0x6F, 0x6E, 0x20, 0x38, 0x2E, 0x30, 0x2E, 0x30, 
+                       0x20, 0x28, 0x63, 0x6C, 0x61, 0x6E, 0x67, 0x2D, 
+                       0x38, 0x30, 0x30, 0x2E, 0x30, 0x2E, 0x32, 0x34, 
+                       0x2E, 0x31, 0x29, 0x00, 0x68, 0x77, 0x2E, 0x63, 
+                       0x00, 0x2F, 0x55, 0x73, 0x65, 0x72, 0x73, 0x2F, 
+                       0x6C, 0x68, 0x61, 0x6D, 0x65, 0x73, 0x2F, 0x50, 
+                       0x72, 0x6F, 0x6A, 0x65, 0x63, 0x74, 0x73, 0x2F, 
+                       0x6C, 0x6C, 0x64, 0x2F, 0x6C, 0x6C, 0x64, 0x2D, 
+                       0x73, 0x76, 0x6E, 0x2D, 0x74, 0x6F, 0x74, 0x2F, 
+                       0x73, 0x63, 0x72, 0x61, 0x74, 0x63, 0x68, 0x00, 
+                       0x6D, 0x61, 0x69, 0x6E, 0x00, 0x69, 0x6E, 0x74, 
+                       0x00, 0x61, 0x72, 0x67, 0x63, 0x00, 0x61, 0x72, 
+                       0x67, 0x76, 0x00, 0x63, 0x68, 0x61, 0x72, 0x00 ]
+  - segment:         __DWARF
+    section:         __debug_loc
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_DEBUG ]
+    address:         0x000000000000008E
+  - segment:         __DWARF
+    section:         __debug_abbrev
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_DEBUG ]
+    address:         0x000000000000008E
+    content:         [ 0x01, 0x11, 0x01, 0x25, 0x0E, 0x13, 0x05, 0x03, 
+                       0x0E, 0x10, 0x06, 0x1B, 0x0E, 0x11, 0x01, 0x12, 
+                       0x01, 0x00, 0x00, 0x02, 0x2E, 0x01, 0x11, 0x01, 
+                       0x12, 0x01, 0x40, 0x0A, 0x03, 0x0E, 0x3A, 0x0B, 
+                       0x3B, 0x0B, 0x27, 0x0C, 0x49, 0x13, 0x3F, 0x0C, 
+                       0x00, 0x00, 0x03, 0x05, 0x00, 0x02, 0x0A, 0x03, 
+                       0x0E, 0x3A, 0x0B, 0x3B, 0x0B, 0x49, 0x13, 0x00, 
+                       0x00, 0x04, 0x24, 0x00, 0x03, 0x0E, 0x3E, 0x0B, 
+                       0x0B, 0x0B, 0x00, 0x00, 0x05, 0x0F, 0x00, 0x49, 
+                       0x13, 0x00, 0x00, 0x00 ]
+  - segment:         __DWARF
+    section:         __debug_info
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_DEBUG ]
+    address:         0x00000000000000DA
+    content:         [ 0x7F, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 
+                       0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 
+                       0x0C, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x00, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
+                       0x56, 0x60, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 
+                       0x6A, 0x00, 0x00, 0x00, 0x01, 0x03, 0x02, 0x91, 
+                       0x78, 0x69, 0x00, 0x00, 0x00, 0x01, 0x01, 0x6A, 
+                       0x00, 0x00, 0x00, 0x03, 0x02, 0x91, 0x70, 0x6E, 
+                       0x00, 0x00, 0x00, 0x01, 0x01, 0x71, 0x00, 0x00, 
+                       0x00, 0x00, 0x04, 0x65, 0x00, 0x00, 0x00, 0x05, 
+                       0x04, 0x05, 0x76, 0x00, 0x00, 0x00, 0x05, 0x7B, 
+                       0x00, 0x00, 0x00, 0x04, 0x73, 0x00, 0x00, 0x00, 
+                       0x06, 0x01, 0x00 ]
+    relocations:     
+      - offset:          0x00000037
+        type:            X86_64_RELOC_UNSIGNED
+        length:          3
+        pc-rel:          false
+        extern:          false
+        symbol:          1
+      - offset:          0x0000002F
+        type:            X86_64_RELOC_UNSIGNED
+        length:          3
+        pc-rel:          false
+        extern:          false
+        symbol:          1
+      - offset:          0x00000026
+        type:            X86_64_RELOC_UNSIGNED
+        length:          3
+        pc-rel:          false
+        extern:          false
+        symbol:          1
+      - offset:          0x0000001E
+        type:            X86_64_RELOC_UNSIGNED
+        length:          3
+        pc-rel:          false
+        extern:          false
+        symbol:          1
+  - segment:         __DWARF
+    section:         __debug_ranges
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_DEBUG ]
+    address:         0x000000000000015D
+  - segment:         __DWARF
+    section:         __debug_macinfo
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_DEBUG ]
+    address:         0x000000000000015D
+    content:         [ 0x00 ]
+  - segment:         __DWARF
+    section:         __apple_names
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_DEBUG ]
+    address:         0x000000000000015E
+    content:         [ 0x48, 0x53, 0x41, 0x48, 0x01, 0x00, 0x00, 0x00, 
+                       0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
+                       0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 
+                       0x00, 0x00, 0x00, 0x00, 0x6A, 0x7F, 0x9A, 0x7C, 
+                       0x2C, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 
+                       0x01, 0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x00, 
+                       0x00, 0x00, 0x00, 0x00 ]
+  - segment:         __DWARF
+    section:         __apple_objc
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_DEBUG ]
+    address:         0x000000000000019A
+    content:         [ 0x48, 0x53, 0x41, 0x48, 0x01, 0x00, 0x00, 0x00, 
+                       0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 
+                       0xFF, 0xFF, 0xFF, 0xFF ]
+  - segment:         __DWARF
+    section:         __apple_namespac
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_DEBUG ]
+    address:         0x00000000000001BE
+    content:         [ 0x48, 0x53, 0x41, 0x48, 0x01, 0x00, 0x00, 0x00, 
+                       0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 
+                       0xFF, 0xFF, 0xFF, 0xFF ]
+  - segment:         __DWARF
+    section:         __apple_types
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_DEBUG ]
+    address:         0x00000000000001E2
+    content:         [ 0x48, 0x53, 0x41, 0x48, 0x01, 0x00, 0x00, 0x00, 
+                       0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 
+                       0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x06, 0x00, 
+                       0x03, 0x00, 0x05, 0x00, 0x04, 0x00, 0x0B, 0x00, 
+                       0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
+                       0x30, 0x80, 0x88, 0x0B, 0x63, 0x20, 0x95, 0x7C, 
+                       0x40, 0x00, 0x00, 0x00, 0x53, 0x00, 0x00, 0x00, 
+                       0x65, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 
+                       0x6A, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 
+                       0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x01, 
+                       0x00, 0x00, 0x00, 0x7B, 0x00, 0x00, 0x00, 0x24, 
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
+  - segment:         __DWARF
+    section:         __apple_exttypes
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_DEBUG ]
+    address:         0x0000000000000248
+    content:         [ 0x48, 0x53, 0x41, 0x48, 0x01, 0x00, 0x00, 0x00, 
+                       0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x06, 0x00, 
+                       0xFF, 0xFF, 0xFF, 0xFF ]
+  - segment:         __LD
+    section:         __compact_unwind
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_DEBUG ]
+    alignment:       8
+    address:         0x0000000000000270
+    content:         [ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
+    relocations:     
+      - offset:          0x00000000
+        type:            X86_64_RELOC_UNSIGNED
+        length:          3
+        pc-rel:          false
+        extern:          false
+        symbol:          1
+  - segment:         __TEXT
+    section:         __eh_frame
+    type:            S_COALESCED
+    attributes:      [  ]
+    alignment:       8
+    address:         0x0000000000000290
+    content:         [ 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x01, 0x7A, 0x52, 0x00, 0x01, 0x78, 0x10, 0x01, 
+                       0x10, 0x0C, 0x07, 0x08, 0x90, 0x01, 0x00, 0x00, 
+                       0x24, 0x00, 0x00, 0x00, 0x1C, 0x00, 0x00, 0x00, 
+                       0x50, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 
+                       0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x00, 0x41, 0x0E, 0x10, 0x86, 0x02, 0x43, 0x0D, 
+                       0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]
+  - segment:         __DWARF
+    section:         __debug_line
+    type:            S_REGULAR
+    attributes:      [ S_ATTR_DEBUG ]
+    address:         0x00000000000002D0
+    content:         [ 0x37, 0x00, 0x00, 0x00, 0x02, 0x00, 0x1B, 0x00, 
+                       0x00, 0x00, 0x01, 0x01, 0xFB, 0x0E, 0x0D, 0x00, 
+                       0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 
+                       0x00, 0x00, 0x01, 0x00, 0x68, 0x77, 0x2E, 0x63, 
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x02, 
+                       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
+                       0x01, 0x05, 0x03, 0x0A, 0x08, 0x3D, 0x02, 0x02, 
+                       0x00, 0x01, 0x01 ]
+    relocations:     
+      - offset:          0x00000028
+        type:            X86_64_RELOC_UNSIGNED
+        length:          3
+        pc-rel:          false
+        extern:          false
+        symbol:          1
+global-symbols:  
+  - name:            _main
+    type:            N_SECT
+    scope:           [ N_EXT ]
+    sect:            1
+    value:           0x0000000000000000
+page-size:       0x00000000
+...




More information about the llvm-commits mailing list