[lld] r276921 - [lld][MachO] Add debug info support for MachO.
Galina Kistanova via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 28 11:02:45 PDT 2016
Hello Lang,
This revision broke at least two builders:
http://lab.llvm.org:8011/builders/llvm-clang-lld-x86_64-scei-ps4-windows10pro-fast/builds/9027
http://lab.llvm.org:8011/builders/lld-x86_64-win7/builds/37314
Please have a look at this?
Thanks
Galina
On Wed, Jul 27, 2016 at 2:31 PM, Lang Hames via llvm-commits <
llvm-commits at lists.llvm.org> wrote:
> Author: lhames
> Date: Wed Jul 27 16:31:25 2016
> New Revision: 276921
>
> URL: http://llvm.org/viewvc/llvm-project?rev=276921&view=rev
> Log:
> [lld][MachO] Add debug info support for MachO.
>
> This patch causes LLD to build stabs debugging symbols for files containing
> DWARF debug info, and to propagate existing stabs symbols for object files
> built using '-r' mode. This enables debugging of binaries generated by LLD
> from MachO objects.
>
>
> 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=276921&r1=276920&r2=276921&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp (original)
> +++ lld/trunk/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp Wed Jul 27
> 16:31:25 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=276921&r1=276920&r2=276921&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt (original)
> +++ lld/trunk/lib/ReaderWriter/MachO/CMakeLists.txt Wed Jul 27 16:31:25
> 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=276921&view=auto
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/MachO/DebugInfo.h (added)
> +++ lld/trunk/lib/ReaderWriter/MachO/DebugInfo.h Wed Jul 27 16:31:25 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=276921&r1=276920&r2=276921&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/MachO/File.h (original)
> +++ lld/trunk/lib/ReaderWriter/MachO/File.h Wed Jul 27 16:31:25 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=276921&r1=276920&r2=276921&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h (original)
> +++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFile.h Wed Jul 27
> 16:31:25 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=276921&r1=276920&r2=276921&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
> (original)
> +++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp
> Wed Jul 27 16:31:25 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 ®istry) 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=276921&r1=276920&r2=276921&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
> (original)
> +++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp
> Wed Jul 27 16:31:25 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=276921&r1=276920&r2=276921&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp
> (original)
> +++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp Wed
> Jul 27 16:31:25 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=276921&r1=276920&r2=276921&view=diff
>
> ==============================================================================
> --- lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp
> (original)
> +++ lld/trunk/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp Wed
> Jul 27 16:31:25 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,296 @@ 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>();
> + *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 +1151,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 +1234,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 +1393,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 +1433,11 @@ normalizedObjectToAtoms(MachOFile *file,
> // Create atoms from each section.
> for (auto § : 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 +1546,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 +1627,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=276921&view=auto
>
> ==============================================================================
> --- lld/trunk/test/mach-o/debug-syms.yaml (added)
> +++ lld/trunk/test/mach-o/debug-syms.yaml Wed Jul 27 16:31:25 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
> +...
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160728/cdb7cd0b/attachment-0001.html>
More information about the llvm-commits
mailing list