diff options
Diffstat (limited to 'lld/lib')
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp | 5 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/DebugInfo.h | 310 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/File.h | 16 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFile.h | 17 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp | 10 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp | 21 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp | 175 | ||||
| -rw-r--r-- | lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp | 333 |
9 files changed, 26 insertions, 862 deletions
diff --git a/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp b/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp index 391cbf66859..c36982a77b1 100644 --- a/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp +++ b/lld/lib/ReaderWriter/MachO/ArchHandler_x86_64.cpp @@ -463,10 +463,7 @@ ArchHandler_x86_64::getPairReferenceInfo(const normalized::Relocation &reloc1, return ec; uint64_t encodedAddend = (int64_t)*(const little64_t *)fixupContent; if (inAtom == fromTarget) { - if (inAtom->contentType() == DefinedAtom::typeCFI) - *kind = unwindFDEToFunction; - else - *kind = delta64; + *kind = delta64; *addend = encodedAddend + offsetInAtom; } else if (inAtom == *target) { *kind = negDelta64; diff --git a/lld/lib/ReaderWriter/MachO/CMakeLists.txt b/lld/lib/ReaderWriter/MachO/CMakeLists.txt index d8f7d9bacc4..70f451c997b 100644 --- a/lld/lib/ReaderWriter/MachO/CMakeLists.txt +++ b/lld/lib/ReaderWriter/MachO/CMakeLists.txt @@ -21,7 +21,6 @@ add_lld_library(lldMachO LINK_LIBS lldCore lldYAML - LLVMDebugInfoDWARF LLVMObject LLVMSupport ${PTHREAD_LIB} diff --git a/lld/lib/ReaderWriter/MachO/DebugInfo.h b/lld/lib/ReaderWriter/MachO/DebugInfo.h deleted file mode 100644 index 7729b020d5e..00000000000 --- a/lld/lib/ReaderWriter/MachO/DebugInfo.h +++ /dev/null @@ -1,310 +0,0 @@ -//===- 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 diff --git a/lld/lib/ReaderWriter/MachO/File.h b/lld/lib/ReaderWriter/MachO/File.h index 82c73e35e76..64a0fcf8284 100644 --- a/lld/lib/ReaderWriter/MachO/File.h +++ b/lld/lib/ReaderWriter/MachO/File.h @@ -11,13 +11,11 @@ #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 { @@ -27,15 +25,11 @@ 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) {} - /// Dummy file constructor - for virtual files. - MachOFile(StringRef path) - : SimpleFile(path, File::kindMachObject) {} + MachOFile(StringRef path) : SimpleFile(path, File::kindMachObject) {} void addDefinedAtom(StringRef name, Atom::Scope scope, DefinedAtom::ContentType type, DefinedAtom::Merge merge, @@ -231,13 +225,6 @@ 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. @@ -278,7 +265,6 @@ 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 { diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h b/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h index c2d0ac3a202..92a21f7ef83 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFile.h @@ -42,7 +42,6 @@ #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" @@ -92,22 +91,8 @@ 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; @@ -241,6 +226,7 @@ struct DataInCode { DataRegionType kind; }; + /// A typedef so that YAML I/O can encode/decode mach_header.flags. LLVM_YAML_STRONG_TYPEDEF(uint32_t, FileFlags) @@ -256,7 +242,6 @@ 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; diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp index d7011351411..a17de5be174 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryReader.cpp @@ -390,14 +390,12 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb, if (sin->n_strx > strSize) return true; sout.name = &strings[sin->n_strx]; - sout.type = static_cast<NListType>(sin->n_type & (N_STAB|N_TYPE)); + sout.type = (NListType)(sin->n_type & 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 (sin->n_type & N_STAB) - f->stabsSymbols.push_back(sout); - else if (sout.type == N_UNDF) + if (sout.type == N_UNDF) f->undefinedSymbols.push_back(sout); else if (sin->n_type & N_EXT) f->globalSymbols.push_back(sout); @@ -431,8 +429,6 @@ readBinary(std::unique_ptr<MemoryBuffer> &mb, 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); } @@ -539,7 +535,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); } diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp index ed58d92a80b..f3e159684e1 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileBinaryWriter.cpp @@ -789,8 +789,8 @@ llvm::Error MachOFileLayout::writeLoadCommands() { st->cmd = LC_SYMTAB; st->cmdsize = sizeof(symtab_command); st->symoff = _startOfSymbols; - st->nsyms = _file.stabsSymbols.size() + _file.localSymbols.size() + - _file.globalSymbols.size() + _file.undefinedSymbols.size(); + st->nsyms = _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::writeLoadCommands() { st->cmd = LC_SYMTAB; st->cmdsize = sizeof(symtab_command); st->symoff = _startOfSymbols; - st->nsyms = _file.stabsSymbols.size() + _file.localSymbols.size() + - _file.globalSymbols.size() + _file.undefinedSymbols.size(); + st->nsyms = _file.localSymbols.size() + _file.globalSymbols.size() + + _file.undefinedSymbols.size(); st->stroff = _startOfSymbolStrings; st->strsize = _endOfSymbolStrings - _startOfSymbolStrings; if (_swap) @@ -890,8 +890,7 @@ llvm::Error MachOFileLayout::writeLoadCommands() { dst->cmd = LC_DYSYMTAB; dst->cmdsize = sizeof(dysymtab_command); dst->ilocalsym = _symbolTableLocalsStartIndex; - dst->nlocalsym = _file.stabsSymbols.size() + - _file.localSymbols.size(); + dst->nlocalsym = _file.localSymbols.size(); dst->iextdefsym = _symbolTableGlobalsStartIndex; dst->nextdefsym = _file.globalSymbols.size(); dst->iundefsym = _symbolTableUndefinesStartIndex; @@ -1103,7 +1102,6 @@ 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); @@ -1416,14 +1414,10 @@ 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.stabsSymbols.size() - + _file.localSymbols.size() + _symbolTableSize = nlistSize * (_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); } @@ -1434,8 +1428,7 @@ void MachOFileLayout::computeSymbolTableSizes() { _symbolStringPoolSize += (sym.name.size()+1); } _symbolTableLocalsStartIndex = 0; - _symbolTableGlobalsStartIndex = _file.stabsSymbols.size() + - _file.localSymbols.size(); + _symbolTableGlobalsStartIndex = _file.localSymbols.size(); _symbolTableUndefinesStartIndex = _symbolTableGlobalsStartIndex + _file.globalSymbols.size(); diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp index 2d95ab7ec9d..4775c75f721 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileFromAtoms.cpp @@ -22,7 +22,6 @@ #include "MachONormalizedFile.h" #include "ArchHandler.h" -#include "DebugInfo.h" #include "MachONormalizedFileBinaryUtils.h" #include "lld/Core/Error.h" #include "lld/Core/LLVM.h" @@ -35,7 +34,6 @@ #include "llvm/Support/MachO.h" #include <map> #include <system_error> -#include <unordered_set> using llvm::StringRef; using llvm::isa; @@ -122,7 +120,6 @@ 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); @@ -204,7 +201,6 @@ private: bool _allSourceFilesHaveMinVersions = true; LoadCommandType _minVersionCommandType = (LoadCommandType)0; uint32_t _minVersion = 0; - std::vector<lld::mach_o::Stab> _stabs; }; Util::~Util() { @@ -789,156 +785,6 @@ 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()) { @@ -1022,27 +868,10 @@ llvm::Error Util::getSymbolTableRegion(const DefinedAtom* atom, 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 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); - } + // Mach-O symbol table has three regions: locals, globals, undefs. // Add all local (non-global) symbols in address order std::vector<AtomAndIndex> globals; @@ -1575,8 +1404,6 @@ normalizedFromAtoms(const lld::File &atomFile, 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)) { diff --git a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp index 9867d92563e..fc760a3eddd 100644 --- a/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp +++ b/lld/lib/ReaderWriter/MachO/MachONormalizedFileToAtoms.cpp @@ -27,11 +27,7 @@ #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" @@ -503,7 +499,7 @@ const Section* findSectionCoveringAddress(const NormalizedFile &normalizedFile, 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) @@ -513,7 +509,7 @@ findAtomCoveringAddress(const NormalizedFile &normalizedFile, MachOFile &file, uint64_t offsetInSect = addr - sect->address; auto atom = file.findAtomCoveringAddress(*sect, offsetInSect, &offsetInTarget); - addend = offsetInTarget; + *addend = offsetInTarget; return atom; } @@ -552,23 +548,19 @@ llvm::Error convertRelocs(const Section §ion, -> 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(); - 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]; + 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]; } 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()) @@ -693,296 +685,6 @@ bool isDebugInfoSection(const Section §ion) { 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); @@ -1151,7 +853,7 @@ static llvm::Error processCIE(const NormalizedFile &normalizedFile, 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); @@ -1234,7 +936,7 @@ static llvm::Error processFDE(const NormalizedFile &normalizedFile, } Reference::Addend addend; auto *target = findAtomCoveringAddress(normalizedFile, file, - targetAddress, addend); + targetAddress, &addend); atom->addReference(Reference::KindNamespace::mach_o, handler.kindArch(), refKind, refAddress, target, addend); @@ -1393,6 +1095,7 @@ llvm::Error parseObjCImageInfo(const Section §, 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, @@ -1433,11 +1136,10 @@ 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)) { @@ -1546,10 +1248,6 @@ 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(); } @@ -1627,13 +1325,6 @@ normalizedToAtoms(const NormalizedFile &normalizedFile, StringRef path, } #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); |

