forked from OSchip/llvm-project
Revert "Initial dsymutil tool commit."
This reverts commit r223793. The review thread wasn't concluded. llvm-svn: 223794
This commit is contained in:
parent
893c4f1e4d
commit
04aef05537
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,25 +0,0 @@
|
|||
/* This is the main file used to produce the basic* objects that are
|
||||
used for the dsymutil tests.
|
||||
|
||||
These are compiled in a couple of different ways (always on a
|
||||
Darwin system):
|
||||
Basic compilation:
|
||||
for FILE in basic1.c basic2.c basic3.c; do
|
||||
clang -g -c $FILE -o ${FILE%.c}.macho.x86_64.o
|
||||
done
|
||||
clang basic1.macho.x86_64.o basic2.macho.x86_64.o basic3.macho.x86_64.o -o basic.macho.x86_64 -Wl,-dead_strip
|
||||
|
||||
LTO compilation:
|
||||
for FILE in basic1.c basic2.c basic3.c; do
|
||||
clang -g -c -flto $FILE -o ${FILE%.c}-lto.o
|
||||
done
|
||||
clang basic1-lto.o basic2-lto.o basic3-lto.o -o basic-lto.macho.x86_64 -Wl,-object_path_lto,$PWD/basic-lto.macho.x86_64.o -Wl,-dead_strip
|
||||
rm basic1-lto.o basic2-lto.o basic3-lto.o
|
||||
|
||||
*/
|
||||
|
||||
int foo(int);
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
return foo(argc);
|
||||
}
|
Binary file not shown.
|
@ -1,22 +0,0 @@
|
|||
/* For compilation instructions see basic1.c. */
|
||||
|
||||
static int baz = 42;
|
||||
static int private_int;
|
||||
extern volatile int val;
|
||||
int unused_data = 1;
|
||||
|
||||
int bar(int);
|
||||
|
||||
void unused1() {
|
||||
bar(baz);
|
||||
}
|
||||
|
||||
static int inc() {
|
||||
return ++private_int;
|
||||
}
|
||||
|
||||
__attribute__((noinline))
|
||||
int foo(int arg) {
|
||||
return bar(arg+val) + inc() + baz++;
|
||||
}
|
||||
|
Binary file not shown.
|
@ -1,20 +0,0 @@
|
|||
/* For compilation instructions see basic1.c. */
|
||||
|
||||
volatile int val;
|
||||
|
||||
extern int foo(int);
|
||||
|
||||
int unused2() {
|
||||
return foo(val);
|
||||
}
|
||||
|
||||
static int inc() {
|
||||
return ++val;
|
||||
}
|
||||
|
||||
__attribute__((noinline))
|
||||
int bar(int arg) {
|
||||
if (arg > 42)
|
||||
return inc();
|
||||
return foo(val + arg);
|
||||
}
|
Binary file not shown.
|
@ -1,48 +0,0 @@
|
|||
RUN: llvm-dsymutil -v -parse-only -oso-prepend-path=%p %p/Inputs/basic.macho.x86_64 | FileCheck %s
|
||||
RUN: llvm-dsymutil -v -parse-only -oso-prepend-path=%p %p/Inputs/basic-lto.macho.x86_64 | FileCheck %s --check-prefix=CHECK-LTO
|
||||
RUN: llvm-dsymutil -v -parse-only %p/Inputs/basic.macho.x86_64 2>&1 | FileCheck %s --check-prefix=NOT-FOUND
|
||||
RUN: not llvm-dsymutil -v -parse-only %p/Inputs/inexistant 2>&1 | FileCheck %s --check-prefix=NO-EXECUTABLE
|
||||
Check that We can parse the debug map of the basic executable.
|
||||
|
||||
CHECK-NOT: error
|
||||
CHECK: DEBUG MAP:
|
||||
CHECK: /Inputs/basic1.macho.x86_64.o:
|
||||
CHECK: 0000000000000000 => 0000000100000ea0 _main
|
||||
CHECK: /Inputs/basic2.macho.x86_64.o:
|
||||
CHECK: 0000000000000310 => 0000000100001000 _baz
|
||||
CHECK: 0000000000000020 => 0000000100000ed0 _foo
|
||||
CHECK: 0000000000000070 => 0000000100000f20 _inc
|
||||
CHECK: 0000000000000560 => 0000000100001008 _private_int
|
||||
CHECK: /Inputs/basic3.macho.x86_64.o:
|
||||
CHECK: 0000000000000020 => 0000000100000f40 _bar
|
||||
CHECK: 0000000000000070 => 0000000100000f90 _inc
|
||||
CHECK: 0000000000000004 => 0000000100001004 _val
|
||||
CHECK: END DEBUG MAP
|
||||
|
||||
|
||||
Check that we can parse the debug-map of the basic-lto executable
|
||||
|
||||
CHECK-LTO-NOT: error
|
||||
CHECK-LTO: DEBUG MAP:
|
||||
CHECK-LTO: /Inputs/basic-lto.macho.x86_64.o:
|
||||
CHECK-LTO: 0000000000000050 => 0000000100000f90 _bar
|
||||
CHECK-LTO: 0000000000000658 => 0000000100001000 _baz
|
||||
CHECK-LTO: 0000000000000010 => 0000000100000f50 _foo
|
||||
CHECK-LTO: 0000000000000000 => 0000000100000f40 _main
|
||||
CHECK-LTO: 00000000000008e8 => 0000000100001008 _private_int
|
||||
CHECK-LTO: 00000000000008ec => 0000000100001004 _val
|
||||
CHECK-LTO: END DEBUG MAP
|
||||
|
||||
Check that we warn about missing object files (this presumes that the files aren't
|
||||
present in the machine's /Inputs/ folder, which should be a pretty safe bet).
|
||||
|
||||
NOT-FOUND: cannot open{{.*}}"/Inputs/basic1.macho.x86_64.o": No such file
|
||||
NOT-FOUND: cannot open{{.*}}"/Inputs/basic2.macho.x86_64.o": No such file
|
||||
NOT-FOUND: cannot open{{.*}}"/Inputs/basic3.macho.x86_64.o": No such file
|
||||
NOT-FOUND: DEBUG MAP:
|
||||
NOT-FOUND-NEXT: END DEBUG MAP
|
||||
|
||||
Check that we correctly error out on invalid executatble.
|
||||
|
||||
NO-EXECUTABLE: cannot parse{{.*}}/inexistant": No such file
|
||||
NO-EXECUTABLE-NOT: DEBUG MAP
|
|
@ -36,7 +36,6 @@ add_llvm_tool_subdirectory(llvm-objdump)
|
|||
add_llvm_tool_subdirectory(llvm-readobj)
|
||||
add_llvm_tool_subdirectory(llvm-rtdyld)
|
||||
add_llvm_tool_subdirectory(llvm-dwarfdump)
|
||||
add_llvm_tool_subdirectory(dsymutil)
|
||||
add_llvm_tool_subdirectory(llvm-vtabledump)
|
||||
if( LLVM_USE_INTEL_JITEVENTS )
|
||||
add_llvm_tool_subdirectory(llvm-jitlistener)
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[common]
|
||||
subdirectories = bugpoint llc lli llvm-ar llvm-as llvm-bcanalyzer llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-jitlistener llvm-link llvm-lto llvm-mc llvm-nm llvm-objdump llvm-profdata llvm-rtdyld llvm-size macho-dump opt llvm-mcmarkup verify-uselistorder dsymutil
|
||||
subdirectories = bugpoint llc lli llvm-ar llvm-as llvm-bcanalyzer llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-jitlistener llvm-link llvm-lto llvm-mc llvm-nm llvm-objdump llvm-profdata llvm-rtdyld llvm-size macho-dump opt llvm-mcmarkup verify-uselistorder
|
||||
|
||||
[component_0]
|
||||
type = Group
|
||||
|
|
|
@ -33,7 +33,7 @@ PARALLEL_DIRS := opt llvm-as llvm-dis llc llvm-ar llvm-nm llvm-link \
|
|||
macho-dump llvm-objdump llvm-readobj llvm-rtdyld \
|
||||
llvm-dwarfdump llvm-cov llvm-size llvm-stress llvm-mcmarkup \
|
||||
llvm-profdata llvm-symbolizer obj2yaml yaml2obj llvm-c-test \
|
||||
llvm-vtabledump verify-uselistorder dsymutil
|
||||
llvm-vtabledump verify-uselistorder
|
||||
|
||||
# If Intel JIT Events support is configured, build an extra tool to test it.
|
||||
ifeq ($(USE_INTEL_JITEVENTS), 1)
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
set(LLVM_LINK_COMPONENTS
|
||||
Object
|
||||
Support
|
||||
)
|
||||
|
||||
add_llvm_tool(llvm-dsymutil
|
||||
dsymutil.cpp
|
||||
DebugMap.cpp
|
||||
DwarfLinker.cpp
|
||||
MachODebugMapParser.cpp
|
||||
)
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
//===- tools/dsymutil/DebugMap.cpp - Generic debug map representation -----===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "DebugMap.h"
|
||||
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <algorithm>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
using namespace llvm::object;
|
||||
|
||||
DebugMapObject::DebugMapObject(StringRef ObjectFilename)
|
||||
: Filename(ObjectFilename) {}
|
||||
|
||||
bool DebugMapObject::addSymbol(StringRef Name, uint64_t ObjectAddress,
|
||||
uint64_t LinkedAddress) {
|
||||
auto InsertResult = Symbols.insert(std::make_pair(Name,
|
||||
SymbolMapping{ObjectAddress,
|
||||
LinkedAddress}));
|
||||
return InsertResult.second;
|
||||
}
|
||||
|
||||
void DebugMapObject::print(raw_ostream& OS) const {
|
||||
OS << getObjectFilename() << ":\n";
|
||||
// Sort the symbols in alphabetical order, like llvm-nm (and to get
|
||||
// deterministic output for testing).
|
||||
typedef StringMapEntry<SymbolMapping> MapEntryTy;
|
||||
std::vector<const MapEntryTy *> Entries;
|
||||
Entries.reserve(Symbols.getNumItems());
|
||||
for (auto SymIt = Symbols.begin(), End = Symbols.end(); SymIt != End; ++SymIt)
|
||||
Entries.push_back(&*SymIt);
|
||||
std::sort(Entries.begin(), Entries.end(),
|
||||
[] (const MapEntryTy *LHS, const MapEntryTy *RHS) {
|
||||
return LHS->getKey() < RHS->getKey();
|
||||
});
|
||||
for (const auto *Entry: Entries) {
|
||||
const auto &Sym = Entry->getValue();
|
||||
OS << format("\t%016" PRIx64 " => %016" PRIx64 "\t%s\n",
|
||||
Sym.ObjectAddress, Sym.BinaryAddress, Entry->getKeyData());
|
||||
}
|
||||
OS << '\n';
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void DebugMapObject::dump() const {
|
||||
print(errs());
|
||||
}
|
||||
#endif
|
||||
|
||||
DebugMapObject& DebugMap::addDebugMapObject(StringRef ObjectFilePath) {
|
||||
Objects.emplace_back(new DebugMapObject(ObjectFilePath));
|
||||
return *Objects.back();
|
||||
}
|
||||
|
||||
const DebugMapObject::SymbolMapping *
|
||||
DebugMapObject::lookupSymbol(StringRef SymbolName) const {
|
||||
StringMap<SymbolMapping>::const_iterator Sym = Symbols.find(SymbolName);
|
||||
if (Sym == Symbols.end())
|
||||
return nullptr;
|
||||
return &Sym->getValue();
|
||||
}
|
||||
|
||||
void DebugMap::print(raw_ostream& OS) const {
|
||||
OS << "DEBUG MAP: object addr => executable addr\tsymbol name\n";
|
||||
for (const auto &Obj: objects())
|
||||
Obj->print(OS);
|
||||
OS << "END DEBUG MAP\n";
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void DebugMap::dump() const {
|
||||
print(errs());
|
||||
}
|
||||
#endif
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
//===- tools/dsymutil/DebugMap.h - Generic debug map representation -------===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
///
|
||||
/// This file contains the class declaration of the DebugMap
|
||||
/// entity. A DebugMap lists all the object files linked together to
|
||||
/// produce an executable along with the linked address of all the
|
||||
/// atoms used in these object files.
|
||||
/// The DebugMap is an input to the DwarfLinker class that will
|
||||
/// extract the Dwarf debug information from the referenced object
|
||||
/// files and link their usefull debug info together.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef DSYMUTIL_DEBUGMAP_H
|
||||
#define DSYMUTIL_DEBUGMAP_H
|
||||
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Support/ErrorOr.h"
|
||||
#include "llvm/Support/Format.h"
|
||||
#include "llvm/ADT/iterator_range.h"
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class raw_ostream;
|
||||
|
||||
class DebugMapObject;
|
||||
|
||||
/// \brief The DebugMap object stores the list of object files to
|
||||
/// query for debug information along with the mapping between the
|
||||
/// symbols' addresses in the object file to their linked address in
|
||||
/// the linked binary.
|
||||
///
|
||||
/// A DebugMap producer could look like this:
|
||||
/// DebugMap *DM = new DebugMap();
|
||||
/// for (const auto &Obj: LinkedObjects) {
|
||||
/// DebugMapObject &DMO = DM->addDebugMapObject(Obj.getPath());
|
||||
/// for (const auto &Sym: Obj.getLinkedSymbols())
|
||||
/// DMO.addSymbol(Sym.getName(), Sym.getObjectFileAddress(),
|
||||
/// Sym.getBinaryAddress());
|
||||
/// }
|
||||
///
|
||||
/// A DebugMap consumer can then use the map to link the debug
|
||||
/// information. For example something along the lines of:
|
||||
/// for (const auto &DMO: DM->objects()) {
|
||||
/// auto Obj = createBinary(DMO.getObjectFilename());
|
||||
/// for (auto &DIE: Obj.getDwarfDIEs()) {
|
||||
/// if (SymbolMapping *Sym = DMO.lookup(DIE.getName()))
|
||||
/// DIE.relocate(Sym->ObjectAddress, Sym->BinaryAddress);
|
||||
/// else
|
||||
/// DIE.discardSubtree();
|
||||
/// }
|
||||
/// }
|
||||
class DebugMap
|
||||
{
|
||||
typedef std::vector<std::unique_ptr<DebugMapObject>> ObjectContainer;
|
||||
ObjectContainer Objects;
|
||||
|
||||
public:
|
||||
typedef ObjectContainer::const_iterator const_iterator;
|
||||
|
||||
iterator_range<const_iterator> objects() const {
|
||||
return make_range(begin(), end());
|
||||
}
|
||||
|
||||
const_iterator begin() const {
|
||||
return Objects.begin();
|
||||
}
|
||||
|
||||
const_iterator end() const {
|
||||
return Objects.end();
|
||||
}
|
||||
|
||||
/// This function adds an DebugMapObject to the list owned by this
|
||||
/// debug map.
|
||||
DebugMapObject& addDebugMapObject(StringRef ObjectFilePath);
|
||||
|
||||
void print(raw_ostream& OS) const;
|
||||
|
||||
#ifndef NDEBUG
|
||||
void dump() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
/// \brief The DebugMapObject represents one object file described by
|
||||
/// the DebugMap. It contains a list of mappings between addresses in
|
||||
/// the object file and in the linked binary for all the linked atoms
|
||||
/// in this object file.
|
||||
class DebugMapObject {
|
||||
public:
|
||||
struct SymbolMapping {
|
||||
uint64_t ObjectAddress;
|
||||
uint64_t BinaryAddress;
|
||||
};
|
||||
|
||||
/// \brief Adds a symbol mapping to this DebugMapObject.
|
||||
/// \returns false if the symbol was already registered. The request
|
||||
/// is discarded in this case.
|
||||
bool addSymbol(llvm::StringRef SymName, uint64_t ObjectAddress,
|
||||
uint64_t LinkedAddress);
|
||||
|
||||
/// \bried Lookup a symbol mapping.
|
||||
/// \returns null if the symbol isn't found.
|
||||
const SymbolMapping *lookupSymbol(StringRef SymbolName) const;
|
||||
|
||||
llvm::StringRef getObjectFilename() const { return Filename; }
|
||||
|
||||
void print(raw_ostream& OS) const;
|
||||
#ifndef NDEBUG
|
||||
void dump() const;
|
||||
#endif
|
||||
private:
|
||||
friend class DebugMap;
|
||||
/// DebugMapObjects can only be constructed by the owning DebugMap.
|
||||
DebugMapObject(StringRef ObjectFilename);
|
||||
|
||||
std::string Filename;
|
||||
StringMap<SymbolMapping> Symbols;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // DSYMUTIL_DEBUGMAP_H
|
|
@ -1,22 +0,0 @@
|
|||
//===- tools/dsymutil/DwarfLinker.cpp - Dwarf debug info linker -----------===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "DwarfLinker.h"
|
||||
#include "DebugMap.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
DwarfLinker::DwarfLinker(StringRef OutputFilename)
|
||||
: OutputFilename(OutputFilename)
|
||||
{}
|
||||
|
||||
bool DwarfLinker::link(const DebugMap &Map) {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
//===- tools/dsymutil/DwarfLinker.h - Dwarf debug info linker -------------===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
///
|
||||
/// This file contains the class declaration of the DwarfLinker
|
||||
/// object. A DwarfLinker takes a DebugMap as input and links the
|
||||
/// debug information of all the referenced object files together. It
|
||||
/// may drop and rewrite some parts of the debug info tree in the
|
||||
/// process.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef DSYMUTIL_DWARFLINKER_H
|
||||
#define DSYMUTIL_DWARFLINKER_H
|
||||
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class DebugMap;
|
||||
|
||||
class DwarfLinker {
|
||||
std::string OutputFilename;
|
||||
public:
|
||||
DwarfLinker(StringRef OutputFilename);
|
||||
|
||||
/// \brief Link the passed debug map into the ouptut file.
|
||||
/// \returns false if the link encountered a fatal error.
|
||||
bool link(const DebugMap&);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,22 +0,0 @@
|
|||
;===- ./tools/dsymutil/LLVMBuild.txt ---------------------*- Conf -*--===;
|
||||
;
|
||||
; The LLVM Compiler Infrastructure
|
||||
;
|
||||
; This file is distributed under the University of Illinois Open Source
|
||||
; License. See LICENSE.TXT for details.
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
;
|
||||
; This is an LLVMBuild description file for the components in this subdirectory.
|
||||
;
|
||||
; For more information on the LLVMBuild system, please see:
|
||||
;
|
||||
; http://llvm.org/docs/LLVMBuild.html
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[component_0]
|
||||
type = Tool
|
||||
name = dsymutil
|
||||
parent = Tools
|
||||
required_libraries = Object Support
|
|
@ -1,194 +0,0 @@
|
|||
//===- tools/dsymutil/MachODebugMapParser.cpp - Parse STABS debug maps ----===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "MachODebugMapParser.h"
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
using namespace llvm::object;
|
||||
|
||||
namespace llvm {
|
||||
|
||||
static void Warning(const Twine &Msg) { errs() << "warning: " + Msg + "\n"; }
|
||||
|
||||
static ErrorOr<OwningBinary<MachOObjectFile>> createMachOBinary(StringRef file) {
|
||||
ErrorOr<OwningBinary<Binary>> BinaryOrErr = createBinary(file);
|
||||
if (BinaryOrErr.getError())
|
||||
return BinaryOrErr.getError();
|
||||
|
||||
std::unique_ptr<Binary> Bin;
|
||||
std::unique_ptr<MemoryBuffer> Buf;
|
||||
std::tie(Bin, Buf) = BinaryOrErr->takeBinary();
|
||||
if (!isa<MachOObjectFile>(Bin.get()))
|
||||
return make_error_code(object_error::invalid_file_type);
|
||||
|
||||
std::unique_ptr<MachOObjectFile> MachOFile(cast<MachOObjectFile>(Bin.release()));
|
||||
return OwningBinary<MachOObjectFile>(std::move(MachOFile), std::move(Buf));
|
||||
}
|
||||
|
||||
/// Reset the parser state coresponding to the current object
|
||||
/// file. This is to be called after an object file is finished
|
||||
/// processing.
|
||||
void MachODebugMapParser::resetParserState() {
|
||||
CurrentObjectFile = OwningBinary<object::MachOObjectFile>();
|
||||
CurrentObjectAddresses.clear();
|
||||
CurrentDebugMapObject = nullptr;
|
||||
}
|
||||
|
||||
/// Create a new DebugMapObject. This function resets the state of the
|
||||
/// parser that was referring to the last object file and sets
|
||||
/// everything up to add symbols to the new one.
|
||||
void MachODebugMapParser::switchToNewDebugMapObject(StringRef Filename) {
|
||||
resetParserState();
|
||||
|
||||
std::string Path = Filename;
|
||||
if (!PathPrefix.empty())
|
||||
Path = PathPrefix + sys::path::get_separator().data() + Path;
|
||||
|
||||
auto MachOOrError = createMachOBinary(Path);
|
||||
if (auto Error = MachOOrError.getError()) {
|
||||
Warning(Twine("cannot open debug object \"") + Path + "\": "
|
||||
+ Error.message() + "\n");
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentObjectFile = std::move(*MachOOrError);
|
||||
loadCurrentObjectFileSymbols();
|
||||
CurrentDebugMapObject = &Result->addDebugMapObject(Path);
|
||||
}
|
||||
|
||||
/// This main parsing routine tries to open the main binary and if
|
||||
/// successful iterates over the STAB entries. The real parsing is
|
||||
/// done in handleStabSymbolTableEntry.
|
||||
ErrorOr<std::unique_ptr<DebugMap>> MachODebugMapParser::parse() {
|
||||
auto MainBinaryOrError = createMachOBinary(BinaryPath);
|
||||
if (MainBinaryOrError.getError())
|
||||
return MainBinaryOrError.getError();
|
||||
|
||||
MainOwningBinary = std::move(*MainBinaryOrError);
|
||||
Result = make_unique<DebugMap>();
|
||||
const auto &MainBinary = *MainOwningBinary.getBinary();
|
||||
for (const SymbolRef &Symbol : MainBinary.symbols()) {
|
||||
const DataRefImpl &DRI = Symbol.getRawDataRefImpl();
|
||||
if (MainBinary.is64Bit())
|
||||
handleStabDebugMapEntry(MainBinary.getSymbol64TableEntry(DRI));
|
||||
else
|
||||
handleStabDebugMapEntry(MainBinary.getSymbolTableEntry(DRI));
|
||||
}
|
||||
|
||||
resetParserState();
|
||||
return std::move(Result);
|
||||
}
|
||||
|
||||
/// Interpret the STAB entries to fill the DebugMap.
|
||||
void MachODebugMapParser::handleStabSymbolTableEntry(uint32_t StringIndex,
|
||||
uint8_t Type,
|
||||
uint8_t SectionIndex,
|
||||
uint16_t Flags,
|
||||
uint64_t Value) {
|
||||
if (!(Type & MachO::N_STAB))
|
||||
return;
|
||||
|
||||
const MachOObjectFile &MachOBinary = *MainOwningBinary.getBinary();
|
||||
const char *Name = &MachOBinary.getStringTableData().data()[StringIndex];
|
||||
|
||||
// An N_OSO entry represents the start of a new object file description.
|
||||
if (Type == MachO::N_OSO)
|
||||
return switchToNewDebugMapObject(Name);
|
||||
|
||||
// If the last N_OSO object file wasn't found,
|
||||
// CurrentDebugMapObject will be null. Do not update anything
|
||||
// until we find the next valid N_OSO entry.
|
||||
if (!CurrentDebugMapObject)
|
||||
return;
|
||||
|
||||
switch (Type) {
|
||||
case MachO::N_GSYM:
|
||||
// This is a global variable. We need to query the main binary
|
||||
// symbol table to find its address as it might not be in the
|
||||
// debug map (for common symbols).
|
||||
Value = getMainBinarySymbolAddress(Name);
|
||||
if (Value == UnknownAddressOrSize)
|
||||
return;
|
||||
break;
|
||||
case MachO::N_FUN:
|
||||
// Functions are scopes in STABS. They have an end marker that we
|
||||
// need to ignore.
|
||||
if (Name[0] == '\0')
|
||||
return;
|
||||
break;
|
||||
case MachO::N_STSYM:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
auto ObjectSymIt = CurrentObjectAddresses.find(Name);
|
||||
if (ObjectSymIt == CurrentObjectAddresses.end())
|
||||
return Warning("could not find object file symbol for symbol " +
|
||||
Twine(Name));
|
||||
if (!CurrentDebugMapObject->addSymbol(Name, ObjectSymIt->getValue(), Value))
|
||||
return Warning(Twine("failed to insert symbol '") + Name + "' in the debug map.");
|
||||
}
|
||||
|
||||
/// Load the current object file symbols into CurrentObjectAddresses.
|
||||
void MachODebugMapParser::loadCurrentObjectFileSymbols() {
|
||||
CurrentObjectAddresses.clear();
|
||||
const auto &Binary = *CurrentObjectFile.getBinary();
|
||||
|
||||
for (auto Sym : Binary.symbols()) {
|
||||
StringRef Name;
|
||||
uint64_t Addr;
|
||||
if (Sym.getAddress(Addr) || Addr == UnknownAddressOrSize ||
|
||||
Sym.getName(Name))
|
||||
continue;
|
||||
CurrentObjectAddresses[Name] = Addr;
|
||||
}
|
||||
}
|
||||
|
||||
/// Lookup a symbol address in the main binary symbol table. The
|
||||
/// parser only needs to query common symbols, thus not every symbol's
|
||||
/// address is available through this function.
|
||||
uint64_t MachODebugMapParser::getMainBinarySymbolAddress(StringRef Name) {
|
||||
if (MainBinarySymbolAddresses.empty())
|
||||
loadMainBinarySymbols();
|
||||
|
||||
auto Sym = MainBinarySymbolAddresses.find(Name);
|
||||
if (Sym == MainBinarySymbolAddresses.end())
|
||||
return UnknownAddressOrSize;
|
||||
return Sym->second;
|
||||
}
|
||||
|
||||
/// Load the interesting main binary symbols' addresses into
|
||||
/// MainBinarySymbolAddresses.
|
||||
void MachODebugMapParser::loadMainBinarySymbols() {
|
||||
const MachOObjectFile &Binary = *MainOwningBinary.getBinary();
|
||||
section_iterator Section = Binary.section_end();
|
||||
for (const auto &Sym : Binary.symbols()) {
|
||||
SymbolRef::Type Type;
|
||||
// Skip undefined and STAB entries.
|
||||
if (Sym.getType(Type) || (Type & SymbolRef::ST_Debug) ||
|
||||
(Type & SymbolRef::ST_Unknown))
|
||||
continue;
|
||||
StringRef Name;
|
||||
uint64_t Addr;
|
||||
// The only symbols of interest are the global variables. These
|
||||
// are the only ones that need to be queried because the address
|
||||
// of common data won't be described in the debug map. All other
|
||||
// addresses should be fetched for the debug map.
|
||||
if (Sym.getAddress(Addr) || Addr == UnknownAddressOrSize ||
|
||||
!(Sym.getFlags() & SymbolRef::SF_Global) ||
|
||||
Sym.getSection(Section) || Section->isText() || Sym.getName(Name) ||
|
||||
Name.size() == 0 || Name[0] == '\0')
|
||||
continue;
|
||||
MainBinarySymbolAddresses[Name] = Addr;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
//===- tools/dsymutil/MachODebugMapParser.h - Parse STABS debug maps ------===//
|
||||
//
|
||||
// The LLVM Linker
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
///
|
||||
/// This file contains the class declaration for the code that parses STABS
|
||||
/// debug maps that are embedded in the binaries symbol tables.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef DSYMUTIL_MACHODEBUGMAPPARSER_H
|
||||
#define DSYMUTIL_MACHODEBUGMAPPARSER_H
|
||||
|
||||
#include "DebugMap.h"
|
||||
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/Object/MachO.h"
|
||||
#include "llvm/Object/Error.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MachODebugMapParser {
|
||||
public:
|
||||
MachODebugMapParser(StringRef BinaryPath)
|
||||
: BinaryPath(BinaryPath) {}
|
||||
|
||||
/// \brief Add a prefix to every object file path before trying to
|
||||
/// open it.
|
||||
void setPreprendPath(StringRef Prefix) { PathPrefix = Prefix; }
|
||||
|
||||
/// \brief Parses and returns the DebugMap of the input binary.
|
||||
/// \returns an error in case the provided BinaryPath doesn't exist
|
||||
/// or isn't of a supported type.
|
||||
ErrorOr<std::unique_ptr<DebugMap>> parse();
|
||||
|
||||
private:
|
||||
std::string BinaryPath;
|
||||
std::string PathPrefix;
|
||||
|
||||
/// OwningBinary constructed from the BinaryPath.
|
||||
object::OwningBinary<object::MachOObjectFile> MainOwningBinary;
|
||||
/// Map of the binary symbol addresses.
|
||||
StringMap<uint64_t> MainBinarySymbolAddresses;
|
||||
/// The constructed DebugMap.
|
||||
std::unique_ptr<DebugMap> Result;
|
||||
|
||||
/// Handle to the currently processed object file.
|
||||
object::OwningBinary<object::MachOObjectFile> CurrentObjectFile;
|
||||
/// Map of the currently processed object file symbol addresses.
|
||||
StringMap<uint64_t> CurrentObjectAddresses;
|
||||
/// Element of the debug map corresponfing to the current object file.
|
||||
DebugMapObject *CurrentDebugMapObject;
|
||||
|
||||
void switchToNewDebugMapObject(StringRef Filename);
|
||||
void resetParserState();
|
||||
uint64_t getMainBinarySymbolAddress(StringRef Name);
|
||||
void loadMainBinarySymbols();
|
||||
void loadCurrentObjectFileSymbols();
|
||||
void handleStabSymbolTableEntry(uint32_t StringIndex, uint8_t Type,
|
||||
uint8_t SectionIndex, uint16_t Flags,
|
||||
uint64_t Value);
|
||||
|
||||
template <typename STEType> void handleStabDebugMapEntry(const STEType &STE) {
|
||||
handleStabSymbolTableEntry(STE.n_strx, STE.n_type, STE.n_sect, STE.n_desc,
|
||||
STE.n_value);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // DSYMUTIL_MACHODEBUGMAPPARSER_H
|
|
@ -1,17 +0,0 @@
|
|||
##===- tools/dsymutil/Makefile -----------------------------*- Makefile -*-===##
|
||||
#
|
||||
# The LLVM Compiler Infrastructure
|
||||
#
|
||||
# This file is distributed under the University of Illinois Open Source
|
||||
# License. See LICENSE.TXT for details.
|
||||
#
|
||||
##===----------------------------------------------------------------------===##
|
||||
|
||||
LEVEL := ../..
|
||||
TOOLNAME := llvm-dsymutil
|
||||
LINK_COMPONENTS := Object Support
|
||||
|
||||
# This tool has no plugins, optimize startup time.
|
||||
TOOL_NO_EXPORTS := 1
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
|
@ -1,67 +0,0 @@
|
|||
//===-- dsymutil.cpp - Debug info dumping utility for llvm ----------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This program is a utility that aims to be a dropin replacement for
|
||||
// Darwin's dsymutil.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "DebugMap.h"
|
||||
#include "DwarfLinker.h"
|
||||
#include "MachODebugMapParser.h"
|
||||
|
||||
#include "llvm/Support/ManagedStatic.h"
|
||||
#include "llvm/Support/PrettyStackTrace.h"
|
||||
#include "llvm/Support/Options.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/Signals.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
static llvm::cl::opt<std::string> InputFile(llvm::cl::Positional,
|
||||
llvm::cl::desc("<input file>"),
|
||||
llvm::cl::init("-"));
|
||||
|
||||
static llvm::cl::opt<std::string> OsoPrependPath("oso-prepend-path",
|
||||
llvm::cl::desc("<path>"));
|
||||
|
||||
static llvm::cl::opt<bool> Verbose("v", llvm::cl::desc("Verbosity level"),
|
||||
llvm::cl::init(false));
|
||||
|
||||
static llvm::cl::opt<bool> ParseOnly("parse-only",
|
||||
llvm::cl::desc("Only parse the debug map, do "
|
||||
"not actaully link the DWARF."),
|
||||
llvm::cl::init(false));
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
llvm::sys::PrintStackTraceOnErrorSignal();
|
||||
llvm::PrettyStackTraceProgram StackPrinter(argc, argv);
|
||||
llvm::llvm_shutdown_obj Shutdown;
|
||||
|
||||
llvm::cl::ParseCommandLineOptions(argc, argv, "llvm dsymutil\n");
|
||||
|
||||
llvm::MachODebugMapParser Parser(InputFile);
|
||||
Parser.setPreprendPath(OsoPrependPath);
|
||||
llvm::ErrorOr<std::unique_ptr<llvm::DebugMap>> DebugMap = Parser.parse();
|
||||
|
||||
if (auto EC = DebugMap.getError()) {
|
||||
llvm::errs() << "error: cannot parse the debug map for \"" << InputFile <<
|
||||
"\": " << EC.message() << '\n';
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (Verbose)
|
||||
(*DebugMap)->print(llvm::outs());
|
||||
|
||||
if (ParseOnly)
|
||||
return 0;
|
||||
|
||||
llvm::DwarfLinker Linker(InputFile + ".dwarf");
|
||||
return !Linker.link(*DebugMap.get());
|
||||
}
|
Loading…
Reference in New Issue