From 6303b661b390ef37185f7e5f5cdd352287caf1fc Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Thu, 28 Feb 2013 14:11:10 +0000 Subject: Add the -disable-opt option to LTO. This adds: - Consistency with opt (which supports the same option with the same meaning and description). - Debugging gold plugin-based linking without optimizations getting in the way. - Debugging programs linked with the gold plugin while preserving the original debug info. - Fine-grained control over LTO passes using the gold plugin in combination with opt (or clang/dragonegg). Patch by Cristiano Giuffrida! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@176257 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/LTOCodeGenerator.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index 477bd2de06..75705154e4 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -46,6 +46,10 @@ #include "llvm/Transforms/IPO/PassManagerBuilder.h" using namespace llvm; +static cl::opt +DisableOpt("disable-opt", cl::init(false), + cl::desc("Do not run any optimization passes")); + static cl::opt DisableInline("disable-inlining", cl::init(false), cl::desc("Do not run the inliner pass")); @@ -376,10 +380,12 @@ bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, // Enabling internalize here would use its AllButMain variant. It // keeps only main if it exists and does nothing for libraries. Instead // we create the pass ourselves with the symbol list provided by the linker. - PassManagerBuilder().populateLTOPassManager(passes, + if (!DisableOpt) { + PassManagerBuilder().populateLTOPassManager(passes, /*Internalize=*/false, !DisableInline, DisableGVNLoadPRE); + } // Make sure everything is still good. passes.add(createVerifierPass()); -- cgit v1.2.3-18-g5258 From 39d994c78bf3d9844dcbf2a236d4178155168ebf Mon Sep 17 00:00:00 2001 From: Daniel Malea Date: Thu, 28 Feb 2013 23:15:15 +0000 Subject: Connect LLVM CMake build scripts to LLDB's CMake scripts: - if you have LLDB checked out in $llvm/tools, CMake will build it now! - LLDB is known to build on Linux with libstdc++ and GCC 4.6/4.7 or Clang 3.3 - to run lldb tests, do "make check-lldb" after a build git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@176307 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 144e8ec3ea..4cf5aa5105 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -56,6 +56,7 @@ endif() add_llvm_external_project(clang) add_llvm_external_project(lld) +add_llvm_external_project(lldb) add_llvm_external_project(polly) set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} PARENT_SCOPE) -- cgit v1.2.3-18-g5258 From a991b254f71173f3911be3b313b5304dd9b3b862 Mon Sep 17 00:00:00 2001 From: Lang Hames Date: Wed, 13 Mar 2013 21:18:46 +0000 Subject: Make LTO codegen use a PassManager, rather than a FunctionPassManager, for the codegen passes. This brings it in to line with clang and llc's codegen setup, and tidies up the code. If I understand correctly, adding ModulePasses to a FunctionPassManager is bogus. It only seems to explode if an added ModulePass depends on a FunctionPass though, which might be why this code has survived so long. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@176977 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/LTOCodeGenerator.cpp | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'tools') diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index 75705154e4..cf7ffe2800 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -390,14 +390,14 @@ bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, // Make sure everything is still good. passes.add(createVerifierPass()); - FunctionPassManager *codeGenPasses = new FunctionPassManager(mergedModule); + PassManager codeGenPasses; - codeGenPasses->add(new DataLayout(*_target->getDataLayout())); - _target->addAnalysisPasses(*codeGenPasses); + codeGenPasses.add(new DataLayout(*_target->getDataLayout())); + _target->addAnalysisPasses(codeGenPasses); formatted_raw_ostream Out(out); - if (_target->addPassesToEmitFile(*codeGenPasses, Out, + if (_target->addPassesToEmitFile(codeGenPasses, Out, TargetMachine::CGFT_ObjectFile)) { errMsg = "target file type not supported"; return true; @@ -407,15 +407,7 @@ bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, passes.run(*mergedModule); // Run the code generator, and write assembly file - codeGenPasses->doInitialization(); - - for (Module::iterator - it = mergedModule->begin(), e = mergedModule->end(); it != e; ++it) - if (!it->isDeclaration()) - codeGenPasses->run(*it); - - codeGenPasses->doFinalization(); - delete codeGenPasses; + codeGenPasses.run(*mergedModule); return false; // success } -- cgit v1.2.3-18-g5258 From df41cf003aa8576a75a7f4e0a992a0a145167ee1 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 17 Mar 2013 12:01:05 +0000 Subject: Build LLVMgold.so on FreeBSD using cmake. Patch by Stephen Checkoway. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177233 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 4cf5aa5105..5e9560491e 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -49,7 +49,8 @@ endif() if( LLVM_ENABLE_PIC ) # TODO: support other systems: - if( CMAKE_SYSTEM_NAME STREQUAL "Linux" ) + if( (CMAKE_SYSTEM_NAME STREQUAL "Linux") + OR (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") ) add_subdirectory(gold) endif() endif() -- cgit v1.2.3-18-g5258 From e9e10d18df7ba3ec65c37eaa25131fbd5c1b130e Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Tue, 19 Mar 2013 10:24:42 +0000 Subject: llvm-symbolizer: flush internal caches functionality git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177390 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-symbolizer/LLVMSymbolize.cpp | 4 ++++ tools/llvm-symbolizer/LLVMSymbolize.h | 1 + 2 files changed, 5 insertions(+) (limited to 'tools') diff --git a/tools/llvm-symbolizer/LLVMSymbolize.cpp b/tools/llvm-symbolizer/LLVMSymbolize.cpp index 86ea34bff6..52ae49c0f1 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.cpp +++ b/tools/llvm-symbolizer/LLVMSymbolize.cpp @@ -186,6 +186,10 @@ std::string LLVMSymbolizer::symbolizeData(const std::string &ModuleName, return ss.str(); } +void LLVMSymbolizer::flush() { + Modules.clear(); +} + // Returns true if the object endianness is known. static bool getObjectEndianness(const ObjectFile *Obj, bool &IsLittleEndian) { // FIXME: Implement this when libLLVMObject allows to do it easily. diff --git a/tools/llvm-symbolizer/LLVMSymbolize.h b/tools/llvm-symbolizer/LLVMSymbolize.h index e6220aa4ce..0733dfbbc5 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.h +++ b/tools/llvm-symbolizer/LLVMSymbolize.h @@ -50,6 +50,7 @@ public: symbolizeCode(const std::string &ModuleName, uint64_t ModuleOffset); std::string symbolizeData(const std::string &ModuleName, uint64_t ModuleOffset); + void flush(); private: ModuleInfo *getOrCreateModuleInfo(const std::string &ModuleName); std::string printDILineInfo(DILineInfo LineInfo) const; -- cgit v1.2.3-18-g5258 From 51283a1513648b235925e8f931707ebdea217359 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Tue, 19 Mar 2013 15:33:18 +0000 Subject: Fix for r177390: map values are pointers, use DeleteContainerSeconds() instead of .clear() git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177409 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-symbolizer/LLVMSymbolize.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/llvm-symbolizer/LLVMSymbolize.cpp b/tools/llvm-symbolizer/LLVMSymbolize.cpp index 52ae49c0f1..29d91a0e92 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.cpp +++ b/tools/llvm-symbolizer/LLVMSymbolize.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "LLVMSymbolize.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Object/MachO.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Path.h" @@ -187,7 +188,7 @@ std::string LLVMSymbolizer::symbolizeData(const std::string &ModuleName, } void LLVMSymbolizer::flush() { - Modules.clear(); + DeleteContainerSeconds(Modules); } // Returns true if the object endianness is known. -- cgit v1.2.3-18-g5258 From 576a0b4d77138434ffc25a5a1de5522d2663e3b1 Mon Sep 17 00:00:00 2001 From: Eli Bendersky Date: Tue, 19 Mar 2013 16:04:02 +0000 Subject: Remove stale comment git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177410 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-link/llvm-link.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'tools') diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp index f6c9f11a5e..769419d186 100644 --- a/tools/llvm-link/llvm-link.cpp +++ b/tools/llvm-link/llvm-link.cpp @@ -111,9 +111,6 @@ int main(int argc, char **argv) { } } - // TODO: Iterate over the -l list and link in any modules containing - // global symbols that have not been resolved so far. - if (DumpAsm) errs() << "Here's the assembly:\n" << *Composite; std::string ErrorInfo; -- cgit v1.2.3-18-g5258 From bd1737c8460ee09d000492831788ecc17dbc368a Mon Sep 17 00:00:00 2001 From: Shankar Easwaran Date: Mon, 25 Mar 2013 16:06:51 +0000 Subject: [tools][llvm-readobj] print the name of the section when iterating the symbol table / dynamic symbol table git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177873 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/llvm-readobj.cpp | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index 8f0917fc91..ea37d105dc 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -39,13 +39,13 @@ static cl::opt InputFilename(cl::Positional, cl::desc(""), cl::init("")); static void dumpSymbolHeader() { - outs() << format(" %-32s", (const char*)"Name") - << format(" %-4s", (const char*)"Type") - << format(" %-16s", (const char*)"Address") - << format(" %-16s", (const char*)"Size") - << format(" %-16s", (const char*)"FileOffset") - << format(" %-26s", (const char*)"Flags") - << "\n"; + outs() << format(" %-32s", (const char *)"Name") + << format(" %-4s", (const char *)"Type") + << format(" %-4s", (const char *)"Section") + << format(" %-16s", (const char *)"Address") + << format(" %-16s", (const char *)"Size") + << format(" %-16s", (const char *)"FileOffset") + << format(" %-26s", (const char *)"Flags") << "\n"; } static void dumpSectionHeader() { @@ -145,6 +145,14 @@ dumpSymbol(const SymbolRef &Sym, const ObjectFile *obj, bool IsDynamic) { checkError(Sym.getFlags(Flags), "SymbolRef.getFlags() failed"); std::string FullName = Name; + llvm::object::section_iterator symSection(obj->begin_sections()); + Sym.getSection(symSection); + StringRef sectionName; + + if (symSection != obj->end_sections()) + checkError(symSection->getName(sectionName), + "SectionRef::getName() failed"); + // If this is a dynamic symbol from an ELF object, append // the symbol's version to the name. if (IsDynamic && obj->isELF()) { @@ -160,11 +168,10 @@ dumpSymbol(const SymbolRef &Sym, const ObjectFile *obj, bool IsDynamic) { // format() can't handle StringRefs outs() << format(" %-32s", FullName.c_str()) << format(" %-4s", getTypeStr(Type)) - << format(" %16" PRIx64, Address) - << format(" %16" PRIx64, Size) - << format(" %16" PRIx64, FileOffset) - << " " << getSymbolFlagStr(Flags) - << "\n"; + << format(" %-32s", std::string(sectionName).c_str()) + << format(" %16" PRIx64, Address) << format(" %16" PRIx64, Size) + << format(" %16" PRIx64, FileOffset) << " " + << getSymbolFlagStr(Flags) << "\n"; } static void dumpStaticSymbol(const SymbolRef &Sym, const ObjectFile *obj) { -- cgit v1.2.3-18-g5258 From 7fc162f893d67ffd96fdb19e2eb9a03b4621f0c0 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Tue, 26 Mar 2013 02:25:37 +0000 Subject: Split out the IRReader header and the utility functions it provides into its own library. These functions are bridging between the bitcode reader and the ll parser which are in different libraries. Previously we didn't have any good library to do this, and instead played fast and loose with a "header only" set of interfaces in the Support library. This really doesn't work well as evidenced by the recent attempt to add timing logic to the these routines. As part of this, make them normal functions rather than weird inline functions, and sink the implementation into the library. Also clean up the header to be nice and minimal. This requires updating lots of build system dependencies to specify that the IRReader library is needed, and several source files to not implicitly rely upon the header file to transitively include all manner of other headers. If you are using IRReader.h, this commit will break you (the header moved) and you'll need to also update your library usage to include 'irreader'. I will commit the corresponding change to Clang momentarily. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177971 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/bugpoint/BugDriver.cpp | 2 +- tools/bugpoint/CMakeLists.txt | 2 +- tools/bugpoint/LLVMBuild.txt | 2 +- tools/llc/CMakeLists.txt | 2 +- tools/llc/LLVMBuild.txt | 2 +- tools/llc/llc.cpp | 3 ++- tools/lli/CMakeLists.txt | 2 +- tools/lli/LLVMBuild.txt | 2 +- tools/lli/lli.cpp | 3 ++- tools/llvm-diff/CMakeLists.txt | 2 +- tools/llvm-diff/LLVMBuild.txt | 2 +- tools/llvm-diff/llvm-diff.cpp | 2 +- tools/llvm-extract/CMakeLists.txt | 2 +- tools/llvm-extract/LLVMBuild.txt | 2 +- tools/llvm-extract/llvm-extract.cpp | 3 ++- tools/llvm-jitlistener/CMakeLists.txt | 1 + tools/llvm-jitlistener/LLVMBuild.txt | 2 +- tools/llvm-jitlistener/llvm-jitlistener.cpp | 2 +- tools/llvm-link/CMakeLists.txt | 2 +- tools/llvm-link/LLVMBuild.txt | 2 +- tools/llvm-link/llvm-link.cpp | 3 ++- tools/opt/CMakeLists.txt | 2 +- tools/opt/LLVMBuild.txt | 2 +- tools/opt/opt.cpp | 3 ++- 24 files changed, 29 insertions(+), 23 deletions(-) (limited to 'tools') diff --git a/tools/bugpoint/BugDriver.cpp b/tools/bugpoint/BugDriver.cpp index cede4ac3ae..e49a96b1e0 100644 --- a/tools/bugpoint/BugDriver.cpp +++ b/tools/bugpoint/BugDriver.cpp @@ -16,12 +16,12 @@ #include "BugDriver.h" #include "ToolRunner.h" #include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" #include "llvm/Linker.h" #include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileUtilities.h" #include "llvm/Support/Host.h" -#include "llvm/Support/IRReader.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" #include diff --git a/tools/bugpoint/CMakeLists.txt b/tools/bugpoint/CMakeLists.txt index 3c5e64fdab..e990cfcbba 100644 --- a/tools/bugpoint/CMakeLists.txt +++ b/tools/bugpoint/CMakeLists.txt @@ -1,5 +1,5 @@ set(LLVM_LINK_COMPONENTS asmparser instrumentation scalaropts ipo - linker bitreader bitwriter vectorize objcarcopts) + linker bitreader bitwriter irreader vectorize objcarcopts) add_llvm_tool(bugpoint BugDriver.cpp diff --git a/tools/bugpoint/LLVMBuild.txt b/tools/bugpoint/LLVMBuild.txt index e03c594bf9..01643553c5 100644 --- a/tools/bugpoint/LLVMBuild.txt +++ b/tools/bugpoint/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Tool name = bugpoint parent = Tools -required_libraries = AsmParser BitReader BitWriter IPO Instrumentation Linker Scalar ObjCARC +required_libraries = AsmParser BitReader BitWriter IRReader IPO Instrumentation Linker Scalar ObjCARC diff --git a/tools/llc/CMakeLists.txt b/tools/llc/CMakeLists.txt index 683f29862d..e5a5550e9e 100644 --- a/tools/llc/CMakeLists.txt +++ b/tools/llc/CMakeLists.txt @@ -1,4 +1,4 @@ -set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} bitreader asmparser) +set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} bitreader asmparser irreader) add_llvm_tool(llc llc.cpp diff --git a/tools/llc/LLVMBuild.txt b/tools/llc/LLVMBuild.txt index 8c8794f620..45cdc6498f 100644 --- a/tools/llc/LLVMBuild.txt +++ b/tools/llc/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Tool name = llc parent = Tools -required_libraries = AsmParser BitReader all-targets +required_libraries = AsmParser BitReader IRReader all-targets diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index aa65223473..1dce9d7b60 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -21,6 +21,7 @@ #include "llvm/CodeGen/LinkAllCodegenComponents.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" #include "llvm/MC/SubtargetFeature.h" #include "llvm/Pass.h" #include "llvm/PassManager.h" @@ -28,11 +29,11 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/Host.h" -#include "llvm/Support/IRReader.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/PluginLoader.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" +#include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/ToolOutputFile.h" diff --git a/tools/lli/CMakeLists.txt b/tools/lli/CMakeLists.txt index 356233f397..aaa6598e71 100644 --- a/tools/lli/CMakeLists.txt +++ b/tools/lli/CMakeLists.txt @@ -1,5 +1,5 @@ -set(LLVM_LINK_COMPONENTS mcjit jit interpreter nativecodegen bitreader asmparser selectiondag native) +set(LLVM_LINK_COMPONENTS mcjit jit interpreter nativecodegen bitreader asmparser irreader selectiondag native) if( LLVM_USE_OPROFILE ) set(LLVM_LINK_COMPONENTS diff --git a/tools/lli/LLVMBuild.txt b/tools/lli/LLVMBuild.txt index 36ceb39b12..5823792ff0 100644 --- a/tools/lli/LLVMBuild.txt +++ b/tools/lli/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Tool name = lli parent = Tools -required_libraries = AsmParser BitReader Interpreter JIT MCJIT NativeCodeGen SelectionDAG Native +required_libraries = AsmParser BitReader IRReader Interpreter JIT MCJIT NativeCodeGen SelectionDAG Native diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index 332660fc1e..297763fcfb 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -29,11 +29,11 @@ #include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" +#include "llvm/IRReader/IRReader.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/Format.h" -#include "llvm/Support/IRReader.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/Memory.h" @@ -42,6 +42,7 @@ #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Process.h" #include "llvm/Support/Signals.h" +#include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" #include diff --git a/tools/llvm-diff/CMakeLists.txt b/tools/llvm-diff/CMakeLists.txt index c59d69ea0d..0df8b9ed79 100644 --- a/tools/llvm-diff/CMakeLists.txt +++ b/tools/llvm-diff/CMakeLists.txt @@ -1,4 +1,4 @@ -set(LLVM_LINK_COMPONENTS support asmparser bitreader) +set(LLVM_LINK_COMPONENTS support asmparser bitreader irreader) add_llvm_tool(llvm-diff llvm-diff.cpp diff --git a/tools/llvm-diff/LLVMBuild.txt b/tools/llvm-diff/LLVMBuild.txt index fa06a03353..5adfdc2bd6 100644 --- a/tools/llvm-diff/LLVMBuild.txt +++ b/tools/llvm-diff/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Tool name = llvm-diff parent = Tools -required_libraries = AsmParser BitReader +required_libraries = AsmParser BitReader IRReader diff --git a/tools/llvm-diff/llvm-diff.cpp b/tools/llvm-diff/llvm-diff.cpp index 0b9e92b1b8..6eca1e2bfc 100644 --- a/tools/llvm-diff/llvm-diff.cpp +++ b/tools/llvm-diff/llvm-diff.cpp @@ -19,8 +19,8 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" +#include "llvm/IRReader/IRReader.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/IRReader.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" diff --git a/tools/llvm-extract/CMakeLists.txt b/tools/llvm-extract/CMakeLists.txt index a4e3266e35..3163c4bbbd 100644 --- a/tools/llvm-extract/CMakeLists.txt +++ b/tools/llvm-extract/CMakeLists.txt @@ -1,4 +1,4 @@ -set(LLVM_LINK_COMPONENTS asmparser ipo bitreader bitwriter) +set(LLVM_LINK_COMPONENTS asmparser ipo bitreader bitwriter irreader) add_llvm_tool(llvm-extract llvm-extract.cpp diff --git a/tools/llvm-extract/LLVMBuild.txt b/tools/llvm-extract/LLVMBuild.txt index 1b1a4c36cd..70e3507a73 100644 --- a/tools/llvm-extract/LLVMBuild.txt +++ b/tools/llvm-extract/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Tool name = llvm-extract parent = Tools -required_libraries = AsmParser BitReader BitWriter IPO +required_libraries = AsmParser BitReader BitWriter IRReader IPO diff --git a/tools/llvm-extract/llvm-extract.cpp b/tools/llvm-extract/llvm-extract.cpp index 85a921118a..fd0a381807 100644 --- a/tools/llvm-extract/llvm-extract.cpp +++ b/tools/llvm-extract/llvm-extract.cpp @@ -19,13 +19,14 @@ #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" #include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/IRReader.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Regex.h" #include "llvm/Support/Signals.h" +#include "llvm/Support/SourceMgr.h" #include "llvm/Support/SystemUtils.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/Transforms/IPO.h" diff --git a/tools/llvm-jitlistener/CMakeLists.txt b/tools/llvm-jitlistener/CMakeLists.txt index d429af928f..c9704fb224 100644 --- a/tools/llvm-jitlistener/CMakeLists.txt +++ b/tools/llvm-jitlistener/CMakeLists.txt @@ -9,6 +9,7 @@ set(LLVM_LINK_COMPONENTS debuginfo inteljitevents interpreter + irreader jit mcjit nativecodegen diff --git a/tools/llvm-jitlistener/LLVMBuild.txt b/tools/llvm-jitlistener/LLVMBuild.txt index c436dd90f9..1ce78acecb 100644 --- a/tools/llvm-jitlistener/LLVMBuild.txt +++ b/tools/llvm-jitlistener/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Tool name = llvm-jitlistener parent = Tools -required_libraries = AsmParser BitReader Interpreter JIT MCJIT NativeCodeGen Object SelectionDAG Native +required_libraries = AsmParser BitReader IRReader Interpreter JIT MCJIT NativeCodeGen Object SelectionDAG Native diff --git a/tools/llvm-jitlistener/llvm-jitlistener.cpp b/tools/llvm-jitlistener/llvm-jitlistener.cpp index d6f5032d6e..dbaf075e91 100644 --- a/tools/llvm-jitlistener/llvm-jitlistener.cpp +++ b/tools/llvm-jitlistener/llvm-jitlistener.cpp @@ -22,9 +22,9 @@ #include "llvm/ExecutionEngine/MCJIT.h" #include "llvm/ExecutionEngine/ObjectImage.h" #include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Host.h" -#include "llvm/Support/IRReader.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/PrettyStackTrace.h" diff --git a/tools/llvm-link/CMakeLists.txt b/tools/llvm-link/CMakeLists.txt index 11933f7f95..4df53564e1 100644 --- a/tools/llvm-link/CMakeLists.txt +++ b/tools/llvm-link/CMakeLists.txt @@ -1,4 +1,4 @@ -set(LLVM_LINK_COMPONENTS linker bitreader bitwriter asmparser) +set(LLVM_LINK_COMPONENTS linker bitreader bitwriter asmparser irreader) add_llvm_tool(llvm-link llvm-link.cpp diff --git a/tools/llvm-link/LLVMBuild.txt b/tools/llvm-link/LLVMBuild.txt index 6399dede78..2e386f3c23 100644 --- a/tools/llvm-link/LLVMBuild.txt +++ b/tools/llvm-link/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Tool name = llvm-link parent = Tools -required_libraries = AsmParser BitReader BitWriter Linker +required_libraries = AsmParser BitReader BitWriter IRReader Linker diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp index 769419d186..83665cc175 100644 --- a/tools/llvm-link/llvm-link.cpp +++ b/tools/llvm-link/llvm-link.cpp @@ -17,12 +17,13 @@ #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/IRReader.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Path.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" +#include "llvm/Support/SourceMgr.h" #include "llvm/Support/SystemUtils.h" #include "llvm/Support/ToolOutputFile.h" #include diff --git a/tools/opt/CMakeLists.txt b/tools/opt/CMakeLists.txt index cf5e5a83cf..1ff8efbed0 100644 --- a/tools/opt/CMakeLists.txt +++ b/tools/opt/CMakeLists.txt @@ -1,4 +1,4 @@ -set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} bitreader asmparser bitwriter instrumentation scalaropts objcarcopts ipo vectorize) +set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} bitreader asmparser bitwriter irreader instrumentation scalaropts objcarcopts ipo vectorize) add_llvm_tool(opt AnalysisWrappers.cpp diff --git a/tools/opt/LLVMBuild.txt b/tools/opt/LLVMBuild.txt index a866d12a26..77b94469ed 100644 --- a/tools/opt/LLVMBuild.txt +++ b/tools/opt/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Tool name = opt parent = Tools -required_libraries = AsmParser BitReader BitWriter IPO Instrumentation Scalar ObjCARC all-targets +required_libraries = AsmParser BitReader BitWriter IRReader IPO Instrumentation Scalar ObjCARC all-targets diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 81a2de2d55..ba82bded2b 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -26,17 +26,18 @@ #include "llvm/DebugInfo.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Module.h" +#include "llvm/IRReader/IRReader.h" #include "llvm/LinkAllIR.h" #include "llvm/LinkAllPasses.h" #include "llvm/MC/SubtargetFeature.h" #include "llvm/PassManager.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/IRReader.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/PassNameParser.h" #include "llvm/Support/PluginLoader.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" +#include "llvm/Support/SourceMgr.h" #include "llvm/Support/SystemUtils.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" -- cgit v1.2.3-18-g5258 From 0f3e4b149503d85403ec1181e5ffe9b60509c090 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Tue, 26 Mar 2013 03:45:47 +0000 Subject: Manually update the dependencies in the Makefiles. It turns out that all that work on the LLVMBuild based dependency specification didn't actually work, we just now maintain dependencies in *3* places instead of 2. Yay. There may still be some missing dependencies, I'm still sifting through the bots and my builds, but this is a step in the right direction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@177988 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/bugpoint/Makefile | 2 +- tools/llc/Makefile | 2 +- tools/lli/Makefile | 2 +- tools/llvm-diff/Makefile | 2 +- tools/llvm-extract/Makefile | 2 +- tools/llvm-jitlistener/Makefile | 2 +- tools/llvm-link/Makefile | 2 +- tools/llvm-stress/Makefile | 2 +- tools/opt/Makefile | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/bugpoint/Makefile b/tools/bugpoint/Makefile index 65ffc13022..20493218b0 100644 --- a/tools/bugpoint/Makefile +++ b/tools/bugpoint/Makefile @@ -10,6 +10,6 @@ LEVEL := ../.. TOOLNAME := bugpoint LINK_COMPONENTS := asmparser instrumentation scalaropts ipo linker bitreader \ - bitwriter vectorize objcarcopts + bitwriter irreader vectorize objcarcopts include $(LEVEL)/Makefile.common diff --git a/tools/llc/Makefile b/tools/llc/Makefile index b32d5575d5..c24f378bc5 100644 --- a/tools/llc/Makefile +++ b/tools/llc/Makefile @@ -9,7 +9,7 @@ LEVEL := ../.. TOOLNAME := llc -LINK_COMPONENTS := all-targets bitreader asmparser +LINK_COMPONENTS := all-targets bitreader asmparser irreader include $(LEVEL)/Makefile.common diff --git a/tools/lli/Makefile b/tools/lli/Makefile index 85ac6b46bb..a6530584a2 100644 --- a/tools/lli/Makefile +++ b/tools/lli/Makefile @@ -12,7 +12,7 @@ TOOLNAME := lli include $(LEVEL)/Makefile.config -LINK_COMPONENTS := mcjit jit interpreter nativecodegen bitreader asmparser selectiondag native +LINK_COMPONENTS := mcjit jit interpreter nativecodegen bitreader asmparser irreader selectiondag native # If Intel JIT Events support is confiured, link against the LLVM Intel JIT # Events interface library diff --git a/tools/llvm-diff/Makefile b/tools/llvm-diff/Makefile index f7fa7159c5..bd97a6a9f5 100644 --- a/tools/llvm-diff/Makefile +++ b/tools/llvm-diff/Makefile @@ -9,7 +9,7 @@ LEVEL := ../.. TOOLNAME := llvm-diff -LINK_COMPONENTS := asmparser bitreader +LINK_COMPONENTS := asmparser bitreader irreader # This tool has no plugins, optimize startup time. TOOL_NO_EXPORTS := 1 diff --git a/tools/llvm-extract/Makefile b/tools/llvm-extract/Makefile index a1e93f5ce4..d371c54759 100644 --- a/tools/llvm-extract/Makefile +++ b/tools/llvm-extract/Makefile @@ -9,7 +9,7 @@ LEVEL := ../.. TOOLNAME := llvm-extract -LINK_COMPONENTS := ipo bitreader bitwriter asmparser +LINK_COMPONENTS := ipo bitreader bitwriter asmparser irreader # This tool has no plugins, optimize startup time. TOOL_NO_EXPORTS := 1 diff --git a/tools/llvm-jitlistener/Makefile b/tools/llvm-jitlistener/Makefile index 30182355c9..b132227317 100644 --- a/tools/llvm-jitlistener/Makefile +++ b/tools/llvm-jitlistener/Makefile @@ -12,7 +12,7 @@ TOOLNAME := llvm-jitlistener include $(LEVEL)/Makefile.config -LINK_COMPONENTS := mcjit jit interpreter nativecodegen bitreader asmparser selectiondag Object +LINK_COMPONENTS := mcjit jit interpreter nativecodegen bitreader asmparser irreader selectiondag Object # If Intel JIT Events support is configured, link against the LLVM Intel JIT # Events interface library. If not, this tool will do nothing useful, but it diff --git a/tools/llvm-link/Makefile b/tools/llvm-link/Makefile index 2553db0cd3..ed30d2d256 100644 --- a/tools/llvm-link/Makefile +++ b/tools/llvm-link/Makefile @@ -9,7 +9,7 @@ LEVEL := ../.. TOOLNAME := llvm-link -LINK_COMPONENTS := linker bitreader bitwriter asmparser +LINK_COMPONENTS := linker bitreader bitwriter asmparser irreader # This tool has no plugins, optimize startup time. TOOL_NO_EXPORTS := 1 diff --git a/tools/llvm-stress/Makefile b/tools/llvm-stress/Makefile index 90d57c3fa9..8767cbe417 100644 --- a/tools/llvm-stress/Makefile +++ b/tools/llvm-stress/Makefile @@ -10,7 +10,7 @@ LEVEL := ../.. TOOLNAME := llvm-stress LINK_COMPONENTS := object -LINK_COMPONENTS := bitreader bitwriter asmparser instrumentation scalaropts ipo +LINK_COMPONENTS := bitreader bitwriter asmparser irreader instrumentation scalaropts ipo # This tool has no plugins, optimize startup time. TOOL_NO_EXPORTS = 1 diff --git a/tools/opt/Makefile b/tools/opt/Makefile index 79ed815dce..a451005574 100644 --- a/tools/opt/Makefile +++ b/tools/opt/Makefile @@ -9,6 +9,6 @@ LEVEL := ../.. TOOLNAME := opt -LINK_COMPONENTS := bitreader bitwriter asmparser instrumentation scalaropts objcarcopts ipo vectorize all-targets +LINK_COMPONENTS := bitreader bitwriter asmparser irreader instrumentation scalaropts objcarcopts ipo vectorize all-targets include $(LEVEL)/Makefile.common -- cgit v1.2.3-18-g5258 From d696544eacbab22277924bc5f5acd85f615f31ea Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Fri, 29 Mar 2013 23:28:55 +0000 Subject: Run the ObjCARCContract pass for LTO. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178385 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/LTOCodeGenerator.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools') diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index cf7ffe2800..e7c83f94f5 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -44,6 +44,7 @@ #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" +#include "llvm/Transforms/ObjCARC.h" using namespace llvm; static cl::opt @@ -397,6 +398,10 @@ bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, formatted_raw_ostream Out(out); + // If the bitcode files contain ARC code and were compiled with optimization, + // the ObjCARCContractPass must be run, so do it unconditionally here. + codeGenPasses.add(createObjCARCContractPass()); + if (_target->addPassesToEmitFile(codeGenPasses, Out, TargetMachine::CGFT_ObjectFile)) { errMsg = "target file type not supported"; -- cgit v1.2.3-18-g5258 From 99ff2ba240979249b61514c1536bbe23be84ecc7 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Wed, 3 Apr 2013 18:31:23 +0000 Subject: Don't disassemble symbols with an unknown address or size. Patch by Nico Rieck! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178678 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/llvm-objdump.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 322bd21b28..7832cf0dff 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -228,6 +228,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { if (!error(i->containsSymbol(*si, contains)) && contains) { uint64_t Address; if (error(si->getAddress(Address))) break; + if (Address == UnknownAddressOrSize) continue; Address -= SectionAddr; StringRef Name; -- cgit v1.2.3-18-g5258 From 76e70f340c09ba759ad96d8dfe416b64f24bc287 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Wed, 3 Apr 2013 18:31:38 +0000 Subject: Implements low-level object file format specific output for COFF and ELF with support for: - File headers - Section headers + data - Relocations - Symbols - Unwind data (only COFF/Win64) The output format follows a few rules: - Values are almost always output one per line (as elf-dump/coff-dump already do). - Many values are translated to something readable (like enum names), with the raw value in parentheses. - Hex numbers are output in uppercase, prefixed with "0x". - Flags are sorted alphabetically. - Lists and groups are always delimited. Example output: ---------- snip ---------- Sections [ Section { Index: 1 Name: .text (5) Type: SHT_PROGBITS (0x1) Flags [ (0x6) SHF_ALLOC (0x2) SHF_EXECINSTR (0x4) ] Address: 0x0 Offset: 0x40 Size: 33 Link: 0 Info: 0 AddressAlignment: 16 EntrySize: 0 Relocations [ 0x6 R_386_32 .rodata.str1.1 0x0 0xB R_386_PC32 puts 0x0 0x12 R_386_32 .rodata.str1.1 0x0 0x17 R_386_PC32 puts 0x0 ] SectionData ( 0000: 83EC04C7 04240000 0000E8FC FFFFFFC7 |.....$..........| 0010: 04240600 0000E8FC FFFFFF31 C083C404 |.$.........1....| 0020: C3 |.| ) } ] ---------- snip ---------- Relocations and symbols can be output standalone or together with the section header as displayed in the example. This feature set supports all tests in test/MC/COFF and test/MC/ELF (and I suspect all additional tests using elf-dump), making elf-dump and coff-dump deprecated. Patch by Nico Rieck! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178679 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/CMakeLists.txt | 13 +- tools/llvm-readobj/COFFDumper.cpp | 1014 +++++++++++++++++++++++++++++++++++ tools/llvm-readobj/ELF.cpp | 196 ------- tools/llvm-readobj/ELFDumper.cpp | 800 +++++++++++++++++++++++++++ tools/llvm-readobj/Error.cpp | 62 +++ tools/llvm-readobj/Error.h | 48 ++ tools/llvm-readobj/LLVMBuild.txt | 2 +- tools/llvm-readobj/MachODumper.cpp | 438 +++++++++++++++ tools/llvm-readobj/Makefile | 2 +- tools/llvm-readobj/ObjDumper.cpp | 33 ++ tools/llvm-readobj/ObjDumper.h | 60 +++ tools/llvm-readobj/StreamWriter.cpp | 79 +++ tools/llvm-readobj/StreamWriter.h | 282 ++++++++++ tools/llvm-readobj/llvm-readobj.cpp | 435 ++++++++------- tools/llvm-readobj/llvm-readobj.h | 35 +- 15 files changed, 3073 insertions(+), 426 deletions(-) create mode 100644 tools/llvm-readobj/COFFDumper.cpp delete mode 100644 tools/llvm-readobj/ELF.cpp create mode 100644 tools/llvm-readobj/ELFDumper.cpp create mode 100644 tools/llvm-readobj/Error.cpp create mode 100644 tools/llvm-readobj/Error.h create mode 100644 tools/llvm-readobj/MachODumper.cpp create mode 100644 tools/llvm-readobj/ObjDumper.cpp create mode 100644 tools/llvm-readobj/ObjDumper.h create mode 100644 tools/llvm-readobj/StreamWriter.cpp create mode 100644 tools/llvm-readobj/StreamWriter.h (limited to 'tools') diff --git a/tools/llvm-readobj/CMakeLists.txt b/tools/llvm-readobj/CMakeLists.txt index 676c23d7ae..3d20def8f5 100644 --- a/tools/llvm-readobj/CMakeLists.txt +++ b/tools/llvm-readobj/CMakeLists.txt @@ -1,6 +1,15 @@ -set(LLVM_LINK_COMPONENTS archive bitreader object) +set(LLVM_LINK_COMPONENTS + ${LLVM_TARGETS_TO_BUILD} + archive + bitreader + object) add_llvm_tool(llvm-readobj - ELF.cpp llvm-readobj.cpp + ObjDumper.cpp + COFFDumper.cpp + ELFDumper.cpp + MachODumper.cpp + Error.cpp + StreamWriter.cpp ) diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp new file mode 100644 index 0000000000..be4e76cc63 --- /dev/null +++ b/tools/llvm-readobj/COFFDumper.cpp @@ -0,0 +1,1014 @@ +//===-- COFFDumper.cpp - COFF-specific dumper -------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief This file implements the COFF-specific dumper for llvm-readobj. +/// +//===----------------------------------------------------------------------===// + +#include "llvm-readobj.h" +#include "ObjDumper.h" + +#include "Error.h" +#include "StreamWriter.h" + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallString.h" +#include "llvm/Object/COFF.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/Win64EH.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/system_error.h" + +#include +#include +#include + +using namespace llvm; +using namespace llvm::object; +using namespace llvm::Win64EH; + +namespace { + +class COFFDumper : public ObjDumper { +public: + COFFDumper(const llvm::object::COFFObjectFile *Obj, StreamWriter& Writer) + : ObjDumper(Writer) + , Obj(Obj) { + cacheRelocations(); + } + + virtual void printFileHeaders() LLVM_OVERRIDE; + virtual void printSections() LLVM_OVERRIDE; + virtual void printRelocations() LLVM_OVERRIDE; + virtual void printSymbols() LLVM_OVERRIDE; + virtual void printDynamicSymbols() LLVM_OVERRIDE; + virtual void printUnwindInfo() LLVM_OVERRIDE; + +private: + void printSymbol(symbol_iterator SymI); + + void printRelocation(section_iterator SecI, relocation_iterator RelI); + + void printX64UnwindInfo(); + + void printRuntimeFunction( + const RuntimeFunction& RTF, + uint64_t OffsetInSection, + const std::vector &Rels); + + void printUnwindInfo( + const Win64EH::UnwindInfo& UI, + uint64_t OffsetInSection, + const std::vector &Rels); + + void printUnwindCode(const Win64EH::UnwindInfo& UI, ArrayRef UCs); + + void cacheRelocations(); + + error_code getSectionContents( + const std::vector &Rels, + uint64_t Offset, + ArrayRef &Contents, + uint64_t &Addr); + + error_code getSection( + const std::vector &Rels, + uint64_t Offset, + const coff_section **Section, + uint64_t *AddrPtr); + + typedef DenseMap > RelocMapTy; + + const llvm::object::COFFObjectFile *Obj; + RelocMapTy RelocMap; + std::vector EmptyRelocs; +}; + +} // namespace + + +namespace llvm { + +error_code createCOFFDumper(const object::ObjectFile *Obj, + StreamWriter& Writer, + OwningPtr &Result) { + const COFFObjectFile *COFFObj = dyn_cast(Obj); + if (!COFFObj) + return readobj_error::unsupported_obj_file_format; + + Result.reset(new COFFDumper(COFFObj, Writer)); + return readobj_error::success; +} + +} // namespace llvm + + +// Returns the name of the unwind code. +static StringRef getUnwindCodeTypeName(uint8_t Code) { + switch(Code) { + default: llvm_unreachable("Invalid unwind code"); + case UOP_PushNonVol: return "PUSH_NONVOL"; + case UOP_AllocLarge: return "ALLOC_LARGE"; + case UOP_AllocSmall: return "ALLOC_SMALL"; + case UOP_SetFPReg: return "SET_FPREG"; + case UOP_SaveNonVol: return "SAVE_NONVOL"; + case UOP_SaveNonVolBig: return "SAVE_NONVOL_FAR"; + case UOP_SaveXMM128: return "SAVE_XMM128"; + case UOP_SaveXMM128Big: return "SAVE_XMM128_FAR"; + case UOP_PushMachFrame: return "PUSH_MACHFRAME"; + } +} + +// Returns the name of a referenced register. +static StringRef getUnwindRegisterName(uint8_t Reg) { + switch(Reg) { + default: llvm_unreachable("Invalid register"); + case 0: return "RAX"; + case 1: return "RCX"; + case 2: return "RDX"; + case 3: return "RBX"; + case 4: return "RSP"; + case 5: return "RBP"; + case 6: return "RSI"; + case 7: return "RDI"; + case 8: return "R8"; + case 9: return "R9"; + case 10: return "R10"; + case 11: return "R11"; + case 12: return "R12"; + case 13: return "R13"; + case 14: return "R14"; + case 15: return "R15"; + } +} + +// Calculates the number of array slots required for the unwind code. +static unsigned getNumUsedSlots(const UnwindCode &UnwindCode) { + switch (UnwindCode.getUnwindOp()) { + default: llvm_unreachable("Invalid unwind code"); + case UOP_PushNonVol: + case UOP_AllocSmall: + case UOP_SetFPReg: + case UOP_PushMachFrame: + return 1; + case UOP_SaveNonVol: + case UOP_SaveXMM128: + return 2; + case UOP_SaveNonVolBig: + case UOP_SaveXMM128Big: + return 3; + case UOP_AllocLarge: + return (UnwindCode.getOpInfo() == 0) ? 2 : 3; + } +} + +// Given a symbol sym this functions returns the address and section of it. +static error_code resolveSectionAndAddress(const COFFObjectFile *Obj, + const SymbolRef &Sym, + const coff_section *&ResolvedSection, + uint64_t &ResolvedAddr) { + if (error_code EC = Sym.getAddress(ResolvedAddr)) + return EC; + + section_iterator iter(Obj->begin_sections()); + if (error_code EC = Sym.getSection(iter)) + return EC; + + ResolvedSection = Obj->getCOFFSection(iter); + return object_error::success; +} + +// Given a vector of relocations for a section and an offset into this section +// the function returns the symbol used for the relocation at the offset. +static error_code resolveSymbol(const std::vector &Rels, + uint64_t Offset, SymbolRef &Sym) { + for (std::vector::const_iterator RelI = Rels.begin(), + RelE = Rels.end(); + RelI != RelE; ++RelI) { + uint64_t Ofs; + if (error_code EC = RelI->getOffset(Ofs)) + return EC; + + if (Ofs == Offset) { + if (error_code EC = RelI->getSymbol(Sym)) + return EC; + return readobj_error::success; + } + } + + return readobj_error::unknown_symbol; +} + +// Given a vector of relocations for a section and an offset into this section +// the function returns the name of the symbol used for the relocation at the +// offset. +static error_code resolveSymbolName(const std::vector &Rels, + uint64_t Offset, StringRef &Name) { + SymbolRef Sym; + if (error_code EC = resolveSymbol(Rels, Offset, Sym)) return EC; + if (error_code EC = Sym.getName(Name)) return EC; + return object_error::success; +} + +static const EnumEntry ImageFileMachineType[] = { + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_UNKNOWN ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AM33 ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_AMD64 ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARM ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_ARMV7 ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_EBC ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_I386 ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_IA64 ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_M32R ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPS16 ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPSFPU ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_MIPSFPU16), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_POWERPC ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_POWERPCFP), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_R4000 ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH3 ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH3DSP ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH4 ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_SH5 ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_THUMB ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_MACHINE_WCEMIPSV2) +}; + +static const EnumEntry ImageFileCharacteristics[] = { + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_RELOCS_STRIPPED ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_EXECUTABLE_IMAGE ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_LINE_NUMS_STRIPPED ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_LOCAL_SYMS_STRIPPED ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_AGGRESSIVE_WS_TRIM ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_LARGE_ADDRESS_AWARE ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_BYTES_REVERSED_LO ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_32BIT_MACHINE ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_DEBUG_STRIPPED ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_NET_RUN_FROM_SWAP ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_SYSTEM ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_DLL ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_UP_SYSTEM_ONLY ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_FILE_BYTES_REVERSED_HI ) +}; + +static const EnumEntry +ImageSectionCharacteristics[] = { + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_TYPE_NO_PAD ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_CODE ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_INITIALIZED_DATA ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_CNT_UNINITIALIZED_DATA), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_OTHER ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_INFO ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_REMOVE ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_COMDAT ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_GPREL ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_PURGEABLE ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_16BIT ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_LOCKED ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_PRELOAD ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1BYTES ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2BYTES ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4BYTES ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8BYTES ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_16BYTES ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_32BYTES ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_64BYTES ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_128BYTES ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_256BYTES ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_512BYTES ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_1024BYTES ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_2048BYTES ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_4096BYTES ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_ALIGN_8192BYTES ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_LNK_NRELOC_OVFL ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_DISCARDABLE ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_CACHED ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_NOT_PAGED ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_SHARED ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_EXECUTE ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_READ ), + LLVM_READOBJ_ENUM_ENT(COFF, IMAGE_SCN_MEM_WRITE ) +}; + +static const EnumEntry ImageSymType[] = { + { "Null" , COFF::IMAGE_SYM_TYPE_NULL }, + { "Void" , COFF::IMAGE_SYM_TYPE_VOID }, + { "Char" , COFF::IMAGE_SYM_TYPE_CHAR }, + { "Short" , COFF::IMAGE_SYM_TYPE_SHORT }, + { "Int" , COFF::IMAGE_SYM_TYPE_INT }, + { "Long" , COFF::IMAGE_SYM_TYPE_LONG }, + { "Float" , COFF::IMAGE_SYM_TYPE_FLOAT }, + { "Double", COFF::IMAGE_SYM_TYPE_DOUBLE }, + { "Struct", COFF::IMAGE_SYM_TYPE_STRUCT }, + { "Union" , COFF::IMAGE_SYM_TYPE_UNION }, + { "Enum" , COFF::IMAGE_SYM_TYPE_ENUM }, + { "MOE" , COFF::IMAGE_SYM_TYPE_MOE }, + { "Byte" , COFF::IMAGE_SYM_TYPE_BYTE }, + { "Word" , COFF::IMAGE_SYM_TYPE_WORD }, + { "UInt" , COFF::IMAGE_SYM_TYPE_UINT }, + { "DWord" , COFF::IMAGE_SYM_TYPE_DWORD } +}; + +static const EnumEntry ImageSymDType[] = { + { "Null" , COFF::IMAGE_SYM_DTYPE_NULL }, + { "Pointer" , COFF::IMAGE_SYM_DTYPE_POINTER }, + { "Function", COFF::IMAGE_SYM_DTYPE_FUNCTION }, + { "Array" , COFF::IMAGE_SYM_DTYPE_ARRAY } +}; + +static const EnumEntry ImageSymClass[] = { + { "EndOfFunction" , COFF::IMAGE_SYM_CLASS_END_OF_FUNCTION }, + { "Null" , COFF::IMAGE_SYM_CLASS_NULL }, + { "Automatic" , COFF::IMAGE_SYM_CLASS_AUTOMATIC }, + { "External" , COFF::IMAGE_SYM_CLASS_EXTERNAL }, + { "Static" , COFF::IMAGE_SYM_CLASS_STATIC }, + { "Register" , COFF::IMAGE_SYM_CLASS_REGISTER }, + { "ExternalDef" , COFF::IMAGE_SYM_CLASS_EXTERNAL_DEF }, + { "Label" , COFF::IMAGE_SYM_CLASS_LABEL }, + { "UndefinedLabel" , COFF::IMAGE_SYM_CLASS_UNDEFINED_LABEL }, + { "MemberOfStruct" , COFF::IMAGE_SYM_CLASS_MEMBER_OF_STRUCT }, + { "Argument" , COFF::IMAGE_SYM_CLASS_ARGUMENT }, + { "StructTag" , COFF::IMAGE_SYM_CLASS_STRUCT_TAG }, + { "MemberOfUnion" , COFF::IMAGE_SYM_CLASS_MEMBER_OF_UNION }, + { "UnionTag" , COFF::IMAGE_SYM_CLASS_UNION_TAG }, + { "TypeDefinition" , COFF::IMAGE_SYM_CLASS_TYPE_DEFINITION }, + { "UndefinedStatic", COFF::IMAGE_SYM_CLASS_UNDEFINED_STATIC }, + { "EnumTag" , COFF::IMAGE_SYM_CLASS_ENUM_TAG }, + { "MemberOfEnum" , COFF::IMAGE_SYM_CLASS_MEMBER_OF_ENUM }, + { "RegisterParam" , COFF::IMAGE_SYM_CLASS_REGISTER_PARAM }, + { "BitField" , COFF::IMAGE_SYM_CLASS_BIT_FIELD }, + { "Block" , COFF::IMAGE_SYM_CLASS_BLOCK }, + { "Function" , COFF::IMAGE_SYM_CLASS_FUNCTION }, + { "EndOfStruct" , COFF::IMAGE_SYM_CLASS_END_OF_STRUCT }, + { "File" , COFF::IMAGE_SYM_CLASS_FILE }, + { "Section" , COFF::IMAGE_SYM_CLASS_SECTION }, + { "WeakExternal" , COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL }, + { "CLRToken" , COFF::IMAGE_SYM_CLASS_CLR_TOKEN } +}; + +static const EnumEntry ImageCOMDATSelect[] = { + { "NoDuplicates", COFF::IMAGE_COMDAT_SELECT_NODUPLICATES }, + { "Any" , COFF::IMAGE_COMDAT_SELECT_ANY }, + { "SameSize" , COFF::IMAGE_COMDAT_SELECT_SAME_SIZE }, + { "ExactMatch" , COFF::IMAGE_COMDAT_SELECT_EXACT_MATCH }, + { "Associative" , COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE }, + { "Largest" , COFF::IMAGE_COMDAT_SELECT_LARGEST }, + { "Newest" , COFF::IMAGE_COMDAT_SELECT_NEWEST } +}; + +static const EnumEntry +WeakExternalCharacteristics[] = { + { "NoLibrary", COFF::IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY }, + { "Library" , COFF::IMAGE_WEAK_EXTERN_SEARCH_LIBRARY }, + { "Alias" , COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS } +}; + +static const EnumEntry UnwindFlags[] = { + { "ExceptionHandler", Win64EH::UNW_ExceptionHandler }, + { "TerminateHandler", Win64EH::UNW_TerminateHandler }, + { "ChainInfo" , Win64EH::UNW_ChainInfo } +}; + +static const EnumEntry UnwindOpInfo[] = { + { "RAX", 0 }, + { "RCX", 1 }, + { "RDX", 2 }, + { "RBX", 3 }, + { "RSP", 4 }, + { "RBP", 5 }, + { "RSI", 6 }, + { "RDI", 7 }, + { "R8", 8 }, + { "R9", 9 }, + { "R10", 10 }, + { "R11", 11 }, + { "R12", 12 }, + { "R13", 13 }, + { "R14", 14 }, + { "R15", 15 } +}; + +// Some additional COFF structures not defined by llvm::object. +namespace { + struct coff_aux_function_definition { + support::ulittle32_t TagIndex; + support::ulittle32_t TotalSize; + support::ulittle32_t PointerToLineNumber; + support::ulittle32_t PointerToNextFunction; + uint8_t Unused[2]; + }; + + struct coff_aux_weak_external_definition { + support::ulittle32_t TagIndex; + support::ulittle32_t Characteristics; + uint8_t Unused[10]; + }; + + struct coff_aux_file_record { + char FileName[18]; + }; + + struct coff_aux_clr_token { + support::ulittle8_t AuxType; + support::ulittle8_t Reserved; + support::ulittle32_t SymbolTableIndex; + uint8_t Unused[12]; + }; +} // namespace + +static uint64_t getOffsetOfLSDA(const Win64EH::UnwindInfo& UI) { + return static_cast(UI.getLanguageSpecificData()) + - reinterpret_cast(&UI); +} + +static uint32_t getLargeSlotValue(ArrayRef UCs) { + if (UCs.size() < 3) + return 0; + + return UCs[1].FrameOffset + (static_cast(UCs[2].FrameOffset) << 16); +} + +template +static error_code getSymbolAuxData(const COFFObjectFile *Obj, + const coff_symbol *Symbol, const T* &Aux) { + ArrayRef AuxData = Obj->getSymbolAuxData(Symbol); + Aux = reinterpret_cast(AuxData.data()); + return readobj_error::success; +} + +static std::string formatSymbol(const std::vector &Rels, + uint64_t Offset, uint32_t Disp) { + std::string Buffer; + raw_string_ostream Str(Buffer); + + StringRef Sym; + if (resolveSymbolName(Rels, Offset, Sym)) { + Str << format(" (0x%X)", Offset); + return Str.str(); + } + + Str << Sym; + if (Disp > 0) { + Str << format(" +0x%X (0x%X)", Disp, Offset); + } else { + Str << format(" (0x%X)", Offset); + } + + return Str.str(); +} + +// Given a vector of relocations for a section and an offset into this section +// the function resolves the symbol used for the relocation at the offset and +// returns the section content and the address inside the content pointed to +// by the symbol. +error_code COFFDumper::getSectionContents( + const std::vector &Rels, uint64_t Offset, + ArrayRef &Contents, uint64_t &Addr) { + + SymbolRef Sym; + const coff_section *Section; + + if (error_code EC = resolveSymbol(Rels, Offset, Sym)) + return EC; + if (error_code EC = resolveSectionAndAddress(Obj, Sym, Section, Addr)) + return EC; + if (error_code EC = Obj->getSectionContents(Section, Contents)) + return EC; + + return object_error::success; +} + +error_code COFFDumper::getSection( + const std::vector &Rels, uint64_t Offset, + const coff_section **SectionPtr, uint64_t *AddrPtr) { + + SymbolRef Sym; + if (error_code EC = resolveSymbol(Rels, Offset, Sym)) + return EC; + + const coff_section *Section; + uint64_t Addr; + if (error_code EC = resolveSectionAndAddress(Obj, Sym, Section, Addr)) + return EC; + + if (SectionPtr) + *SectionPtr = Section; + if (AddrPtr) + *AddrPtr = Addr; + + return object_error::success; +} + +void COFFDumper::cacheRelocations() { + error_code EC; + for (section_iterator SecI = Obj->begin_sections(), + SecE = Obj->end_sections(); + SecI != SecE; SecI.increment(EC)) { + if (error(EC)) + break; + + const coff_section *Section = Obj->getCOFFSection(SecI); + + for (relocation_iterator RelI = SecI->begin_relocations(), + RelE = SecI->end_relocations(); + RelI != RelE; RelI.increment(EC)) { + if (error(EC)) + break; + + RelocMap[Section].push_back(*RelI); + } + + // Sort relocations by address. + std::sort(RelocMap[Section].begin(), RelocMap[Section].end(), + relocAddressLess); + } +} + +void COFFDumper::printFileHeaders() { + const coff_file_header *Header = 0; + if (error(Obj->getHeader(Header))) + return; + + time_t TDS = Header->TimeDateStamp; + char FormattedTime[20] = { }; + strftime(FormattedTime, 20, "%Y-%m-%d %H:%M:%S", gmtime(&TDS)); + + { + DictScope D(W, "ImageFileHeader"); + W.printEnum ("Machine", Header->Machine, + makeArrayRef(ImageFileMachineType)); + W.printNumber("SectionCount", Header->NumberOfSections); + W.printHex ("TimeDateStamp", FormattedTime, Header->TimeDateStamp); + W.printHex ("PointerToSymbolTable", Header->PointerToSymbolTable); + W.printNumber("SymbolCount", Header->NumberOfSymbols); + W.printNumber("OptionalHeaderSize", Header->SizeOfOptionalHeader); + W.printFlags ("Characteristics", Header->Characteristics, + makeArrayRef(ImageFileCharacteristics)); + } +} + +void COFFDumper::printSections() { + error_code EC; + + ListScope SectionsD(W, "Sections"); + int SectionNumber = 0; + for (section_iterator SecI = Obj->begin_sections(), + SecE = Obj->end_sections(); + SecI != SecE; SecI.increment(EC)) { + if (error(EC)) + break; + + ++SectionNumber; + const coff_section *Section = Obj->getCOFFSection(SecI); + + StringRef Name; + if (error(SecI->getName(Name))) + Name = ""; + + DictScope D(W, "Section"); + W.printNumber("Number", SectionNumber); + W.printBinary("Name", Name, Section->Name); + W.printHex ("VirtualSize", Section->VirtualSize); + W.printHex ("VirtualAddress", Section->VirtualAddress); + W.printNumber("RawDataSize", Section->SizeOfRawData); + W.printHex ("PointerToRawData", Section->PointerToRawData); + W.printHex ("PointerToRelocations", Section->PointerToRelocations); + W.printHex ("PointerToLineNumbers", Section->PointerToLinenumbers); + W.printNumber("RelocationCount", Section->NumberOfRelocations); + W.printNumber("LineNumberCount", Section->NumberOfLinenumbers); + W.printFlags ("Characteristics", Section->Characteristics, + makeArrayRef(ImageSectionCharacteristics), + COFF::SectionCharacteristics(0x00F00000)); + + if (opts::SectionRelocations) { + ListScope D(W, "Relocations"); + for (relocation_iterator RelI = SecI->begin_relocations(), + RelE = SecI->end_relocations(); + RelI != RelE; RelI.increment(EC)) { + if (error(EC)) break; + + printRelocation(SecI, RelI); + } + } + + if (opts::SectionSymbols) { + ListScope D(W, "Symbols"); + for (symbol_iterator SymI = Obj->begin_symbols(), + SymE = Obj->end_symbols(); + SymI != SymE; SymI.increment(EC)) { + if (error(EC)) break; + + bool Contained = false; + if (SecI->containsSymbol(*SymI, Contained) || !Contained) + continue; + + printSymbol(SymI); + } + } + + if (opts::SectionData) { + StringRef Data; + if (error(SecI->getContents(Data))) break; + + W.printBinaryBlock("SectionData", Data); + } + } +} + +void COFFDumper::printRelocations() { + ListScope D(W, "Relocations"); + + error_code EC; + int SectionNumber = 0; + for (section_iterator SecI = Obj->begin_sections(), + SecE = Obj->end_sections(); + SecI != SecE; SecI.increment(EC)) { + ++SectionNumber; + if (error(EC)) + break; + + StringRef Name; + if (error(SecI->getName(Name))) + continue; + + bool PrintedGroup = false; + for (relocation_iterator RelI = SecI->begin_relocations(), + RelE = SecI->end_relocations(); + RelI != RelE; RelI.increment(EC)) { + if (error(EC)) break; + + if (!PrintedGroup) { + W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n"; + W.indent(); + PrintedGroup = true; + } + + printRelocation(SecI, RelI); + } + + if (PrintedGroup) { + W.unindent(); + W.startLine() << "}\n"; + } + } +} + +void COFFDumper::printRelocation(section_iterator SecI, + relocation_iterator RelI) { + uint64_t Offset; + uint64_t RelocType; + SmallString<32> RelocName; + SymbolRef Symbol; + StringRef SymbolName; + StringRef Contents; + if (error(RelI->getOffset(Offset))) return; + if (error(RelI->getType(RelocType))) return; + if (error(RelI->getTypeName(RelocName))) return; + if (error(RelI->getSymbol(Symbol))) return; + if (error(Symbol.getName(SymbolName))) return; + if (error(SecI->getContents(Contents))) return; + + raw_ostream& OS = W.startLine(); + OS << W.hex(Offset) + << " " << RelocName + << " " << (SymbolName.size() > 0 ? SymbolName : "-") + << "\n"; +} + +void COFFDumper::printSymbols() { + ListScope Group(W, "Symbols"); + + error_code EC; + for (symbol_iterator SymI = Obj->begin_symbols(), + SymE = Obj->end_symbols(); + SymI != SymE; SymI.increment(EC)) { + if (error(EC)) break; + + printSymbol(SymI); + } +} + +void COFFDumper::printDynamicSymbols() { + ListScope Group(W, "DynamicSymbols"); +} + +void COFFDumper::printSymbol(symbol_iterator SymI) { + DictScope D(W, "Symbol"); + + const coff_symbol *Symbol = Obj->getCOFFSymbol(SymI); + const coff_section *Section; + if (error_code EC = Obj->getSection(Symbol->SectionNumber, Section)) { + W.startLine() << "Invalid section number: " << EC.message() << "\n"; + W.flush(); + return; + } + + StringRef SymbolName; + if (Obj->getSymbolName(Symbol, SymbolName)) + SymbolName = ""; + + StringRef SectionName; + if (Section && Obj->getSectionName(Section, SectionName)) + SectionName = ""; + + W.printString("Name", SymbolName); + W.printNumber("Value", Symbol->Value); + W.printNumber("Section", SectionName, Symbol->SectionNumber); + W.printEnum ("BaseType", Symbol->getBaseType(), makeArrayRef(ImageSymType)); + W.printEnum ("ComplexType", Symbol->getComplexType(), + makeArrayRef(ImageSymDType)); + W.printEnum ("StorageClass", Symbol->StorageClass, + makeArrayRef(ImageSymClass)); + W.printNumber("AuxSymbolCount", Symbol->NumberOfAuxSymbols); + + for (unsigned I = 0; I < Symbol->NumberOfAuxSymbols; ++I) { + if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && + Symbol->getBaseType() == COFF::IMAGE_SYM_TYPE_NULL && + Symbol->getComplexType() == COFF::IMAGE_SYM_DTYPE_FUNCTION && + Symbol->SectionNumber > 0) { + const coff_aux_function_definition *Aux; + if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) + break; + + DictScope AS(W, "AuxFunctionDef"); + W.printNumber("TagIndex", Aux->TagIndex); + W.printNumber("TotalSize", Aux->TotalSize); + W.printHex("PointerToLineNumber", Aux->PointerToLineNumber); + W.printHex("PointerToNextFunction", Aux->PointerToNextFunction); + W.printBinary("Unused", makeArrayRef(Aux->Unused)); + + } else if ( + Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL || + (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && + Symbol->SectionNumber == 0 && + Symbol->Value == 0)) { + const coff_aux_weak_external_definition *Aux; + if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) + break; + + const coff_symbol *Linked; + StringRef LinkedName; + error_code EC; + if ((EC = Obj->getSymbol(Aux->TagIndex, Linked)) || + (EC = Obj->getSymbolName(Linked, LinkedName))) { + LinkedName = ""; + error(EC); + } + + DictScope AS(W, "AuxWeakExternal"); + W.printNumber("Linked", LinkedName, Aux->TagIndex); + W.printEnum ("Search", Aux->Characteristics, + makeArrayRef(WeakExternalCharacteristics)); + W.printBinary("Unused", Aux->Unused); + + } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_FILE) { + const coff_aux_file_record *Aux; + if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) + break; + + } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC) { + const coff_aux_section_definition *Aux; + if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) + break; + + DictScope AS(W, "AuxSectionDef"); + W.printNumber("Length", Aux->Length); + W.printNumber("RelocationCount", Aux->NumberOfRelocations); + W.printNumber("LineNumberCount", Aux->NumberOfLinenumbers); + W.printHex("Checksum", Aux->CheckSum); + W.printNumber("Number", Aux->Number); + W.printEnum("Selection", Aux->Selection, makeArrayRef(ImageCOMDATSelect)); + W.printBinary("Unused", makeArrayRef(Aux->Unused)); + + if (Section->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT + && Aux->Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) { + const coff_section *Assoc; + StringRef AssocName; + error_code EC; + if ((EC = Obj->getSection(Aux->Number, Assoc)) || + (EC = Obj->getSectionName(Assoc, AssocName))) { + AssocName = ""; + error(EC); + } + + W.printNumber("AssocSection", AssocName, Aux->Number); + } + } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_CLR_TOKEN) { + const coff_aux_clr_token *Aux; + if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) + break; + + DictScope AS(W, "AuxCLRToken"); + W.printNumber("AuxType", Aux->AuxType); + W.printNumber("Reserved", Aux->Reserved); + W.printNumber("SymbolTableIndex", Aux->SymbolTableIndex); + W.printBinary("Unused", Aux->Unused); + + } else { + W.startLine() << "\n"; + } + } +} + +void COFFDumper::printUnwindInfo() { + const coff_file_header *Header; + if (error(Obj->getHeader(Header))) + return; + + ListScope D(W, "UnwindInformation"); + if (Header->Machine != COFF::IMAGE_FILE_MACHINE_AMD64) { + W.startLine() << "Unsupported image machine type " + "(currently only AMD64 is supported).\n"; + return; + } + + printX64UnwindInfo(); +} + +void COFFDumper::printX64UnwindInfo() { + error_code EC; + for (section_iterator SecI = Obj->begin_sections(), + SecE = Obj->end_sections(); + SecI != SecE; SecI.increment(EC)) { + if (error(EC)) break; + + StringRef Name; + if (error(SecI->getName(Name))) + continue; + if (Name != ".pdata" && !Name.startswith(".pdata$")) + continue; + + const coff_section *PData = Obj->getCOFFSection(SecI); + + ArrayRef Contents; + if (error(Obj->getSectionContents(PData, Contents)) || + Contents.empty()) + continue; + + ArrayRef RFs( + reinterpret_cast(Contents.data()), + Contents.size() / sizeof(RuntimeFunction)); + + for (const RuntimeFunction *I = RFs.begin(), *E = RFs.end(); I < E; ++I) { + const uint64_t OffsetInSection = std::distance(RFs.begin(), I) + * sizeof(RuntimeFunction); + + printRuntimeFunction(*I, OffsetInSection, RelocMap[PData]); + } + } +} + +void COFFDumper::printRuntimeFunction( + const RuntimeFunction& RTF, + uint64_t OffsetInSection, + const std::vector &Rels) { + + DictScope D(W, "RuntimeFunction"); + W.printString("StartAddress", + formatSymbol(Rels, OffsetInSection + 0, RTF.StartAddress)); + W.printString("EndAddress", + formatSymbol(Rels, OffsetInSection + 4, RTF.EndAddress)); + W.printString("UnwindInfoAddress", + formatSymbol(Rels, OffsetInSection + 8, RTF.UnwindInfoOffset)); + + const coff_section* XData = 0; + uint64_t UnwindInfoOffset = 0; + if (error(getSection(Rels, OffsetInSection + 8, &XData, &UnwindInfoOffset))) + return; + + ArrayRef XContents; + if (error(Obj->getSectionContents(XData, XContents)) || XContents.empty()) + return; + + UnwindInfoOffset += RTF.UnwindInfoOffset; + if (UnwindInfoOffset > XContents.size()) + return; + + const Win64EH::UnwindInfo *UI = + reinterpret_cast( + XContents.data() + UnwindInfoOffset); + + printUnwindInfo(*UI, UnwindInfoOffset, RelocMap[XData]); +} + +void COFFDumper::printUnwindInfo( + const Win64EH::UnwindInfo& UI, + uint64_t OffsetInSection, + const std::vector &Rels) { + DictScope D(W, "UnwindInfo"); + W.printNumber("Version", UI.getVersion()); + W.printFlags("Flags", UI.getFlags(), makeArrayRef(UnwindFlags)); + W.printNumber("PrologSize", UI.PrologSize); + if (UI.getFrameRegister() != 0) { + W.printEnum("FrameRegister", UI.getFrameRegister(), + makeArrayRef(UnwindOpInfo)); + W.printHex("FrameOffset", UI.getFrameOffset()); + } else { + W.printString("FrameRegister", StringRef("-")); + W.printString("FrameOffset", StringRef("-")); + } + + W.printNumber("UnwindCodeCount", UI.NumCodes); + { + ListScope CodesD(W, "UnwindCodes"); + ArrayRef UCs(&UI.UnwindCodes[0], UI.NumCodes); + for (const UnwindCode *I = UCs.begin(), *E = UCs.end(); I < E; ++I) { + unsigned UsedSlots = getNumUsedSlots(*I); + if (UsedSlots > UCs.size()) { + errs() << "Corrupt unwind data"; + return; + } + printUnwindCode(UI, ArrayRef(I, E)); + I += UsedSlots - 1; + } + } + + uint64_t LSDAOffset = OffsetInSection + getOffsetOfLSDA(UI); + if (UI.getFlags() & (UNW_ExceptionHandler | UNW_TerminateHandler)) { + W.printString("Handler", formatSymbol(Rels, LSDAOffset, + UI.getLanguageSpecificHandlerOffset())); + } else if (UI.getFlags() & UNW_ChainInfo) { + const RuntimeFunction *Chained = UI.getChainedFunctionEntry(); + if (Chained) { + DictScope D(W, "Chained"); + W.printString("StartAddress", formatSymbol(Rels, LSDAOffset + 0, + Chained->StartAddress)); + W.printString("EndAddress", formatSymbol(Rels, LSDAOffset + 4, + Chained->EndAddress)); + W.printString("UnwindInfoAddress", formatSymbol(Rels, LSDAOffset + 8, + Chained->UnwindInfoOffset)); + } + } +} + +// Prints one unwind code. Because an unwind code can occupy up to 3 slots in +// the unwind codes array, this function requires that the correct number of +// slots is provided. +void COFFDumper::printUnwindCode(const Win64EH::UnwindInfo& UI, + ArrayRef UCs) { + assert(UCs.size() >= getNumUsedSlots(UCs[0])); + + W.startLine() << format("0x%02X: ", unsigned(UCs[0].u.CodeOffset)) + << getUnwindCodeTypeName(UCs[0].getUnwindOp()); + + uint32_t AllocSize = 0; + + switch (UCs[0].getUnwindOp()) { + case UOP_PushNonVol: + outs() << " reg=" << getUnwindRegisterName(UCs[0].getOpInfo()); + break; + + case UOP_AllocLarge: + if (UCs[0].getOpInfo() == 0) { + AllocSize = UCs[1].FrameOffset * 8; + } else { + AllocSize = getLargeSlotValue(UCs); + } + outs() << " size=" << AllocSize; + break; + case UOP_AllocSmall: + outs() << " size=" << ((UCs[0].getOpInfo() + 1) * 8); + break; + case UOP_SetFPReg: + if (UI.getFrameRegister() == 0) { + outs() << " reg="; + } else { + outs() << " reg=" << getUnwindRegisterName(UI.getFrameRegister()) + << format(", offset=0x%X", UI.getFrameOffset() * 16); + } + break; + case UOP_SaveNonVol: + outs() << " reg=" << getUnwindRegisterName(UCs[0].getOpInfo()) + << format(", offset=0x%X", UCs[1].FrameOffset * 8); + break; + case UOP_SaveNonVolBig: + outs() << " reg=" << getUnwindRegisterName(UCs[0].getOpInfo()) + << format(", offset=0x%X", getLargeSlotValue(UCs)); + break; + case UOP_SaveXMM128: + outs() << " reg=XMM" << static_cast(UCs[0].getOpInfo()) + << format(", offset=0x%X", UCs[1].FrameOffset * 16); + break; + case UOP_SaveXMM128Big: + outs() << " reg=XMM" << static_cast(UCs[0].getOpInfo()) + << format(", offset=0x%X", getLargeSlotValue(UCs)); + break; + case UOP_PushMachFrame: + outs() << " errcode=" << (UCs[0].getOpInfo() == 0 ? "no" : "yes"); + break; + } + + outs() << "\n"; +} diff --git a/tools/llvm-readobj/ELF.cpp b/tools/llvm-readobj/ELF.cpp deleted file mode 100644 index 07f15b3a6d..0000000000 --- a/tools/llvm-readobj/ELF.cpp +++ /dev/null @@ -1,196 +0,0 @@ -//===- llvm-readobj/ELF.cpp - ELF Specific Dumper -------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "llvm-readobj.h" - -#include "llvm/Object/ELF.h" -#include "llvm/Support/Casting.h" -#include "llvm/Support/Format.h" - -namespace llvm { -using namespace object; -using namespace ELF; - -const char *getTypeString(uint64_t Type) { - switch (Type) { - case DT_BIND_NOW: - return "(BIND_NOW)"; - case DT_DEBUG: - return "(DEBUG)"; - case DT_FINI: - return "(FINI)"; - case DT_FINI_ARRAY: - return "(FINI_ARRAY)"; - case DT_FINI_ARRAYSZ: - return "(FINI_ARRAYSZ)"; - case DT_FLAGS: - return "(FLAGS)"; - case DT_HASH: - return "(HASH)"; - case DT_INIT: - return "(INIT)"; - case DT_INIT_ARRAY: - return "(INIT_ARRAY)"; - case DT_INIT_ARRAYSZ: - return "(INIT_ARRAYSZ)"; - case DT_PREINIT_ARRAY: - return "(PREINIT_ARRAY)"; - case DT_PREINIT_ARRAYSZ: - return "(PREINIT_ARRAYSZ)"; - case DT_JMPREL: - return "(JMPREL)"; - case DT_NEEDED: - return "(NEEDED)"; - case DT_NULL: - return "(NULL)"; - case DT_PLTGOT: - return "(PLTGOT)"; - case DT_PLTREL: - return "(PLTREL)"; - case DT_PLTRELSZ: - return "(PLTRELSZ)"; - case DT_REL: - return "(REL)"; - case DT_RELA: - return "(RELA)"; - case DT_RELENT: - return "(RELENT)"; - case DT_RELSZ: - return "(RELSZ)"; - case DT_RELAENT: - return "(RELAENT)"; - case DT_RELASZ: - return "(RELASZ)"; - case DT_RPATH: - return "(RPATH)"; - case DT_RUNPATH: - return "(RUNPATH)"; - case DT_SONAME: - return "(SONAME)"; - case DT_STRSZ: - return "(STRSZ)"; - case DT_STRTAB: - return "(STRTAB)"; - case DT_SYMBOLIC: - return "(SYMBOLIC)"; - case DT_SYMENT: - return "(SYMENT)"; - case DT_SYMTAB: - return "(SYMTAB)"; - case DT_TEXTREL: - return "(TEXTREL)"; - default: - return "unknown"; - } -} - -template -void printValue(const ELFObjectFile *O, uint64_t Type, uint64_t Value, - bool Is64, raw_ostream &OS) { - switch (Type) { - case DT_PLTREL: - if (Value == DT_REL) { - OS << "REL"; - break; - } else if (Value == DT_RELA) { - OS << "RELA"; - break; - } - // Fallthrough. - case DT_PLTGOT: - case DT_HASH: - case DT_STRTAB: - case DT_SYMTAB: - case DT_RELA: - case DT_INIT: - case DT_FINI: - case DT_REL: - case DT_JMPREL: - case DT_INIT_ARRAY: - case DT_FINI_ARRAY: - case DT_PREINIT_ARRAY: - case DT_DEBUG: - case DT_NULL: - OS << format("0x%" PRIx64, Value); - break; - case DT_PLTRELSZ: - case DT_RELASZ: - case DT_RELAENT: - case DT_STRSZ: - case DT_SYMENT: - case DT_RELSZ: - case DT_RELENT: - case DT_INIT_ARRAYSZ: - case DT_FINI_ARRAYSZ: - case DT_PREINIT_ARRAYSZ: - OS << Value << " (bytes)"; - break; - case DT_NEEDED: - OS << "Shared library: [" - << O->getString(O->getDynamicStringTableSectionHeader(), Value) << "]"; - break; - case DT_SONAME: - OS << "Library soname: [" - << O->getString(O->getDynamicStringTableSectionHeader(), Value) << "]"; - break; - } -} - -template -ErrorOr dumpDynamicTable(const ELFObjectFile *O, raw_ostream &OS) { - typedef ELFObjectFile ELFO; - typedef typename ELFO::Elf_Dyn_iterator EDI; - EDI Start = O->begin_dynamic_table(), - End = O->end_dynamic_table(true); - - if (Start == End) - return error_code::success(); - - ptrdiff_t Total = std::distance(Start, End); - OS << "Dynamic section contains " << Total << " entries\n"; - - bool Is64 = O->getBytesInAddress() == 8; - - OS << " Tag" << (Is64 ? " " : " ") << "Type" - << " " << "Name/Value\n"; - for (; Start != End; ++Start) { - OS << " " - << format(Is64 ? "0x%016" PRIx64 : "0x%08" PRIx64, Start->getTag()) - << " " << format("%-21s", getTypeString(Start->getTag())); - printValue(O, Start->getTag(), Start->getVal(), Is64, OS); - OS << "\n"; - } - - OS << " Total: " << Total << "\n\n"; - return error_code::success(); -} - -ErrorOr dumpELFDynamicTable(ObjectFile *O, raw_ostream &OS) { - // Little-endian 32-bit - if (const ELFObjectFile > *ELFObj = - dyn_cast > >(O)) - return dumpDynamicTable(ELFObj, OS); - - // Big-endian 32-bit - if (const ELFObjectFile > *ELFObj = - dyn_cast > >(O)) - return dumpDynamicTable(ELFObj, OS); - - // Little-endian 64-bit - if (const ELFObjectFile > *ELFObj = - dyn_cast > >(O)) - return dumpDynamicTable(ELFObj, OS); - - // Big-endian 64-bit - if (const ELFObjectFile > *ELFObj = - dyn_cast > >(O)) - return dumpDynamicTable(ELFObj, OS); - return error_code(object_error::invalid_file_type); -} -} // end namespace llvm diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp new file mode 100644 index 0000000000..9e111dd905 --- /dev/null +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -0,0 +1,800 @@ +//===-- ELFDumper.cpp - ELF-specific dumper ---------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief This file implements the ELF-specific dumper for llvm-readobj. +/// +//===----------------------------------------------------------------------===// + +#include "llvm-readobj.h" +#include "Error.h" +#include "ObjDumper.h" +#include "StreamWriter.h" + +#include "llvm/ADT/SmallString.h" +#include "llvm/Object/ELF.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; +using namespace llvm::object; +using namespace ELF; + + +#define LLVM_READOBJ_ENUM_CASE(ns, enum) \ + case ns::enum: return #enum; + +namespace { + +template +class ELFDumper : public ObjDumper { +public: + ELFDumper(const ELFObjectFile *Obj, StreamWriter& Writer) + : ObjDumper(Writer) + , Obj(Obj) { } + + virtual void printFileHeaders() LLVM_OVERRIDE; + virtual void printSections() LLVM_OVERRIDE; + virtual void printRelocations() LLVM_OVERRIDE; + virtual void printSymbols() LLVM_OVERRIDE; + virtual void printDynamicSymbols() LLVM_OVERRIDE; + virtual void printUnwindInfo() LLVM_OVERRIDE; + + virtual void printDynamicTable() LLVM_OVERRIDE; + virtual void printNeededLibraries() LLVM_OVERRIDE; + +private: + typedef typename ELFObjectFile::Elf_Shdr Elf_Shdr; + typedef typename ELFObjectFile::Elf_Sym Elf_Sym; + + void printSymbol(symbol_iterator SymI, bool IsDynamic = false); + + void printRelocation(section_iterator SecI, relocation_iterator RelI); + + const ELFObjectFile *Obj; +}; + +} // namespace + + +namespace llvm { + +error_code createELFDumper(const object::ObjectFile *Obj, + StreamWriter& Writer, + OwningPtr &Result) { + typedef ELFType Little32ELF; + typedef ELFType Big32ELF; + typedef ELFType Little64ELF; + typedef ELFType Big64ELF; + + typedef ELFObjectFile LittleELF32Obj; + typedef ELFObjectFile BigELF32Obj; + typedef ELFObjectFile LittleELF64Obj; + typedef ELFObjectFile BigELF64Obj; + + // Little-endian 32-bit + if (const LittleELF32Obj *ELFObj = dyn_cast(Obj)) { + Result.reset(new ELFDumper(ELFObj, Writer)); + return readobj_error::success; + } + + // Big-endian 32-bit + if (const BigELF32Obj *ELFObj = dyn_cast(Obj)) { + Result.reset(new ELFDumper(ELFObj, Writer)); + return readobj_error::success; + } + + // Little-endian 64-bit + if (const LittleELF64Obj *ELFObj = dyn_cast(Obj)) { + Result.reset(new ELFDumper(ELFObj, Writer)); + return readobj_error::success; + } + + // Big-endian 64-bit + if (const BigELF64Obj *ELFObj = dyn_cast(Obj)) { + Result.reset(new ELFDumper(ELFObj, Writer)); + return readobj_error::success; + } + + return readobj_error::unsupported_obj_file_format; +} + +} // namespace llvm + + +static const EnumEntry ElfClass[] = { + { "None", ELF::ELFCLASSNONE }, + { "32-bit", ELF::ELFCLASS32 }, + { "64-bit", ELF::ELFCLASS64 }, +}; + +static const EnumEntry ElfDataEncoding[] = { + { "None", ELF::ELFDATANONE }, + { "LittleEndian", ELF::ELFDATA2LSB }, + { "BigEndian", ELF::ELFDATA2MSB }, +}; + +static const EnumEntry ElfObjectFileType[] = { + { "None", ELF::ET_NONE }, + { "Relocatable", ELF::ET_REL }, + { "Executable", ELF::ET_EXEC }, + { "SharedObject", ELF::ET_DYN }, + { "Core", ELF::ET_CORE }, +}; + +static const EnumEntry ElfOSABI[] = { + { "SystemV", ELF::ELFOSABI_NONE }, + { "HPUX", ELF::ELFOSABI_HPUX }, + { "NetBSD", ELF::ELFOSABI_NETBSD }, + { "GNU/Linux", ELF::ELFOSABI_LINUX }, + { "GNU/Hurd", ELF::ELFOSABI_HURD }, + { "Solaris", ELF::ELFOSABI_SOLARIS }, + { "AIX", ELF::ELFOSABI_AIX }, + { "IRIX", ELF::ELFOSABI_IRIX }, + { "FreeBSD", ELF::ELFOSABI_FREEBSD }, + { "TRU64", ELF::ELFOSABI_TRU64 }, + { "Modesto", ELF::ELFOSABI_MODESTO }, + { "OpenBSD", ELF::ELFOSABI_OPENBSD }, + { "OpenVMS", ELF::ELFOSABI_OPENVMS }, + { "NSK", ELF::ELFOSABI_NSK }, + { "AROS", ELF::ELFOSABI_AROS }, + { "FenixOS", ELF::ELFOSABI_FENIXOS }, + { "C6000_ELFABI", ELF::ELFOSABI_C6000_ELFABI }, + { "C6000_LINUX" , ELF::ELFOSABI_C6000_LINUX }, + { "ARM", ELF::ELFOSABI_ARM }, + { "Standalone" , ELF::ELFOSABI_STANDALONE } +}; + +static const EnumEntry ElfMachineType[] = { + LLVM_READOBJ_ENUM_ENT(ELF, EM_NONE ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_M32 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARC ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_386 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_68K ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_88K ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_486 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_860 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_S370 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS_RS3_LE ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_PARISC ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_VPP500 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARC32PLUS ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_960 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_PPC ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_PPC64 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_S390 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_SPU ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_V800 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_FR20 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_RH32 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_RCE ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_ARM ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_ALPHA ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_SH ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_SPARCV9 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_TRICORE ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_300 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_300H ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_H8S ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_H8_500 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_IA_64 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_MIPS_X ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_COLDFIRE ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC12 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_MMA ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_PCP ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_NCPU ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_NDR1 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_STARCORE ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_ME16 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_ST100 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_TINYJ ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_X86_64 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_PDSP ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_PDP10 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_PDP11 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_FX66 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_ST9PLUS ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_ST7 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC16 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC11 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC08 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_68HC05 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_SVX ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_ST19 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_VAX ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_CRIS ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_JAVELIN ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_FIREPATH ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_ZSP ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_MMIX ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_HUANY ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_PRISM ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_AVR ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_FR30 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_D10V ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_D30V ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_V850 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_M32R ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_MN10300 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_MN10200 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_PJ ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_OPENRISC ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC_COMPACT ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_XTENSA ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_TMM_GPP ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_NS32K ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_TPC ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_SNP1K ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_ST200 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_IP2K ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_MAX ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_CR ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_F2MC16 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_MSP430 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_BLACKFIN ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_SE_C33 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_SEP ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_ARCA ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_UNICORE ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_EXCESS ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_DXP ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_ALTERA_NIOS2 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_CRX ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_XGATE ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_C166 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_M16C ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_DSPIC30F ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_CE ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_M32C ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_TSK3000 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_RS08 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_SHARC ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG2 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_SCORE7 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_DSP24 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE3 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_LATTICEMICO32), + LLVM_READOBJ_ENUM_ENT(ELF, EM_SE_C17 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C6000 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C2000 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_TI_C5500 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_MMDSP_PLUS ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_CYPRESS_M8C ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_R32C ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_TRIMEDIA ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_HEXAGON ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_8051 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_STXP7X ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_NDS32 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG1 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG1X ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_MAXQ30 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_XIMO16 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_MANIK ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_CRAYNV2 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_RX ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_METAG ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_MCST_ELBRUS ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_ECOG16 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_CR16 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_ETPU ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_SLE9X ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_L10M ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_K10M ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_AARCH64 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_AVR32 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_STM8 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_TILE64 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_TILEPRO ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_MICROBLAZE ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_CUDA ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_TILEGX ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_CLOUDSHIELD ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_COREA_1ST ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_COREA_2ND ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_ARC_COMPACT2 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_OPEN8 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_RL78 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_VIDEOCORE5 ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_78KOR ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_56800EX ), + LLVM_READOBJ_ENUM_ENT(ELF, EM_MBLAZE ) +}; + +static const EnumEntry ElfSymbolBindings[] = { + { "Local", ELF::STB_LOCAL }, + { "Global", ELF::STB_GLOBAL }, + { "Weak", ELF::STB_WEAK } +}; + +static const EnumEntry ElfSymbolTypes[] = { + { "None", ELF::STT_NOTYPE }, + { "Object", ELF::STT_OBJECT }, + { "Function", ELF::STT_FUNC }, + { "Section", ELF::STT_SECTION }, + { "File", ELF::STT_FILE }, + { "Common", ELF::STT_COMMON }, + { "TLS", ELF::STT_TLS }, + { "GNU_IFunc", ELF::STT_GNU_IFUNC } +}; + +static const char *getElfSectionType(unsigned Arch, unsigned Type) { + switch (Arch) { + case Triple::arm: + switch (Type) { + LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_EXIDX); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_ATTRIBUTES); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION); + } + case Triple::hexagon: + switch (Type) { + LLVM_READOBJ_ENUM_CASE(ELF, SHT_HEX_ORDERED); + } + case Triple::x86_64: + switch (Type) { + LLVM_READOBJ_ENUM_CASE(ELF, SHT_X86_64_UNWIND); + } + case Triple::mips: + case Triple::mipsel: + switch (Type) { + LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_REGINFO); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_OPTIONS); + } + } + + switch (Type) { + LLVM_READOBJ_ENUM_CASE(ELF, SHT_NULL ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_PROGBITS ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_STRTAB ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_RELA ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_HASH ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNAMIC ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOTE ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_NOBITS ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_REL ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_SHLIB ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_DYNSYM ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_INIT_ARRAY ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_FINI_ARRAY ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_PREINIT_ARRAY ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_GROUP ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_SYMTAB_SHNDX ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_ATTRIBUTES ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_HASH ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verdef ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_verneed ); + LLVM_READOBJ_ENUM_CASE(ELF, SHT_GNU_versym ); + default: return ""; + } +} + +static const EnumEntry ElfSectionFlags[] = { + LLVM_READOBJ_ENUM_ENT(ELF, SHF_WRITE ), + LLVM_READOBJ_ENUM_ENT(ELF, SHF_ALLOC ), + LLVM_READOBJ_ENUM_ENT(ELF, SHF_EXECINSTR ), + LLVM_READOBJ_ENUM_ENT(ELF, SHF_MERGE ), + LLVM_READOBJ_ENUM_ENT(ELF, SHF_STRINGS ), + LLVM_READOBJ_ENUM_ENT(ELF, SHF_INFO_LINK ), + LLVM_READOBJ_ENUM_ENT(ELF, SHF_LINK_ORDER ), + LLVM_READOBJ_ENUM_ENT(ELF, SHF_OS_NONCONFORMING), + LLVM_READOBJ_ENUM_ENT(ELF, SHF_GROUP ), + LLVM_READOBJ_ENUM_ENT(ELF, SHF_TLS ), + LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_CP_SECTION), + LLVM_READOBJ_ENUM_ENT(ELF, XCORE_SHF_DP_SECTION), + LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NOSTRIP ) +}; + + +template +void ELFDumper::printFileHeaders() { + error_code EC; + typedef ELFObjectFile ELFO; + + const typename ELFO::Elf_Ehdr *Header = Obj->getElfHeader(); + + { + DictScope D(W, "ElfHeader"); + { + DictScope D(W, "Ident"); + W.printBinary("Magic", makeArrayRef(Header->e_ident).slice(ELF::EI_MAG0, + 4)); + W.printEnum ("Class", Header->e_ident[ELF::EI_CLASS], + makeArrayRef(ElfClass)); + W.printEnum ("DataEncoding", Header->e_ident[ELF::EI_DATA], + makeArrayRef(ElfDataEncoding)); + W.printNumber("FileVersion", Header->e_ident[ELF::EI_VERSION]); + W.printEnum ("OS/ABI", Header->e_ident[ELF::EI_OSABI], + makeArrayRef(ElfOSABI)); + W.printNumber("ABIVersion", Header->e_ident[ELF::EI_ABIVERSION]); + W.printBinary("Unused", makeArrayRef(Header->e_ident).slice(ELF::EI_PAD)); + } + + W.printEnum ("Type", Header->e_type, makeArrayRef(ElfObjectFileType)); + W.printEnum ("Machine", Header->e_machine, makeArrayRef(ElfMachineType)); + W.printNumber("Version", Header->e_version); + W.printHex ("Entry", Header->e_entry); + W.printHex ("ProgramHeaderOffset", Header->e_phoff); + W.printHex ("SectionHeaderOffset", Header->e_shoff); + W.printFlags ("Flags", Header->e_flags); + W.printNumber("HeaderSize", Header->e_ehsize); + W.printNumber("ProgramHeaderEntrySize", Header->e_phentsize); + W.printNumber("ProgramHeaderCount", Header->e_phnum); + W.printNumber("SectionHeaderEntrySize", Header->e_shentsize); + W.printNumber("SectionHeaderCount", Header->e_shnum); + W.printNumber("StringTableSectionIndex", Header->e_shstrndx); + } +} + +template +void ELFDumper::printSections() { + ListScope SectionsD(W, "Sections"); + + int SectionIndex = -1; + error_code EC; + for (section_iterator SecI = Obj->begin_sections(), + SecE = Obj->end_sections(); + SecI != SecE; SecI.increment(EC)) { + if (error(EC)) break; + + ++SectionIndex; + + const Elf_Shdr *Section = Obj->getElfSection(SecI); + StringRef Name; + if (error(SecI->getName(Name))) + Name = ""; + + DictScope SectionD(W, "Section"); + W.printNumber("Index", SectionIndex); + W.printNumber("Name", Name, Section->sh_name); + W.printHex ("Type", getElfSectionType(Obj->getArch(), Section->sh_type), + Section->sh_type); + W.printFlags ("Flags", Section->sh_flags, makeArrayRef(ElfSectionFlags)); + W.printHex ("Address", Section->sh_addr); + W.printHex ("Offset", Section->sh_offset); + W.printNumber("Size", Section->sh_size); + W.printNumber("Link", Section->sh_link); + W.printNumber("Info", Section->sh_info); + W.printNumber("AddressAlignment", Section->sh_addralign); + W.printNumber("EntrySize", Section->sh_entsize); + + if (opts::SectionRelocations) { + ListScope D(W, "Relocations"); + for (relocation_iterator RelI = SecI->begin_relocations(), + RelE = SecI->end_relocations(); + RelI != RelE; RelI.increment(EC)) { + if (error(EC)) break; + + printRelocation(SecI, RelI); + } + } + + if (opts::SectionSymbols) { + ListScope D(W, "Symbols"); + for (symbol_iterator SymI = Obj->begin_symbols(), + SymE = Obj->end_symbols(); + SymI != SymE; SymI.increment(EC)) { + if (error(EC)) break; + + bool Contained = false; + if (SecI->containsSymbol(*SymI, Contained) || !Contained) + continue; + + printSymbol(SymI); + } + } + + if (opts::SectionData) { + StringRef Data; + if (error(SecI->getContents(Data))) break; + + W.printBinaryBlock("SectionData", Data); + } + } +} + +template +void ELFDumper::printRelocations() { + ListScope D(W, "Relocations"); + + error_code EC; + int SectionNumber = -1; + for (section_iterator SecI = Obj->begin_sections(), + SecE = Obj->end_sections(); + SecI != SecE; SecI.increment(EC)) { + if (error(EC)) break; + + ++SectionNumber; + StringRef Name; + if (error(SecI->getName(Name))) + continue; + + bool PrintedGroup = false; + for (relocation_iterator RelI = SecI->begin_relocations(), + RelE = SecI->end_relocations(); + RelI != RelE; RelI.increment(EC)) { + if (error(EC)) break; + + if (!PrintedGroup) { + W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n"; + W.indent(); + PrintedGroup = true; + } + + printRelocation(SecI, RelI); + } + + if (PrintedGroup) { + W.unindent(); + W.startLine() << "}\n"; + } + } +} + +template +void ELFDumper::printRelocation(section_iterator Sec, + relocation_iterator RelI) { + uint64_t Offset; + SmallString<32> RelocName; + int64_t Info; + StringRef SymbolName; + SymbolRef Symbol; + if (error(RelI->getOffset(Offset))) return; + if (error(RelI->getTypeName(RelocName))) return; + if (error(RelI->getAdditionalInfo(Info))) return; + if (error(RelI->getSymbol(Symbol))) return; + if (error(Symbol.getName(SymbolName))) return; + + raw_ostream& OS = W.startLine(); + OS << W.hex(Offset) + << " " << RelocName + << " " << (SymbolName.size() > 0 ? SymbolName : "-") + << " " << W.hex(Info) + << "\n"; +} + +template +void ELFDumper::printSymbols() { + ListScope Group(W, "Symbols"); + + error_code EC; + for (symbol_iterator SymI = Obj->begin_symbols(), SymE = Obj->end_symbols(); + SymI != SymE; SymI.increment(EC)) { + if (error(EC)) break; + + printSymbol(SymI); + } +} + +template +void ELFDumper::printDynamicSymbols() { + ListScope Group(W, "DynamicSymbols"); + + error_code EC; + for (symbol_iterator SymI = Obj->begin_dynamic_symbols(), + SymE = Obj->end_dynamic_symbols(); + SymI != SymE; SymI.increment(EC)) { + if (error(EC)) break; + + printSymbol(SymI, true); + } +} + +template +void ELFDumper::printSymbol(symbol_iterator SymI, bool IsDynamic) { + error_code EC; + + const Elf_Sym *Symbol = Obj->getElfSymbol(SymI); + const Elf_Shdr *Section = Obj->getSection(Symbol); + + StringRef SymbolName; + if (SymI->getName(SymbolName)) + SymbolName = ""; + + StringRef SectionName; + if (Section && Obj->getSectionName(Section, SectionName)) + SectionName = ""; + + std::string FullSymbolName(SymbolName); + if (IsDynamic) { + StringRef Version; + bool IsDefault; + if (error(Obj->getSymbolVersion(*SymI, Version, IsDefault))) + return; + if (!Version.empty()) { + FullSymbolName += (IsDefault ? "@@" : "@"); + FullSymbolName += Version; + } + } + + DictScope D(W, "Symbol"); + W.printNumber("Name", FullSymbolName, Symbol->st_name); + W.printHex ("Value", Symbol->st_value); + W.printNumber("Size", Symbol->st_size); + W.printEnum ("Binding", Symbol->getBinding(), + makeArrayRef(ElfSymbolBindings)); + W.printEnum ("Type", Symbol->getType(), makeArrayRef(ElfSymbolTypes)); + W.printNumber("Other", Symbol->st_other); + W.printHex ("Section", SectionName, Symbol->st_shndx); +} + +#define LLVM_READOBJ_TYPE_CASE(name) \ + case DT_##name: return #name + +static const char *getTypeString(uint64_t Type) { + switch (Type) { + LLVM_READOBJ_TYPE_CASE(BIND_NOW); + LLVM_READOBJ_TYPE_CASE(DEBUG); + LLVM_READOBJ_TYPE_CASE(FINI); + LLVM_READOBJ_TYPE_CASE(FINI_ARRAY); + LLVM_READOBJ_TYPE_CASE(FINI_ARRAYSZ); + LLVM_READOBJ_TYPE_CASE(FLAGS); + LLVM_READOBJ_TYPE_CASE(HASH); + LLVM_READOBJ_TYPE_CASE(INIT); + LLVM_READOBJ_TYPE_CASE(INIT_ARRAY); + LLVM_READOBJ_TYPE_CASE(INIT_ARRAYSZ); + LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAY); + LLVM_READOBJ_TYPE_CASE(PREINIT_ARRAYSZ); + LLVM_READOBJ_TYPE_CASE(JMPREL); + LLVM_READOBJ_TYPE_CASE(NEEDED); + LLVM_READOBJ_TYPE_CASE(NULL); + LLVM_READOBJ_TYPE_CASE(PLTGOT); + LLVM_READOBJ_TYPE_CASE(PLTREL); + LLVM_READOBJ_TYPE_CASE(PLTRELSZ); + LLVM_READOBJ_TYPE_CASE(REL); + LLVM_READOBJ_TYPE_CASE(RELA); + LLVM_READOBJ_TYPE_CASE(RELENT); + LLVM_READOBJ_TYPE_CASE(RELSZ); + LLVM_READOBJ_TYPE_CASE(RELAENT); + LLVM_READOBJ_TYPE_CASE(RELASZ); + LLVM_READOBJ_TYPE_CASE(RPATH); + LLVM_READOBJ_TYPE_CASE(RUNPATH); + LLVM_READOBJ_TYPE_CASE(SONAME); + LLVM_READOBJ_TYPE_CASE(STRSZ); + LLVM_READOBJ_TYPE_CASE(STRTAB); + LLVM_READOBJ_TYPE_CASE(SYMBOLIC); + LLVM_READOBJ_TYPE_CASE(SYMENT); + LLVM_READOBJ_TYPE_CASE(SYMTAB); + LLVM_READOBJ_TYPE_CASE(TEXTREL); + default: return "unknown"; + } +} + +#undef LLVM_READOBJ_TYPE_CASE + +template +static void printValue(const ELFObjectFile *O, uint64_t Type, + uint64_t Value, bool Is64, raw_ostream &OS) { + switch (Type) { + case DT_PLTREL: + if (Value == DT_REL) { + OS << "REL"; + break; + } else if (Value == DT_RELA) { + OS << "RELA"; + break; + } + // Fallthrough. + case DT_PLTGOT: + case DT_HASH: + case DT_STRTAB: + case DT_SYMTAB: + case DT_RELA: + case DT_INIT: + case DT_FINI: + case DT_REL: + case DT_JMPREL: + case DT_INIT_ARRAY: + case DT_FINI_ARRAY: + case DT_PREINIT_ARRAY: + case DT_DEBUG: + case DT_NULL: + OS << format("0x%" PRIX64, Value); + break; + case DT_PLTRELSZ: + case DT_RELASZ: + case DT_RELAENT: + case DT_STRSZ: + case DT_SYMENT: + case DT_RELSZ: + case DT_RELENT: + case DT_INIT_ARRAYSZ: + case DT_FINI_ARRAYSZ: + case DT_PREINIT_ARRAYSZ: + OS << Value << " (bytes)"; + break; + case DT_NEEDED: + OS << "SharedLibrary (" + << O->getString(O->getDynamicStringTableSectionHeader(), Value) << ")"; + break; + case DT_SONAME: + OS << "LibrarySoname (" + << O->getString(O->getDynamicStringTableSectionHeader(), Value) << ")"; + break; + } +} + +template +void ELFDumper::printUnwindInfo() { + W.startLine() << "UnwindInfo not implemented.\n"; +} + +template +void ELFDumper::printDynamicTable() { + typedef ELFObjectFile ELFO; + typedef typename ELFO::Elf_Dyn_iterator EDI; + EDI Start = Obj->begin_dynamic_table(), + End = Obj->end_dynamic_table(true); + + if (Start == End) + return; + + ptrdiff_t Total = std::distance(Start, End); + raw_ostream &OS = W.getOStream(); + W.startLine() << "DynamicSection [ (" << Total << " entries)\n"; + + bool Is64 = Obj->getBytesInAddress() == 8; + + W.startLine() + << " Tag" << (Is64 ? " " : " ") << "Type" + << " " << "Name/Value\n"; + for (; Start != End; ++Start) { + W.startLine() + << " " + << format(Is64 ? "0x%016" PRIX64 : "0x%08" PRIX64, Start->getTag()) + << " " << format("%-21s", getTypeString(Start->getTag())); + printValue(Obj, Start->getTag(), Start->getVal(), Is64, OS); + OS << "\n"; + } + + W.startLine() << "]\n"; +} + +static bool compareLibraryName(const LibraryRef &L, const LibraryRef &R) { + StringRef LPath, RPath; + L.getPath(LPath); + R.getPath(RPath); + return LPath < RPath; +} + +template +void ELFDumper::printNeededLibraries() { + ListScope D(W, "NeededLibraries"); + + error_code EC; + + typedef std::vector LibsTy; + LibsTy Libs; + + for (library_iterator I = Obj->begin_libraries_needed(), + E = Obj->end_libraries_needed(); + I != E; I.increment(EC)) { + if (EC) + report_fatal_error("Needed libraries iteration failed"); + + Libs.push_back(*I); + } + + std::sort(Libs.begin(), Libs.end(), &compareLibraryName); + + for (LibsTy::const_iterator I = Libs.begin(), E = Libs.end(); + I != E; ++I) { + StringRef Path; + I->getPath(Path); + outs() << " " << Path << "\n"; + } +} diff --git a/tools/llvm-readobj/Error.cpp b/tools/llvm-readobj/Error.cpp new file mode 100644 index 0000000000..a6c61321c6 --- /dev/null +++ b/tools/llvm-readobj/Error.cpp @@ -0,0 +1,62 @@ +//===- Error.cpp - system_error extensions for llvm-readobj -----*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This defines a new error_category for the llvm-readobj tool. +// +//===----------------------------------------------------------------------===// + +#include "Error.h" +#include "llvm/Support/ErrorHandling.h" + +using namespace llvm; + +namespace { +class _readobj_error_category : public _do_message { +public: + virtual const char* name() const; + virtual std::string message(int ev) const; + virtual error_condition default_error_condition(int ev) const; +}; +} // namespace + +const char *_readobj_error_category::name() const { + return "llvm.readobj"; +} + +std::string _readobj_error_category::message(int ev) const { + switch (ev) { + case readobj_error::success: return "Success"; + case readobj_error::file_not_found: + return "No such file."; + case readobj_error::unsupported_file_format: + return "The file was not recognized as a valid object file."; + case readobj_error::unrecognized_file_format: + return "Unrecognized file type."; + case readobj_error::unsupported_obj_file_format: + return "Unsupported object file format."; + case readobj_error::unknown_symbol: + return "Unknown symbol."; + default: + llvm_unreachable("An enumerator of readobj_error does not have a message " + "defined."); + } +} + +error_condition _readobj_error_category::default_error_condition(int ev) const { + if (ev == readobj_error::success) + return errc::success; + return errc::invalid_argument; +} + +namespace llvm { +const error_category &readobj_category() { + static _readobj_error_category o; + return o; +} +} // namespace llvm diff --git a/tools/llvm-readobj/Error.h b/tools/llvm-readobj/Error.h new file mode 100644 index 0000000000..cf68da89c1 --- /dev/null +++ b/tools/llvm-readobj/Error.h @@ -0,0 +1,48 @@ +//===- Error.h - system_error extensions for llvm-readobj -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This declares a new error_category for the llvm-readobj tool. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_READOBJ_ERROR_H +#define LLVM_READOBJ_ERROR_H + +#include "llvm/Support/system_error.h" + +namespace llvm { + +const error_category &readobj_category(); + +struct readobj_error { + enum _ { + success = 0, + file_not_found, + unsupported_file_format, + unrecognized_file_format, + unsupported_obj_file_format, + unknown_symbol + }; + _ v_; + + readobj_error(_ v) : v_(v) {} + explicit readobj_error(int v) : v_(_(v)) {} + operator int() const {return v_;} +}; + +inline error_code make_error_code(readobj_error e) { + return error_code(static_cast(e), readobj_category()); +} + +template <> struct is_error_code_enum : true_type { }; +template <> struct is_error_code_enum : true_type { }; + +} // namespace llvm + +#endif diff --git a/tools/llvm-readobj/LLVMBuild.txt b/tools/llvm-readobj/LLVMBuild.txt index c9f934f4b6..813c12b752 100644 --- a/tools/llvm-readobj/LLVMBuild.txt +++ b/tools/llvm-readobj/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Tool name = llvm-readobj parent = Tools -required_libraries = Archive BitReader Object +required_libraries = all-targets Archive BitReader Object diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp new file mode 100644 index 0000000000..798c941772 --- /dev/null +++ b/tools/llvm-readobj/MachODumper.cpp @@ -0,0 +1,438 @@ +//===-- MachODump.cpp - Object file 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 file implements the MachO-specific dumper for llvm-readobj. +// +//===----------------------------------------------------------------------===// + +#include "llvm-readobj.h" +#include "Error.h" +#include "ObjDumper.h" +#include "StreamWriter.h" + +#include "llvm/ADT/SmallString.h" +#include "llvm/Object/MachO.h" +#include "llvm/Support/Casting.h" + +using namespace llvm; +using namespace object; + +namespace { + +class MachODumper : public ObjDumper { +public: + MachODumper(const llvm::object::MachOObjectFile *Obj, StreamWriter& Writer) + : ObjDumper(Writer) + , Obj(Obj) { } + + virtual void printFileHeaders() LLVM_OVERRIDE; + virtual void printSections() LLVM_OVERRIDE; + virtual void printRelocations() LLVM_OVERRIDE; + virtual void printSymbols() LLVM_OVERRIDE; + virtual void printDynamicSymbols() LLVM_OVERRIDE; + virtual void printUnwindInfo() LLVM_OVERRIDE; + +private: + void printSymbol(symbol_iterator SymI); + + void printRelocation(section_iterator SecI, relocation_iterator RelI); + + const llvm::object::MachOObjectFile *Obj; +}; + +} // namespace + + +namespace llvm { + +error_code createMachODumper(const object::ObjectFile *Obj, + StreamWriter& Writer, + OwningPtr &Result) { + const MachOObjectFile *MachOObj = dyn_cast(Obj); + if (!MachOObj) + return readobj_error::unsupported_obj_file_format; + + Result.reset(new MachODumper(MachOObj, Writer)); + return readobj_error::success; +} + +} // namespace llvm + + +static const EnumEntry MachOSectionTypes[] = { + { "Regular" , 0x00 }, + { "ZeroFill" , 0x01 }, + { "CStringLiterals" , 0x02 }, + { "4ByteLiterals" , 0x03 }, + { "8ByteLiterals" , 0x04 }, + { "LiteralPointers" , 0x05 }, + { "NonLazySymbolPointers" , 0x06 }, + { "LazySymbolPointers" , 0x07 }, + { "SymbolStubs" , 0x08 }, + { "ModInitFuncs" , 0x09 }, + { "ModTermFuncs" , 0x0A }, + { "Coalesced" , 0x0B }, + { "GBZeroFill" , 0x0C }, + { "Interposing" , 0x0D }, + { "16ByteLiterals" , 0x0E }, + { "DTraceDOF" , 0x0F }, + { "LazyDylibSymbolPoints" , 0x10 }, + { "ThreadLocalRegular" , 0x11 }, + { "ThreadLocalZerofill" , 0x12 }, + { "ThreadLocalVariables" , 0x13 }, + { "ThreadLocalVariablePointers" , 0x14 }, + { "ThreadLocalInitFunctionPointers", 0x15 } +}; + +static const EnumEntry MachOSectionAttributes[] = { + { "LocReloc" , 1 << 0 /*S_ATTR_LOC_RELOC */ }, + { "ExtReloc" , 1 << 1 /*S_ATTR_EXT_RELOC */ }, + { "SomeInstructions" , 1 << 2 /*S_ATTR_SOME_INSTRUCTIONS */ }, + { "Debug" , 1 << 17 /*S_ATTR_DEBUG */ }, + { "SelfModifyingCode", 1 << 18 /*S_ATTR_SELF_MODIFYING_CODE*/ }, + { "LiveSupport" , 1 << 19 /*S_ATTR_LIVE_SUPPORT */ }, + { "NoDeadStrip" , 1 << 20 /*S_ATTR_NO_DEAD_STRIP */ }, + { "StripStaticSyms" , 1 << 21 /*S_ATTR_STRIP_STATIC_SYMS */ }, + { "NoTOC" , 1 << 22 /*S_ATTR_NO_TOC */ }, + { "PureInstructions" , 1 << 23 /*S_ATTR_PURE_INSTRUCTIONS */ }, +}; + +static const EnumEntry MachOSymbolRefTypes[] = { + { "UndefinedNonLazy", 0 }, + { "ReferenceFlagUndefinedLazy", 1 }, + { "ReferenceFlagDefined", 2 }, + { "ReferenceFlagPrivateDefined", 3 }, + { "ReferenceFlagPrivateUndefinedNonLazy", 4 }, + { "ReferenceFlagPrivateUndefinedLazy", 5 } +}; + +static const EnumEntry MachOSymbolFlags[] = { + { "ReferencedDynamically", 0x10 }, + { "NoDeadStrip", 0x20 }, + { "WeakRef", 0x40 }, + { "WeakDef", 0x80 } +}; + +static const EnumEntry MachOSymbolTypes[] = { + { "Undef", 0x0 }, + { "External", 0x1 }, + { "Abs", 0x2 }, + { "Indirect", 0xA }, + { "PreboundUndef", 0xC }, + { "Section", 0xE }, + { "PrivateExternal", 0x10 } +}; + +namespace { + enum { + N_STAB = 0xE0 + }; + + struct MachOSection { + ArrayRef Name; + ArrayRef SegmentName; + uint64_t Address; + uint64_t Size; + uint32_t Offset; + uint32_t Alignment; + uint32_t RelocationTableOffset; + uint32_t NumRelocationTableEntries; + uint32_t Flags; + uint32_t Reserved1; + uint32_t Reserved2; + }; + + struct MachOSymbol { + uint32_t StringIndex; + uint8_t Type; + uint8_t SectionIndex; + uint16_t Flags; + uint64_t Value; + }; +} + +static StringRef parseSegmentOrSectionName(ArrayRef P) { + if (P[15] == 0) + // Null terminated. + return StringRef(P.data()); + // Not null terminated, so this is a 16 char string. + return StringRef(P.data(), 16); +} + +static bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) { + LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); + if (LCI.Command.Type == macho::LCT_Segment64) + return true; + assert(LCI.Command.Type == macho::LCT_Segment && "Unexpected Type."); + return false; +} + +static void getSection(const MachOObject *MachOObj, + DataRefImpl DRI, + MachOSection &Section) { + LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); + if (is64BitLoadCommand(MachOObj, DRI)) { + InMemoryStruct Sect; + MachOObj->ReadSection64(LCI, DRI.d.b, Sect); + + Section.Name = ArrayRef(Sect->Name); + Section.SegmentName = ArrayRef(Sect->SegmentName); + Section.Address = Sect->Address; + Section.Size = Sect->Size; + Section.Offset = Sect->Offset; + Section.Alignment = Sect->Align; + Section.RelocationTableOffset = Sect->RelocationTableOffset; + Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries; + Section.Flags = Sect->Flags; + Section.Reserved1 = Sect->Reserved1; + Section.Reserved2 = Sect->Reserved2; + } else { + InMemoryStruct Sect; + MachOObj->ReadSection(LCI, DRI.d.b, Sect); + + Section.Name = Sect->Name; + Section.SegmentName = Sect->SegmentName; + Section.Address = Sect->Address; + Section.Size = Sect->Size; + Section.Offset = Sect->Offset; + Section.Alignment = Sect->Align; + Section.RelocationTableOffset = Sect->RelocationTableOffset; + Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries; + Section.Flags = Sect->Flags; + Section.Reserved1 = Sect->Reserved1; + Section.Reserved2 = Sect->Reserved2; + } +} + +static void getSymbolTableEntry(const MachOObject *MachO, + DataRefImpl DRI, + InMemoryStruct &Res) { + InMemoryStruct SymtabLoadCmd; + LoadCommandInfo LCI = MachO->getLoadCommandInfo(DRI.d.a); + MachO->ReadSymtabLoadCommand(LCI, SymtabLoadCmd); + MachO->ReadSymbolTableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b, Res); +} + +static void getSymbol64TableEntry(const MachOObject *MachO, + DataRefImpl DRI, + InMemoryStruct &Res) { + InMemoryStruct SymtabLoadCmd; + LoadCommandInfo LCI = MachO->getLoadCommandInfo(DRI.d.a); + MachO->ReadSymtabLoadCommand(LCI, SymtabLoadCmd); + MachO->ReadSymbol64TableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b, Res); +} + +static void getSymbol(const MachOObject *MachOObj, + DataRefImpl DRI, + MachOSymbol &Symbol) { + if (MachOObj->is64Bit()) { + InMemoryStruct Entry; + getSymbol64TableEntry(MachOObj, DRI, Entry); + Symbol.StringIndex = Entry->StringIndex; + Symbol.Type = Entry->Type; + Symbol.SectionIndex = Entry->SectionIndex; + Symbol.Flags = Entry->Flags; + Symbol.Value = Entry->Value; + } else { + InMemoryStruct Entry; + getSymbolTableEntry(MachOObj, DRI, Entry); + Symbol.StringIndex = Entry->StringIndex; + Symbol.Type = Entry->Type; + Symbol.SectionIndex = Entry->SectionIndex; + Symbol.Flags = Entry->Flags; + Symbol.Value = Entry->Value; + } +} + +void MachODumper::printFileHeaders() { + W.startLine() << "FileHeaders not implemented.\n"; +} + +void MachODumper::printSections() { + ListScope Group(W, "Sections"); + + int SectionIndex = -1; + error_code EC; + for (section_iterator SecI = Obj->begin_sections(), + SecE = Obj->end_sections(); + SecI != SecE; SecI.increment(EC)) { + if (error(EC)) break; + + ++SectionIndex; + + const MachOObject *MachO = const_cast(Obj)->getObject(); + + MachOSection Section; + getSection(MachO, SecI->getRawDataRefImpl(), Section); + StringRef Name; + if (error(SecI->getName(Name))) + Name = ""; + + DictScope SectionD(W, "Section"); + W.printNumber("Index", SectionIndex); + W.printBinary("Name", Name, Section.Name); + W.printBinary("Segment", parseSegmentOrSectionName(Section.SegmentName), + Section.SegmentName); + W.printHex ("Address", Section.Address); + W.printHex ("Size", Section.Size); + W.printNumber("Offset", Section.Offset); + W.printNumber("Alignment", Section.Alignment); + W.printHex ("RelocationOffset", Section.RelocationTableOffset); + W.printNumber("RelocationCount", Section.NumRelocationTableEntries); + W.printEnum ("Type", Section.Flags & 0xFF, + makeArrayRef(MachOSectionAttributes)); + W.printFlags ("Attributes", Section.Flags >> 8, + makeArrayRef(MachOSectionAttributes)); + W.printHex ("Reserved1", Section.Reserved1); + W.printHex ("Reserved2", Section.Reserved2); + + if (opts::SectionRelocations) { + ListScope D(W, "Relocations"); + for (relocation_iterator RelI = SecI->begin_relocations(), + RelE = SecI->end_relocations(); + RelI != RelE; RelI.increment(EC)) { + if (error(EC)) break; + + printRelocation(SecI, RelI); + } + } + + if (opts::SectionSymbols) { + ListScope D(W, "Symbols"); + for (symbol_iterator SymI = Obj->begin_symbols(), + SymE = Obj->end_symbols(); + SymI != SymE; SymI.increment(EC)) { + if (error(EC)) break; + + bool Contained = false; + if (SecI->containsSymbol(*SymI, Contained) || !Contained) + continue; + + printSymbol(SymI); + } + } + + if (opts::SectionData) { + StringRef Data; + if (error(SecI->getContents(Data))) break; + + W.printBinaryBlock("SectionData", Data); + } + } +} + +void MachODumper::printRelocations() { + ListScope D(W, "Relocations"); + + error_code EC; + for (section_iterator SecI = Obj->begin_sections(), + SecE = Obj->end_sections(); + SecI != SecE; SecI.increment(EC)) { + if (error(EC)) break; + + StringRef Name; + if (error(SecI->getName(Name))) + continue; + + bool PrintedGroup = false; + for (relocation_iterator RelI = SecI->begin_relocations(), + RelE = SecI->end_relocations(); + RelI != RelE; RelI.increment(EC)) { + if (error(EC)) break; + + if (!PrintedGroup) { + W.startLine() << "Section " << Name << " {\n"; + W.indent(); + PrintedGroup = true; + } + + printRelocation(SecI, RelI); + } + + if (PrintedGroup) { + W.unindent(); + W.startLine() << "}\n"; + } + } +} + +void MachODumper::printRelocation(section_iterator SecI, + relocation_iterator RelI) { + uint64_t Offset; + SmallString<32> RelocName; + int64_t Info; + StringRef SymbolName; + SymbolRef Symbol; + if (error(RelI->getOffset(Offset))) return; + if (error(RelI->getTypeName(RelocName))) return; + if (error(RelI->getAdditionalInfo(Info))) return; + if (error(RelI->getSymbol(Symbol))) return; + if (error(Symbol.getName(SymbolName))) return; + + raw_ostream& OS = W.startLine(); + OS << W.hex(Offset) + << " " << RelocName + << " " << (SymbolName.size() > 0 ? SymbolName : "-") + << " " << W.hex(Info) + << "\n"; +} + +void MachODumper::printSymbols() { + ListScope Group(W, "Symbols"); + + error_code EC; + for (symbol_iterator SymI = Obj->begin_symbols(), + SymE = Obj->end_symbols(); + SymI != SymE; SymI.increment(EC)) { + if (error(EC)) break; + + printSymbol(SymI); + } +} + +void MachODumper::printDynamicSymbols() { + ListScope Group(W, "DynamicSymbols"); +} + +void MachODumper::printSymbol(symbol_iterator SymI) { + error_code EC; + + StringRef SymbolName; + if (SymI->getName(SymbolName)) + SymbolName = ""; + + const MachOObject *MachO = const_cast(Obj)->getObject(); + + MachOSymbol Symbol; + getSymbol(MachO, SymI->getRawDataRefImpl(), Symbol); + + StringRef SectionName; + section_iterator SecI(Obj->end_sections()); + if (error(SymI->getSection(SecI)) || + error(SecI->getName(SectionName))) + SectionName = ""; + + DictScope D(W, "Symbol"); + W.printNumber("Name", SymbolName, Symbol.StringIndex); + if (Symbol.Type & N_STAB) { + W.printHex ("Type", "SymDebugTable", Symbol.Type); + } else { + W.printEnum("Type", Symbol.Type, makeArrayRef(MachOSymbolTypes)); + } + W.printHex ("Section", SectionName, Symbol.SectionIndex); + W.printEnum ("RefType", static_cast(Symbol.Flags & 0xF), + makeArrayRef(MachOSymbolRefTypes)); + W.printFlags ("Flags", static_cast(Symbol.Flags & ~0xF), + makeArrayRef(MachOSymbolFlags)); + W.printHex ("Value", Symbol.Value); +} + +void MachODumper::printUnwindInfo() { + W.startLine() << "UnwindInfo not implemented.\n"; +} diff --git a/tools/llvm-readobj/Makefile b/tools/llvm-readobj/Makefile index a7a7de3563..1bb72955f0 100644 --- a/tools/llvm-readobj/Makefile +++ b/tools/llvm-readobj/Makefile @@ -9,7 +9,7 @@ LEVEL := ../.. TOOLNAME := llvm-readobj -LINK_COMPONENTS := archive bitreader object +LINK_COMPONENTS := archive bitreader object all-targets # This tool has no plugins, optimize startup time. TOOL_NO_EXPORTS := 1 diff --git a/tools/llvm-readobj/ObjDumper.cpp b/tools/llvm-readobj/ObjDumper.cpp new file mode 100644 index 0000000000..61f511740a --- /dev/null +++ b/tools/llvm-readobj/ObjDumper.cpp @@ -0,0 +1,33 @@ +//===-- ObjDumper.cpp - Base dumper class -----------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// \brief This file implements ObjDumper. +/// +//===----------------------------------------------------------------------===// + +#include "ObjDumper.h" + +#include "Error.h" +#include "StreamWriter.h" + +#include "llvm/ADT/StringRef.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Support/raw_ostream.h" + +namespace llvm { + +ObjDumper::ObjDumper(StreamWriter& Writer) + : W(Writer) { +} + +ObjDumper::~ObjDumper() { +} + +} // namespace llvm diff --git a/tools/llvm-readobj/ObjDumper.h b/tools/llvm-readobj/ObjDumper.h new file mode 100644 index 0000000000..8d191cbe07 --- /dev/null +++ b/tools/llvm-readobj/ObjDumper.h @@ -0,0 +1,60 @@ +//===-- ObjDumper.h -------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_READOBJ_OBJDUMPER_H +#define LLVM_READOBJ_OBJDUMPER_H + +namespace llvm { + +namespace object { + class ObjectFile; +} + +class error_code; + +template +class OwningPtr; + +class StreamWriter; + +class ObjDumper { +public: + ObjDumper(StreamWriter& Writer); + virtual ~ObjDumper(); + + virtual void printFileHeaders() = 0; + virtual void printSections() = 0; + virtual void printRelocations() = 0; + virtual void printSymbols() = 0; + virtual void printDynamicSymbols() = 0; + virtual void printUnwindInfo() = 0; + + // Only implemented for ELF at this time. + virtual void printDynamicTable() { } + virtual void printNeededLibraries() { } + +protected: + StreamWriter& W; +}; + +error_code createCOFFDumper(const object::ObjectFile *Obj, + StreamWriter& Writer, + OwningPtr &Result); + +error_code createELFDumper(const object::ObjectFile *Obj, + StreamWriter& Writer, + OwningPtr &Result); + +error_code createMachODumper(const object::ObjectFile *Obj, + StreamWriter& Writer, + OwningPtr &Result); + +} // namespace llvm + +#endif diff --git a/tools/llvm-readobj/StreamWriter.cpp b/tools/llvm-readobj/StreamWriter.cpp new file mode 100644 index 0000000000..871811233a --- /dev/null +++ b/tools/llvm-readobj/StreamWriter.cpp @@ -0,0 +1,79 @@ +#include "StreamWriter.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/Support/Format.h" +#include + +using namespace llvm::support; + +namespace llvm { + +raw_ostream &operator<<(raw_ostream &OS, const HexNumber& Value) { + uint64_t N = Value.Value; + // Zero is a special case. + if (N == 0) + return OS << "0x0"; + + char NumberBuffer[20]; + char *EndPtr = NumberBuffer + sizeof(NumberBuffer); + char *CurPtr = EndPtr; + + while (N) { + uintptr_t X = N % 16; + *--CurPtr = (X < 10 ? '0' + X : 'A' + X - 10); + N /= 16; + } + + OS << "0x"; + return OS.write(CurPtr, EndPtr - CurPtr); +} + +void StreamWriter::printBinaryImpl(StringRef Label, StringRef Str, + ArrayRef Data, bool Block) { + if (Data.size() > 16) + Block = true; + + if (Block) { + startLine() << Label; + if (Str.size() > 0) + OS << ": " << Str; + OS << " (\n"; + for (size_t addr = 0, end = Data.size(); addr < end; addr += 16) { + startLine() << format(" %04" PRIX64 ": ", uint64_t(addr)); + // Dump line of hex. + for (size_t i = 0; i < 16; ++i) { + if (i != 0 && i % 4 == 0) + OS << ' '; + if (addr + i < end) + OS << hexdigit((Data[addr + i] >> 4) & 0xF, false) + << hexdigit(Data[addr + i] & 0xF, false); + else + OS << " "; + } + // Print ascii. + OS << " |"; + for (std::size_t i = 0; i < 16 && addr + i < end; ++i) { + if (std::isprint(Data[addr + i] & 0xFF)) + OS << Data[addr + i]; + else + OS << "."; + } + OS << "|\n"; + } + + startLine() << ")\n"; + } else { + startLine() << Label << ":"; + if (Str.size() > 0) + OS << " " << Str; + OS << " ("; + for (size_t i = 0; i < Data.size(); ++i) { + if (i > 0) + OS << " "; + + OS << format("%02X", static_cast(Data[i])); + } + OS << ")\n"; + } +} + +} // namespace llvm diff --git a/tools/llvm-readobj/StreamWriter.h b/tools/llvm-readobj/StreamWriter.h new file mode 100644 index 0000000000..129f6e7933 --- /dev/null +++ b/tools/llvm-readobj/StreamWriter.h @@ -0,0 +1,282 @@ +//===-- StreamWriter.h ----------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_READOBJ_STREAMWRITER_H +#define LLVM_READOBJ_STREAMWRITER_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/raw_ostream.h" +#include + +using namespace llvm; +using namespace llvm::support; + +namespace llvm { + +template +struct EnumEntry { + StringRef Name; + T Value; +}; + +struct HexNumber { + // To avoid sign-extension we have to explicitly cast to the appropriate + // unsigned type. The overloads are here so that every type that is implicitly + // convertible to an integer (including enums and endian helpers) can be used + // without requiring type traits or call-site changes. + HexNumber(int8_t Value) : Value(static_cast(Value)) { } + HexNumber(int16_t Value) : Value(static_cast(Value)) { } + HexNumber(int32_t Value) : Value(static_cast(Value)) { } + HexNumber(int64_t Value) : Value(static_cast(Value)) { } + HexNumber(uint8_t Value) : Value(Value) { } + HexNumber(uint16_t Value) : Value(Value) { } + HexNumber(uint32_t Value) : Value(Value) { } + HexNumber(uint64_t Value) : Value(Value) { } + uint64_t Value; +}; + +raw_ostream &operator<<(raw_ostream &OS, const HexNumber& Value); + +class StreamWriter { +public: + StreamWriter(raw_ostream &OS) + : OS(OS) + , IndentLevel(0) { + } + + void flush() { + OS.flush(); + } + + void indent(int Levels = 1) { + IndentLevel += Levels; + } + + void unindent(int Levels = 1) { + IndentLevel = std::max(0, IndentLevel - Levels); + } + + void printIndent() { + for (int i = 0; i < IndentLevel; ++i) + OS << " "; + } + + template + HexNumber hex(T Value) { + return HexNumber(Value); + } + + template + void printEnum(StringRef Label, T Value, + ArrayRef > EnumValues) { + StringRef Name; + bool Found = false; + for (size_t i = 0; i < EnumValues.size(); ++i) { + if (EnumValues[i].Value == Value) { + Name = EnumValues[i].Name; + Found = true; + break; + } + } + + if (Found) { + startLine() << Label << ": " << Name << " (" << hex(Value) << ")\n"; + } else { + startLine() << Label << ": " << hex(Value) << "\n"; + } + } + + template + void printFlags(StringRef Label, T Value, ArrayRef > Flags, + TFlag EnumMask = TFlag(0)) { + typedef EnumEntry FlagEntry; + typedef SmallVector FlagVector; + FlagVector SetFlags; + + for (typename ArrayRef::const_iterator I = Flags.begin(), + E = Flags.end(); I != E; ++I) { + if (I->Value == 0) + continue; + + bool IsEnum = (I->Value & EnumMask) != 0; + if ((!IsEnum && (Value & I->Value) == I->Value) || + (IsEnum && (Value & EnumMask) == I->Value)) { + SetFlags.push_back(*I); + } + } + + std::sort(SetFlags.begin(), SetFlags.end(), &flagName); + + startLine() << Label << " [ (" << hex(Value) << ")\n"; + for (typename FlagVector::const_iterator I = SetFlags.begin(), + E = SetFlags.end(); + I != E; ++I) { + startLine() << " " << I->Name << " (" << hex(I->Value) << ")\n"; + } + startLine() << "]\n"; + } + + template + void printFlags(StringRef Label, T Value) { + startLine() << Label << " [ (" << hex(Value) << ")\n"; + uint64_t Flag = 1; + uint64_t Curr = Value; + while (Curr > 0) { + if (Curr & 1) + startLine() << " " << hex(Flag) << "\n"; + Curr >>= 1; + Flag <<= 1; + } + startLine() << "]\n"; + } + + void printNumber(StringRef Label, uint64_t Value) { + startLine() << Label << ": " << Value << "\n"; + } + + void printNumber(StringRef Label, uint32_t Value) { + startLine() << Label << ": " << Value << "\n"; + } + + void printNumber(StringRef Label, uint16_t Value) { + startLine() << Label << ": " << Value << "\n"; + } + + void printNumber(StringRef Label, uint8_t Value) { + startLine() << Label << ": " << unsigned(Value) << "\n"; + } + + void printNumber(StringRef Label, int64_t Value) { + startLine() << Label << ": " << Value << "\n"; + } + + void printNumber(StringRef Label, int32_t Value) { + startLine() << Label << ": " << Value << "\n"; + } + + void printNumber(StringRef Label, int16_t Value) { + startLine() << Label << ": " << Value << "\n"; + } + + void printNumber(StringRef Label, int8_t Value) { + startLine() << Label << ": " << int(Value) << "\n"; + } + + template + void printHex(StringRef Label, T Value) { + startLine() << Label << ": " << hex(Value) << "\n"; + } + + template + void printHex(StringRef Label, StringRef Str, T Value) { + startLine() << Label << ": " << Str << " (" << hex(Value) << ")\n"; + } + + void printString(StringRef Label, StringRef Value) { + startLine() << Label << ": " << Value << "\n"; + } + + void printString(StringRef Label, const std::string &Value) { + startLine() << Label << ": " << Value << "\n"; + } + + template + void printNumber(StringRef Label, StringRef Str, T Value) { + startLine() << Label << ": " << Str << " (" << Value << ")\n"; + } + + void printBinary(StringRef Label, StringRef Str, ArrayRef Value) { + printBinaryImpl(Label, Str, Value, false); + } + + void printBinary(StringRef Label, StringRef Str, ArrayRef Value) { + ArrayRef V(reinterpret_cast(Value.data()), + Value.size()); + printBinaryImpl(Label, Str, V, false); + } + + void printBinary(StringRef Label, ArrayRef Value) { + printBinaryImpl(Label, StringRef(), Value, false); + } + + void printBinary(StringRef Label, ArrayRef Value) { + ArrayRef V(reinterpret_cast(Value.data()), + Value.size()); + printBinaryImpl(Label, StringRef(), V, false); + } + + void printBinary(StringRef Label, StringRef Value) { + ArrayRef V(reinterpret_cast(Value.data()), + Value.size()); + printBinaryImpl(Label, StringRef(), V, false); + } + + void printBinaryBlock(StringRef Label, StringRef Value) { + ArrayRef V(reinterpret_cast(Value.data()), + Value.size()); + printBinaryImpl(Label, StringRef(), V, true); + } + + raw_ostream& startLine() { + printIndent(); + return OS; + } + + raw_ostream& getOStream() { + return OS; + } + +private: + template + static bool flagName(const EnumEntry& lhs, const EnumEntry& rhs) { + return lhs.Name < rhs.Name; + } + + void printBinaryImpl(StringRef Label, StringRef Str, ArrayRef Value, + bool Block); + + raw_ostream &OS; + int IndentLevel; +}; + +struct DictScope { + DictScope(StreamWriter& W, StringRef N) : W(W) { + W.startLine() << N << " {\n"; + W.indent(); + } + + ~DictScope() { + W.unindent(); + W.startLine() << "}\n"; + } + + StreamWriter& W; +}; + +struct ListScope { + ListScope(StreamWriter& W, StringRef N) : W(W) { + W.startLine() << N << " [\n"; + W.indent(); + } + + ~ListScope() { + W.unindent(); + W.startLine() << "]\n"; + } + + StreamWriter& W; +}; + +} // namespace llvm + +#endif diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index ea37d105dc..67c9a98f40 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -21,268 +21,263 @@ #include "llvm-readobj.h" -#include "llvm/ADT/Triple.h" -#include "llvm/Analysis/Verifier.h" -#include "llvm/Object/ELF.h" +#include "Error.h" +#include "ObjDumper.h" +#include "StreamWriter.h" + +#include "llvm/Object/Archive.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/DataTypes.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/Format.h" -#include "llvm/Support/FormattedStream.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/ManagedStatic.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" +#include "llvm/Support/TargetRegistry.h" +#include "llvm/Support/TargetSelect.h" +#include "llvm/Support/system_error.h" + +#include + using namespace llvm; using namespace llvm::object; -static cl::opt -InputFilename(cl::Positional, cl::desc(""), cl::init("")); - -static void dumpSymbolHeader() { - outs() << format(" %-32s", (const char *)"Name") - << format(" %-4s", (const char *)"Type") - << format(" %-4s", (const char *)"Section") - << format(" %-16s", (const char *)"Address") - << format(" %-16s", (const char *)"Size") - << format(" %-16s", (const char *)"FileOffset") - << format(" %-26s", (const char *)"Flags") << "\n"; +namespace opts { + cl::list InputFilenames(cl::Positional, + cl::desc(""), + cl::ZeroOrMore); + + // -file-headers, -h + cl::opt FileHeaders("file-headers", + cl::desc("Display file headers ")); + cl::alias FileHeadersShort("h", + cl::desc("Alias for --file-headers"), + cl::aliasopt(FileHeaders)); + + // -sections, -s + cl::opt Sections("sections", + cl::desc("Display all sections.")); + cl::alias SectionsShort("s", + cl::desc("Alias for --sections"), + cl::aliasopt(Sections)); + + // -section-relocations, -sr + cl::opt SectionRelocations("section-relocations", + cl::desc("Display relocations for each section shown.")); + cl::alias SectionRelocationsShort("sr", + cl::desc("Alias for --section-relocations"), + cl::aliasopt(SectionRelocations)); + + // -section-symbols, -st + cl::opt SectionSymbols("section-symbols", + cl::desc("Display symbols for each section shown.")); + cl::alias SectionSymbolsShort("st", + cl::desc("Alias for --section-symbols"), + cl::aliasopt(SectionSymbols)); + + // -section-data, -sd + cl::opt SectionData("section-data", + cl::desc("Display section data for each section shown.")); + cl::alias SectionDataShort("sd", + cl::desc("Alias for --section-data"), + cl::aliasopt(SectionData)); + + // -relocations, -r + cl::opt Relocations("relocations", + cl::desc("Display the relocation entries in the file")); + cl::alias RelocationsShort("r", + cl::desc("Alias for --relocations"), + cl::aliasopt(Relocations)); + + // -symbols, -t + cl::opt Symbols("symbols", + cl::desc("Display the symbol table")); + cl::alias SymbolsShort("t", + cl::desc("Alias for --symbols"), + cl::aliasopt(Symbols)); + + // -dyn-symbols, -dt + cl::opt DynamicSymbols("dyn-symbols", + cl::desc("Display the dynamic symbol table")); + cl::alias DynamicSymbolsShort("dt", + cl::desc("Alias for --dyn-symbols"), + cl::aliasopt(DynamicSymbols)); + + // -unwind, -u + cl::opt UnwindInfo("unwind", + cl::desc("Display unwind information")); + cl::alias UnwindInfoShort("u", + cl::desc("Alias for --unwind"), + cl::aliasopt(UnwindInfo)); + + // -dynamic-table + cl::opt DynamicTable("dynamic-table", + cl::desc("Display the ELF .dynamic section table")); + + // -needed-libs + cl::opt NeededLibraries("needed-libs", + cl::desc("Display the needed libraries")); +} // namespace opts + +namespace llvm { + +bool error(error_code EC) { + if (!EC) + return false; + + outs() << "\nError reading file: " << EC.message() << ".\n"; + outs().flush(); + return true; } -static void dumpSectionHeader() { - outs() << format(" %-24s", (const char*)"Name") - << format(" %-16s", (const char*)"Address") - << format(" %-16s", (const char*)"Size") - << format(" %-8s", (const char*)"Align") - << format(" %-26s", (const char*)"Flags") - << "\n"; +bool relocAddressLess(RelocationRef a, RelocationRef b) { + uint64_t a_addr, b_addr; + if (error(a.getAddress(a_addr))) return false; + if (error(b.getAddress(b_addr))) return false; + return a_addr < b_addr; } -static const char *getTypeStr(SymbolRef::Type Type) { - switch (Type) { - case SymbolRef::ST_Unknown: return "?"; - case SymbolRef::ST_Data: return "DATA"; - case SymbolRef::ST_Debug: return "DBG"; - case SymbolRef::ST_File: return "FILE"; - case SymbolRef::ST_Function: return "FUNC"; - case SymbolRef::ST_Other: return "-"; - } - return "INV"; -} - -static std::string getSymbolFlagStr(uint32_t Flags) { - std::string result; - if (Flags & SymbolRef::SF_Undefined) - result += "undef,"; - if (Flags & SymbolRef::SF_Global) - result += "global,"; - if (Flags & SymbolRef::SF_Weak) - result += "weak,"; - if (Flags & SymbolRef::SF_Absolute) - result += "absolute,"; - if (Flags & SymbolRef::SF_ThreadLocal) - result += "threadlocal,"; - if (Flags & SymbolRef::SF_Common) - result += "common,"; - if (Flags & SymbolRef::SF_FormatSpecific) - result += "formatspecific,"; - - // Remove trailing comma - if (result.size() > 0) { - result.erase(result.size() - 1); - } - return result; -} +} // namespace llvm -static void checkError(error_code ec, const char *msg) { - if (ec) - report_fatal_error(std::string(msg) + ": " + ec.message()); -} -static std::string getSectionFlagStr(const SectionRef &Section) { - const struct { - error_code (SectionRef::*MemF)(bool &) const; - const char *FlagStr, *ErrorStr; - } Work[] = - {{ &SectionRef::isText, "text,", "Section.isText() failed" }, - { &SectionRef::isData, "data,", "Section.isData() failed" }, - { &SectionRef::isBSS, "bss,", "Section.isBSS() failed" }, - { &SectionRef::isRequiredForExecution, "required,", - "Section.isRequiredForExecution() failed" }, - { &SectionRef::isVirtual, "virtual,", "Section.isVirtual() failed" }, - { &SectionRef::isZeroInit, "zeroinit,", "Section.isZeroInit() failed" }, - { &SectionRef::isReadOnlyData, "rodata,", - "Section.isReadOnlyData() failed" }}; - - std::string result; - for (uint32_t I = 0; I < sizeof(Work)/sizeof(*Work); ++I) { - bool B; - checkError((Section.*Work[I].MemF)(B), Work[I].ErrorStr); - if (B) - result += Work[I].FlagStr; - } +static void reportError(StringRef Input, error_code EC) { + if (Input == "-") + Input = ""; - // Remove trailing comma - if (result.size() > 0) { - result.erase(result.size() - 1); - } - return result; + errs() << Input << ": " << EC.message() << "\n"; + errs().flush(); } -static void -dumpSymbol(const SymbolRef &Sym, const ObjectFile *obj, bool IsDynamic) { - StringRef Name; - SymbolRef::Type Type; - uint32_t Flags; - uint64_t Address; - uint64_t Size; - uint64_t FileOffset; - checkError(Sym.getName(Name), "SymbolRef.getName() failed"); - checkError(Sym.getAddress(Address), "SymbolRef.getAddress() failed"); - checkError(Sym.getSize(Size), "SymbolRef.getSize() failed"); - checkError(Sym.getFileOffset(FileOffset), - "SymbolRef.getFileOffset() failed"); - checkError(Sym.getType(Type), "SymbolRef.getType() failed"); - checkError(Sym.getFlags(Flags), "SymbolRef.getFlags() failed"); - std::string FullName = Name; - - llvm::object::section_iterator symSection(obj->begin_sections()); - Sym.getSection(symSection); - StringRef sectionName; - - if (symSection != obj->end_sections()) - checkError(symSection->getName(sectionName), - "SectionRef::getName() failed"); - - // If this is a dynamic symbol from an ELF object, append - // the symbol's version to the name. - if (IsDynamic && obj->isELF()) { - StringRef Version; - bool IsDefault; - GetELFSymbolVersion(obj, Sym, Version, IsDefault); - if (!Version.empty()) { - FullName += (IsDefault ? "@@" : "@"); - FullName += Version; - } - } +static void reportError(StringRef Input, StringRef Message) { + if (Input == "-") + Input = ""; - // format() can't handle StringRefs - outs() << format(" %-32s", FullName.c_str()) - << format(" %-4s", getTypeStr(Type)) - << format(" %-32s", std::string(sectionName).c_str()) - << format(" %16" PRIx64, Address) << format(" %16" PRIx64, Size) - << format(" %16" PRIx64, FileOffset) << " " - << getSymbolFlagStr(Flags) << "\n"; + errs() << Input << ": " << Message << "\n"; } -static void dumpStaticSymbol(const SymbolRef &Sym, const ObjectFile *obj) { - return dumpSymbol(Sym, obj, false); +/// @brief Creates an format-specific object file dumper. +static error_code createDumper(const ObjectFile *Obj, + StreamWriter &Writer, + OwningPtr &Result) { + if (!Obj) + return readobj_error::unsupported_file_format; + + if (Obj->isCOFF()) + return createCOFFDumper(Obj, Writer, Result); + if (Obj->isELF()) + return createELFDumper(Obj, Writer, Result); + if (Obj->isMachO()) + return createMachODumper(Obj, Writer, Result); + + return readobj_error::unsupported_obj_file_format; } -static void dumpDynamicSymbol(const SymbolRef &Sym, const ObjectFile *obj) { - return dumpSymbol(Sym, obj, true); -} - -static void dumpSection(const SectionRef &Section, const ObjectFile *obj) { - StringRef Name; - checkError(Section.getName(Name), "SectionRef::getName() failed"); - uint64_t Addr, Size, Align; - checkError(Section.getAddress(Addr), "SectionRef::getAddress() failed"); - checkError(Section.getSize(Size), "SectionRef::getSize() failed"); - checkError(Section.getAlignment(Align), "SectionRef::getAlignment() failed"); - outs() << format(" %-24s", std::string(Name).c_str()) - << format(" %16" PRIx64, Addr) - << format(" %16" PRIx64, Size) - << format(" %8" PRIx64, Align) - << " " << getSectionFlagStr(Section) - << "\n"; -} -static void dumpLibrary(const LibraryRef &lib, const ObjectFile *obj) { - StringRef path; - lib.getPath(path); - outs() << " " << path << "\n"; -} - -template -static void dump(const ObjectFile *obj, Func f, Iterator begin, Iterator end, - const char *errStr) { - error_code ec; - uint32_t count = 0; - Iterator it = begin, ie = end; - while (it != ie) { - f(*it, obj); - it.increment(ec); - if (ec) - report_fatal_error(errStr); - ++count; +/// @brief Dumps the specified object file. +static void dumpObject(const ObjectFile *Obj) { + StreamWriter Writer(outs()); + OwningPtr Dumper; + if (error_code EC = createDumper(Obj, Writer, Dumper)) { + reportError(Obj->getFileName(), EC); + return; } - outs() << " Total: " << count << "\n\n"; -} -static void dumpHeaders(const ObjectFile *obj) { - outs() << "File Format : " << obj->getFileFormatName() << "\n"; - outs() << "Arch : " - << Triple::getArchTypeName((llvm::Triple::ArchType)obj->getArch()) + outs() << '\n'; + outs() << "File: " << Obj->getFileName() << "\n"; + outs() << "Format: " << Obj->getFileFormatName() << "\n"; + outs() << "Arch: " + << Triple::getArchTypeName((llvm::Triple::ArchType)Obj->getArch()) << "\n"; - outs() << "Address Size: " << (8*obj->getBytesInAddress()) << " bits\n"; - outs() << "Load Name : " << obj->getLoadName() << "\n"; - outs() << "\n"; + outs() << "AddressSize: " << (8*Obj->getBytesInAddress()) << "bit\n"; + if (Obj->isELF()) + outs() << "LoadName: " << Obj->getLoadName() << "\n"; + + if (opts::FileHeaders) + Dumper->printFileHeaders(); + if (opts::Sections) + Dumper->printSections(); + if (opts::Relocations) + Dumper->printRelocations(); + if (opts::Symbols) + Dumper->printSymbols(); + if (opts::DynamicSymbols) + Dumper->printDynamicSymbols(); + if (opts::UnwindInfo) + Dumper->printUnwindInfo(); + if (opts::DynamicTable) + Dumper->printDynamicTable(); + if (opts::NeededLibraries) + Dumper->printNeededLibraries(); } -int main(int argc, char** argv) { - error_code ec; - sys::PrintStackTraceOnErrorSignal(); - PrettyStackTraceProgram X(argc, argv); - cl::ParseCommandLineOptions(argc, argv, - "LLVM Object Reader\n"); +/// @brief Dumps each object file in \a Arc; +static void dumpArchive(const Archive *Arc) { + for (Archive::child_iterator ArcI = Arc->begin_children(), + ArcE = Arc->end_children(); + ArcI != ArcE; ++ArcI) { + OwningPtr child; + if (error_code EC = ArcI->getAsBinary(child)) { + // Ignore non-object files. + if (EC != object_error::invalid_file_type) + reportError(Arc->getFileName(), EC.message()); + continue; + } - if (InputFilename.empty()) { - errs() << "Please specify an input filename\n"; - return 1; + if (ObjectFile *Obj = dyn_cast(child.get())) + dumpObject(Obj); + else + reportError(Arc->getFileName(), readobj_error::unrecognized_file_format); } +} + - // Open the object file - OwningPtr File; - if (MemoryBuffer::getFile(InputFilename, File)) { - errs() << InputFilename << ": Open failed\n"; - return 1; +/// @brief Opens \a File and dumps it. +static void dumpInput(StringRef File) { + // If file isn't stdin, check that it exists. + if (File != "-" && !sys::fs::exists(File)) { + reportError(File, readobj_error::file_not_found); + return; } - OwningPtr o(ObjectFile::createObjectFile(File.take())); - ObjectFile *obj = o.get(); - if (!obj) { - errs() << InputFilename << ": Object type not recognized\n"; + // Attempt to open the binary. + OwningPtr Binary; + if (error_code EC = createBinary(File, Binary)) { + reportError(File, EC); + return; } - dumpHeaders(obj); + if (Archive *Arc = dyn_cast(Binary.get())) + dumpArchive(Arc); + else if (ObjectFile *Obj = dyn_cast(Binary.get())) + dumpObject(Obj); + else + reportError(File, readobj_error::unrecognized_file_format); +} - outs() << "Symbols:\n"; - dumpSymbolHeader(); - dump(obj, dumpStaticSymbol, obj->begin_symbols(), obj->end_symbols(), - "Symbol iteration failed"); - outs() << "Dynamic Symbols:\n"; - dumpSymbolHeader(); - dump(obj, dumpDynamicSymbol, obj->begin_dynamic_symbols(), - obj->end_dynamic_symbols(), "Symbol iteration failed"); +int main(int argc, const char *argv[]) { + sys::PrintStackTraceOnErrorSignal(); + PrettyStackTraceProgram X(argc, argv); + llvm_shutdown_obj Y; - outs() << "Sections:\n"; - dumpSectionHeader(); - dump(obj, &dumpSection, obj->begin_sections(), obj->end_sections(), - "Section iteration failed"); + // Initialize targets. + llvm::InitializeAllTargetInfos(); - if (obj->isELF()) { - if (ErrorOr e = dumpELFDynamicTable(obj, outs())) - ; - else - errs() << "InputFilename" << ": " << error_code(e).message() << "\n"; - } + // Register the target printer for --version. + cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); + + cl::ParseCommandLineOptions(argc, argv, "LLVM Object Reader\n"); - outs() << "Libraries needed:\n"; - dump(obj, &dumpLibrary, obj->begin_libraries_needed(), - obj->end_libraries_needed(), "Needed libraries iteration failed"); + // Default to stdin if no filename is specified. + if (opts::InputFilenames.size() == 0) + opts::InputFilenames.push_back("-"); + + std::for_each(opts::InputFilenames.begin(), opts::InputFilenames.end(), + dumpInput); return 0; } - diff --git a/tools/llvm-readobj/llvm-readobj.h b/tools/llvm-readobj/llvm-readobj.h index cf492b2a8d..be18268a7f 100644 --- a/tools/llvm-readobj/llvm-readobj.h +++ b/tools/llvm-readobj/llvm-readobj.h @@ -1,4 +1,4 @@ -//===- llvm-readobj.h - Dump contents of an Object File -------------------===// +//===-- llvm-readobj.h ----------------------------------------------------===// // // The LLVM Compiler Infrastructure // @@ -10,13 +10,36 @@ #ifndef LLVM_TOOLS_READ_OBJ_H #define LLVM_TOOLS_READ_OBJ_H -#include "llvm/Support/ErrorOr.h" +#include "llvm/Support/CommandLine.h" +#include namespace llvm { -namespace object { class ObjectFile; } -class raw_ostream; + namespace object { + class RelocationRef; + } -ErrorOr dumpELFDynamicTable(object::ObjectFile *O, raw_ostream &OS); -} // end namespace llvm + class error_code; + + // Various helper functions. + bool error(error_code ec); + bool relocAddressLess(object::RelocationRef A, + object::RelocationRef B); +} // namespace llvm + +namespace opts { + extern llvm::cl::list InputFilenames; + extern llvm::cl::opt FileHeaders; + extern llvm::cl::opt Sections; + extern llvm::cl::opt SectionRelocations; + extern llvm::cl::opt SectionSymbols; + extern llvm::cl::opt SectionData; + extern llvm::cl::opt Relocations; + extern llvm::cl::opt Symbols; + extern llvm::cl::opt DynamicSymbols; + extern llvm::cl::opt UnwindInfo; +} // namespace opts + +#define LLVM_READOBJ_ENUM_ENT(ns, enum) \ + { #enum, ns::enum } #endif -- cgit v1.2.3-18-g5258 From 436633e2a281ff620f2f4d9a06b33d3a99924717 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 4 Apr 2013 01:01:32 +0000 Subject: Don't export symbols in every binary on linux. On freebsd this makes sure that symbols are exported on the binaries that need them. The net result is that we should get symbols in the binaries that need them on every platform. On linux x86-64 this reduces the size of the bin directory from 262MB to 250MB. Patch by Stephen Checkoway. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178725 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/bugpoint/CMakeLists.txt | 1 + tools/opt/CMakeLists.txt | 1 + 2 files changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/bugpoint/CMakeLists.txt b/tools/bugpoint/CMakeLists.txt index e990cfcbba..0000d977ac 100644 --- a/tools/bugpoint/CMakeLists.txt +++ b/tools/bugpoint/CMakeLists.txt @@ -12,3 +12,4 @@ add_llvm_tool(bugpoint ToolRunner.cpp bugpoint.cpp ) +set_target_properties(bugpoint PROPERTIES ENABLE_EXPORTS 1) diff --git a/tools/opt/CMakeLists.txt b/tools/opt/CMakeLists.txt index 1ff8efbed0..91959119e4 100644 --- a/tools/opt/CMakeLists.txt +++ b/tools/opt/CMakeLists.txt @@ -6,3 +6,4 @@ add_llvm_tool(opt PrintSCC.cpp opt.cpp ) +set_target_properties(opt PROPERTIES ENABLE_EXPORTS 1) -- cgit v1.2.3-18-g5258 From 46af06799732192ec7c8d0cc76ea151874b51129 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 5 Apr 2013 02:57:22 +0000 Subject: Move obj2yaml to tools to sort out make's dependencies. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178835 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/CMakeLists.txt | 2 + tools/Makefile | 2 +- tools/obj2yaml/CMakeLists.txt | 7 + tools/obj2yaml/Makefile | 20 +++ tools/obj2yaml/coff2yaml.cpp | 361 ++++++++++++++++++++++++++++++++++++++++++ tools/obj2yaml/obj2yaml.cpp | 86 ++++++++++ tools/obj2yaml/obj2yaml.h | 34 ++++ 7 files changed, 511 insertions(+), 1 deletion(-) create mode 100644 tools/obj2yaml/CMakeLists.txt create mode 100644 tools/obj2yaml/Makefile create mode 100644 tools/obj2yaml/coff2yaml.cpp create mode 100644 tools/obj2yaml/obj2yaml.cpp create mode 100644 tools/obj2yaml/obj2yaml.h (limited to 'tools') diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 5e9560491e..9b80ee5a23 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -43,6 +43,8 @@ add_subdirectory(llvm-mcmarkup) add_subdirectory(llvm-symbolizer) +add_subdirectory(obj2yaml) + if( NOT WIN32 ) add_subdirectory(lto) endif() diff --git a/tools/Makefile b/tools/Makefile index c405868cea..b8f21d2ce1 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -35,7 +35,7 @@ PARALLEL_DIRS := opt llvm-as llvm-dis \ llvm-diff macho-dump llvm-objdump llvm-readobj \ llvm-rtdyld llvm-dwarfdump llvm-cov \ llvm-size llvm-stress llvm-mcmarkup \ - llvm-symbolizer + llvm-symbolizer obj2yaml # If Intel JIT Events support is configured, build an extra tool to test it. ifeq ($(USE_INTEL_JITEVENTS), 1) diff --git a/tools/obj2yaml/CMakeLists.txt b/tools/obj2yaml/CMakeLists.txt new file mode 100644 index 0000000000..d64bf1bad8 --- /dev/null +++ b/tools/obj2yaml/CMakeLists.txt @@ -0,0 +1,7 @@ +set(LLVM_LINK_COMPONENTS archive object) + +add_llvm_utility(obj2yaml + obj2yaml.cpp coff2yaml.cpp + ) + +target_link_libraries(obj2yaml LLVMSupport) diff --git a/tools/obj2yaml/Makefile b/tools/obj2yaml/Makefile new file mode 100644 index 0000000000..95f393ddd6 --- /dev/null +++ b/tools/obj2yaml/Makefile @@ -0,0 +1,20 @@ +##===- utils/obj2yaml/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 = obj2yaml +LINK_COMPONENTS := object + +# This tool has no plugins, optimize startup time. +TOOL_NO_EXPORTS = 1 + +# Don't install this utility +NO_INSTALL = 1 + +include $(LEVEL)/Makefile.common diff --git a/tools/obj2yaml/coff2yaml.cpp b/tools/obj2yaml/coff2yaml.cpp new file mode 100644 index 0000000000..f0241d931e --- /dev/null +++ b/tools/obj2yaml/coff2yaml.cpp @@ -0,0 +1,361 @@ +//===------ utils/obj2yaml.cpp - obj2yaml conversion tool -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "obj2yaml.h" +#include "llvm/Object/COFF.h" + + +template +struct pod_pair { // I'd much rather use std::pair, but it's not a POD + One first; + Two second; +}; + +#define STRING_PAIR(x) {llvm::COFF::x, #x} +static const pod_pair +MachineTypePairs [] = { + STRING_PAIR(IMAGE_FILE_MACHINE_UNKNOWN), + STRING_PAIR(IMAGE_FILE_MACHINE_AM33), + STRING_PAIR(IMAGE_FILE_MACHINE_AMD64), + STRING_PAIR(IMAGE_FILE_MACHINE_ARM), + STRING_PAIR(IMAGE_FILE_MACHINE_ARMV7), + STRING_PAIR(IMAGE_FILE_MACHINE_EBC), + STRING_PAIR(IMAGE_FILE_MACHINE_I386), + STRING_PAIR(IMAGE_FILE_MACHINE_IA64), + STRING_PAIR(IMAGE_FILE_MACHINE_M32R), + STRING_PAIR(IMAGE_FILE_MACHINE_MIPS16), + STRING_PAIR(IMAGE_FILE_MACHINE_MIPSFPU), + STRING_PAIR(IMAGE_FILE_MACHINE_MIPSFPU16), + STRING_PAIR(IMAGE_FILE_MACHINE_POWERPC), + STRING_PAIR(IMAGE_FILE_MACHINE_POWERPCFP), + STRING_PAIR(IMAGE_FILE_MACHINE_R4000), + STRING_PAIR(IMAGE_FILE_MACHINE_SH3), + STRING_PAIR(IMAGE_FILE_MACHINE_SH3DSP), + STRING_PAIR(IMAGE_FILE_MACHINE_SH4), + STRING_PAIR(IMAGE_FILE_MACHINE_SH5), + STRING_PAIR(IMAGE_FILE_MACHINE_THUMB), + STRING_PAIR(IMAGE_FILE_MACHINE_WCEMIPSV2) +}; + +static const pod_pair +SectionCharacteristicsPairs1 [] = { + STRING_PAIR(IMAGE_SCN_TYPE_NO_PAD), + STRING_PAIR(IMAGE_SCN_CNT_CODE), + STRING_PAIR(IMAGE_SCN_CNT_INITIALIZED_DATA), + STRING_PAIR(IMAGE_SCN_CNT_UNINITIALIZED_DATA), + STRING_PAIR(IMAGE_SCN_LNK_OTHER), + STRING_PAIR(IMAGE_SCN_LNK_INFO), + STRING_PAIR(IMAGE_SCN_LNK_REMOVE), + STRING_PAIR(IMAGE_SCN_LNK_COMDAT), + STRING_PAIR(IMAGE_SCN_GPREL), + STRING_PAIR(IMAGE_SCN_MEM_PURGEABLE), + STRING_PAIR(IMAGE_SCN_MEM_16BIT), + STRING_PAIR(IMAGE_SCN_MEM_LOCKED), + STRING_PAIR(IMAGE_SCN_MEM_PRELOAD) +}; + +static const pod_pair +SectionCharacteristicsPairsAlignment [] = { + STRING_PAIR(IMAGE_SCN_ALIGN_1BYTES), + STRING_PAIR(IMAGE_SCN_ALIGN_2BYTES), + STRING_PAIR(IMAGE_SCN_ALIGN_4BYTES), + STRING_PAIR(IMAGE_SCN_ALIGN_8BYTES), + STRING_PAIR(IMAGE_SCN_ALIGN_16BYTES), + STRING_PAIR(IMAGE_SCN_ALIGN_32BYTES), + STRING_PAIR(IMAGE_SCN_ALIGN_64BYTES), + STRING_PAIR(IMAGE_SCN_ALIGN_128BYTES), + STRING_PAIR(IMAGE_SCN_ALIGN_256BYTES), + STRING_PAIR(IMAGE_SCN_ALIGN_512BYTES), + STRING_PAIR(IMAGE_SCN_ALIGN_1024BYTES), + STRING_PAIR(IMAGE_SCN_ALIGN_2048BYTES), + STRING_PAIR(IMAGE_SCN_ALIGN_4096BYTES), + STRING_PAIR(IMAGE_SCN_ALIGN_8192BYTES) +}; + +static const pod_pair +SectionCharacteristicsPairs2 [] = { + STRING_PAIR(IMAGE_SCN_LNK_NRELOC_OVFL), + STRING_PAIR(IMAGE_SCN_MEM_DISCARDABLE), + STRING_PAIR(IMAGE_SCN_MEM_NOT_CACHED), + STRING_PAIR(IMAGE_SCN_MEM_NOT_PAGED), + STRING_PAIR(IMAGE_SCN_MEM_SHARED), + STRING_PAIR(IMAGE_SCN_MEM_EXECUTE), + STRING_PAIR(IMAGE_SCN_MEM_READ), + STRING_PAIR(IMAGE_SCN_MEM_WRITE) +}; + +static const pod_pair +SymbolBaseTypePairs [] = { + STRING_PAIR(IMAGE_SYM_TYPE_NULL), + STRING_PAIR(IMAGE_SYM_TYPE_VOID), + STRING_PAIR(IMAGE_SYM_TYPE_CHAR), + STRING_PAIR(IMAGE_SYM_TYPE_SHORT), + STRING_PAIR(IMAGE_SYM_TYPE_INT), + STRING_PAIR(IMAGE_SYM_TYPE_LONG), + STRING_PAIR(IMAGE_SYM_TYPE_FLOAT), + STRING_PAIR(IMAGE_SYM_TYPE_DOUBLE), + STRING_PAIR(IMAGE_SYM_TYPE_STRUCT), + STRING_PAIR(IMAGE_SYM_TYPE_UNION), + STRING_PAIR(IMAGE_SYM_TYPE_ENUM), + STRING_PAIR(IMAGE_SYM_TYPE_MOE), + STRING_PAIR(IMAGE_SYM_TYPE_BYTE), + STRING_PAIR(IMAGE_SYM_TYPE_WORD), + STRING_PAIR(IMAGE_SYM_TYPE_UINT), + STRING_PAIR(IMAGE_SYM_TYPE_DWORD) +}; + +static const pod_pair +SymbolComplexTypePairs [] = { + STRING_PAIR(IMAGE_SYM_DTYPE_NULL), + STRING_PAIR(IMAGE_SYM_DTYPE_POINTER), + STRING_PAIR(IMAGE_SYM_DTYPE_FUNCTION), + STRING_PAIR(IMAGE_SYM_DTYPE_ARRAY), +}; + +static const pod_pair +SymbolStorageClassPairs [] = { + STRING_PAIR(IMAGE_SYM_CLASS_END_OF_FUNCTION), + STRING_PAIR(IMAGE_SYM_CLASS_NULL), + STRING_PAIR(IMAGE_SYM_CLASS_AUTOMATIC), + STRING_PAIR(IMAGE_SYM_CLASS_EXTERNAL), + STRING_PAIR(IMAGE_SYM_CLASS_STATIC), + STRING_PAIR(IMAGE_SYM_CLASS_REGISTER), + STRING_PAIR(IMAGE_SYM_CLASS_EXTERNAL_DEF), + STRING_PAIR(IMAGE_SYM_CLASS_LABEL), + STRING_PAIR(IMAGE_SYM_CLASS_UNDEFINED_LABEL), + STRING_PAIR(IMAGE_SYM_CLASS_MEMBER_OF_STRUCT), + STRING_PAIR(IMAGE_SYM_CLASS_ARGUMENT), + STRING_PAIR(IMAGE_SYM_CLASS_STRUCT_TAG), + STRING_PAIR(IMAGE_SYM_CLASS_MEMBER_OF_UNION), + STRING_PAIR(IMAGE_SYM_CLASS_UNION_TAG), + STRING_PAIR(IMAGE_SYM_CLASS_TYPE_DEFINITION), + STRING_PAIR(IMAGE_SYM_CLASS_UNDEFINED_STATIC), + STRING_PAIR(IMAGE_SYM_CLASS_ENUM_TAG), + STRING_PAIR(IMAGE_SYM_CLASS_MEMBER_OF_ENUM), + STRING_PAIR(IMAGE_SYM_CLASS_REGISTER_PARAM), + STRING_PAIR(IMAGE_SYM_CLASS_BIT_FIELD), + STRING_PAIR(IMAGE_SYM_CLASS_BLOCK), + STRING_PAIR(IMAGE_SYM_CLASS_FUNCTION), + STRING_PAIR(IMAGE_SYM_CLASS_END_OF_STRUCT), + STRING_PAIR(IMAGE_SYM_CLASS_FILE), + STRING_PAIR(IMAGE_SYM_CLASS_SECTION), + STRING_PAIR(IMAGE_SYM_CLASS_WEAK_EXTERNAL), + STRING_PAIR(IMAGE_SYM_CLASS_CLR_TOKEN), +}; + +static const pod_pair +RelocationTypeX86Pairs [] = { + STRING_PAIR(IMAGE_REL_I386_ABSOLUTE), + STRING_PAIR(IMAGE_REL_I386_DIR16), + STRING_PAIR(IMAGE_REL_I386_REL16), + STRING_PAIR(IMAGE_REL_I386_DIR32), + STRING_PAIR(IMAGE_REL_I386_DIR32NB), + STRING_PAIR(IMAGE_REL_I386_SEG12), + STRING_PAIR(IMAGE_REL_I386_SECTION), + STRING_PAIR(IMAGE_REL_I386_SECREL), + STRING_PAIR(IMAGE_REL_I386_TOKEN), + STRING_PAIR(IMAGE_REL_I386_SECREL7), + STRING_PAIR(IMAGE_REL_I386_REL32), + STRING_PAIR(IMAGE_REL_AMD64_ABSOLUTE), + STRING_PAIR(IMAGE_REL_AMD64_ADDR64), + STRING_PAIR(IMAGE_REL_AMD64_ADDR32), + STRING_PAIR(IMAGE_REL_AMD64_ADDR32NB), + STRING_PAIR(IMAGE_REL_AMD64_REL32), + STRING_PAIR(IMAGE_REL_AMD64_REL32_1), + STRING_PAIR(IMAGE_REL_AMD64_REL32_2), + STRING_PAIR(IMAGE_REL_AMD64_REL32_3), + STRING_PAIR(IMAGE_REL_AMD64_REL32_4), + STRING_PAIR(IMAGE_REL_AMD64_REL32_5), + STRING_PAIR(IMAGE_REL_AMD64_SECTION), + STRING_PAIR(IMAGE_REL_AMD64_SECREL), + STRING_PAIR(IMAGE_REL_AMD64_SECREL7), + STRING_PAIR(IMAGE_REL_AMD64_TOKEN), + STRING_PAIR(IMAGE_REL_AMD64_SREL32), + STRING_PAIR(IMAGE_REL_AMD64_PAIR), + STRING_PAIR(IMAGE_REL_AMD64_SSPAN32) +}; + +static const pod_pair +RelocationTypesARMPairs [] = { + STRING_PAIR(IMAGE_REL_ARM_ABSOLUTE), + STRING_PAIR(IMAGE_REL_ARM_ADDR32), + STRING_PAIR(IMAGE_REL_ARM_ADDR32NB), + STRING_PAIR(IMAGE_REL_ARM_BRANCH24), + STRING_PAIR(IMAGE_REL_ARM_BRANCH11), + STRING_PAIR(IMAGE_REL_ARM_TOKEN), + STRING_PAIR(IMAGE_REL_ARM_BLX24), + STRING_PAIR(IMAGE_REL_ARM_BLX11), + STRING_PAIR(IMAGE_REL_ARM_SECTION), + STRING_PAIR(IMAGE_REL_ARM_SECREL), + STRING_PAIR(IMAGE_REL_ARM_MOV32A), + STRING_PAIR(IMAGE_REL_ARM_MOV32T), + STRING_PAIR(IMAGE_REL_ARM_BRANCH20T), + STRING_PAIR(IMAGE_REL_ARM_BRANCH24T), + STRING_PAIR(IMAGE_REL_ARM_BLX23T) +}; +#undef STRING_PAIR + + +static const char endl = '\n'; + +namespace yaml { // COFF-specific yaml-writing specific routines + +static llvm::raw_ostream &writeName(llvm::raw_ostream &Out, + const char *Name, std::size_t NameSize) { + for (std::size_t i = 0; i < NameSize; ++i) { + if (!Name[i]) break; + Out << Name[i]; + } + return Out; +} + +// Given an array of pod_pair, write all enums that match +template +static llvm::raw_ostream &writeBitMask(llvm::raw_ostream &Out, + const pod_pair (&Arr)[N], unsigned long Val) { + for (std::size_t i = 0; i < N; ++i) + if (Val & Arr[i].first) + Out << Arr[i].second << ", "; + return Out; +} + +} // end of yaml namespace + +// Given an array of pod_pair, look up a value +template +const char *nameLookup(const pod_pair (&Arr)[N], + unsigned long Val, const char *NotFound = NULL) { + T n = static_cast(Val); + for (std::size_t i = 0; i < N; ++i) + if (n == Arr[i].first) + return Arr[i].second; + return NotFound; +} + + +static llvm::raw_ostream &yamlCOFFHeader( + const llvm::object::coff_file_header *Header,llvm::raw_ostream &Out) { + + Out << "header: !Header" << endl; + Out << " Machine: "; + Out << nameLookup(MachineTypePairs, Header->Machine, "# Unknown_MachineTypes") + << " # ("; + return yaml::writeHexNumber(Out, Header->Machine) << ")" << endl << endl; +} + + +static llvm::raw_ostream &yamlCOFFSections(llvm::object::COFFObjectFile &Obj, + std::size_t NumSections, llvm::raw_ostream &Out) { + llvm::error_code ec; + Out << "sections:" << endl; + for (llvm::object::section_iterator iter = Obj.begin_sections(); + iter != Obj.end_sections(); iter.increment(ec)) { + const llvm::object::coff_section *sect = Obj.getCOFFSection(iter); + + Out << " - !Section" << endl; + Out << " Name: "; + yaml::writeName(Out, sect->Name, sizeof(sect->Name)) << endl; + + Out << " Characteristics: ["; + yaml::writeBitMask(Out, SectionCharacteristicsPairs1, sect->Characteristics); + Out << nameLookup(SectionCharacteristicsPairsAlignment, + sect->Characteristics & 0x00F00000, "# Unrecognized_IMAGE_SCN_ALIGN") + << ", "; + yaml::writeBitMask(Out, SectionCharacteristicsPairs2, sect->Characteristics); + Out << "] # "; + yaml::writeHexNumber(Out, sect->Characteristics) << endl; + + llvm::ArrayRef sectionData; + Obj.getSectionContents(sect, sectionData); + Out << " SectionData: "; + yaml::writeHexStream(Out, sectionData) << endl; + if (iter->begin_relocations() != iter->end_relocations()) + Out << " Relocations:\n"; + for (llvm::object::relocation_iterator rIter = iter->begin_relocations(); + rIter != iter->end_relocations(); rIter.increment(ec)) { + const llvm::object::coff_relocation *reloc = Obj.getCOFFRelocation(rIter); + + Out << " - !Relocation" << endl; + Out << " VirtualAddress: " ; + yaml::writeHexNumber(Out, reloc->VirtualAddress) << endl; + Out << " SymbolTableIndex: " << reloc->SymbolTableIndex << endl; + Out << " Type: " + << nameLookup(RelocationTypeX86Pairs, reloc->Type) << endl; + // TODO: Use the correct reloc type for the machine. + Out << endl; + } + + } + return Out; +} + +static llvm::raw_ostream& yamlCOFFSymbols(llvm::object::COFFObjectFile &Obj, + std::size_t NumSymbols, llvm::raw_ostream &Out) { + llvm::error_code ec; + Out << "symbols:" << endl; + for (llvm::object::symbol_iterator iter = Obj.begin_symbols(); + iter != Obj.end_symbols(); iter.increment(ec)) { + // Gather all the info that we need + llvm::StringRef str; + const llvm::object::coff_symbol *symbol = Obj.getCOFFSymbol(iter); + Obj.getSymbolName(symbol, str); + std::size_t simpleType = symbol->getBaseType(); + std::size_t complexType = symbol->getComplexType(); + std::size_t storageClass = symbol->StorageClass; + + Out << " - !Symbol" << endl; + Out << " Name: " << str << endl; + + Out << " Value: " << symbol->Value << endl; + Out << " SectionNumber: " << symbol->SectionNumber << endl; + + Out << " SimpleType: " + << nameLookup(SymbolBaseTypePairs, simpleType, + "# Unknown_SymbolBaseType") + << " # (" << simpleType << ")" << endl; + + Out << " ComplexType: " + << nameLookup(SymbolComplexTypePairs, complexType, + "# Unknown_SymbolComplexType") + << " # (" << complexType << ")" << endl; + + Out << " StorageClass: " + << nameLookup(SymbolStorageClassPairs, storageClass, + "# Unknown_StorageClass") + << " # (" << (int) storageClass << ")" << endl; + + if (symbol->NumberOfAuxSymbols > 0) { + llvm::ArrayRef aux = Obj.getSymbolAuxData(symbol); + Out << " NumberOfAuxSymbols: " + << (int) symbol->NumberOfAuxSymbols << endl; + Out << " AuxillaryData: "; + yaml::writeHexStream(Out, aux); + } + + Out << endl; + } + + return Out; +} + + +llvm::error_code coff2yaml(llvm::raw_ostream &Out, llvm::MemoryBuffer *TheObj) { + llvm::error_code ec; + llvm::object::COFFObjectFile obj(TheObj, ec); + if (!ec) { + const llvm::object::coff_file_header *hd; + ec = obj.getHeader(hd); + if (!ec) { + yamlCOFFHeader(hd, Out); + yamlCOFFSections(obj, hd->NumberOfSections, Out); + yamlCOFFSymbols(obj, hd->NumberOfSymbols, Out); + } + } + return ec; +} diff --git a/tools/obj2yaml/obj2yaml.cpp b/tools/obj2yaml/obj2yaml.cpp new file mode 100644 index 0000000000..bdc461a947 --- /dev/null +++ b/tools/obj2yaml/obj2yaml.cpp @@ -0,0 +1,86 @@ +//===------ utils/obj2yaml.cpp - obj2yaml conversion tool -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "obj2yaml.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/Object/Archive.h" +#include "llvm/Object/COFF.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/Signals.h" + +const char endl = '\n'; + +namespace yaml { // generic yaml-writing specific routines + +unsigned char printable(unsigned char Ch) { + return Ch >= ' ' && Ch <= '~' ? Ch : '.'; +} + +llvm::raw_ostream &writeHexStream(llvm::raw_ostream &Out, + const llvm::ArrayRef arr) { + const char *hex = "0123456789ABCDEF"; + Out << " !hex \""; + + typedef llvm::ArrayRef::const_iterator iter_t; + const iter_t end = arr.end(); + for (iter_t iter = arr.begin(); iter != end; ++iter) + Out << hex[(*iter >> 4) & 0x0F] << hex[(*iter & 0x0F)]; + + Out << "\" # |"; + for (iter_t iter = arr.begin(); iter != end; ++iter) + Out << printable(*iter); + Out << "|" << endl; + + return Out; + } + +llvm::raw_ostream &writeHexNumber(llvm::raw_ostream &Out, unsigned long long N) { + if (N >= 10) + Out << "0x"; + Out.write_hex(N); + return Out; +} + +} + + +using namespace llvm; +enum ObjectFileType { coff }; + +cl::opt InputFormat( + cl::desc("Choose input format"), + cl::values( + clEnumVal(coff, "process COFF object files"), + clEnumValEnd)); + +cl::opt InputFilename(cl::Positional, cl::desc(""), cl::init("-")); + +int main(int argc, char * argv[]) { + cl::ParseCommandLineOptions(argc, argv); + sys::PrintStackTraceOnErrorSignal(); + PrettyStackTraceProgram X(argc, argv); + llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + +// Process the input file + OwningPtr buf; + +// TODO: If this is an archive, then burst it and dump each entry + if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, buf)) + llvm::errs() << "Error: '" << ec.message() << "' opening file '" + << InputFilename << "'" << endl; + else { + ec = coff2yaml(llvm::outs(), buf.take()); + if (ec) + llvm::errs() << "Error: " << ec.message() << " dumping COFF file" << endl; + } + + return 0; +} diff --git a/tools/obj2yaml/obj2yaml.h b/tools/obj2yaml/obj2yaml.h new file mode 100644 index 0000000000..0bc376a6db --- /dev/null +++ b/tools/obj2yaml/obj2yaml.h @@ -0,0 +1,34 @@ +//===------ utils/obj2yaml.hpp - obj2yaml conversion tool -------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +// This file declares some helper routines, and also the format-specific +// writers. To add a new format, add the declaration here, and, in a separate +// source file, implement it. +//===----------------------------------------------------------------------===// + +#ifndef LLVM_UTILS_OBJ2YAML_H +#define LLVM_UTILS_OBJ2YAML_H + +#include "llvm/ADT/ArrayRef.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/system_error.h" + +namespace yaml { // routines for writing YAML +// Write a hex stream: +// !hex: "" #|\n + llvm::raw_ostream &writeHexStream + (llvm::raw_ostream &Out, const llvm::ArrayRef arr); + +// Writes a number in hex; prefix it by 0x if it is >= 10 + llvm::raw_ostream &writeHexNumber + (llvm::raw_ostream &Out, unsigned long long N); +} + +llvm::error_code coff2yaml(llvm::raw_ostream &Out, llvm::MemoryBuffer *TheObj); + +#endif -- cgit v1.2.3-18-g5258 From ef148afba873b1e24af1b3c22148f967b9b8a232 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Fri, 5 Apr 2013 09:22:24 +0000 Subject: llvm-symbolizer: correctly parse filenames given in quotes git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178859 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-symbolizer/llvm-symbolizer.cpp | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/llvm-symbolizer/llvm-symbolizer.cpp b/tools/llvm-symbolizer/llvm-symbolizer.cpp index d039ec691f..0cafffaf71 100644 --- a/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -70,12 +70,25 @@ static bool parseCommand(bool &IsData, std::string &ModuleName, // If no cmd, assume it's CODE. IsData = false; } - // FIXME: Handle case when filename is given in quotes. - if (char *FilePath = strtok(pos, kDelimiters)) { - ModuleName = FilePath; - if (char *OffsetStr = strtok((char *)0, kDelimiters)) - ModuleOffsetStr = OffsetStr; + // Skip delimiters and parse input filename. + pos += strspn(pos, kDelimiters); + if (*pos == '"' || *pos == '\'') { + char quote = *pos; + pos++; + char *end = strchr(pos, quote); + if (end == 0) + return false; + ModuleName = std::string(pos, end - pos); + pos = end + 1; + } else { + int name_length = strcspn(pos, kDelimiters); + ModuleName = std::string(pos, name_length); + pos += name_length; } + // Skip delimiters and parse module offset. + pos += strspn(pos, kDelimiters); + int offset_length = strcspn(pos, kDelimiters); + ModuleOffsetStr = std::string(pos, offset_length); if (StringRef(ModuleOffsetStr).getAsInteger(0, ModuleOffset)) return false; return true; -- cgit v1.2.3-18-g5258 From f16c2bb320f4d5b33dfaf8df8865f547e6d66005 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 5 Apr 2013 15:15:22 +0000 Subject: Don't fetch pointers from a InMemoryStruct. InMemoryStruct is extremely dangerous as it returns data from an internal buffer when the endiannes doesn't match. This should fix the tests on big endian hosts. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178875 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/MachODump.cpp | 5 ++--- tools/llvm-objdump/llvm-objdump.cpp | 7 ++----- tools/llvm-readobj/MachODumper.cpp | 23 ++++++++--------------- 3 files changed, 12 insertions(+), 23 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index c324ff13a6..e9d2b3b1a8 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -337,10 +337,9 @@ void llvm::DisassembleInputMachO(StringRef Filename) { SectName != "__text") continue; // Skip non-text sections - StringRef SegmentName; DataRefImpl DR = Sections[SectIdx].getRawDataRefImpl(); - if (MachOOF->getSectionFinalSegmentName(DR, SegmentName) || - SegmentName != "__TEXT") + StringRef SegmentName = MachOOF->getSectionFinalSegmentName(DR); + if (SegmentName != "__TEXT") continue; // Insert the functions from the function starts segment into our map. diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 7832cf0dff..9a36e8253d 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -257,8 +257,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { StringRef SegmentName = ""; if (const MachOObjectFile *MachO = dyn_cast(Obj)) { DataRefImpl DR = i->getRawDataRefImpl(); - if (error(MachO->getSectionFinalSegmentName(DR, SegmentName))) - break; + SegmentName = MachO->getSectionFinalSegmentName(DR); } StringRef name; if (error(i->getName(name))) break; @@ -593,10 +592,8 @@ static void PrintSymbolTable(const ObjectFile *o) { outs() << "*UND*"; else { if (const MachOObjectFile *MachO = dyn_cast(o)) { - StringRef SegmentName; DataRefImpl DR = Section->getRawDataRefImpl(); - if (error(MachO->getSectionFinalSegmentName(DR, SegmentName))) - SegmentName = ""; + StringRef SegmentName = MachO->getSectionFinalSegmentName(DR); outs() << SegmentName << ","; } StringRef SectionName; diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index 798c941772..0354e767ba 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -157,14 +157,6 @@ namespace { }; } -static StringRef parseSegmentOrSectionName(ArrayRef P) { - if (P[15] == 0) - // Null terminated. - return StringRef(P.data()); - // Not null terminated, so this is a 16 char string. - return StringRef(P.data(), 16); -} - static bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) { LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); if (LCI.Command.Type == macho::LCT_Segment64) @@ -181,8 +173,6 @@ static void getSection(const MachOObject *MachOObj, InMemoryStruct Sect; MachOObj->ReadSection64(LCI, DRI.d.b, Sect); - Section.Name = ArrayRef(Sect->Name); - Section.SegmentName = ArrayRef(Sect->SegmentName); Section.Address = Sect->Address; Section.Size = Sect->Size; Section.Offset = Sect->Offset; @@ -196,8 +186,6 @@ static void getSection(const MachOObject *MachOObj, InMemoryStruct Sect; MachOObj->ReadSection(LCI, DRI.d.b, Sect); - Section.Name = Sect->Name; - Section.SegmentName = Sect->SegmentName; Section.Address = Sect->Address; Section.Size = Sect->Size; Section.Offset = Sect->Offset; @@ -270,15 +258,20 @@ void MachODumper::printSections() { MachOSection Section; getSection(MachO, SecI->getRawDataRefImpl(), Section); + DataRefImpl DR = SecI->getRawDataRefImpl(); + StringRef Name; if (error(SecI->getName(Name))) Name = ""; + ArrayRef RawName = Obj->getSectionRawName(DR); + StringRef SegmentName = Obj->getSectionFinalSegmentName(DR); + ArrayRef RawSegmentName = Obj->getSectionRawFinalSegmentName(DR); + DictScope SectionD(W, "Section"); W.printNumber("Index", SectionIndex); - W.printBinary("Name", Name, Section.Name); - W.printBinary("Segment", parseSegmentOrSectionName(Section.SegmentName), - Section.SegmentName); + W.printBinary("Name", Name, RawName); + W.printBinary("Segment", SegmentName, RawSegmentName); W.printHex ("Address", Section.Address); W.printHex ("Size", Section.Size); W.printNumber("Offset", Section.Offset); -- cgit v1.2.3-18-g5258 From 3440d0b857fa6def37c1a4185ac9602be2393c9c Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 5 Apr 2013 15:31:16 +0000 Subject: Fix include guards to match new location. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178877 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/obj2yaml/obj2yaml.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/obj2yaml/obj2yaml.h b/tools/obj2yaml/obj2yaml.h index 0bc376a6db..b4a012607a 100644 --- a/tools/obj2yaml/obj2yaml.h +++ b/tools/obj2yaml/obj2yaml.h @@ -10,8 +10,8 @@ // source file, implement it. //===----------------------------------------------------------------------===// -#ifndef LLVM_UTILS_OBJ2YAML_H -#define LLVM_UTILS_OBJ2YAML_H +#ifndef LLVM_TOOLS_OBJ2YAML_H +#define LLVM_TOOLS_OBJ2YAML_H #include "llvm/ADT/ArrayRef.h" #include "llvm/Support/MemoryBuffer.h" -- cgit v1.2.3-18-g5258 From 3455b32b3e795ea27a31b6cb1c225812515e3e2c Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 5 Apr 2013 20:00:35 +0000 Subject: Move yaml2obj to tools too. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178904 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/CMakeLists.txt | 1 + tools/Makefile | 2 +- tools/yaml2obj/CMakeLists.txt | 5 + tools/yaml2obj/Makefile | 20 ++ tools/yaml2obj/yaml2obj.cpp | 707 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 734 insertions(+), 1 deletion(-) create mode 100644 tools/yaml2obj/CMakeLists.txt create mode 100644 tools/yaml2obj/Makefile create mode 100644 tools/yaml2obj/yaml2obj.cpp (limited to 'tools') diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 9b80ee5a23..6b7c884516 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -44,6 +44,7 @@ add_subdirectory(llvm-mcmarkup) add_subdirectory(llvm-symbolizer) add_subdirectory(obj2yaml) +add_subdirectory(yaml2obj) if( NOT WIN32 ) add_subdirectory(lto) diff --git a/tools/Makefile b/tools/Makefile index b8f21d2ce1..eaf9ed3577 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -35,7 +35,7 @@ PARALLEL_DIRS := opt llvm-as llvm-dis \ llvm-diff macho-dump llvm-objdump llvm-readobj \ llvm-rtdyld llvm-dwarfdump llvm-cov \ llvm-size llvm-stress llvm-mcmarkup \ - llvm-symbolizer obj2yaml + llvm-symbolizer obj2yaml yaml2obj # If Intel JIT Events support is configured, build an extra tool to test it. ifeq ($(USE_INTEL_JITEVENTS), 1) diff --git a/tools/yaml2obj/CMakeLists.txt b/tools/yaml2obj/CMakeLists.txt new file mode 100644 index 0000000000..f8b1197524 --- /dev/null +++ b/tools/yaml2obj/CMakeLists.txt @@ -0,0 +1,5 @@ +add_llvm_utility(yaml2obj + yaml2obj.cpp + ) + +target_link_libraries(yaml2obj LLVMSupport) diff --git a/tools/yaml2obj/Makefile b/tools/yaml2obj/Makefile new file mode 100644 index 0000000000..cb6f47724b --- /dev/null +++ b/tools/yaml2obj/Makefile @@ -0,0 +1,20 @@ +##===- utils/yaml2obj/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 = yaml2obj +LINK_COMPONENTS := support + +# This tool has no plugins, optimize startup time. +TOOL_NO_EXPORTS = 1 + +# Don't install this utility +NO_INSTALL = 1 + +include $(LEVEL)/Makefile.common diff --git a/tools/yaml2obj/yaml2obj.cpp b/tools/yaml2obj/yaml2obj.cpp new file mode 100644 index 0000000000..191c49fb59 --- /dev/null +++ b/tools/yaml2obj/yaml2obj.cpp @@ -0,0 +1,707 @@ +//===- yaml2obj - Convert YAML to a binary object file --------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This program takes a YAML description of an object file and outputs the +// binary equivalent. +// +// This is used for writing tests that require binary files. +// +//===----------------------------------------------------------------------===// + +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/COFF.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/YAMLTraits.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/system_error.h" +#include + +using namespace llvm; + +static cl::opt + Input(cl::Positional, cl::desc(""), cl::init("-")); + +template +typename llvm::enable_if_c::is_integer, bool>::type +getAs(const llvm::yaml::ScalarNode *SN, T &Result) { + SmallString<4> Storage; + StringRef Value = SN->getValue(Storage); + if (Value.getAsInteger(0, Result)) + return false; + return true; +} + +// Given a container with begin and end with ::value_type of a character type. +// Iterate through pairs of characters in the the set of [a-fA-F0-9] ignoring +// all other characters. +struct hex_pair_iterator { + StringRef::const_iterator Current, End; + typedef SmallVector value_type; + value_type Pair; + bool IsDone; + + hex_pair_iterator(StringRef C) + : Current(C.begin()), End(C.end()), IsDone(false) { + // Initalize Pair. + ++*this; + } + + // End iterator. + hex_pair_iterator() : Current(), End(), IsDone(true) {} + + value_type operator *() const { + return Pair; + } + + hex_pair_iterator operator ++() { + // We're at the end of the input. + if (Current == End) { + IsDone = true; + return *this; + } + Pair = value_type(); + for (; Current != End && Pair.size() != 2; ++Current) { + // Is a valid hex digit. + if ((*Current >= '0' && *Current <= '9') || + (*Current >= 'a' && *Current <= 'f') || + (*Current >= 'A' && *Current <= 'F')) + Pair.push_back(*Current); + } + // Hit the end without getting 2 hex digits. Pair is invalid. + if (Pair.size() != 2) + IsDone = true; + return *this; + } + + bool operator ==(const hex_pair_iterator Other) { + return (IsDone == Other.IsDone) || + (Current == Other.Current && End == Other.End); + } + + bool operator !=(const hex_pair_iterator Other) { + return !(*this == Other); + } +}; + +template +static bool hexStringToByteArray(StringRef Str, ContainerOut &Out) { + for (hex_pair_iterator I(Str), E; I != E; ++I) { + typename hex_pair_iterator::value_type Pair = *I; + typename ContainerOut::value_type Byte; + if (StringRef(Pair.data(), 2).getAsInteger(16, Byte)) + return false; + Out.push_back(Byte); + } + return true; +} + +// The structure of the yaml files is not an exact 1:1 match to COFF. In order +// to use yaml::IO, we use these structures which are closer to the source. +namespace COFFYAML { + struct Relocation { + uint32_t VirtualAddress; + uint32_t SymbolTableIndex; + COFF::RelocationTypeX86 Type; + }; + + struct Section { + COFF::SectionCharacteristics Characteristics; + StringRef SectionData; + std::vector Relocations; + StringRef Name; + }; + + struct Header { + COFF::MachineTypes Machine; + COFF::Characteristics Characteristics; + }; + + struct Symbol { + COFF::SymbolBaseType SimpleType; + uint8_t NumberOfAuxSymbols; + StringRef Name; + COFF::SymbolStorageClass StorageClass; + StringRef AuxillaryData; + COFF::SymbolComplexType ComplexType; + uint32_t Value; + uint16_t SectionNumber; + }; + + struct Object { + Header HeaderData; + std::vector
Sections; + std::vector Symbols; + }; +} + +/// This parses a yaml stream that represents a COFF object file. +/// See docs/yaml2obj for the yaml scheema. +struct COFFParser { + COFFParser(COFFYAML::Object &Obj) : Obj(Obj) { + std::memset(&Header, 0, sizeof(Header)); + // A COFF string table always starts with a 4 byte size field. Offsets into + // it include this size, so allocate it now. + StringTable.append(4, 0); + } + + void parseHeader() { + Header.Machine = Obj.HeaderData.Machine; + Header.Characteristics = Obj.HeaderData.Characteristics; + } + + bool parseSections() { + for (std::vector::iterator i = Obj.Sections.begin(), + e = Obj.Sections.end(); i != e; ++i) { + const COFFYAML::Section &YamlSection = *i; + Section Sec; + std::memset(&Sec.Header, 0, sizeof(Sec.Header)); + + // If the name is less than 8 bytes, store it in place, otherwise + // store it in the string table. + StringRef Name = YamlSection.Name; + std::fill_n(Sec.Header.Name, unsigned(COFF::NameSize), 0); + if (Name.size() <= COFF::NameSize) { + std::copy(Name.begin(), Name.end(), Sec.Header.Name); + } else { + // Add string to the string table and format the index for output. + unsigned Index = getStringIndex(Name); + std::string str = utostr(Index); + if (str.size() > 7) { + errs() << "String table got too large"; + return false; + } + Sec.Header.Name[0] = '/'; + std::copy(str.begin(), str.end(), Sec.Header.Name + 1); + } + + Sec.Header.Characteristics = YamlSection.Characteristics; + + StringRef Data = YamlSection.SectionData; + if (!hexStringToByteArray(Data, Sec.Data)) { + errs() << "SectionData must be a collection of pairs of hex bytes"; + return false; + } + Sections.push_back(Sec); + } + return true; + } + + bool parseSymbols() { + for (std::vector::iterator i = Obj.Symbols.begin(), + e = Obj.Symbols.end(); i != e; ++i) { + COFFYAML::Symbol YamlSymbol = *i; + Symbol Sym; + std::memset(&Sym.Header, 0, sizeof(Sym.Header)); + + // If the name is less than 8 bytes, store it in place, otherwise + // store it in the string table. + StringRef Name = YamlSymbol.Name; + std::fill_n(Sym.Header.Name, unsigned(COFF::NameSize), 0); + if (Name.size() <= COFF::NameSize) { + std::copy(Name.begin(), Name.end(), Sym.Header.Name); + } else { + // Add string to the string table and format the index for output. + unsigned Index = getStringIndex(Name); + *reinterpret_cast( + Sym.Header.Name + 4) = Index; + } + + Sym.Header.Value = YamlSymbol.Value; + Sym.Header.Type |= YamlSymbol.SimpleType; + Sym.Header.Type |= YamlSymbol.ComplexType << COFF::SCT_COMPLEX_TYPE_SHIFT; + Sym.Header.StorageClass = YamlSymbol.StorageClass; + Sym.Header.SectionNumber = YamlSymbol.SectionNumber; + + StringRef Data = YamlSymbol.AuxillaryData; + if (!hexStringToByteArray(Data, Sym.AuxSymbols)) { + errs() << "AuxillaryData must be a collection of pairs of hex bytes"; + return false; + } + Symbols.push_back(Sym); + } + return true; + } + + bool parse() { + parseHeader(); + if (!parseSections()) + return false; + if (!parseSymbols()) + return false; + return true; + } + + unsigned getStringIndex(StringRef Str) { + StringMap::iterator i = StringTableMap.find(Str); + if (i == StringTableMap.end()) { + unsigned Index = StringTable.size(); + StringTable.append(Str.begin(), Str.end()); + StringTable.push_back(0); + StringTableMap[Str] = Index; + return Index; + } + return i->second; + } + + COFFYAML::Object &Obj; + COFF::header Header; + + struct Section { + COFF::section Header; + std::vector Data; + std::vector Relocations; + }; + + struct Symbol { + COFF::symbol Header; + std::vector AuxSymbols; + }; + + std::vector
Sections; + std::vector Symbols; + StringMap StringTableMap; + std::string StringTable; +}; + +// Take a CP and assign addresses and sizes to everything. Returns false if the +// layout is not valid to do. +static bool layoutCOFF(COFFParser &CP) { + uint32_t SectionTableStart = 0; + uint32_t SectionTableSize = 0; + + // The section table starts immediately after the header, including the + // optional header. + SectionTableStart = sizeof(COFF::header) + CP.Header.SizeOfOptionalHeader; + SectionTableSize = sizeof(COFF::section) * CP.Sections.size(); + + uint32_t CurrentSectionDataOffset = SectionTableStart + SectionTableSize; + + // Assign each section data address consecutively. + for (std::vector::iterator i = CP.Sections.begin(), + e = CP.Sections.end(); + i != e; ++i) { + if (!i->Data.empty()) { + i->Header.SizeOfRawData = i->Data.size(); + i->Header.PointerToRawData = CurrentSectionDataOffset; + CurrentSectionDataOffset += i->Header.SizeOfRawData; + // TODO: Handle alignment. + } else { + i->Header.SizeOfRawData = 0; + i->Header.PointerToRawData = 0; + } + } + + uint32_t SymbolTableStart = CurrentSectionDataOffset; + + // Calculate number of symbols. + uint32_t NumberOfSymbols = 0; + for (std::vector::iterator i = CP.Symbols.begin(), + e = CP.Symbols.end(); + i != e; ++i) { + if (i->AuxSymbols.size() % COFF::SymbolSize != 0) { + errs() << "AuxillaryData size not a multiple of symbol size!\n"; + return false; + } + i->Header.NumberOfAuxSymbols = i->AuxSymbols.size() / COFF::SymbolSize; + NumberOfSymbols += 1 + i->Header.NumberOfAuxSymbols; + } + + // Store all the allocated start addresses in the header. + CP.Header.NumberOfSections = CP.Sections.size(); + CP.Header.NumberOfSymbols = NumberOfSymbols; + CP.Header.PointerToSymbolTable = SymbolTableStart; + + *reinterpret_cast(&CP.StringTable[0]) + = CP.StringTable.size(); + + return true; +} + +template +struct binary_le_impl { + value_type Value; + binary_le_impl(value_type V) : Value(V) {} +}; + +template +raw_ostream &operator <<( raw_ostream &OS + , const binary_le_impl &BLE) { + char Buffer[sizeof(BLE.Value)]; + support::endian::write( + Buffer, BLE.Value); + OS.write(Buffer, sizeof(BLE.Value)); + return OS; +} + +template +binary_le_impl binary_le(value_type V) { + return binary_le_impl(V); +} + +void writeCOFF(COFFParser &CP, raw_ostream &OS) { + OS << binary_le(CP.Header.Machine) + << binary_le(CP.Header.NumberOfSections) + << binary_le(CP.Header.TimeDateStamp) + << binary_le(CP.Header.PointerToSymbolTable) + << binary_le(CP.Header.NumberOfSymbols) + << binary_le(CP.Header.SizeOfOptionalHeader) + << binary_le(CP.Header.Characteristics); + + // Output section table. + for (std::vector::const_iterator i = CP.Sections.begin(), + e = CP.Sections.end(); + i != e; ++i) { + OS.write(i->Header.Name, COFF::NameSize); + OS << binary_le(i->Header.VirtualSize) + << binary_le(i->Header.VirtualAddress) + << binary_le(i->Header.SizeOfRawData) + << binary_le(i->Header.PointerToRawData) + << binary_le(i->Header.PointerToRelocations) + << binary_le(i->Header.PointerToLineNumbers) + << binary_le(i->Header.NumberOfRelocations) + << binary_le(i->Header.NumberOfLineNumbers) + << binary_le(i->Header.Characteristics); + } + + // Output section data. + for (std::vector::const_iterator i = CP.Sections.begin(), + e = CP.Sections.end(); + i != e; ++i) { + if (!i->Data.empty()) + OS.write(reinterpret_cast(&i->Data[0]), i->Data.size()); + } + + // Output symbol table. + + for (std::vector::const_iterator i = CP.Symbols.begin(), + e = CP.Symbols.end(); + i != e; ++i) { + OS.write(i->Header.Name, COFF::NameSize); + OS << binary_le(i->Header.Value) + << binary_le(i->Header.SectionNumber) + << binary_le(i->Header.Type) + << binary_le(i->Header.StorageClass) + << binary_le(i->Header.NumberOfAuxSymbols); + if (!i->AuxSymbols.empty()) + OS.write( reinterpret_cast(&i->AuxSymbols[0]) + , i->AuxSymbols.size()); + } + + // Output string table. + OS.write(&CP.StringTable[0], CP.StringTable.size()); +} + +LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Relocation) +LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Section) +LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Symbol) + +namespace llvm { + +namespace COFF { + Characteristics operator|(Characteristics a, Characteristics b) { + uint32_t Ret = static_cast(a) | static_cast(b); + return static_cast(Ret); + } + + SectionCharacteristics + operator|(SectionCharacteristics a, SectionCharacteristics b) { + uint32_t Ret = static_cast(a) | static_cast(b); + return static_cast(Ret); + } +} + +namespace yaml { + +#define BCase(X) IO.bitSetCase(Value, #X, COFF::X); + +template <> +struct ScalarBitSetTraits { + static void bitset(IO &IO, COFF::SectionCharacteristics &Value) { + BCase(IMAGE_SCN_TYPE_NO_PAD); + BCase(IMAGE_SCN_CNT_CODE); + BCase(IMAGE_SCN_CNT_INITIALIZED_DATA); + BCase(IMAGE_SCN_CNT_UNINITIALIZED_DATA); + BCase(IMAGE_SCN_LNK_OTHER); + BCase(IMAGE_SCN_LNK_INFO); + BCase(IMAGE_SCN_LNK_REMOVE); + BCase(IMAGE_SCN_LNK_COMDAT); + BCase(IMAGE_SCN_GPREL); + BCase(IMAGE_SCN_MEM_PURGEABLE); + BCase(IMAGE_SCN_MEM_16BIT); + BCase(IMAGE_SCN_MEM_LOCKED); + BCase(IMAGE_SCN_MEM_PRELOAD); + BCase(IMAGE_SCN_ALIGN_1BYTES); + BCase(IMAGE_SCN_ALIGN_2BYTES); + BCase(IMAGE_SCN_ALIGN_4BYTES); + BCase(IMAGE_SCN_ALIGN_8BYTES); + BCase(IMAGE_SCN_ALIGN_16BYTES); + BCase(IMAGE_SCN_ALIGN_32BYTES); + BCase(IMAGE_SCN_ALIGN_64BYTES); + BCase(IMAGE_SCN_ALIGN_128BYTES); + BCase(IMAGE_SCN_ALIGN_256BYTES); + BCase(IMAGE_SCN_ALIGN_512BYTES); + BCase(IMAGE_SCN_ALIGN_1024BYTES); + BCase(IMAGE_SCN_ALIGN_2048BYTES); + BCase(IMAGE_SCN_ALIGN_4096BYTES); + BCase(IMAGE_SCN_ALIGN_8192BYTES); + BCase(IMAGE_SCN_LNK_NRELOC_OVFL); + BCase(IMAGE_SCN_MEM_DISCARDABLE); + BCase(IMAGE_SCN_MEM_NOT_CACHED); + BCase(IMAGE_SCN_MEM_NOT_PAGED); + BCase(IMAGE_SCN_MEM_SHARED); + BCase(IMAGE_SCN_MEM_EXECUTE); + BCase(IMAGE_SCN_MEM_READ); + BCase(IMAGE_SCN_MEM_WRITE); + } +}; + +template <> +struct ScalarBitSetTraits { + static void bitset(IO &IO, COFF::Characteristics &Value) { + BCase(IMAGE_FILE_RELOCS_STRIPPED); + BCase(IMAGE_FILE_EXECUTABLE_IMAGE); + BCase(IMAGE_FILE_LINE_NUMS_STRIPPED); + BCase(IMAGE_FILE_LOCAL_SYMS_STRIPPED); + BCase(IMAGE_FILE_AGGRESSIVE_WS_TRIM); + BCase(IMAGE_FILE_LARGE_ADDRESS_AWARE); + BCase(IMAGE_FILE_BYTES_REVERSED_LO); + BCase(IMAGE_FILE_32BIT_MACHINE); + BCase(IMAGE_FILE_DEBUG_STRIPPED); + BCase(IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP); + BCase(IMAGE_FILE_NET_RUN_FROM_SWAP); + BCase(IMAGE_FILE_SYSTEM); + BCase(IMAGE_FILE_DLL); + BCase(IMAGE_FILE_UP_SYSTEM_ONLY); + BCase(IMAGE_FILE_BYTES_REVERSED_HI); + } +}; +#undef BCase + +#define ECase(X) IO.enumCase(Value, #X, COFF::X); + +template <> +struct ScalarEnumerationTraits { + static void enumeration(IO &IO, COFF::SymbolComplexType &Value) { + ECase(IMAGE_SYM_DTYPE_NULL); + ECase(IMAGE_SYM_DTYPE_POINTER); + ECase(IMAGE_SYM_DTYPE_FUNCTION); + ECase(IMAGE_SYM_DTYPE_ARRAY); + } +}; + +template <> +struct ScalarEnumerationTraits { + static void enumeration(IO &IO, COFF::SymbolStorageClass &Value) { + ECase(IMAGE_SYM_CLASS_END_OF_FUNCTION); + ECase(IMAGE_SYM_CLASS_NULL); + ECase(IMAGE_SYM_CLASS_AUTOMATIC); + ECase(IMAGE_SYM_CLASS_EXTERNAL); + ECase(IMAGE_SYM_CLASS_STATIC); + ECase(IMAGE_SYM_CLASS_REGISTER); + ECase(IMAGE_SYM_CLASS_EXTERNAL_DEF); + ECase(IMAGE_SYM_CLASS_LABEL); + ECase(IMAGE_SYM_CLASS_UNDEFINED_LABEL); + ECase(IMAGE_SYM_CLASS_MEMBER_OF_STRUCT); + ECase(IMAGE_SYM_CLASS_ARGUMENT); + ECase(IMAGE_SYM_CLASS_STRUCT_TAG); + ECase(IMAGE_SYM_CLASS_MEMBER_OF_UNION); + ECase(IMAGE_SYM_CLASS_UNION_TAG); + ECase(IMAGE_SYM_CLASS_TYPE_DEFINITION); + ECase(IMAGE_SYM_CLASS_UNDEFINED_STATIC); + ECase(IMAGE_SYM_CLASS_ENUM_TAG); + ECase(IMAGE_SYM_CLASS_MEMBER_OF_ENUM); + ECase(IMAGE_SYM_CLASS_REGISTER_PARAM); + ECase(IMAGE_SYM_CLASS_BIT_FIELD); + ECase(IMAGE_SYM_CLASS_BLOCK); + ECase(IMAGE_SYM_CLASS_FUNCTION); + ECase(IMAGE_SYM_CLASS_END_OF_STRUCT); + ECase(IMAGE_SYM_CLASS_FILE); + ECase(IMAGE_SYM_CLASS_SECTION); + ECase(IMAGE_SYM_CLASS_WEAK_EXTERNAL); + ECase(IMAGE_SYM_CLASS_CLR_TOKEN); + } +}; + +template <> +struct ScalarEnumerationTraits { + static void enumeration(IO &IO, COFF::SymbolBaseType &Value) { + ECase(IMAGE_SYM_TYPE_NULL); + ECase(IMAGE_SYM_TYPE_VOID); + ECase(IMAGE_SYM_TYPE_CHAR); + ECase(IMAGE_SYM_TYPE_SHORT); + ECase(IMAGE_SYM_TYPE_INT); + ECase(IMAGE_SYM_TYPE_LONG); + ECase(IMAGE_SYM_TYPE_FLOAT); + ECase(IMAGE_SYM_TYPE_DOUBLE); + ECase(IMAGE_SYM_TYPE_STRUCT); + ECase(IMAGE_SYM_TYPE_UNION); + ECase(IMAGE_SYM_TYPE_ENUM); + ECase(IMAGE_SYM_TYPE_MOE); + ECase(IMAGE_SYM_TYPE_BYTE); + ECase(IMAGE_SYM_TYPE_WORD); + ECase(IMAGE_SYM_TYPE_UINT); + ECase(IMAGE_SYM_TYPE_DWORD); + } +}; + +template <> +struct ScalarEnumerationTraits { + static void enumeration(IO &IO, COFF::MachineTypes &Value) { + ECase(IMAGE_FILE_MACHINE_UNKNOWN); + ECase(IMAGE_FILE_MACHINE_AM33); + ECase(IMAGE_FILE_MACHINE_AMD64); + ECase(IMAGE_FILE_MACHINE_ARM); + ECase(IMAGE_FILE_MACHINE_ARMV7); + ECase(IMAGE_FILE_MACHINE_EBC); + ECase(IMAGE_FILE_MACHINE_I386); + ECase(IMAGE_FILE_MACHINE_IA64); + ECase(IMAGE_FILE_MACHINE_M32R); + ECase(IMAGE_FILE_MACHINE_MIPS16); + ECase(IMAGE_FILE_MACHINE_MIPSFPU); + ECase(IMAGE_FILE_MACHINE_MIPSFPU16); + ECase(IMAGE_FILE_MACHINE_POWERPC); + ECase(IMAGE_FILE_MACHINE_POWERPCFP); + ECase(IMAGE_FILE_MACHINE_R4000); + ECase(IMAGE_FILE_MACHINE_SH3); + ECase(IMAGE_FILE_MACHINE_SH3DSP); + ECase(IMAGE_FILE_MACHINE_SH4); + ECase(IMAGE_FILE_MACHINE_SH5); + ECase(IMAGE_FILE_MACHINE_THUMB); + ECase(IMAGE_FILE_MACHINE_WCEMIPSV2); + } +}; + +template <> +struct ScalarEnumerationTraits { + static void enumeration(IO &IO, COFF::RelocationTypeX86 &Value) { + ECase(IMAGE_REL_I386_ABSOLUTE); + ECase(IMAGE_REL_I386_DIR16); + ECase(IMAGE_REL_I386_REL16); + ECase(IMAGE_REL_I386_DIR32); + ECase(IMAGE_REL_I386_DIR32NB); + ECase(IMAGE_REL_I386_SEG12); + ECase(IMAGE_REL_I386_SECTION); + ECase(IMAGE_REL_I386_SECREL); + ECase(IMAGE_REL_I386_TOKEN); + ECase(IMAGE_REL_I386_SECREL7); + ECase(IMAGE_REL_I386_REL32); + ECase(IMAGE_REL_AMD64_ABSOLUTE); + ECase(IMAGE_REL_AMD64_ADDR64); + ECase(IMAGE_REL_AMD64_ADDR32); + ECase(IMAGE_REL_AMD64_ADDR32NB); + ECase(IMAGE_REL_AMD64_REL32); + ECase(IMAGE_REL_AMD64_REL32_1); + ECase(IMAGE_REL_AMD64_REL32_2); + ECase(IMAGE_REL_AMD64_REL32_3); + ECase(IMAGE_REL_AMD64_REL32_4); + ECase(IMAGE_REL_AMD64_REL32_5); + ECase(IMAGE_REL_AMD64_SECTION); + ECase(IMAGE_REL_AMD64_SECREL); + ECase(IMAGE_REL_AMD64_SECREL7); + ECase(IMAGE_REL_AMD64_TOKEN); + ECase(IMAGE_REL_AMD64_SREL32); + ECase(IMAGE_REL_AMD64_PAIR); + ECase(IMAGE_REL_AMD64_SSPAN32); + } +}; + +#undef ECase + +template <> +struct MappingTraits { + static void mapping(IO &IO, COFFYAML::Symbol &S) { + IO.mapRequired("SimpleType", S.SimpleType); + IO.mapOptional("NumberOfAuxSymbols", S.NumberOfAuxSymbols); + IO.mapRequired("Name", S.Name); + IO.mapRequired("StorageClass", S.StorageClass); + IO.mapOptional("AuxillaryData", S.AuxillaryData); // FIXME: typo + IO.mapRequired("ComplexType", S.ComplexType); + IO.mapRequired("Value", S.Value); + IO.mapRequired("SectionNumber", S.SectionNumber); + } +}; + +template <> +struct MappingTraits { + static void mapping(IO &IO, COFFYAML::Header &H) { + IO.mapRequired("Machine", H.Machine); + IO.mapOptional("Characteristics", H.Characteristics); + } +}; + +template <> +struct MappingTraits { + static void mapping(IO &IO, COFFYAML::Relocation &Rel) { + IO.mapRequired("Type", Rel.Type); + IO.mapRequired("VirtualAddress", Rel.VirtualAddress); + IO.mapRequired("SymbolTableIndex", Rel.SymbolTableIndex); + } +}; + +template <> +struct MappingTraits { + static void mapping(IO &IO, COFFYAML::Section &Sec) { + IO.mapOptional("Relocations", Sec.Relocations); + IO.mapRequired("SectionData", Sec.SectionData); + IO.mapRequired("Characteristics", Sec.Characteristics); + IO.mapRequired("Name", Sec.Name); + } +}; + +template <> +struct MappingTraits { + static void mapping(IO &IO, COFFYAML::Object &Obj) { + IO.mapRequired("sections", Obj.Sections); + IO.mapRequired("header", Obj.HeaderData); + IO.mapRequired("symbols", Obj.Symbols); + } +}; +} // end namespace yaml +} // end namespace llvm + +int main(int argc, char **argv) { + cl::ParseCommandLineOptions(argc, argv); + sys::PrintStackTraceOnErrorSignal(); + PrettyStackTraceProgram X(argc, argv); + llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + + OwningPtr Buf; + if (MemoryBuffer::getFileOrSTDIN(Input, Buf)) + return 1; + + yaml::Input YIn(Buf->getBuffer()); + COFFYAML::Object Doc; + YIn >> Doc; + if (YIn.error()) { + errs() << "yaml2obj: Failed to parse YAML file!\n"; + return 1; + } + + COFFParser CP(Doc); + if (!CP.parse()) { + errs() << "yaml2obj: Failed to parse YAML file!\n"; + return 1; + } + + if (!layoutCOFF(CP)) { + errs() << "yaml2obj: Failed to layout COFF file!\n"; + return 1; + } + writeCOFF(CP, outs()); +} -- cgit v1.2.3-18-g5258 From eb721c0fbdd154c47bf177426776ab7b4b7c0cbc Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 14:25:39 +0000 Subject: Remove unused argument. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178976 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/MachODump.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index e9d2b3b1a8..ee4711fb34 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -201,7 +201,6 @@ static void emitDOTFile(const char *FileName, const MCFunction &f, static void getSectionsAndSymbols(const macho::Header &Header, MachOObjectFile *MachOObj, - InMemoryStruct *SymtabLC, std::vector &Sections, std::vector &Symbols, SmallVectorImpl &FoundFns) { @@ -295,8 +294,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) { std::vector Symbols; SmallVector FoundFns; - getSectionsAndSymbols(Header, MachOOF.get(), &SymtabLC, Sections, Symbols, - FoundFns); + getSectionsAndSymbols(Header, MachOOF.get(), Sections, Symbols, FoundFns); // Make a copy of the unsorted symbol list. FIXME: duplication std::vector UnsortedSymbols(Symbols); -- cgit v1.2.3-18-g5258 From 13d297260f62ffae53b5349a55250fe3a4c4bcc2 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 14:30:21 +0000 Subject: Remove dead code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178977 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/MachODump.cpp | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index ee4711fb34..b122cd3b7a 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -273,23 +273,6 @@ void llvm::DisassembleInputMachO(StringRef Filename) { const macho::Header &Header = MachOObj->getHeader(); - const MachOObject::LoadCommandInfo *SymtabLCI = 0; - // First, find the symbol table segment. - for (unsigned i = 0; i != Header.NumLoadCommands; ++i) { - const MachOObject::LoadCommandInfo &LCI = MachOObj->getLoadCommandInfo(i); - if (LCI.Command.Type == macho::LCT_Symtab) { - SymtabLCI = &LCI; - break; - } - } - - // Read and register the symbol table data. - InMemoryStruct SymtabLC; - if (SymtabLCI) { - MachOObj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC); - MachOObj->RegisterStringTable(*SymtabLC); - } - std::vector Sections; std::vector Symbols; SmallVector FoundFns; -- cgit v1.2.3-18-g5258 From 196abbffe9b7a760593d68b99cbb5f961efc8e2a Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 14:40:18 +0000 Subject: Remove last use of InMemoryStruct in llvm-objdump. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178979 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/MachODump.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index b122cd3b7a..894e769115 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -223,8 +223,8 @@ static void getSectionsAndSymbols(const macho::Header &Header, if (LCI.Command.Type == macho::LCT_FunctionStarts) { // We found a function starts segment, parse the addresses for later // consumption. - InMemoryStruct LLC; - MachOObj->getObject()->ReadLinkeditDataLoadCommand(LCI, LLC); + const MachOFormat::LinkeditDataLoadCommand *LLC = + MachOObj->getLinkeditDataLoadCommand(LCI); MachOObj->getObject()->ReadULEB128s(LLC->DataOffset, FoundFns); } -- cgit v1.2.3-18-g5258 From 305b826f92e0dc7b670238e7caa35ab6e1cf341a Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 14:50:40 +0000 Subject: Make getObject const. Remove a const_cast. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178980 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/MachODump.cpp | 4 ++-- tools/llvm-readobj/MachODumper.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 894e769115..282f04db2e 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -108,7 +108,7 @@ struct SymbolSorter { // Print additional information about an address, if available. static void DumpAddress(uint64_t Address, ArrayRef Sections, - MachOObject *MachOObj, raw_ostream &OS) { + const MachOObject *MachOObj, raw_ostream &OS) { for (unsigned i = 0; i != Sections.size(); ++i) { uint64_t SectAddr = 0, SectSize = 0; Sections[i].getAddress(SectAddr); @@ -241,7 +241,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) { OwningPtr MachOOF(static_cast( ObjectFile::createMachOObjectFile(Buff.take()))); - MachOObject *MachOObj = MachOOF->getObject(); + const MachOObject *MachOObj = MachOOF->getObject(); const Target *TheTarget = GetTarget(MachOObj); if (!TheTarget) { diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index 0354e767ba..006158e027 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -254,7 +254,7 @@ void MachODumper::printSections() { ++SectionIndex; - const MachOObject *MachO = const_cast(Obj)->getObject(); + const MachOObject *MachO = Obj->getObject(); MachOSection Section; getSection(MachO, SecI->getRawDataRefImpl(), Section); -- cgit v1.2.3-18-g5258 From 7ea2e4869496fb27876d35b93fe99397be29b978 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 15:05:12 +0000 Subject: Remove a use of InMemoryStruct in llvm-readobj. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178981 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/MachODumper.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index 006158e027..717569cd43 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -165,13 +165,13 @@ static bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) { return false; } -static void getSection(const MachOObject *MachOObj, +static void getSection(const MachOObjectFile *Obj, DataRefImpl DRI, MachOSection &Section) { - LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); + const MachOObject *MachOObj = Obj->getObject(); + if (is64BitLoadCommand(MachOObj, DRI)) { - InMemoryStruct Sect; - MachOObj->ReadSection64(LCI, DRI.d.b, Sect); + const MachOFormat::Section64 *Sect = Obj->getSection64(DRI); Section.Address = Sect->Address; Section.Size = Sect->Size; @@ -183,8 +183,7 @@ static void getSection(const MachOObject *MachOObj, Section.Reserved1 = Sect->Reserved1; Section.Reserved2 = Sect->Reserved2; } else { - InMemoryStruct Sect; - MachOObj->ReadSection(LCI, DRI.d.b, Sect); + const MachOFormat::Section *Sect = Obj->getSection(DRI); Section.Address = Sect->Address; Section.Size = Sect->Size; @@ -254,10 +253,8 @@ void MachODumper::printSections() { ++SectionIndex; - const MachOObject *MachO = Obj->getObject(); - MachOSection Section; - getSection(MachO, SecI->getRawDataRefImpl(), Section); + getSection(Obj, SecI->getRawDataRefImpl(), Section); DataRefImpl DR = SecI->getRawDataRefImpl(); StringRef Name; -- cgit v1.2.3-18-g5258 From 1efa60453be658242f468f4be4f8d4855ace60d1 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 15:35:18 +0000 Subject: Remove usage of InMemoryStruct in getSymbol. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178984 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/MachODumper.cpp | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) (limited to 'tools') diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index 717569cd43..8f37b9a183 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -197,38 +197,20 @@ static void getSection(const MachOObjectFile *Obj, } } -static void getSymbolTableEntry(const MachOObject *MachO, - DataRefImpl DRI, - InMemoryStruct &Res) { - InMemoryStruct SymtabLoadCmd; - LoadCommandInfo LCI = MachO->getLoadCommandInfo(DRI.d.a); - MachO->ReadSymtabLoadCommand(LCI, SymtabLoadCmd); - MachO->ReadSymbolTableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b, Res); -} - -static void getSymbol64TableEntry(const MachOObject *MachO, - DataRefImpl DRI, - InMemoryStruct &Res) { - InMemoryStruct SymtabLoadCmd; - LoadCommandInfo LCI = MachO->getLoadCommandInfo(DRI.d.a); - MachO->ReadSymtabLoadCommand(LCI, SymtabLoadCmd); - MachO->ReadSymbol64TableEntry(SymtabLoadCmd->SymbolTableOffset, DRI.d.b, Res); -} - -static void getSymbol(const MachOObject *MachOObj, +static void getSymbol(const MachOObjectFile *Obj, DataRefImpl DRI, MachOSymbol &Symbol) { + const MachOObject *MachOObj = Obj->getObject(); if (MachOObj->is64Bit()) { - InMemoryStruct Entry; - getSymbol64TableEntry(MachOObj, DRI, Entry); + const MachOFormat::Symbol64TableEntry *Entry = + Obj->getSymbol64TableEntry( DRI); Symbol.StringIndex = Entry->StringIndex; Symbol.Type = Entry->Type; Symbol.SectionIndex = Entry->SectionIndex; Symbol.Flags = Entry->Flags; Symbol.Value = Entry->Value; } else { - InMemoryStruct Entry; - getSymbolTableEntry(MachOObj, DRI, Entry); + const MachOFormat::SymbolTableEntry *Entry = Obj->getSymbolTableEntry(DRI); Symbol.StringIndex = Entry->StringIndex; Symbol.Type = Entry->Type; Symbol.SectionIndex = Entry->SectionIndex; @@ -397,10 +379,8 @@ void MachODumper::printSymbol(symbol_iterator SymI) { if (SymI->getName(SymbolName)) SymbolName = ""; - const MachOObject *MachO = const_cast(Obj)->getObject(); - MachOSymbol Symbol; - getSymbol(MachO, SymI->getRawDataRefImpl(), Symbol); + getSymbol(Obj, SymI->getRawDataRefImpl(), Symbol); StringRef SectionName; section_iterator SecI(Obj->end_sections()); -- cgit v1.2.3-18-g5258 From 0be4eafd9c90d5e584b951fe2970f024341486c3 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 15:46:05 +0000 Subject: Remove two uses of getObject. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178985 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/MachODumper.cpp | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'tools') diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index 8f37b9a183..190baa229b 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -157,20 +157,10 @@ namespace { }; } -static bool is64BitLoadCommand(const MachOObject *MachOObj, DataRefImpl DRI) { - LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(DRI.d.a); - if (LCI.Command.Type == macho::LCT_Segment64) - return true; - assert(LCI.Command.Type == macho::LCT_Segment && "Unexpected Type."); - return false; -} - static void getSection(const MachOObjectFile *Obj, DataRefImpl DRI, MachOSection &Section) { - const MachOObject *MachOObj = Obj->getObject(); - - if (is64BitLoadCommand(MachOObj, DRI)) { + if (Obj->is64Bit()) { const MachOFormat::Section64 *Sect = Obj->getSection64(DRI); Section.Address = Sect->Address; @@ -200,8 +190,7 @@ static void getSection(const MachOObjectFile *Obj, static void getSymbol(const MachOObjectFile *Obj, DataRefImpl DRI, MachOSymbol &Symbol) { - const MachOObject *MachOObj = Obj->getObject(); - if (MachOObj->is64Bit()) { + if (Obj->is64Bit()) { const MachOFormat::Symbol64TableEntry *Entry = Obj->getSymbol64TableEntry( DRI); Symbol.StringIndex = Entry->StringIndex; -- cgit v1.2.3-18-g5258 From 3eff318cbac281d46e8c8dfef16ffccbceebc855 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 16:07:35 +0000 Subject: Remove MachOObjectFile::getObject. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178986 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/MachODump.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 282f04db2e..d3f29d2d50 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -52,7 +52,7 @@ static cl::opt static cl::opt DSYMFile("dsym", cl::desc("Use .dSYM file for debug info")); -static const Target *GetTarget(const MachOObject *MachOObj) { +static const Target *GetTarget(const MachOObjectFile *MachOObj) { // Figure out the target triple. if (TripleName.empty()) { llvm::Triple TT("unknown-unknown-unknown"); @@ -108,7 +108,7 @@ struct SymbolSorter { // Print additional information about an address, if available. static void DumpAddress(uint64_t Address, ArrayRef Sections, - const MachOObject *MachOObj, raw_ostream &OS) { + const MachOObjectFile *MachOObj, raw_ostream &OS) { for (unsigned i = 0; i != Sections.size(); ++i) { uint64_t SectAddr = 0, SectSize = 0; Sections[i].getAddress(SectAddr); @@ -218,15 +218,14 @@ static void getSectionsAndSymbols(const macho::Header &Header, } for (unsigned i = 0; i != Header.NumLoadCommands; ++i) { - const MachOObject::LoadCommandInfo &LCI = - MachOObj->getObject()->getLoadCommandInfo(i); + const MachOObject::LoadCommandInfo &LCI = MachOObj->getLoadCommandInfo(i); if (LCI.Command.Type == macho::LCT_FunctionStarts) { // We found a function starts segment, parse the addresses for later // consumption. const MachOFormat::LinkeditDataLoadCommand *LLC = MachOObj->getLinkeditDataLoadCommand(LCI); - MachOObj->getObject()->ReadULEB128s(LLC->DataOffset, FoundFns); + MachOObj->ReadULEB128s(LLC->DataOffset, FoundFns); } } } @@ -241,9 +240,8 @@ void llvm::DisassembleInputMachO(StringRef Filename) { OwningPtr MachOOF(static_cast( ObjectFile::createMachOObjectFile(Buff.take()))); - const MachOObject *MachOObj = MachOOF->getObject(); - const Target *TheTarget = GetTarget(MachOObj); + const Target *TheTarget = GetTarget(MachOOF.get()); if (!TheTarget) { // GetTarget prints out stuff. return; @@ -271,7 +269,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) { outs() << '\n' << Filename << ":\n\n"; - const macho::Header &Header = MachOObj->getHeader(); + const macho::Header &Header = MachOOF->getHeader(); std::vector Sections; std::vector Symbols; @@ -580,7 +578,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) { Relocs[j].second.getName(SymName); outs() << "\t# " << SymName << ' '; - DumpAddress(Addr, Sections, MachOObj, outs()); + DumpAddress(Addr, Sections, MachOOF.get(), outs()); } // If this instructions contains an address, see if we can evaluate @@ -589,7 +587,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) { Inst.Address, Inst.Size); if (targ != -1ULL) - DumpAddress(targ, Sections, MachOObj, outs()); + DumpAddress(targ, Sections, MachOOF.get(), outs()); // Print debug info. if (diContext) { -- cgit v1.2.3-18-g5258 From 77638d9110d67333e4ea8e6bd3206606a89bc24f Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 18:08:12 +0000 Subject: Add MachOObjectFile::LoadCommandInfo. This avoids using MachOObject::getLoadCommandInfo. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178990 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/MachODump.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index d3f29d2d50..44a6221c15 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -218,8 +218,8 @@ static void getSectionsAndSymbols(const macho::Header &Header, } for (unsigned i = 0; i != Header.NumLoadCommands; ++i) { - const MachOObject::LoadCommandInfo &LCI = MachOObj->getLoadCommandInfo(i); - if (LCI.Command.Type == macho::LCT_FunctionStarts) { + MachOObjectFile::LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(i); + if (LCI.Command->Type == macho::LCT_FunctionStarts) { // We found a function starts segment, parse the addresses for later // consumption. const MachOFormat::LinkeditDataLoadCommand *LLC = -- cgit v1.2.3-18-g5258 From 6ab85a81d711b1e9d3bbc02e05812e7f867a7c40 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 18:42:06 +0000 Subject: Remove LoadCommandInfo now that we always have a pointer to the command. LoadCommandInfo was needed to keep a command and its offset in the file. Now that we always have a pointer to the command, we don't need the offset. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178991 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/MachODump.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 44a6221c15..9275fe147a 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -218,12 +218,12 @@ static void getSectionsAndSymbols(const macho::Header &Header, } for (unsigned i = 0; i != Header.NumLoadCommands; ++i) { - MachOObjectFile::LoadCommandInfo LCI = MachOObj->getLoadCommandInfo(i); - if (LCI.Command->Type == macho::LCT_FunctionStarts) { + const MachOFormat::LoadCommand *Command = MachOObj->getLoadCommandInfo(i); + if (Command->Type == macho::LCT_FunctionStarts) { // We found a function starts segment, parse the addresses for later // consumption. const MachOFormat::LinkeditDataLoadCommand *LLC = - MachOObj->getLinkeditDataLoadCommand(LCI); + reinterpret_cast(Command); MachOObj->ReadULEB128s(LLC->DataOffset, FoundFns); } -- cgit v1.2.3-18-g5258 From 433611bdf395d08093e3edd52846c1774b46caf2 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sun, 7 Apr 2013 19:26:57 +0000 Subject: Implement MachOObjectFile::getHeader directly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178994 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/MachODump.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 9275fe147a..7c6565832e 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -56,7 +56,7 @@ static const Target *GetTarget(const MachOObjectFile *MachOObj) { // Figure out the target triple. if (TripleName.empty()) { llvm::Triple TT("unknown-unknown-unknown"); - switch (MachOObj->getHeader().CPUType) { + switch (MachOObj->getHeader()->CPUType) { case llvm::MachO::CPUTypeI386: TT.setArch(Triple::ArchType(Triple::x86)); break; @@ -199,7 +199,7 @@ static void emitDOTFile(const char *FileName, const MCFunction &f, Out << "}\n"; } -static void getSectionsAndSymbols(const macho::Header &Header, +static void getSectionsAndSymbols(const MachOFormat::Header *Header, MachOObjectFile *MachOObj, std::vector &Sections, std::vector &Symbols, @@ -217,7 +217,7 @@ static void getSectionsAndSymbols(const macho::Header &Header, Sections.push_back(*SI); } - for (unsigned i = 0; i != Header.NumLoadCommands; ++i) { + for (unsigned i = 0; i != Header->NumLoadCommands; ++i) { const MachOFormat::LoadCommand *Command = MachOObj->getLoadCommandInfo(i); if (Command->Type == macho::LCT_FunctionStarts) { // We found a function starts segment, parse the addresses for later @@ -269,7 +269,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) { outs() << '\n' << Filename << ":\n\n"; - const macho::Header &Header = MachOOF->getHeader(); + const MachOFormat::Header *Header = MachOOF->getHeader(); std::vector Sections; std::vector Symbols; -- cgit v1.2.3-18-g5258 From bcff69a1e0788377b8bec87f850a6f5977fe9d22 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Mon, 8 Apr 2013 08:30:47 +0000 Subject: Don't define our own global 'endl' variable. While technically it had internal linkage and so wasn't a patent bug, it doesn't make any sense here. We can avoid even calling operator<< by just embedding the newline in the string literals that were already being streamed out. It also gives the impression of some line-ending agnosticisms which is not present, and that flushing happens when it doesn't. If we want to use std::endl, we could do that, but honestly it doesn't seem remotely worth it. Using '\n' directly is much more clear when working with raw_ostream. It also happens to fix builds with old crufty GCC STL implementations that include std::endl into the global namespace (or headers written to be compatible with such atrocities). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179003 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/obj2yaml/obj2yaml.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/obj2yaml/obj2yaml.cpp b/tools/obj2yaml/obj2yaml.cpp index bdc461a947..68701dea56 100644 --- a/tools/obj2yaml/obj2yaml.cpp +++ b/tools/obj2yaml/obj2yaml.cpp @@ -16,8 +16,6 @@ #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" -const char endl = '\n'; - namespace yaml { // generic yaml-writing specific routines unsigned char printable(unsigned char Ch) { @@ -37,7 +35,7 @@ llvm::raw_ostream &writeHexStream(llvm::raw_ostream &Out, Out << "\" # |"; for (iter_t iter = arr.begin(); iter != end; ++iter) Out << printable(*iter); - Out << "|" << endl; + Out << "|\n"; return Out; } @@ -75,11 +73,11 @@ int main(int argc, char * argv[]) { // TODO: If this is an archive, then burst it and dump each entry if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, buf)) llvm::errs() << "Error: '" << ec.message() << "' opening file '" - << InputFilename << "'" << endl; + << InputFilename << "'\n"; else { ec = coff2yaml(llvm::outs(), buf.take()); if (ec) - llvm::errs() << "Error: " << ec.message() << " dumping COFF file" << endl; + llvm::errs() << "Error: " << ec.message() << " dumping COFF file\n"; } return 0; -- cgit v1.2.3-18-g5258 From 724a7b145d480018ddae894ffdd848154cd5478f Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Mon, 8 Apr 2013 08:39:59 +0000 Subject: Cleanup the formatting of obj2yaml.cpp. I couldn't touch this file and not clean it up some. These reformattings brought to you by clang-format, with some minor adjustments by me. More spring cleaning to follow here. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179004 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/obj2yaml/obj2yaml.cpp | 45 +++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 22 deletions(-) (limited to 'tools') diff --git a/tools/obj2yaml/obj2yaml.cpp b/tools/obj2yaml/obj2yaml.cpp index 68701dea56..615ff863b1 100644 --- a/tools/obj2yaml/obj2yaml.cpp +++ b/tools/obj2yaml/obj2yaml.cpp @@ -21,9 +21,9 @@ namespace yaml { // generic yaml-writing specific routines unsigned char printable(unsigned char Ch) { return Ch >= ' ' && Ch <= '~' ? Ch : '.'; } - -llvm::raw_ostream &writeHexStream(llvm::raw_ostream &Out, - const llvm::ArrayRef arr) { + +llvm::raw_ostream &writeHexStream(llvm::raw_ostream &Out, + const llvm::ArrayRef arr) { const char *hex = "0123456789ABCDEF"; Out << " !hex \""; @@ -38,9 +38,10 @@ llvm::raw_ostream &writeHexStream(llvm::raw_ostream &Out, Out << "|\n"; return Out; - } +} -llvm::raw_ostream &writeHexNumber(llvm::raw_ostream &Out, unsigned long long N) { +llvm::raw_ostream &writeHexNumber(llvm::raw_ostream &Out, + unsigned long long N) { if (N >= 10) Out << "0x"; Out.write_hex(N); @@ -49,32 +50,32 @@ llvm::raw_ostream &writeHexNumber(llvm::raw_ostream &Out, unsigned long long N) } - using namespace llvm; -enum ObjectFileType { coff }; +enum ObjectFileType { + coff +}; cl::opt InputFormat( - cl::desc("Choose input format"), - cl::values( - clEnumVal(coff, "process COFF object files"), - clEnumValEnd)); - -cl::opt InputFilename(cl::Positional, cl::desc(""), cl::init("-")); - -int main(int argc, char * argv[]) { + cl::desc("Choose input format"), + cl::values(clEnumVal(coff, "process COFF object files"), clEnumValEnd)); + +cl::opt InputFilename(cl::Positional, cl::desc(""), + cl::init("-")); + +int main(int argc, char *argv[]) { cl::ParseCommandLineOptions(argc, argv); sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); - llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. -// Process the input file + // Process the input file OwningPtr buf; -// TODO: If this is an archive, then burst it and dump each entry - if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, buf)) - llvm::errs() << "Error: '" << ec.message() << "' opening file '" - << InputFilename << "'\n"; - else { + // TODO: If this is an archive, then burst it and dump each entry + if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, buf)) { + llvm::errs() << "Error: '" << ec.message() << "' opening file '" + << InputFilename << "'\n"; + } else { ec = coff2yaml(llvm::outs(), buf.take()); if (ec) llvm::errs() << "Error: " << ec.message() << " dumping COFF file\n"; -- cgit v1.2.3-18-g5258 From 97034bb95d4bc76f096d0014332f0a683971e33a Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Mon, 8 Apr 2013 08:55:14 +0000 Subject: Clean up namespaces in obj2yaml.cpp. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179009 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/obj2yaml/obj2yaml.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/obj2yaml/obj2yaml.cpp b/tools/obj2yaml/obj2yaml.cpp index 615ff863b1..f089e0aba5 100644 --- a/tools/obj2yaml/obj2yaml.cpp +++ b/tools/obj2yaml/obj2yaml.cpp @@ -16,18 +16,19 @@ #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" +using namespace llvm; + namespace yaml { // generic yaml-writing specific routines unsigned char printable(unsigned char Ch) { return Ch >= ' ' && Ch <= '~' ? Ch : '.'; } -llvm::raw_ostream &writeHexStream(llvm::raw_ostream &Out, - const llvm::ArrayRef arr) { +raw_ostream &writeHexStream(raw_ostream &Out, const ArrayRef arr) { const char *hex = "0123456789ABCDEF"; Out << " !hex \""; - typedef llvm::ArrayRef::const_iterator iter_t; + typedef ArrayRef::const_iterator iter_t; const iter_t end = arr.end(); for (iter_t iter = arr.begin(); iter != end; ++iter) Out << hex[(*iter >> 4) & 0x0F] << hex[(*iter & 0x0F)]; @@ -40,20 +41,20 @@ llvm::raw_ostream &writeHexStream(llvm::raw_ostream &Out, return Out; } -llvm::raw_ostream &writeHexNumber(llvm::raw_ostream &Out, - unsigned long long N) { +raw_ostream &writeHexNumber(raw_ostream &Out, unsigned long long N) { if (N >= 10) Out << "0x"; Out.write_hex(N); return Out; } -} +} // end namespace yaml -using namespace llvm; +namespace { enum ObjectFileType { coff }; +} cl::opt InputFormat( cl::desc("Choose input format"), @@ -73,12 +74,12 @@ int main(int argc, char *argv[]) { // TODO: If this is an archive, then burst it and dump each entry if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, buf)) { - llvm::errs() << "Error: '" << ec.message() << "' opening file '" - << InputFilename << "'\n"; + errs() << "Error: '" << ec.message() << "' opening file '" << InputFilename + << "'\n"; } else { - ec = coff2yaml(llvm::outs(), buf.take()); + ec = coff2yaml(outs(), buf.take()); if (ec) - llvm::errs() << "Error: " << ec.message() << " dumping COFF file\n"; + errs() << "Error: " << ec.message() << " dumping COFF file\n"; } return 0; -- cgit v1.2.3-18-g5258 From 89ec385e5e2f080bbe97bddefbff38232419c7f3 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Mon, 8 Apr 2013 08:55:18 +0000 Subject: Remove a global 'endl' variable from the other file as well. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179010 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/obj2yaml/coff2yaml.cpp | 47 +++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 25 deletions(-) (limited to 'tools') diff --git a/tools/obj2yaml/coff2yaml.cpp b/tools/obj2yaml/coff2yaml.cpp index f0241d931e..cc7ac00276 100644 --- a/tools/obj2yaml/coff2yaml.cpp +++ b/tools/obj2yaml/coff2yaml.cpp @@ -201,9 +201,6 @@ RelocationTypesARMPairs [] = { }; #undef STRING_PAIR - -static const char endl = '\n'; - namespace yaml { // COFF-specific yaml-writing specific routines static llvm::raw_ostream &writeName(llvm::raw_ostream &Out, @@ -242,25 +239,25 @@ const char *nameLookup(const pod_pair (&Arr)[N], static llvm::raw_ostream &yamlCOFFHeader( const llvm::object::coff_file_header *Header,llvm::raw_ostream &Out) { - Out << "header: !Header" << endl; + Out << "header: !Header\n"; Out << " Machine: "; Out << nameLookup(MachineTypePairs, Header->Machine, "# Unknown_MachineTypes") << " # ("; - return yaml::writeHexNumber(Out, Header->Machine) << ")" << endl << endl; + return yaml::writeHexNumber(Out, Header->Machine) << ")\n\n"; } static llvm::raw_ostream &yamlCOFFSections(llvm::object::COFFObjectFile &Obj, std::size_t NumSections, llvm::raw_ostream &Out) { llvm::error_code ec; - Out << "sections:" << endl; + Out << "sections:\n"; for (llvm::object::section_iterator iter = Obj.begin_sections(); iter != Obj.end_sections(); iter.increment(ec)) { const llvm::object::coff_section *sect = Obj.getCOFFSection(iter); - Out << " - !Section" << endl; + Out << " - !Section\n"; Out << " Name: "; - yaml::writeName(Out, sect->Name, sizeof(sect->Name)) << endl; + yaml::writeName(Out, sect->Name, sizeof(sect->Name)) << '\n'; Out << " Characteristics: ["; yaml::writeBitMask(Out, SectionCharacteristicsPairs1, sect->Characteristics); @@ -269,26 +266,26 @@ static llvm::raw_ostream &yamlCOFFSections(llvm::object::COFFObjectFile &Obj, << ", "; yaml::writeBitMask(Out, SectionCharacteristicsPairs2, sect->Characteristics); Out << "] # "; - yaml::writeHexNumber(Out, sect->Characteristics) << endl; + yaml::writeHexNumber(Out, sect->Characteristics) << '\n'; llvm::ArrayRef sectionData; Obj.getSectionContents(sect, sectionData); Out << " SectionData: "; - yaml::writeHexStream(Out, sectionData) << endl; + yaml::writeHexStream(Out, sectionData) << '\n'; if (iter->begin_relocations() != iter->end_relocations()) Out << " Relocations:\n"; for (llvm::object::relocation_iterator rIter = iter->begin_relocations(); rIter != iter->end_relocations(); rIter.increment(ec)) { const llvm::object::coff_relocation *reloc = Obj.getCOFFRelocation(rIter); - Out << " - !Relocation" << endl; + Out << " - !Relocation\n"; Out << " VirtualAddress: " ; - yaml::writeHexNumber(Out, reloc->VirtualAddress) << endl; - Out << " SymbolTableIndex: " << reloc->SymbolTableIndex << endl; + yaml::writeHexNumber(Out, reloc->VirtualAddress) << '\n'; + Out << " SymbolTableIndex: " << reloc->SymbolTableIndex << '\n'; Out << " Type: " - << nameLookup(RelocationTypeX86Pairs, reloc->Type) << endl; + << nameLookup(RelocationTypeX86Pairs, reloc->Type) << '\n'; // TODO: Use the correct reloc type for the machine. - Out << endl; + Out << '\n'; } } @@ -298,7 +295,7 @@ static llvm::raw_ostream &yamlCOFFSections(llvm::object::COFFObjectFile &Obj, static llvm::raw_ostream& yamlCOFFSymbols(llvm::object::COFFObjectFile &Obj, std::size_t NumSymbols, llvm::raw_ostream &Out) { llvm::error_code ec; - Out << "symbols:" << endl; + Out << "symbols:\n"; for (llvm::object::symbol_iterator iter = Obj.begin_symbols(); iter != Obj.end_symbols(); iter.increment(ec)) { // Gather all the info that we need @@ -309,36 +306,36 @@ static llvm::raw_ostream& yamlCOFFSymbols(llvm::object::COFFObjectFile &Obj, std::size_t complexType = symbol->getComplexType(); std::size_t storageClass = symbol->StorageClass; - Out << " - !Symbol" << endl; - Out << " Name: " << str << endl; + Out << " - !Symbol\n"; + Out << " Name: " << str << '\n'; - Out << " Value: " << symbol->Value << endl; - Out << " SectionNumber: " << symbol->SectionNumber << endl; + Out << " Value: " << symbol->Value << '\n'; + Out << " SectionNumber: " << symbol->SectionNumber << '\n'; Out << " SimpleType: " << nameLookup(SymbolBaseTypePairs, simpleType, "# Unknown_SymbolBaseType") - << " # (" << simpleType << ")" << endl; + << " # (" << simpleType << ")\n"; Out << " ComplexType: " << nameLookup(SymbolComplexTypePairs, complexType, "# Unknown_SymbolComplexType") - << " # (" << complexType << ")" << endl; + << " # (" << complexType << ")\n"; Out << " StorageClass: " << nameLookup(SymbolStorageClassPairs, storageClass, "# Unknown_StorageClass") - << " # (" << (int) storageClass << ")" << endl; + << " # (" << (int) storageClass << ")\n"; if (symbol->NumberOfAuxSymbols > 0) { llvm::ArrayRef aux = Obj.getSymbolAuxData(symbol); Out << " NumberOfAuxSymbols: " - << (int) symbol->NumberOfAuxSymbols << endl; + << (int) symbol->NumberOfAuxSymbols << '\n'; Out << " AuxillaryData: "; yaml::writeHexStream(Out, aux); } - Out << endl; + Out << '\n'; } return Out; -- cgit v1.2.3-18-g5258 From 335f1d46d82a4d6b5a7317ccc73178a47b62fc25 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 8 Apr 2013 20:45:01 +0000 Subject: Template the MachO types over the word size. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179051 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/MachODumper.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index 190baa229b..89402808bf 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -161,7 +161,7 @@ static void getSection(const MachOObjectFile *Obj, DataRefImpl DRI, MachOSection &Section) { if (Obj->is64Bit()) { - const MachOFormat::Section64 *Sect = Obj->getSection64(DRI); + const MachOFormat::Section *Sect = Obj->getSection64(DRI); Section.Address = Sect->Address; Section.Size = Sect->Size; @@ -173,7 +173,7 @@ static void getSection(const MachOObjectFile *Obj, Section.Reserved1 = Sect->Reserved1; Section.Reserved2 = Sect->Reserved2; } else { - const MachOFormat::Section *Sect = Obj->getSection(DRI); + const MachOFormat::Section *Sect = Obj->getSection(DRI); Section.Address = Sect->Address; Section.Size = Sect->Size; @@ -191,15 +191,16 @@ static void getSymbol(const MachOObjectFile *Obj, DataRefImpl DRI, MachOSymbol &Symbol) { if (Obj->is64Bit()) { - const MachOFormat::Symbol64TableEntry *Entry = - Obj->getSymbol64TableEntry( DRI); + const MachOFormat::SymbolTableEntry *Entry = + Obj->getSymbol64TableEntry(DRI); Symbol.StringIndex = Entry->StringIndex; Symbol.Type = Entry->Type; Symbol.SectionIndex = Entry->SectionIndex; Symbol.Flags = Entry->Flags; Symbol.Value = Entry->Value; } else { - const MachOFormat::SymbolTableEntry *Entry = Obj->getSymbolTableEntry(DRI); + const MachOFormat::SymbolTableEntry *Entry = + Obj->getSymbolTableEntry(DRI); Symbol.StringIndex = Entry->StringIndex; Symbol.Type = Entry->Type; Symbol.SectionIndex = Entry->SectionIndex; -- cgit v1.2.3-18-g5258 From f6cfc15705140cc958b784a1bc98f7f0f09be6be Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 9 Apr 2013 14:49:08 +0000 Subject: Convert MachOObjectFile to a template. For now it is templated only on being 64 or 32 bits. I will add little/big endian next. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179097 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/MachODump.cpp | 8 ++++---- tools/llvm-objdump/llvm-objdump.cpp | 4 ++-- tools/llvm-readobj/MachODumper.cpp | 28 +++++++++++++++------------- tools/llvm-symbolizer/LLVMSymbolize.cpp | 2 +- 4 files changed, 22 insertions(+), 20 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 7c6565832e..b0a1aca26f 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -52,7 +52,7 @@ static cl::opt static cl::opt DSYMFile("dsym", cl::desc("Use .dSYM file for debug info")); -static const Target *GetTarget(const MachOObjectFile *MachOObj) { +static const Target *GetTarget(const MachOObjectFileBase *MachOObj) { // Figure out the target triple. if (TripleName.empty()) { llvm::Triple TT("unknown-unknown-unknown"); @@ -108,7 +108,7 @@ struct SymbolSorter { // Print additional information about an address, if available. static void DumpAddress(uint64_t Address, ArrayRef Sections, - const MachOObjectFile *MachOObj, raw_ostream &OS) { + const MachOObjectFileBase *MachOObj, raw_ostream &OS) { for (unsigned i = 0; i != Sections.size(); ++i) { uint64_t SectAddr = 0, SectSize = 0; Sections[i].getAddress(SectAddr); @@ -200,7 +200,7 @@ static void emitDOTFile(const char *FileName, const MCFunction &f, } static void getSectionsAndSymbols(const MachOFormat::Header *Header, - MachOObjectFile *MachOObj, + MachOObjectFileBase *MachOObj, std::vector &Sections, std::vector &Symbols, SmallVectorImpl &FoundFns) { @@ -238,7 +238,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) { return; } - OwningPtr MachOOF(static_cast( + OwningPtr MachOOF(static_cast( ObjectFile::createMachOObjectFile(Buff.take()))); const Target *TheTarget = GetTarget(MachOOF.get()); diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 9a36e8253d..4790d7a5fe 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -255,7 +255,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { std::sort(Rels.begin(), Rels.end(), RelocAddressLess); StringRef SegmentName = ""; - if (const MachOObjectFile *MachO = dyn_cast(Obj)) { + if (const MachOObjectFileBase *MachO = dyn_cast(Obj)) { DataRefImpl DR = i->getRawDataRefImpl(); SegmentName = MachO->getSectionFinalSegmentName(DR); } @@ -591,7 +591,7 @@ static void PrintSymbolTable(const ObjectFile *o) { else if (Section == o->end_sections()) outs() << "*UND*"; else { - if (const MachOObjectFile *MachO = dyn_cast(o)) { + if (const MachOObjectFileBase *MachO = dyn_cast(o)) { DataRefImpl DR = Section->getRawDataRefImpl(); StringRef SegmentName = MachO->getSectionFinalSegmentName(DR); outs() << SegmentName << ","; diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index 89402808bf..3dad4d6e54 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -27,7 +27,7 @@ namespace { class MachODumper : public ObjDumper { public: - MachODumper(const llvm::object::MachOObjectFile *Obj, StreamWriter& Writer) + MachODumper(const llvm::object::MachOObjectFileBase *Obj, StreamWriter& Writer) : ObjDumper(Writer) , Obj(Obj) { } @@ -43,7 +43,7 @@ private: void printRelocation(section_iterator SecI, relocation_iterator RelI); - const llvm::object::MachOObjectFile *Obj; + const llvm::object::MachOObjectFileBase *Obj; }; } // namespace @@ -54,7 +54,7 @@ namespace llvm { error_code createMachODumper(const object::ObjectFile *Obj, StreamWriter& Writer, OwningPtr &Result) { - const MachOObjectFile *MachOObj = dyn_cast(Obj); + const MachOObjectFileBase *MachOObj = dyn_cast(Obj); if (!MachOObj) return readobj_error::unsupported_obj_file_format; @@ -157,11 +157,11 @@ namespace { }; } -static void getSection(const MachOObjectFile *Obj, +static void getSection(const MachOObjectFileBase *Obj, DataRefImpl DRI, MachOSection &Section) { - if (Obj->is64Bit()) { - const MachOFormat::Section *Sect = Obj->getSection64(DRI); + if (const MachOObjectFile *O = dyn_cast >(Obj)) { + const MachOObjectFile::Section *Sect = O->getSection(DRI); Section.Address = Sect->Address; Section.Size = Sect->Size; @@ -173,7 +173,8 @@ static void getSection(const MachOObjectFile *Obj, Section.Reserved1 = Sect->Reserved1; Section.Reserved2 = Sect->Reserved2; } else { - const MachOFormat::Section *Sect = Obj->getSection(DRI); + const MachOObjectFile *O2 = cast >(Obj); + const MachOObjectFile::Section *Sect = O2->getSection(DRI); Section.Address = Sect->Address; Section.Size = Sect->Size; @@ -187,20 +188,21 @@ static void getSection(const MachOObjectFile *Obj, } } -static void getSymbol(const MachOObjectFile *Obj, +static void getSymbol(const MachOObjectFileBase *Obj, DataRefImpl DRI, MachOSymbol &Symbol) { - if (Obj->is64Bit()) { - const MachOFormat::SymbolTableEntry *Entry = - Obj->getSymbol64TableEntry(DRI); + if (const MachOObjectFile *O = dyn_cast >(Obj)) { + const MachOObjectFile::SymbolTableEntry *Entry = + O->getSymbolTableEntry(DRI); Symbol.StringIndex = Entry->StringIndex; Symbol.Type = Entry->Type; Symbol.SectionIndex = Entry->SectionIndex; Symbol.Flags = Entry->Flags; Symbol.Value = Entry->Value; } else { - const MachOFormat::SymbolTableEntry *Entry = - Obj->getSymbolTableEntry(DRI); + const MachOObjectFile *O2 = cast >(Obj); + const MachOObjectFile::SymbolTableEntry *Entry = + O2->getSymbolTableEntry(DRI); Symbol.StringIndex = Entry->StringIndex; Symbol.Type = Entry->Type; Symbol.SectionIndex = Entry->SectionIndex; diff --git a/tools/llvm-symbolizer/LLVMSymbolize.cpp b/tools/llvm-symbolizer/LLVMSymbolize.cpp index 29d91a0e92..ffe8712a65 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.cpp +++ b/tools/llvm-symbolizer/LLVMSymbolize.cpp @@ -233,7 +233,7 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) { // On Darwin we may find DWARF in separate object file in // resource directory. ObjectFile *DbgObj = Obj; - if (isa(Obj)) { + if (isa(Obj)) { const std::string &ResourceName = getDarwinDWARFResourceForModule(ModuleName); ObjectFile *ResourceObj = getObjectFile(ResourceName); -- cgit v1.2.3-18-g5258 From a2561a0153237291980722383f409a6499b12efc Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 10 Apr 2013 03:48:25 +0000 Subject: Template the MachO types over endianness. For now they are still only used as little endian. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179147 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/MachODump.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index b0a1aca26f..d1e7d695f6 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -199,7 +199,7 @@ static void emitDOTFile(const char *FileName, const MCFunction &f, Out << "}\n"; } -static void getSectionsAndSymbols(const MachOFormat::Header *Header, +static void getSectionsAndSymbols(const MachOObjectFileBase::Header *Header, MachOObjectFileBase *MachOObj, std::vector &Sections, std::vector &Symbols, @@ -218,12 +218,13 @@ static void getSectionsAndSymbols(const MachOFormat::Header *Header, } for (unsigned i = 0; i != Header->NumLoadCommands; ++i) { - const MachOFormat::LoadCommand *Command = MachOObj->getLoadCommandInfo(i); + const MachOObjectFileBase::LoadCommand *Command = + MachOObj->getLoadCommandInfo(i); if (Command->Type == macho::LCT_FunctionStarts) { // We found a function starts segment, parse the addresses for later // consumption. - const MachOFormat::LinkeditDataLoadCommand *LLC = - reinterpret_cast(Command); + const MachOObjectFileBase::LinkeditDataLoadCommand *LLC = + reinterpret_cast(Command); MachOObj->ReadULEB128s(LLC->DataOffset, FoundFns); } @@ -269,7 +270,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) { outs() << '\n' << Filename << ":\n\n"; - const MachOFormat::Header *Header = MachOOF->getHeader(); + const MachOObjectFileBase::Header *Header = MachOOF->getHeader(); std::vector Sections; std::vector Symbols; -- cgit v1.2.3-18-g5258 From b08c6df6787971502bd51e30b0f1038c1ea0dc2c Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 10 Apr 2013 15:33:44 +0000 Subject: Template MachOObjectFile over endianness too. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179179 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/MachODumper.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index 3dad4d6e54..2073ddf463 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -160,8 +160,8 @@ namespace { static void getSection(const MachOObjectFileBase *Obj, DataRefImpl DRI, MachOSection &Section) { - if (const MachOObjectFile *O = dyn_cast >(Obj)) { - const MachOObjectFile::Section *Sect = O->getSection(DRI); + if (const MachOObjectFile64Le *O = dyn_cast(Obj)) { + const MachOObjectFile64Le::Section *Sect = O->getSection(DRI); Section.Address = Sect->Address; Section.Size = Sect->Size; @@ -173,8 +173,8 @@ static void getSection(const MachOObjectFileBase *Obj, Section.Reserved1 = Sect->Reserved1; Section.Reserved2 = Sect->Reserved2; } else { - const MachOObjectFile *O2 = cast >(Obj); - const MachOObjectFile::Section *Sect = O2->getSection(DRI); + const MachOObjectFile32Le *O2 = cast(Obj); + const MachOObjectFile32Le::Section *Sect = O2->getSection(DRI); Section.Address = Sect->Address; Section.Size = Sect->Size; @@ -191,8 +191,8 @@ static void getSection(const MachOObjectFileBase *Obj, static void getSymbol(const MachOObjectFileBase *Obj, DataRefImpl DRI, MachOSymbol &Symbol) { - if (const MachOObjectFile *O = dyn_cast >(Obj)) { - const MachOObjectFile::SymbolTableEntry *Entry = + if (const MachOObjectFile64Le *O = dyn_cast(Obj)) { + const MachOObjectFile64Le::SymbolTableEntry *Entry = O->getSymbolTableEntry(DRI); Symbol.StringIndex = Entry->StringIndex; Symbol.Type = Entry->Type; @@ -200,8 +200,8 @@ static void getSymbol(const MachOObjectFileBase *Obj, Symbol.Flags = Entry->Flags; Symbol.Value = Entry->Value; } else { - const MachOObjectFile *O2 = cast >(Obj); - const MachOObjectFile::SymbolTableEntry *Entry = + const MachOObjectFile32Le *O2 = cast(Obj); + const MachOObjectFile32Le::SymbolTableEntry *Entry = O2->getSymbolTableEntry(DRI); Symbol.StringIndex = Entry->StringIndex; Symbol.Type = Entry->Type; -- cgit v1.2.3-18-g5258 From 317d3f48fd53be5238dfba5e9fbac51a2366de0e Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 11 Apr 2013 03:34:37 +0000 Subject: Simplify the code. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179259 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/MachODump.cpp | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index d1e7d695f6..89847d0499 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -56,23 +56,7 @@ static const Target *GetTarget(const MachOObjectFileBase *MachOObj) { // Figure out the target triple. if (TripleName.empty()) { llvm::Triple TT("unknown-unknown-unknown"); - switch (MachOObj->getHeader()->CPUType) { - case llvm::MachO::CPUTypeI386: - TT.setArch(Triple::ArchType(Triple::x86)); - break; - case llvm::MachO::CPUTypeX86_64: - TT.setArch(Triple::ArchType(Triple::x86_64)); - break; - case llvm::MachO::CPUTypeARM: - TT.setArch(Triple::ArchType(Triple::arm)); - break; - case llvm::MachO::CPUTypePowerPC: - TT.setArch(Triple::ArchType(Triple::ppc)); - break; - case llvm::MachO::CPUTypePowerPC64: - TT.setArch(Triple::ArchType(Triple::ppc64)); - break; - } + TT.setArch(Triple::ArchType(MachOObj->getArch())); TripleName = TT.str(); } -- cgit v1.2.3-18-g5258 From 4edf092787cab37d46da96eb1e9df0677ca30b1d Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 11 Apr 2013 16:31:37 +0000 Subject: Print more information about relocations. With this patch llvm-readobj now prints if a relocation is pcrel, its length, if it is extern and if it is scattered. It also refactors the code a bit to use bit fields instead of shifts and masks all over the place. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179294 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/MachODumper.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index 2073ddf463..b027d40bea 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -330,20 +330,28 @@ void MachODumper::printRelocation(section_iterator SecI, relocation_iterator RelI) { uint64_t Offset; SmallString<32> RelocName; - int64_t Info; StringRef SymbolName; SymbolRef Symbol; if (error(RelI->getOffset(Offset))) return; if (error(RelI->getTypeName(RelocName))) return; - if (error(RelI->getAdditionalInfo(Info))) return; if (error(RelI->getSymbol(Symbol))) return; if (error(Symbol.getName(SymbolName))) return; + DataRefImpl DR = RelI->getRawDataRefImpl(); + const MachOObjectFileBase::RelocationEntry *RE = Obj->getRelocation(DR); + bool IsScattered = Obj->isScattered(RE); + raw_ostream& OS = W.startLine(); OS << W.hex(Offset) - << " " << RelocName + << " " << Obj->isPCRel(RE) + << " " << Obj->getLength(RE); + if (IsScattered) + OS << " n/a"; + else + OS << " " << RE->External; + OS << " " << RelocName + << " " << IsScattered << " " << (SymbolName.size() > 0 ? SymbolName : "-") - << " " << W.hex(Info) << "\n"; } -- cgit v1.2.3-18-g5258 From 59a8b5a8f09ae4c4f3b0e3d8025c6b4cf3ca1f1a Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 11 Apr 2013 17:46:10 +0000 Subject: Revert my last two commits while I debug what is wrong in a big endian host. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179303 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/MachODumper.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index b027d40bea..2073ddf463 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -330,28 +330,20 @@ void MachODumper::printRelocation(section_iterator SecI, relocation_iterator RelI) { uint64_t Offset; SmallString<32> RelocName; + int64_t Info; StringRef SymbolName; SymbolRef Symbol; if (error(RelI->getOffset(Offset))) return; if (error(RelI->getTypeName(RelocName))) return; + if (error(RelI->getAdditionalInfo(Info))) return; if (error(RelI->getSymbol(Symbol))) return; if (error(Symbol.getName(SymbolName))) return; - DataRefImpl DR = RelI->getRawDataRefImpl(); - const MachOObjectFileBase::RelocationEntry *RE = Obj->getRelocation(DR); - bool IsScattered = Obj->isScattered(RE); - raw_ostream& OS = W.startLine(); OS << W.hex(Offset) - << " " << Obj->isPCRel(RE) - << " " << Obj->getLength(RE); - if (IsScattered) - OS << " n/a"; - else - OS << " " << RE->External; - OS << " " << RelocName - << " " << IsScattered + << " " << RelocName << " " << (SymbolName.size() > 0 ? SymbolName : "-") + << " " << W.hex(Info) << "\n"; } -- cgit v1.2.3-18-g5258 From e292347503cd7598429c08f9984ab3e0a44ab8a3 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 12 Apr 2013 00:17:33 +0000 Subject: Add 179294 back, but don't use bit fields so that it works on big endian hosts. Original message: Print more information about relocations. With this patch llvm-readobj now prints if a relocation is pcrel, its length, if it is extern and if it is scattered. It also refactors the code a bit to use bit fields instead of shifts and masks all over the place. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179345 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/MachODumper.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index 2073ddf463..a13593b448 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -330,20 +330,28 @@ void MachODumper::printRelocation(section_iterator SecI, relocation_iterator RelI) { uint64_t Offset; SmallString<32> RelocName; - int64_t Info; StringRef SymbolName; SymbolRef Symbol; if (error(RelI->getOffset(Offset))) return; if (error(RelI->getTypeName(RelocName))) return; - if (error(RelI->getAdditionalInfo(Info))) return; if (error(RelI->getSymbol(Symbol))) return; if (error(Symbol.getName(SymbolName))) return; + DataRefImpl DR = RelI->getRawDataRefImpl(); + const MachOObjectFileBase::RelocationEntry *RE = Obj->getRelocation(DR); + bool IsScattered = Obj->isScattered(RE); + raw_ostream& OS = W.startLine(); OS << W.hex(Offset) - << " " << RelocName + << " " << Obj->isPCRel(RE) + << " " << Obj->getLength(RE); + if (IsScattered) + OS << " n/a"; + else + OS << " " << RE->getExternal(); + OS << " " << RelocName + << " " << IsScattered << " " << (SymbolName.size() > 0 ? SymbolName : "-") - << " " << W.hex(Info) << "\n"; } -- cgit v1.2.3-18-g5258 From 1c8dfa5e90fa7ba5d351d2e2511dc1495c83f6fd Mon Sep 17 00:00:00 2001 From: Nico Rieck Date: Fri, 12 Apr 2013 04:01:52 +0000 Subject: Add -expand-relocs to llvm-readobj This option expands shown relocations from single line to a dictionary format: Relocation { Offset: 0x4 Type: R_386_32 (1) Symbol: sym Info: 0x0 } git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179359 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/COFFDumper.cpp | 17 ++++++++++++----- tools/llvm-readobj/ELFDumper.cpp | 22 +++++++++++++++------ tools/llvm-readobj/MachODumper.cpp | 38 +++++++++++++++++++++++++------------ tools/llvm-readobj/llvm-readobj.cpp | 4 ++++ tools/llvm-readobj/llvm-readobj.h | 1 + 5 files changed, 59 insertions(+), 23 deletions(-) (limited to 'tools') diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp index be4e76cc63..d600bc3fd2 100644 --- a/tools/llvm-readobj/COFFDumper.cpp +++ b/tools/llvm-readobj/COFFDumper.cpp @@ -680,11 +680,18 @@ void COFFDumper::printRelocation(section_iterator SecI, if (error(Symbol.getName(SymbolName))) return; if (error(SecI->getContents(Contents))) return; - raw_ostream& OS = W.startLine(); - OS << W.hex(Offset) - << " " << RelocName - << " " << (SymbolName.size() > 0 ? SymbolName : "-") - << "\n"; + if (opts::ExpandRelocs) { + DictScope Group(W, "Relocation"); + W.printHex("Offset", Offset); + W.printNumber("Type", RelocName, RelocType); + W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-"); + } else { + raw_ostream& OS = W.startLine(); + OS << W.hex(Offset) + << " " << RelocName + << " " << (SymbolName.size() > 0 ? SymbolName : "-") + << "\n"; + } } void COFFDumper::printSymbols() { diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index 9e111dd905..b0e2734ac9 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -549,22 +549,32 @@ template void ELFDumper::printRelocation(section_iterator Sec, relocation_iterator RelI) { uint64_t Offset; + uint64_t RelocType; SmallString<32> RelocName; int64_t Info; StringRef SymbolName; SymbolRef Symbol; if (error(RelI->getOffset(Offset))) return; + if (error(RelI->getType(RelocType))) return; if (error(RelI->getTypeName(RelocName))) return; if (error(RelI->getAdditionalInfo(Info))) return; if (error(RelI->getSymbol(Symbol))) return; if (error(Symbol.getName(SymbolName))) return; - raw_ostream& OS = W.startLine(); - OS << W.hex(Offset) - << " " << RelocName - << " " << (SymbolName.size() > 0 ? SymbolName : "-") - << " " << W.hex(Info) - << "\n"; + if (opts::ExpandRelocs) { + DictScope Group(W, "Relocation"); + W.printHex("Offset", Offset); + W.printNumber("Type", RelocName, RelocType); + W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-"); + W.printHex("Info", Info); + } else { + raw_ostream& OS = W.startLine(); + OS << W.hex(Offset) + << " " << RelocName + << " " << (SymbolName.size() > 0 ? SymbolName : "-") + << " " << W.hex(Info) + << "\n"; + } } template diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index a13593b448..69f1d63b12 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -341,18 +341,32 @@ void MachODumper::printRelocation(section_iterator SecI, const MachOObjectFileBase::RelocationEntry *RE = Obj->getRelocation(DR); bool IsScattered = Obj->isScattered(RE); - raw_ostream& OS = W.startLine(); - OS << W.hex(Offset) - << " " << Obj->isPCRel(RE) - << " " << Obj->getLength(RE); - if (IsScattered) - OS << " n/a"; - else - OS << " " << RE->getExternal(); - OS << " " << RelocName - << " " << IsScattered - << " " << (SymbolName.size() > 0 ? SymbolName : "-") - << "\n"; + if (opts::ExpandRelocs) { + DictScope Group(W, "Relocation"); + W.printHex("Offset", Offset); + W.printNumber("PCRel", Obj->isPCRel(RE)); + W.printNumber("Length", Obj->getLength(RE)); + if (IsScattered) + W.printString("Extern", StringRef("N/A")); + else + W.printNumber("Extern", RE->getExternal()); + W.printNumber("Type", RelocName, RE->getType()); + W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-"); + W.printNumber("Scattered", IsScattered); + } else { + raw_ostream& OS = W.startLine(); + OS << W.hex(Offset) + << " " << Obj->isPCRel(RE) + << " " << Obj->getLength(RE); + if (IsScattered) + OS << " n/a"; + else + OS << " " << RE->getExternal(); + OS << " " << RelocName + << " " << IsScattered + << " " << (SymbolName.size() > 0 ? SymbolName : "-") + << "\n"; + } } void MachODumper::printSymbols() { diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index 67c9a98f40..9d5cfcbd6a 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -120,6 +120,10 @@ namespace opts { // -needed-libs cl::opt NeededLibraries("needed-libs", cl::desc("Display the needed libraries")); + + // -expand-relocs + cl::opt ExpandRelocs("expand-relocs", + cl::desc("Expand each shown relocation to multiple lines")); } // namespace opts namespace llvm { diff --git a/tools/llvm-readobj/llvm-readobj.h b/tools/llvm-readobj/llvm-readobj.h index be18268a7f..3f756106c9 100644 --- a/tools/llvm-readobj/llvm-readobj.h +++ b/tools/llvm-readobj/llvm-readobj.h @@ -37,6 +37,7 @@ namespace opts { extern llvm::cl::opt Symbols; extern llvm::cl::opt DynamicSymbols; extern llvm::cl::opt UnwindInfo; + extern llvm::cl::opt ExpandRelocs; } // namespace opts #define LLVM_READOBJ_ENUM_ENT(ns, enum) \ -- cgit v1.2.3-18-g5258 From cf3b55ab18b6d0f5b658e746b57ec3cf193d5688 Mon Sep 17 00:00:00 2001 From: Nico Rieck Date: Fri, 12 Apr 2013 04:07:39 +0000 Subject: Teach llvm-readobj to print ELF program headers git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179363 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/ELFDumper.cpp | 56 +++++++++++++++++++++++++++++++++---- tools/llvm-readobj/ObjDumper.h | 1 + tools/llvm-readobj/llvm-readobj.cpp | 6 ++++ 3 files changed, 58 insertions(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index b0e2734ac9..3757b09c39 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -50,16 +50,18 @@ public: virtual void printDynamicTable() LLVM_OVERRIDE; virtual void printNeededLibraries() LLVM_OVERRIDE; + virtual void printProgramHeaders() LLVM_OVERRIDE; private: - typedef typename ELFObjectFile::Elf_Shdr Elf_Shdr; - typedef typename ELFObjectFile::Elf_Sym Elf_Sym; + typedef ELFObjectFile ELFO; + typedef typename ELFO::Elf_Shdr Elf_Shdr; + typedef typename ELFO::Elf_Sym Elf_Sym; void printSymbol(symbol_iterator SymI, bool IsDynamic = false); void printRelocation(section_iterator SecI, relocation_iterator RelI); - const ELFObjectFile *Obj; + const ELFO *Obj; }; } // namespace @@ -399,11 +401,37 @@ static const EnumEntry ElfSectionFlags[] = { LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NOSTRIP ) }; +static const EnumEntry ElfSegmentTypes[] = { + LLVM_READOBJ_ENUM_ENT(ELF, PT_NULL ), + LLVM_READOBJ_ENUM_ENT(ELF, PT_LOAD ), + LLVM_READOBJ_ENUM_ENT(ELF, PT_DYNAMIC), + LLVM_READOBJ_ENUM_ENT(ELF, PT_INTERP ), + LLVM_READOBJ_ENUM_ENT(ELF, PT_NOTE ), + LLVM_READOBJ_ENUM_ENT(ELF, PT_SHLIB ), + LLVM_READOBJ_ENUM_ENT(ELF, PT_PHDR ), + LLVM_READOBJ_ENUM_ENT(ELF, PT_TLS ), + + LLVM_READOBJ_ENUM_ENT(ELF, PT_GNU_EH_FRAME), + LLVM_READOBJ_ENUM_ENT(ELF, PT_SUNW_EH_FRAME), + LLVM_READOBJ_ENUM_ENT(ELF, PT_SUNW_UNWIND), + + LLVM_READOBJ_ENUM_ENT(ELF, PT_GNU_STACK), + LLVM_READOBJ_ENUM_ENT(ELF, PT_GNU_RELRO), + + LLVM_READOBJ_ENUM_ENT(ELF, PT_ARM_EXIDX), + LLVM_READOBJ_ENUM_ENT(ELF, PT_ARM_UNWIND) +}; + +static const EnumEntry ElfSegmentFlags[] = { + LLVM_READOBJ_ENUM_ENT(ELF, PF_X), + LLVM_READOBJ_ENUM_ENT(ELF, PF_W), + LLVM_READOBJ_ENUM_ENT(ELF, PF_R) +}; + template void ELFDumper::printFileHeaders() { error_code EC; - typedef ELFObjectFile ELFO; const typename ELFO::Elf_Ehdr *Header = Obj->getElfHeader(); @@ -745,7 +773,6 @@ void ELFDumper::printUnwindInfo() { template void ELFDumper::printDynamicTable() { - typedef ELFObjectFile ELFO; typedef typename ELFO::Elf_Dyn_iterator EDI; EDI Start = Obj->begin_dynamic_table(), End = Obj->end_dynamic_table(true); @@ -808,3 +835,22 @@ void ELFDumper::printNeededLibraries() { outs() << " " << Path << "\n"; } } + +template +void ELFDumper::printProgramHeaders() { + ListScope L(W, "ProgramHeaders"); + + for (typename ELFO::Elf_Phdr_Iter PI = Obj->begin_program_headers(), + PE = Obj->end_program_headers(); + PI != PE; ++PI) { + DictScope P(W, "ProgramHeader"); + W.printEnum ("Type", PI->p_type, makeArrayRef(ElfSegmentTypes)); + W.printHex ("Offset", PI->p_offset); + W.printHex ("VirtualAddress", PI->p_vaddr); + W.printHex ("PhysicalAddress", PI->p_paddr); + W.printNumber("FileSize", PI->p_filesz); + W.printNumber("MemSize", PI->p_memsz); + W.printFlags ("Flags", PI->p_flags, makeArrayRef(ElfSegmentFlags)); + W.printNumber("Alignment", PI->p_align); + } +} diff --git a/tools/llvm-readobj/ObjDumper.h b/tools/llvm-readobj/ObjDumper.h index 8d191cbe07..6918e28cb9 100644 --- a/tools/llvm-readobj/ObjDumper.h +++ b/tools/llvm-readobj/ObjDumper.h @@ -38,6 +38,7 @@ public: // Only implemented for ELF at this time. virtual void printDynamicTable() { } virtual void printNeededLibraries() { } + virtual void printProgramHeaders() { } protected: StreamWriter& W; diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index 9d5cfcbd6a..7a4b4e4431 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -121,6 +121,10 @@ namespace opts { cl::opt NeededLibraries("needed-libs", cl::desc("Display the needed libraries")); + // -program-headers + cl::opt ProgramHeaders("program-headers", + cl::desc("Display ELF program headers")); + // -expand-relocs cl::opt ExpandRelocs("expand-relocs", cl::desc("Expand each shown relocation to multiple lines")); @@ -215,6 +219,8 @@ static void dumpObject(const ObjectFile *Obj) { Dumper->printDynamicTable(); if (opts::NeededLibraries) Dumper->printNeededLibraries(); + if (opts::ProgramHeaders) + Dumper->printProgramHeaders(); } -- cgit v1.2.3-18-g5258 From 200241e4de11981523b3d14f3acab6129efed701 Mon Sep 17 00:00:00 2001 From: Andy Gibbs Date: Fri, 12 Apr 2013 10:56:28 +0000 Subject: Replace uses of the deprecated std::auto_ptr with OwningPtr. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179373 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/bugpoint/BugDriver.cpp | 2 +- tools/llc/llc.cpp | 4 ++-- tools/llvm-as/llvm-as.cpp | 2 +- tools/llvm-dis/llvm-dis.cpp | 2 +- tools/llvm-extract/llvm-extract.cpp | 2 +- tools/llvm-link/llvm-link.cpp | 19 +++++++++---------- tools/llvm-ranlib/llvm-ranlib.cpp | 2 +- tools/opt/opt.cpp | 4 ++-- 8 files changed, 18 insertions(+), 19 deletions(-) (limited to 'tools') diff --git a/tools/bugpoint/BugDriver.cpp b/tools/bugpoint/BugDriver.cpp index e49a96b1e0..937d86a5b8 100644 --- a/tools/bugpoint/BugDriver.cpp +++ b/tools/bugpoint/BugDriver.cpp @@ -122,7 +122,7 @@ bool BugDriver::addSources(const std::vector &Filenames) { outs() << "Read input file : '" << Filenames[0] << "'\n"; for (unsigned i = 1, e = Filenames.size(); i != e; ++i) { - std::auto_ptr M(ParseInputFile(Filenames[i], Context)); + OwningPtr M(ParseInputFile(Filenames[i], Context)); if (M.get() == 0) return true; outs() << "Linking in input file: '" << Filenames[i] << "'\n"; diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index 1dce9d7b60..8a462c608a 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -200,7 +200,7 @@ int main(int argc, char **argv) { static int compileModule(char **argv, LLVMContext &Context) { // Load the module to be compiled... SMDiagnostic Err; - std::auto_ptr M; + OwningPtr M; Module *mod = 0; Triple TheTriple; @@ -281,7 +281,7 @@ static int compileModule(char **argv, LLVMContext &Context) { Options.UseInitArray = UseInitArray; Options.SSPBufferSize = SSPBufferSize; - std::auto_ptr + OwningPtr target(TheTarget->createTargetMachine(TheTriple.getTriple(), MCPU, FeaturesStr, Options, RelocModel, CMModel, OLvl)); diff --git a/tools/llvm-as/llvm-as.cpp b/tools/llvm-as/llvm-as.cpp index 273c4274b5..d6f191961d 100644 --- a/tools/llvm-as/llvm-as.cpp +++ b/tools/llvm-as/llvm-as.cpp @@ -94,7 +94,7 @@ int main(int argc, char **argv) { // Parse the file now... SMDiagnostic Err; - std::auto_ptr M(ParseAssemblyFile(InputFilename, Err, Context)); + OwningPtr M(ParseAssemblyFile(InputFilename, Err, Context)); if (M.get() == 0) { Err.print(argv[0], errs()); return 1; diff --git a/tools/llvm-dis/llvm-dis.cpp b/tools/llvm-dis/llvm-dis.cpp index 2baa91da50..067955e5cc 100644 --- a/tools/llvm-dis/llvm-dis.cpp +++ b/tools/llvm-dis/llvm-dis.cpp @@ -123,7 +123,7 @@ int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n"); std::string ErrorMessage; - std::auto_ptr M; + OwningPtr M; // Use the bitcode streaming interface DataStreamer *streamer = getDataFileStreamer(InputFilename, &ErrorMessage); diff --git a/tools/llvm-extract/llvm-extract.cpp b/tools/llvm-extract/llvm-extract.cpp index fd0a381807..2f45b4eae5 100644 --- a/tools/llvm-extract/llvm-extract.cpp +++ b/tools/llvm-extract/llvm-extract.cpp @@ -100,7 +100,7 @@ int main(int argc, char **argv) { // Use lazy loading, since we only care about selected global values. SMDiagnostic Err; - std::auto_ptr M; + OwningPtr M; M.reset(getLazyIRFileModule(InputFilename, Err, Context)); if (M.get() == 0) { diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp index 83665cc175..b195ca88de 100644 --- a/tools/llvm-link/llvm-link.cpp +++ b/tools/llvm-link/llvm-link.cpp @@ -53,13 +53,13 @@ DumpAsm("d", cl::desc("Print assembly as linked"), cl::Hidden); // LoadFile - Read the specified bitcode file in and return it. This routine // searches the link path for the specified file to try to find it... // -static inline std::auto_ptr LoadFile(const char *argv0, - const std::string &FN, - LLVMContext& Context) { +static inline OwningPtr LoadFile(const char *argv0, + const std::string &FN, + LLVMContext& Context) { sys::Path Filename; if (!Filename.set(FN)) { errs() << "Invalid file name: '" << FN << "'\n"; - return std::auto_ptr(); + return OwningPtr(); } SMDiagnostic Err; @@ -68,10 +68,10 @@ static inline std::auto_ptr LoadFile(const char *argv0, const std::string &FNStr = Filename.str(); Result = ParseIRFile(FNStr, Err, Context); - if (Result) return std::auto_ptr(Result); // Load successful! + if (Result) return OwningPtr(Result); // Load successful! Err.print(argv0, errs()); - return std::auto_ptr(); + return OwningPtr(); } int main(int argc, char **argv) { @@ -86,8 +86,8 @@ int main(int argc, char **argv) { unsigned BaseArg = 0; std::string ErrorMessage; - std::auto_ptr Composite(LoadFile(argv[0], - InputFilenames[BaseArg], Context)); + OwningPtr Composite(LoadFile(argv[0], + InputFilenames[BaseArg], Context)); if (Composite.get() == 0) { errs() << argv[0] << ": error loading file '" << InputFilenames[BaseArg] << "'\n"; @@ -95,8 +95,7 @@ int main(int argc, char **argv) { } for (unsigned i = BaseArg+1; i < InputFilenames.size(); ++i) { - std::auto_ptr M(LoadFile(argv[0], - InputFilenames[i], Context)); + OwningPtr M(LoadFile(argv[0], InputFilenames[i], Context)); if (M.get() == 0) { errs() << argv[0] << ": error loading file '" < + OwningPtr AutoArchive(Archive::OpenAndLoad(ArchivePath, Context, &err_msg)); Archive* TheArchive = AutoArchive.get(); if (!TheArchive) { diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index ba82bded2b..e385d7f577 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -589,7 +589,7 @@ int main(int argc, char **argv) { SMDiagnostic Err; // Load the input module... - std::auto_ptr M; + OwningPtr M; M.reset(ParseIRFile(InputFilename, Err, Context)); if (M.get() == 0) { @@ -656,7 +656,7 @@ int main(int argc, char **argv) { TargetMachine *Machine = 0; if (ModuleTriple.getArch()) Machine = GetTargetMachine(Triple(ModuleTriple)); - std::auto_ptr TM(Machine); + OwningPtr TM(Machine); // Add internal analysis passes from the target machine. if (TM.get()) -- cgit v1.2.3-18-g5258 From 3389e10d675f7723d3ab24deda60dfba568b42c0 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Fri, 12 Apr 2013 12:13:51 +0000 Subject: Revert broken pieces of r179373. You can't copy an OwningPtr, and move semantics aren't available in C++98. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179374 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-link/llvm-link.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp index b195ca88de..83665cc175 100644 --- a/tools/llvm-link/llvm-link.cpp +++ b/tools/llvm-link/llvm-link.cpp @@ -53,13 +53,13 @@ DumpAsm("d", cl::desc("Print assembly as linked"), cl::Hidden); // LoadFile - Read the specified bitcode file in and return it. This routine // searches the link path for the specified file to try to find it... // -static inline OwningPtr LoadFile(const char *argv0, - const std::string &FN, - LLVMContext& Context) { +static inline std::auto_ptr LoadFile(const char *argv0, + const std::string &FN, + LLVMContext& Context) { sys::Path Filename; if (!Filename.set(FN)) { errs() << "Invalid file name: '" << FN << "'\n"; - return OwningPtr(); + return std::auto_ptr(); } SMDiagnostic Err; @@ -68,10 +68,10 @@ static inline OwningPtr LoadFile(const char *argv0, const std::string &FNStr = Filename.str(); Result = ParseIRFile(FNStr, Err, Context); - if (Result) return OwningPtr(Result); // Load successful! + if (Result) return std::auto_ptr(Result); // Load successful! Err.print(argv0, errs()); - return OwningPtr(); + return std::auto_ptr(); } int main(int argc, char **argv) { @@ -86,8 +86,8 @@ int main(int argc, char **argv) { unsigned BaseArg = 0; std::string ErrorMessage; - OwningPtr Composite(LoadFile(argv[0], - InputFilenames[BaseArg], Context)); + std::auto_ptr Composite(LoadFile(argv[0], + InputFilenames[BaseArg], Context)); if (Composite.get() == 0) { errs() << argv[0] << ": error loading file '" << InputFilenames[BaseArg] << "'\n"; @@ -95,7 +95,8 @@ int main(int argc, char **argv) { } for (unsigned i = BaseArg+1; i < InputFilenames.size(); ++i) { - OwningPtr M(LoadFile(argv[0], InputFilenames[i], Context)); + std::auto_ptr M(LoadFile(argv[0], + InputFilenames[i], Context)); if (M.get() == 0) { errs() << argv[0] << ": error loading file '" < Date: Sat, 13 Apr 2013 01:45:40 +0000 Subject: Finish templating MachObjectFile over endianness. We are now able to handle big endian macho files in llvm-readobject. Thanks to David Fang for providing the object files. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179440 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/MachODump.cpp | 48 +++++++++---- tools/llvm-objdump/llvm-objdump.cpp | 18 +++-- tools/llvm-readobj/MachODumper.cpp | 132 ++++++++++++++++++++++-------------- 3 files changed, 128 insertions(+), 70 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 89847d0499..4b6cb5f54c 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -27,6 +27,7 @@ #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Object/MachO.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Format.h" @@ -183,11 +184,14 @@ static void emitDOTFile(const char *FileName, const MCFunction &f, Out << "}\n"; } -static void getSectionsAndSymbols(const MachOObjectFileBase::Header *Header, - MachOObjectFileBase *MachOObj, - std::vector &Sections, - std::vector &Symbols, - SmallVectorImpl &FoundFns) { +template +static void +getSectionsAndSymbols(const typename MachOObjectFileMiddle::Header *Header, + const MachOObjectFileMiddle *MachOObj, + std::vector &Sections, + std::vector &Symbols, + SmallVectorImpl &FoundFns) { + typedef MachOObjectFileMiddle ObjType; error_code ec; for (symbol_iterator SI = MachOObj->begin_symbols(), SE = MachOObj->end_symbols(); SI != SE; SI.increment(ec)) @@ -202,19 +206,23 @@ static void getSectionsAndSymbols(const MachOObjectFileBase::Header *Header, } for (unsigned i = 0; i != Header->NumLoadCommands; ++i) { - const MachOObjectFileBase::LoadCommand *Command = + const typename ObjType::LoadCommand *Command = MachOObj->getLoadCommandInfo(i); if (Command->Type == macho::LCT_FunctionStarts) { // We found a function starts segment, parse the addresses for later // consumption. - const MachOObjectFileBase::LinkeditDataLoadCommand *LLC = - reinterpret_cast(Command); + const typename ObjType::LinkeditDataLoadCommand *LLC = + reinterpret_cast(Command); MachOObj->ReadULEB128s(LLC->DataOffset, FoundFns); } } } +template +static void DisassembleInputMachO2(StringRef Filename, + MachOObjectFileMiddle *MachOOF); + void llvm::DisassembleInputMachO(StringRef Filename) { OwningPtr Buff; @@ -226,7 +234,18 @@ void llvm::DisassembleInputMachO(StringRef Filename) { OwningPtr MachOOF(static_cast( ObjectFile::createMachOObjectFile(Buff.take()))); - const Target *TheTarget = GetTarget(MachOOF.get()); + if (MachOObjectFileLE *O = dyn_cast(MachOOF.get())) { + DisassembleInputMachO2(Filename, O); + return; + } + MachOObjectFileBE *O = cast(MachOOF.get()); + DisassembleInputMachO2(Filename, O); +} + +template +static void DisassembleInputMachO2(StringRef Filename, + MachOObjectFileMiddle *MachOOF) { + const Target *TheTarget = GetTarget(MachOOF); if (!TheTarget) { // GetTarget prints out stuff. return; @@ -254,13 +273,14 @@ void llvm::DisassembleInputMachO(StringRef Filename) { outs() << '\n' << Filename << ":\n\n"; - const MachOObjectFileBase::Header *Header = MachOOF->getHeader(); + const typename MachOObjectFileMiddle::Header *Header = + MachOOF->getHeader(); std::vector Sections; std::vector Symbols; SmallVector FoundFns; - getSectionsAndSymbols(Header, MachOOF.get(), Sections, Symbols, FoundFns); + getSectionsAndSymbols(Header, MachOOF, Sections, Symbols, FoundFns); // Make a copy of the unsorted symbol list. FIXME: duplication std::vector UnsortedSymbols(Symbols); @@ -274,7 +294,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) { #endif OwningPtr diContext; - ObjectFile *DbgObj = MachOOF.get(); + ObjectFile *DbgObj = MachOOF; // Try to find debug info and set up the DIContext for it. if (UseDbg) { // A separate DSym file path was specified, parse it as a macho file, @@ -563,7 +583,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) { Relocs[j].second.getName(SymName); outs() << "\t# " << SymName << ' '; - DumpAddress(Addr, Sections, MachOOF.get(), outs()); + DumpAddress(Addr, Sections, MachOOF, outs()); } // If this instructions contains an address, see if we can evaluate @@ -572,7 +592,7 @@ void llvm::DisassembleInputMachO(StringRef Filename) { Inst.Address, Inst.Size); if (targ != -1ULL) - DumpAddress(targ, Sections, MachOOF.get(), outs()); + DumpAddress(targ, Sections, MachOOF, outs()); // Print debug info. if (diContext) { diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 4790d7a5fe..5a0519ddc1 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -191,6 +191,14 @@ bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) { return a_addr < b_addr; } +StringRef +getSectionFinalSegmentName(const MachOObjectFileBase *MachO, DataRefImpl DR) { + if (const MachOObjectFileLE *O = dyn_cast(MachO)) + return O->getSectionFinalSegmentName(DR); + const MachOObjectFileBE *O = dyn_cast(MachO); + return O->getSectionFinalSegmentName(DR); +} + static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { const Target *TheTarget = getTarget(Obj); // getTarget() will have already issued a diagnostic if necessary, so @@ -255,9 +263,10 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { std::sort(Rels.begin(), Rels.end(), RelocAddressLess); StringRef SegmentName = ""; - if (const MachOObjectFileBase *MachO = dyn_cast(Obj)) { + if (const MachOObjectFileBase *MachO = + dyn_cast(Obj)) { DataRefImpl DR = i->getRawDataRefImpl(); - SegmentName = MachO->getSectionFinalSegmentName(DR); + SegmentName = getSectionFinalSegmentName(MachO, DR); } StringRef name; if (error(i->getName(name))) break; @@ -591,9 +600,10 @@ static void PrintSymbolTable(const ObjectFile *o) { else if (Section == o->end_sections()) outs() << "*UND*"; else { - if (const MachOObjectFileBase *MachO = dyn_cast(o)) { + if (const MachOObjectFileBase *MachO = + dyn_cast(o)) { DataRefImpl DR = Section->getRawDataRefImpl(); - StringRef SegmentName = MachO->getSectionFinalSegmentName(DR); + StringRef SegmentName = getSectionFinalSegmentName(MachO, DR); outs() << SegmentName << ","; } StringRef SectionName; diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index 69f1d63b12..d207eabb52 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -27,7 +27,7 @@ namespace { class MachODumper : public ObjDumper { public: - MachODumper(const llvm::object::MachOObjectFileBase *Obj, StreamWriter& Writer) + MachODumper(const MachOObjectFileBase *Obj, StreamWriter& Writer) : ObjDumper(Writer) , Obj(Obj) { } @@ -43,7 +43,14 @@ private: void printRelocation(section_iterator SecI, relocation_iterator RelI); - const llvm::object::MachOObjectFileBase *Obj; + template + void printRelocation(const MachOObjectFileMiddle *Obj, + section_iterator SecI, relocation_iterator RelI); + + template + void printSections(const MachOObjectFileMiddle *Obj); + + const MachOObjectFileBase *Obj; }; } // namespace @@ -157,58 +164,59 @@ namespace { }; } +template +static void getSection(const MachOObjectFile *Obj, + DataRefImpl DRI, + MachOSection &Section) { + const typename MachOObjectFile::Section *Sect = Obj->getSection(DRI); + Section.Address = Sect->Address; + Section.Size = Sect->Size; + Section.Offset = Sect->Offset; + Section.Alignment = Sect->Align; + Section.RelocationTableOffset = Sect->RelocationTableOffset; + Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries; + Section.Flags = Sect->Flags; + Section.Reserved1 = Sect->Reserved1; + Section.Reserved2 = Sect->Reserved2; +} + static void getSection(const MachOObjectFileBase *Obj, DataRefImpl DRI, MachOSection &Section) { - if (const MachOObjectFile64Le *O = dyn_cast(Obj)) { - const MachOObjectFile64Le::Section *Sect = O->getSection(DRI); - - Section.Address = Sect->Address; - Section.Size = Sect->Size; - Section.Offset = Sect->Offset; - Section.Alignment = Sect->Align; - Section.RelocationTableOffset = Sect->RelocationTableOffset; - Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries; - Section.Flags = Sect->Flags; - Section.Reserved1 = Sect->Reserved1; - Section.Reserved2 = Sect->Reserved2; - } else { - const MachOObjectFile32Le *O2 = cast(Obj); - const MachOObjectFile32Le::Section *Sect = O2->getSection(DRI); - - Section.Address = Sect->Address; - Section.Size = Sect->Size; - Section.Offset = Sect->Offset; - Section.Alignment = Sect->Align; - Section.RelocationTableOffset = Sect->RelocationTableOffset; - Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries; - Section.Flags = Sect->Flags; - Section.Reserved1 = Sect->Reserved1; - Section.Reserved2 = Sect->Reserved2; - } + if (const MachOObjectFileLE32 *O = dyn_cast(Obj)) + return getSection(O, DRI, Section); + if (const MachOObjectFileLE64 *O = dyn_cast(Obj)) + return getSection(O, DRI, Section); + if (const MachOObjectFileBE32 *O = dyn_cast(Obj)) + return getSection(O, DRI, Section); + const MachOObjectFileBE64 *O = cast(Obj); + getSection(O, DRI, Section); +} + +template +static void getSymbol(const MachOObjectFile *Obj, + DataRefImpl DRI, + MachOSymbol &Symbol) { + const typename MachOObjectFile::SymbolTableEntry *Entry = + Obj->getSymbolTableEntry(DRI); + Symbol.StringIndex = Entry->StringIndex; + Symbol.Type = Entry->Type; + Symbol.SectionIndex = Entry->SectionIndex; + Symbol.Flags = Entry->Flags; + Symbol.Value = Entry->Value; } static void getSymbol(const MachOObjectFileBase *Obj, DataRefImpl DRI, MachOSymbol &Symbol) { - if (const MachOObjectFile64Le *O = dyn_cast(Obj)) { - const MachOObjectFile64Le::SymbolTableEntry *Entry = - O->getSymbolTableEntry(DRI); - Symbol.StringIndex = Entry->StringIndex; - Symbol.Type = Entry->Type; - Symbol.SectionIndex = Entry->SectionIndex; - Symbol.Flags = Entry->Flags; - Symbol.Value = Entry->Value; - } else { - const MachOObjectFile32Le *O2 = cast(Obj); - const MachOObjectFile32Le::SymbolTableEntry *Entry = - O2->getSymbolTableEntry(DRI); - Symbol.StringIndex = Entry->StringIndex; - Symbol.Type = Entry->Type; - Symbol.SectionIndex = Entry->SectionIndex; - Symbol.Flags = Entry->Flags; - Symbol.Value = Entry->Value; - } + if (const MachOObjectFileLE32 *O = dyn_cast(Obj)) + return getSymbol(O, DRI, Symbol); + if (const MachOObjectFileLE64 *O = dyn_cast(Obj)) + return getSymbol(O, DRI, Symbol); + if (const MachOObjectFileBE32 *O = dyn_cast(Obj)) + return getSymbol(O, DRI, Symbol); + const MachOObjectFileBE64 *O = cast(Obj); + getSymbol(O, DRI, Symbol); } void MachODumper::printFileHeaders() { @@ -216,6 +224,14 @@ void MachODumper::printFileHeaders() { } void MachODumper::printSections() { + if (const MachOObjectFileLE *O = dyn_cast(Obj)) + return printSections(O); + const MachOObjectFileBE *O = cast(Obj); + return printSections(O); +} + +template +void MachODumper::printSections(const MachOObjectFileMiddle *Obj) { ListScope Group(W, "Sections"); int SectionIndex = -1; @@ -328,6 +344,16 @@ void MachODumper::printRelocations() { void MachODumper::printRelocation(section_iterator SecI, relocation_iterator RelI) { + if (const MachOObjectFileLE *O = dyn_cast(Obj)) + return printRelocation(O, SecI, RelI); + const MachOObjectFileBE *O = cast(Obj); + return printRelocation(O, SecI, RelI); +} + +template +void MachODumper::printRelocation(const MachOObjectFileMiddle *Obj, + section_iterator SecI, + relocation_iterator RelI) { uint64_t Offset; SmallString<32> RelocName; StringRef SymbolName; @@ -338,14 +364,15 @@ void MachODumper::printRelocation(section_iterator SecI, if (error(Symbol.getName(SymbolName))) return; DataRefImpl DR = RelI->getRawDataRefImpl(); - const MachOObjectFileBase::RelocationEntry *RE = Obj->getRelocation(DR); - bool IsScattered = Obj->isScattered(RE); + const typename MachOObjectFileMiddle::RelocationEntry *RE = + Obj->getRelocation(DR); + bool IsScattered = Obj->isRelocationScattered(RE); if (opts::ExpandRelocs) { DictScope Group(W, "Relocation"); W.printHex("Offset", Offset); - W.printNumber("PCRel", Obj->isPCRel(RE)); - W.printNumber("Length", Obj->getLength(RE)); + W.printNumber("PCRel", Obj->isRelocationPCRel(RE)); + W.printNumber("Length", Obj->getRelocationLength(RE)); if (IsScattered) W.printString("Extern", StringRef("N/A")); else @@ -356,8 +383,8 @@ void MachODumper::printRelocation(section_iterator SecI, } else { raw_ostream& OS = W.startLine(); OS << W.hex(Offset) - << " " << Obj->isPCRel(RE) - << " " << Obj->getLength(RE); + << " " << Obj->isRelocationPCRel(RE) + << " " << Obj->getRelocationLength(RE); if (IsScattered) OS << " n/a"; else @@ -399,6 +426,7 @@ void MachODumper::printSymbol(symbol_iterator SymI) { StringRef SectionName; section_iterator SecI(Obj->end_sections()); if (error(SymI->getSection(SecI)) || + SecI == Obj->end_sections() || error(SecI->getName(SectionName))) SectionName = ""; -- cgit v1.2.3-18-g5258 From 10f8d2bb5bec3630ab4c56429e942fc422d94ddb Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Sun, 14 Apr 2013 23:32:40 +0000 Subject: If we've specified a triple on the command line then go ahead and use that as the default triple for the module and target data layout. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179497 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/opt/opt.cpp | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'tools') diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index e385d7f577..e3aa77d3af 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -36,6 +36,7 @@ #include "llvm/Support/PassNameParser.h" #include "llvm/Support/PluginLoader.h" #include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Support/Signals.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/SystemUtils.h" @@ -529,9 +530,8 @@ static TargetMachine* GetTargetMachine(Triple TheTriple) { const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, Error); // Some modules don't specify a triple, and this is okay. - if (!TheTarget) { + if (!TheTarget) return 0; - } // Package up features to be passed to target/subtarget std::string FeaturesStr; @@ -598,9 +598,12 @@ int main(int argc, char **argv) { } // If we are supposed to override the target triple, do so now. - if (!TargetTriple.empty()) + const DataLayout *TD; + if (!TargetTriple.empty()) { M->setTargetTriple(Triple::normalize(TargetTriple)); - + TD = GetTargetMachine(Triple(TargetTriple))->getDataLayout(); + } + // Figure out what stream we are supposed to write to... OwningPtr Out; if (NoOutput) { @@ -641,16 +644,16 @@ int main(int argc, char **argv) { TLI->disableAllFunctions(); Passes.add(TLI); - // Add an appropriate DataLayout instance for this module. - DataLayout *TD = 0; - const std::string &ModuleDataLayout = M.get()->getDataLayout(); - if (!ModuleDataLayout.empty()) - TD = new DataLayout(ModuleDataLayout); - else if (!DefaultDataLayout.empty()) - TD = new DataLayout(DefaultDataLayout); - + // If we don't have a data layout by now go ahead and set it if we can. + if (!TD) { + const std::string &ModuleDataLayout = M.get()->getDataLayout(); + if (!ModuleDataLayout.empty()) + TD = new DataLayout(ModuleDataLayout); + else if (!DefaultDataLayout.empty()) + TD = new DataLayout(DefaultDataLayout); + } if (TD) - Passes.add(TD); + Passes.add(new DataLayout(*TD)); Triple ModuleTriple(M->getTargetTriple()); TargetMachine *Machine = 0; -- cgit v1.2.3-18-g5258 From f1216abf7ec0d37152a0aaaad5a238beca65ecb6 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Sun, 14 Apr 2013 23:35:36 +0000 Subject: Revert "Remove some unused triple and data layout." This reverts commit r179497 and the accompanying commit as it broke random platforms that aren't osx. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179499 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/opt/opt.cpp | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) (limited to 'tools') diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index e3aa77d3af..e385d7f577 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -36,7 +36,6 @@ #include "llvm/Support/PassNameParser.h" #include "llvm/Support/PluginLoader.h" #include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Support/Signals.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/SystemUtils.h" @@ -530,8 +529,9 @@ static TargetMachine* GetTargetMachine(Triple TheTriple) { const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, Error); // Some modules don't specify a triple, and this is okay. - if (!TheTarget) + if (!TheTarget) { return 0; + } // Package up features to be passed to target/subtarget std::string FeaturesStr; @@ -598,12 +598,9 @@ int main(int argc, char **argv) { } // If we are supposed to override the target triple, do so now. - const DataLayout *TD; - if (!TargetTriple.empty()) { + if (!TargetTriple.empty()) M->setTargetTriple(Triple::normalize(TargetTriple)); - TD = GetTargetMachine(Triple(TargetTriple))->getDataLayout(); - } - + // Figure out what stream we are supposed to write to... OwningPtr Out; if (NoOutput) { @@ -644,16 +641,16 @@ int main(int argc, char **argv) { TLI->disableAllFunctions(); Passes.add(TLI); - // If we don't have a data layout by now go ahead and set it if we can. - if (!TD) { - const std::string &ModuleDataLayout = M.get()->getDataLayout(); - if (!ModuleDataLayout.empty()) - TD = new DataLayout(ModuleDataLayout); - else if (!DefaultDataLayout.empty()) - TD = new DataLayout(DefaultDataLayout); - } + // Add an appropriate DataLayout instance for this module. + DataLayout *TD = 0; + const std::string &ModuleDataLayout = M.get()->getDataLayout(); + if (!ModuleDataLayout.empty()) + TD = new DataLayout(ModuleDataLayout); + else if (!DefaultDataLayout.empty()) + TD = new DataLayout(DefaultDataLayout); + if (TD) - Passes.add(new DataLayout(*TD)); + Passes.add(TD); Triple ModuleTriple(M->getTargetTriple()); TargetMachine *Machine = 0; -- cgit v1.2.3-18-g5258 From fdf9624f3c20a24345a543979e1cb5c94a9d6715 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Mon, 15 Apr 2013 07:07:21 +0000 Subject: Recommit r179497 after fixing uninitialized variable. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179512 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/opt/opt.cpp | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index e385d7f577..de8bd41d11 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -403,7 +403,7 @@ struct BreakpointPrinter : public ModulePass { AU.setPreservesAll(); } }; - + } // anonymous namespace char BreakpointPrinter::ID = 0; @@ -446,7 +446,7 @@ static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, Builder.DisableUnitAtATime = !UnitAtATime; Builder.DisableUnrollLoops = OptLevel == 0; Builder.DisableSimplifyLibCalls = DisableSimplifyLibCalls; - + Builder.populateFunctionPassManager(FPM); Builder.populateModulePassManager(MPM); } @@ -529,9 +529,8 @@ static TargetMachine* GetTargetMachine(Triple TheTriple) { const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, Error); // Some modules don't specify a triple, and this is okay. - if (!TheTarget) { + if (!TheTarget) return 0; - } // Package up features to be passed to target/subtarget std::string FeaturesStr; @@ -598,8 +597,11 @@ int main(int argc, char **argv) { } // If we are supposed to override the target triple, do so now. - if (!TargetTriple.empty()) + const DataLayout *TD = 0; + if (!TargetTriple.empty()) { M->setTargetTriple(Triple::normalize(TargetTriple)); + TD = GetTargetMachine(Triple(TargetTriple))->getDataLayout(); + } // Figure out what stream we are supposed to write to... OwningPtr Out; @@ -641,16 +643,16 @@ int main(int argc, char **argv) { TLI->disableAllFunctions(); Passes.add(TLI); - // Add an appropriate DataLayout instance for this module. - DataLayout *TD = 0; - const std::string &ModuleDataLayout = M.get()->getDataLayout(); - if (!ModuleDataLayout.empty()) - TD = new DataLayout(ModuleDataLayout); - else if (!DefaultDataLayout.empty()) - TD = new DataLayout(DefaultDataLayout); - + // If we don't have a data layout by now go ahead and set it if we can. + if (!TD) { + const std::string &ModuleDataLayout = M.get()->getDataLayout(); + if (!ModuleDataLayout.empty()) + TD = new DataLayout(ModuleDataLayout); + else if (!DefaultDataLayout.empty()) + TD = new DataLayout(DefaultDataLayout); + } if (TD) - Passes.add(TD); + Passes.add(new DataLayout(*TD)); Triple ModuleTriple(M->getTargetTriple()); TargetMachine *Machine = 0; -- cgit v1.2.3-18-g5258 From 60d20a81fcf91818db6b52520dd2ce520ad57a42 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Mon, 15 Apr 2013 07:31:37 +0000 Subject: Revert "Recommit r179497 after fixing uninitialized variable." until I can fix the testcases here: http://lab.llvm.org:8011/builders/clang-native-arm-cortex-a9/builds/6952 This reverts commit r179512 due to testcases specifying triples that they didn't actually mean and causing failures on other platforms. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179513 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/opt/opt.cpp | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'tools') diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index de8bd41d11..e385d7f577 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -403,7 +403,7 @@ struct BreakpointPrinter : public ModulePass { AU.setPreservesAll(); } }; - + } // anonymous namespace char BreakpointPrinter::ID = 0; @@ -446,7 +446,7 @@ static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, Builder.DisableUnitAtATime = !UnitAtATime; Builder.DisableUnrollLoops = OptLevel == 0; Builder.DisableSimplifyLibCalls = DisableSimplifyLibCalls; - + Builder.populateFunctionPassManager(FPM); Builder.populateModulePassManager(MPM); } @@ -529,8 +529,9 @@ static TargetMachine* GetTargetMachine(Triple TheTriple) { const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, Error); // Some modules don't specify a triple, and this is okay. - if (!TheTarget) + if (!TheTarget) { return 0; + } // Package up features to be passed to target/subtarget std::string FeaturesStr; @@ -597,11 +598,8 @@ int main(int argc, char **argv) { } // If we are supposed to override the target triple, do so now. - const DataLayout *TD = 0; - if (!TargetTriple.empty()) { + if (!TargetTriple.empty()) M->setTargetTriple(Triple::normalize(TargetTriple)); - TD = GetTargetMachine(Triple(TargetTriple))->getDataLayout(); - } // Figure out what stream we are supposed to write to... OwningPtr Out; @@ -643,16 +641,16 @@ int main(int argc, char **argv) { TLI->disableAllFunctions(); Passes.add(TLI); - // If we don't have a data layout by now go ahead and set it if we can. - if (!TD) { - const std::string &ModuleDataLayout = M.get()->getDataLayout(); - if (!ModuleDataLayout.empty()) - TD = new DataLayout(ModuleDataLayout); - else if (!DefaultDataLayout.empty()) - TD = new DataLayout(DefaultDataLayout); - } + // Add an appropriate DataLayout instance for this module. + DataLayout *TD = 0; + const std::string &ModuleDataLayout = M.get()->getDataLayout(); + if (!ModuleDataLayout.empty()) + TD = new DataLayout(ModuleDataLayout); + else if (!DefaultDataLayout.empty()) + TD = new DataLayout(DefaultDataLayout); + if (TD) - Passes.add(new DataLayout(*TD)); + Passes.add(TD); Triple ModuleTriple(M->getTargetTriple()); TargetMachine *Machine = 0; -- cgit v1.2.3-18-g5258 From 604b3573f955d61ba87215c25ba2f52477c71ecc Mon Sep 17 00:00:00 2001 From: Andy Gibbs Date: Mon, 15 Apr 2013 12:06:32 +0000 Subject: Replace uses of the deprecated std::auto_ptr with OwningPtr. This is a rework of the broken parts in r179373 which were subsequently reverted in r179374 due to incompatibility with C++98 compilers. This version should be ok under C++98. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179520 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-link/llvm-link.cpp | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp index 83665cc175..3a2d84a533 100644 --- a/tools/llvm-link/llvm-link.cpp +++ b/tools/llvm-link/llvm-link.cpp @@ -53,13 +53,12 @@ DumpAsm("d", cl::desc("Print assembly as linked"), cl::Hidden); // LoadFile - Read the specified bitcode file in and return it. This routine // searches the link path for the specified file to try to find it... // -static inline std::auto_ptr LoadFile(const char *argv0, - const std::string &FN, - LLVMContext& Context) { +static inline Module *LoadFile(const char *argv0, const std::string &FN, + LLVMContext& Context) { sys::Path Filename; if (!Filename.set(FN)) { errs() << "Invalid file name: '" << FN << "'\n"; - return std::auto_ptr(); + return NULL; } SMDiagnostic Err; @@ -68,10 +67,10 @@ static inline std::auto_ptr LoadFile(const char *argv0, const std::string &FNStr = Filename.str(); Result = ParseIRFile(FNStr, Err, Context); - if (Result) return std::auto_ptr(Result); // Load successful! + if (Result) return Result; // Load successful! Err.print(argv0, errs()); - return std::auto_ptr(); + return NULL; } int main(int argc, char **argv) { @@ -86,8 +85,8 @@ int main(int argc, char **argv) { unsigned BaseArg = 0; std::string ErrorMessage; - std::auto_ptr Composite(LoadFile(argv[0], - InputFilenames[BaseArg], Context)); + OwningPtr Composite(LoadFile(argv[0], + InputFilenames[BaseArg], Context)); if (Composite.get() == 0) { errs() << argv[0] << ": error loading file '" << InputFilenames[BaseArg] << "'\n"; @@ -95,8 +94,7 @@ int main(int argc, char **argv) { } for (unsigned i = BaseArg+1; i < InputFilenames.size(); ++i) { - std::auto_ptr M(LoadFile(argv[0], - InputFilenames[i], Context)); + OwningPtr M(LoadFile(argv[0], InputFilenames[i], Context)); if (M.get() == 0) { errs() << argv[0] << ": error loading file '" < Date: Mon, 15 Apr 2013 16:08:02 +0000 Subject: Remove getters now that we can specialize structs on the host endianness. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179534 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/MachODumper.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index d207eabb52..d4eaae615c 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -376,8 +376,8 @@ void MachODumper::printRelocation(const MachOObjectFileMiddle *Obj, if (IsScattered) W.printString("Extern", StringRef("N/A")); else - W.printNumber("Extern", RE->getExternal()); - W.printNumber("Type", RelocName, RE->getType()); + W.printNumber("Extern", RE->External); + W.printNumber("Type", RelocName, RE->Type); W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-"); W.printNumber("Scattered", IsScattered); } else { @@ -388,7 +388,7 @@ void MachODumper::printRelocation(const MachOObjectFileMiddle *Obj, if (IsScattered) OS << " n/a"; else - OS << " " << RE->getExternal(); + OS << " " << RE->External; OS << " " << RelocName << " " << IsScattered << " " << (SymbolName.size() > 0 ? SymbolName : "-") -- cgit v1.2.3-18-g5258 From 0eaa6f675cafb2bb1b6a6210797c1d7b3da3ff9f Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Tue, 16 Apr 2013 10:53:11 +0000 Subject: llvm-objdump: Don't print contents of BSS sections: it makes no sense and crashes llvm-objdump on relocated objects with large bss git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179589 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/llvm-objdump.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'tools') diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 5a0519ddc1..6f4b101c30 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -468,11 +468,19 @@ static void PrintSectionContents(const ObjectFile *o) { StringRef Name; StringRef Contents; uint64_t BaseAddr; + bool BSS; if (error(si->getName(Name))) continue; if (error(si->getContents(Contents))) continue; if (error(si->getAddress(BaseAddr))) continue; + if (error(si->isBSS(BSS))) continue; outs() << "Contents of section " << Name << ":\n"; + if (BSS) { + outs() << format("\n", BaseAddr, + BaseAddr + Contents.size()); + continue; + } // Dump out the content as hex and printable ascii characters. for (std::size_t addr = 0, end = Contents.size(); addr < end; addr += 16) { -- cgit v1.2.3-18-g5258 From df39be6cb4eb44011db3d3e86f8fe463f81ce127 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Wed, 17 Apr 2013 21:18:16 +0000 Subject: Add support for subsections to the ELF assembler. Fixes PR8717. Differential Revision: http://llvm-reviews.chandlerc.com/D598 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179725 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/LTOModule.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp index ff67769192..d805f49f9a 100644 --- a/tools/lto/LTOModule.cpp +++ b/tools/lto/LTOModule.cpp @@ -743,7 +743,7 @@ namespace { AddValueSymbols(Inst.getOperand(i).getExpr()); } virtual void EmitLabel(MCSymbol *Symbol) { - Symbol->setSection(*getCurrentSection()); + Symbol->setSection(*getCurrentSection().first); markDefined(*Symbol); } virtual void EmitDebugLabel(MCSymbol *Symbol) { @@ -771,7 +771,8 @@ namespace { virtual void EmitBundleUnlock() {} // Noop calls. - virtual void ChangeSection(const MCSection *Section) {} + virtual void ChangeSection(const MCSection *Section, + const MCExpr *Subsection) {} virtual void InitToTextSection() {} virtual void InitSections() {} virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {} -- cgit v1.2.3-18-g5258 From fd7aa38e304a09fa0ef51b85b773b649b7e58c5e Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 18 Apr 2013 18:08:55 +0000 Subject: At Jim Grosbach's request detemplate Object/MachO.h. We are still able to handle mixed endian objects by swapping one struct at a time. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179778 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/MachODump.cpp | 43 ++++------- tools/llvm-objdump/llvm-objdump.cpp | 20 ++--- tools/llvm-readobj/MachODumper.cpp | 133 ++++++++++++++------------------ tools/llvm-symbolizer/LLVMSymbolize.cpp | 2 +- 4 files changed, 82 insertions(+), 116 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 4b6cb5f54c..e4d9ce2498 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -53,7 +53,7 @@ static cl::opt static cl::opt DSYMFile("dsym", cl::desc("Use .dSYM file for debug info")); -static const Target *GetTarget(const MachOObjectFileBase *MachOObj) { +static const Target *GetTarget(const MachOObjectFile *MachOObj) { // Figure out the target triple. if (TripleName.empty()) { llvm::Triple TT("unknown-unknown-unknown"); @@ -93,7 +93,7 @@ struct SymbolSorter { // Print additional information about an address, if available. static void DumpAddress(uint64_t Address, ArrayRef Sections, - const MachOObjectFileBase *MachOObj, raw_ostream &OS) { + const MachOObjectFile *MachOObj, raw_ostream &OS) { for (unsigned i = 0; i != Sections.size(); ++i) { uint64_t SectAddr = 0, SectSize = 0; Sections[i].getAddress(SectAddr); @@ -184,14 +184,12 @@ static void emitDOTFile(const char *FileName, const MCFunction &f, Out << "}\n"; } -template static void -getSectionsAndSymbols(const typename MachOObjectFileMiddle::Header *Header, - const MachOObjectFileMiddle *MachOObj, +getSectionsAndSymbols(const macho::Header Header, + MachOObjectFile *MachOObj, std::vector &Sections, std::vector &Symbols, SmallVectorImpl &FoundFns) { - typedef MachOObjectFileMiddle ObjType; error_code ec; for (symbol_iterator SI = MachOObj->begin_symbols(), SE = MachOObj->end_symbols(); SI != SE; SI.increment(ec)) @@ -205,23 +203,23 @@ getSectionsAndSymbols(const typename MachOObjectFileMiddle::Header *Header, Sections.push_back(*SI); } - for (unsigned i = 0; i != Header->NumLoadCommands; ++i) { - const typename ObjType::LoadCommand *Command = - MachOObj->getLoadCommandInfo(i); - if (Command->Type == macho::LCT_FunctionStarts) { + MachOObjectFile::LoadCommandInfo Command = + MachOObj->getFirstLoadCommandInfo(); + for (unsigned i = 0; i != Header.NumLoadCommands; ++i) { + if (Command.C.Type == macho::LCT_FunctionStarts) { // We found a function starts segment, parse the addresses for later // consumption. - const typename ObjType::LinkeditDataLoadCommand *LLC = - reinterpret_cast(Command); + macho::LinkeditDataLoadCommand LLC = + MachOObj->getLinkeditDataLoadCommand(Command); - MachOObj->ReadULEB128s(LLC->DataOffset, FoundFns); + MachOObj->ReadULEB128s(LLC.DataOffset, FoundFns); } + Command = MachOObj->getNextLoadCommandInfo(Command); } } -template static void DisassembleInputMachO2(StringRef Filename, - MachOObjectFileMiddle *MachOOF); + MachOObjectFile *MachOOF); void llvm::DisassembleInputMachO(StringRef Filename) { OwningPtr Buff; @@ -231,20 +229,14 @@ void llvm::DisassembleInputMachO(StringRef Filename) { return; } - OwningPtr MachOOF(static_cast( + OwningPtr MachOOF(static_cast( ObjectFile::createMachOObjectFile(Buff.take()))); - if (MachOObjectFileLE *O = dyn_cast(MachOOF.get())) { - DisassembleInputMachO2(Filename, O); - return; - } - MachOObjectFileBE *O = cast(MachOOF.get()); - DisassembleInputMachO2(Filename, O); + DisassembleInputMachO2(Filename, MachOOF.get()); } -template static void DisassembleInputMachO2(StringRef Filename, - MachOObjectFileMiddle *MachOOF) { + MachOObjectFile *MachOOF) { const Target *TheTarget = GetTarget(MachOOF); if (!TheTarget) { // GetTarget prints out stuff. @@ -273,8 +265,7 @@ static void DisassembleInputMachO2(StringRef Filename, outs() << '\n' << Filename << ":\n\n"; - const typename MachOObjectFileMiddle::Header *Header = - MachOOF->getHeader(); + macho::Header Header = MachOOF->getHeader(); std::vector Sections; std::vector Symbols; diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 6f4b101c30..9985599565 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -191,14 +191,6 @@ bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) { return a_addr < b_addr; } -StringRef -getSectionFinalSegmentName(const MachOObjectFileBase *MachO, DataRefImpl DR) { - if (const MachOObjectFileLE *O = dyn_cast(MachO)) - return O->getSectionFinalSegmentName(DR); - const MachOObjectFileBE *O = dyn_cast(MachO); - return O->getSectionFinalSegmentName(DR); -} - static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { const Target *TheTarget = getTarget(Obj); // getTarget() will have already issued a diagnostic if necessary, so @@ -263,10 +255,10 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { std::sort(Rels.begin(), Rels.end(), RelocAddressLess); StringRef SegmentName = ""; - if (const MachOObjectFileBase *MachO = - dyn_cast(Obj)) { + if (const MachOObjectFile *MachO = + dyn_cast(Obj)) { DataRefImpl DR = i->getRawDataRefImpl(); - SegmentName = getSectionFinalSegmentName(MachO, DR); + SegmentName = MachO->getSectionFinalSegmentName(DR); } StringRef name; if (error(i->getName(name))) break; @@ -608,10 +600,10 @@ static void PrintSymbolTable(const ObjectFile *o) { else if (Section == o->end_sections()) outs() << "*UND*"; else { - if (const MachOObjectFileBase *MachO = - dyn_cast(o)) { + if (const MachOObjectFile *MachO = + dyn_cast(o)) { DataRefImpl DR = Section->getRawDataRefImpl(); - StringRef SegmentName = getSectionFinalSegmentName(MachO, DR); + StringRef SegmentName = MachO->getSectionFinalSegmentName(DR); outs() << SegmentName << ","; } StringRef SectionName; diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index d4eaae615c..54de49c310 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -27,7 +27,7 @@ namespace { class MachODumper : public ObjDumper { public: - MachODumper(const MachOObjectFileBase *Obj, StreamWriter& Writer) + MachODumper(const MachOObjectFile *Obj, StreamWriter& Writer) : ObjDumper(Writer) , Obj(Obj) { } @@ -43,14 +43,12 @@ private: void printRelocation(section_iterator SecI, relocation_iterator RelI); - template - void printRelocation(const MachOObjectFileMiddle *Obj, + void printRelocation(const MachOObjectFile *Obj, section_iterator SecI, relocation_iterator RelI); - template - void printSections(const MachOObjectFileMiddle *Obj); + void printSections(const MachOObjectFile *Obj); - const MachOObjectFileBase *Obj; + const MachOObjectFile *Obj; }; } // namespace @@ -61,7 +59,7 @@ namespace llvm { error_code createMachODumper(const object::ObjectFile *Obj, StreamWriter& Writer, OwningPtr &Result) { - const MachOObjectFileBase *MachOObj = dyn_cast(Obj); + const MachOObjectFile *MachOObj = dyn_cast(Obj); if (!MachOObj) return readobj_error::unsupported_obj_file_format; @@ -164,59 +162,53 @@ namespace { }; } -template -static void getSection(const MachOObjectFile *Obj, - DataRefImpl DRI, +static void getSection(const MachOObjectFile *Obj, + DataRefImpl Sec, MachOSection &Section) { - const typename MachOObjectFile::Section *Sect = Obj->getSection(DRI); - Section.Address = Sect->Address; - Section.Size = Sect->Size; - Section.Offset = Sect->Offset; - Section.Alignment = Sect->Align; - Section.RelocationTableOffset = Sect->RelocationTableOffset; - Section.NumRelocationTableEntries = Sect->NumRelocationTableEntries; - Section.Flags = Sect->Flags; - Section.Reserved1 = Sect->Reserved1; - Section.Reserved2 = Sect->Reserved2; -} - -static void getSection(const MachOObjectFileBase *Obj, - DataRefImpl DRI, - MachOSection &Section) { - if (const MachOObjectFileLE32 *O = dyn_cast(Obj)) - return getSection(O, DRI, Section); - if (const MachOObjectFileLE64 *O = dyn_cast(Obj)) - return getSection(O, DRI, Section); - if (const MachOObjectFileBE32 *O = dyn_cast(Obj)) - return getSection(O, DRI, Section); - const MachOObjectFileBE64 *O = cast(Obj); - getSection(O, DRI, Section); + if (!Obj->is64Bit()) { + macho::Section Sect = Obj->getSection(Sec); + Section.Address = Sect.Address; + Section.Size = Sect.Size; + Section.Offset = Sect.Offset; + Section.Alignment = Sect.Align; + Section.RelocationTableOffset = Sect.RelocationTableOffset; + Section.NumRelocationTableEntries = Sect.NumRelocationTableEntries; + Section.Flags = Sect.Flags; + Section.Reserved1 = Sect.Reserved1; + Section.Reserved2 = Sect.Reserved2; + return; + } + macho::Section64 Sect = Obj->getSection64(Sec); + Section.Address = Sect.Address; + Section.Size = Sect.Size; + Section.Offset = Sect.Offset; + Section.Alignment = Sect.Align; + Section.RelocationTableOffset = Sect.RelocationTableOffset; + Section.NumRelocationTableEntries = Sect.NumRelocationTableEntries; + Section.Flags = Sect.Flags; + Section.Reserved1 = Sect.Reserved1; + Section.Reserved2 = Sect.Reserved2; } -template -static void getSymbol(const MachOObjectFile *Obj, - DataRefImpl DRI, - MachOSymbol &Symbol) { - const typename MachOObjectFile::SymbolTableEntry *Entry = - Obj->getSymbolTableEntry(DRI); - Symbol.StringIndex = Entry->StringIndex; - Symbol.Type = Entry->Type; - Symbol.SectionIndex = Entry->SectionIndex; - Symbol.Flags = Entry->Flags; - Symbol.Value = Entry->Value; -} -static void getSymbol(const MachOObjectFileBase *Obj, +static void getSymbol(const MachOObjectFile *Obj, DataRefImpl DRI, MachOSymbol &Symbol) { - if (const MachOObjectFileLE32 *O = dyn_cast(Obj)) - return getSymbol(O, DRI, Symbol); - if (const MachOObjectFileLE64 *O = dyn_cast(Obj)) - return getSymbol(O, DRI, Symbol); - if (const MachOObjectFileBE32 *O = dyn_cast(Obj)) - return getSymbol(O, DRI, Symbol); - const MachOObjectFileBE64 *O = cast(Obj); - getSymbol(O, DRI, Symbol); + if (!Obj->is64Bit()) { + macho::SymbolTableEntry Entry = Obj->getSymbolTableEntry(DRI); + Symbol.StringIndex = Entry.StringIndex; + Symbol.Type = Entry.Type; + Symbol.SectionIndex = Entry.SectionIndex; + Symbol.Flags = Entry.Flags; + Symbol.Value = Entry.Value; + return; + } + macho::Symbol64TableEntry Entry = Obj->getSymbol64TableEntry(DRI); + Symbol.StringIndex = Entry.StringIndex; + Symbol.Type = Entry.Type; + Symbol.SectionIndex = Entry.SectionIndex; + Symbol.Flags = Entry.Flags; + Symbol.Value = Entry.Value; } void MachODumper::printFileHeaders() { @@ -224,14 +216,10 @@ void MachODumper::printFileHeaders() { } void MachODumper::printSections() { - if (const MachOObjectFileLE *O = dyn_cast(Obj)) - return printSections(O); - const MachOObjectFileBE *O = cast(Obj); - return printSections(O); + return printSections(Obj); } -template -void MachODumper::printSections(const MachOObjectFileMiddle *Obj) { +void MachODumper::printSections(const MachOObjectFile *Obj) { ListScope Group(W, "Sections"); int SectionIndex = -1; @@ -344,14 +332,10 @@ void MachODumper::printRelocations() { void MachODumper::printRelocation(section_iterator SecI, relocation_iterator RelI) { - if (const MachOObjectFileLE *O = dyn_cast(Obj)) - return printRelocation(O, SecI, RelI); - const MachOObjectFileBE *O = cast(Obj); - return printRelocation(O, SecI, RelI); + return printRelocation(Obj, SecI, RelI); } -template -void MachODumper::printRelocation(const MachOObjectFileMiddle *Obj, +void MachODumper::printRelocation(const MachOObjectFile *Obj, section_iterator SecI, relocation_iterator RelI) { uint64_t Offset; @@ -364,31 +348,30 @@ void MachODumper::printRelocation(const MachOObjectFileMiddle *Obj, if (error(Symbol.getName(SymbolName))) return; DataRefImpl DR = RelI->getRawDataRefImpl(); - const typename MachOObjectFileMiddle::RelocationEntry *RE = - Obj->getRelocation(DR); + macho::RelocationEntry RE = Obj->getRelocation(DR); bool IsScattered = Obj->isRelocationScattered(RE); if (opts::ExpandRelocs) { DictScope Group(W, "Relocation"); W.printHex("Offset", Offset); - W.printNumber("PCRel", Obj->isRelocationPCRel(RE)); - W.printNumber("Length", Obj->getRelocationLength(RE)); + W.printNumber("PCRel", Obj->getAnyRelocationPCRel(RE)); + W.printNumber("Length", Obj->getAnyRelocationLength(RE)); if (IsScattered) W.printString("Extern", StringRef("N/A")); else - W.printNumber("Extern", RE->External); - W.printNumber("Type", RelocName, RE->Type); + W.printNumber("Extern", Obj->getPlainRelocationExternal(RE)); + W.printNumber("Type", RelocName, Obj->getAnyRelocationType(RE)); W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-"); W.printNumber("Scattered", IsScattered); } else { raw_ostream& OS = W.startLine(); OS << W.hex(Offset) - << " " << Obj->isRelocationPCRel(RE) - << " " << Obj->getRelocationLength(RE); + << " " << Obj->getAnyRelocationPCRel(RE) + << " " << Obj->getAnyRelocationLength(RE); if (IsScattered) OS << " n/a"; else - OS << " " << RE->External; + OS << " " << Obj->getPlainRelocationExternal(RE); OS << " " << RelocName << " " << IsScattered << " " << (SymbolName.size() > 0 ? SymbolName : "-") diff --git a/tools/llvm-symbolizer/LLVMSymbolize.cpp b/tools/llvm-symbolizer/LLVMSymbolize.cpp index ffe8712a65..29d91a0e92 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.cpp +++ b/tools/llvm-symbolizer/LLVMSymbolize.cpp @@ -233,7 +233,7 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) { // On Darwin we may find DWARF in separate object file in // resource directory. ObjectFile *DbgObj = Obj; - if (isa(Obj)) { + if (isa(Obj)) { const std::string &ResourceName = getDarwinDWARFResourceForModule(ModuleName); ObjectFile *ResourceObj = getObjectFile(ResourceName); -- cgit v1.2.3-18-g5258 From db5f9270207292b62ea847560c5dd4e9873b57f5 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 19 Apr 2013 11:36:47 +0000 Subject: Don't read one command past the end. Thanks to Evgeniy Stepanov for reporting this. It might be a good idea to add a command iterator abstraction to MachO.h, but this fixes the bug for now. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179848 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/MachODump.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index e4d9ce2498..d78d7f31a6 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -205,7 +205,7 @@ getSectionsAndSymbols(const macho::Header Header, MachOObjectFile::LoadCommandInfo Command = MachOObj->getFirstLoadCommandInfo(); - for (unsigned i = 0; i != Header.NumLoadCommands; ++i) { + for (unsigned i = 0; ; ++i) { if (Command.C.Type == macho::LCT_FunctionStarts) { // We found a function starts segment, parse the addresses for later // consumption. @@ -214,7 +214,11 @@ getSectionsAndSymbols(const macho::Header Header, MachOObj->ReadULEB128s(LLC.DataOffset, FoundFns); } - Command = MachOObj->getNextLoadCommandInfo(Command); + + if (i == Header.NumLoadCommands - 1) + break; + else + Command = MachOObj->getNextLoadCommandInfo(Command); } } -- cgit v1.2.3-18-g5258 From 7a7e83ae59bd80e8f0e4816702ac0bda105e433f Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 19 Apr 2013 21:28:07 +0000 Subject: Remove COFFYAML::Relocation. Use MappingNormalization to read a COFF::relocation directly. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179891 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/yaml2obj/yaml2obj.cpp | 30 +++++++++++++++++++----------- 1 file changed, 19 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/yaml2obj/yaml2obj.cpp b/tools/yaml2obj/yaml2obj.cpp index 191c49fb59..67488023d5 100644 --- a/tools/yaml2obj/yaml2obj.cpp +++ b/tools/yaml2obj/yaml2obj.cpp @@ -114,16 +114,10 @@ static bool hexStringToByteArray(StringRef Str, ContainerOut &Out) { // The structure of the yaml files is not an exact 1:1 match to COFF. In order // to use yaml::IO, we use these structures which are closer to the source. namespace COFFYAML { - struct Relocation { - uint32_t VirtualAddress; - uint32_t SymbolTableIndex; - COFF::RelocationTypeX86 Type; - }; - struct Section { COFF::SectionCharacteristics Characteristics; StringRef SectionData; - std::vector Relocations; + std::vector Relocations; StringRef Name; }; @@ -407,7 +401,7 @@ void writeCOFF(COFFParser &CP, raw_ostream &OS) { OS.write(&CP.StringTable[0], CP.StringTable.size()); } -LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Relocation) +LLVM_YAML_IS_SEQUENCE_VECTOR(COFF::relocation) LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Section) LLVM_YAML_IS_SEQUENCE_VECTOR(COFFYAML::Symbol) @@ -646,9 +640,23 @@ struct MappingTraits { }; template <> -struct MappingTraits { - static void mapping(IO &IO, COFFYAML::Relocation &Rel) { - IO.mapRequired("Type", Rel.Type); +struct MappingTraits { + struct NormalizedType { + public: + NormalizedType(IO &) : Type(COFF::RelocationTypeX86(0)) { + } + NormalizedType(IO &, uint16_t T) : Type(COFF::RelocationTypeX86(T)) { + } + uint16_t denormalize(IO &) { + return Type; + } + + COFF::RelocationTypeX86 Type; + }; + static void mapping(IO &IO, COFF::relocation &Rel) { + MappingNormalization foo(IO, Rel.Type); + + IO.mapRequired("Type", foo->Type); IO.mapRequired("VirtualAddress", Rel.VirtualAddress); IO.mapRequired("SymbolTableIndex", Rel.SymbolTableIndex); } -- cgit v1.2.3-18-g5258 From f59a2a86fffa55d5a4f6a2bc339bfa55f4ccf059 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 20 Apr 2013 02:02:25 +0000 Subject: Remove COFFYAML::Header. Instead, use MappingNormalization to directly parse COFF::header. Also change the naming convention of the helper classes to be a bit shorter. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179917 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/yaml2obj/yaml2obj.cpp | 55 +++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 17 deletions(-) (limited to 'tools') diff --git a/tools/yaml2obj/yaml2obj.cpp b/tools/yaml2obj/yaml2obj.cpp index 67488023d5..5741d95c54 100644 --- a/tools/yaml2obj/yaml2obj.cpp +++ b/tools/yaml2obj/yaml2obj.cpp @@ -121,11 +121,6 @@ namespace COFFYAML { StringRef Name; }; - struct Header { - COFF::MachineTypes Machine; - COFF::Characteristics Characteristics; - }; - struct Symbol { COFF::SymbolBaseType SimpleType; uint8_t NumberOfAuxSymbols; @@ -138,7 +133,7 @@ namespace COFFYAML { }; struct Object { - Header HeaderData; + COFF::header HeaderData; std::vector
Sections; std::vector Symbols; }; @@ -632,31 +627,57 @@ struct MappingTraits { }; template <> -struct MappingTraits { - static void mapping(IO &IO, COFFYAML::Header &H) { - IO.mapRequired("Machine", H.Machine); - IO.mapOptional("Characteristics", H.Characteristics); +struct MappingTraits { + struct NMachine { + NMachine(IO&) : Machine(COFF::MachineTypes(0)) { + } + NMachine(IO&, uint16_t M) : Machine(COFF::MachineTypes(M)) { + } + uint16_t denormalize(IO &) { + return Machine; + } + COFF::MachineTypes Machine; + }; + + struct NCharacteristics { + NCharacteristics(IO&) : Characteristics(COFF::Characteristics(0)) { + } + NCharacteristics(IO&, uint16_t C) : + Characteristics(COFF::Characteristics(C)) { + } + uint16_t denormalize(IO &) { + return Characteristics; + } + + COFF::Characteristics Characteristics; + }; + + static void mapping(IO &IO, COFF::header &H) { + MappingNormalization NM(IO, H.Machine); + MappingNormalization NC(IO, H.Characteristics); + + IO.mapRequired("Machine", NM->Machine); + IO.mapOptional("Characteristics", NC->Characteristics); } }; template <> struct MappingTraits { - struct NormalizedType { - public: - NormalizedType(IO &) : Type(COFF::RelocationTypeX86(0)) { + struct NType { + NType(IO &) : Type(COFF::RelocationTypeX86(0)) { } - NormalizedType(IO &, uint16_t T) : Type(COFF::RelocationTypeX86(T)) { + NType(IO &, uint16_t T) : Type(COFF::RelocationTypeX86(T)) { } uint16_t denormalize(IO &) { return Type; } - COFF::RelocationTypeX86 Type; }; + static void mapping(IO &IO, COFF::relocation &Rel) { - MappingNormalization foo(IO, Rel.Type); + MappingNormalization NT(IO, Rel.Type); - IO.mapRequired("Type", foo->Type); + IO.mapRequired("Type", NT->Type); IO.mapRequired("VirtualAddress", Rel.VirtualAddress); IO.mapRequired("SymbolTableIndex", Rel.SymbolTableIndex); } -- cgit v1.2.3-18-g5258 From da177ce51c2c718e2655e96b9fdcebb68d4fd291 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 20 Apr 2013 02:55:00 +0000 Subject: Small obj2yaml cleanups. * using namespace llvm. * whitespace. * early return. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179920 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/obj2yaml/coff2yaml.cpp | 145 +++++++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 69 deletions(-) (limited to 'tools') diff --git a/tools/obj2yaml/coff2yaml.cpp b/tools/obj2yaml/coff2yaml.cpp index cc7ac00276..4a8ffbd81e 100644 --- a/tools/obj2yaml/coff2yaml.cpp +++ b/tools/obj2yaml/coff2yaml.cpp @@ -10,6 +10,7 @@ #include "obj2yaml.h" #include "llvm/Object/COFF.h" +using namespace llvm; template struct pod_pair { // I'd much rather use std::pair, but it's not a POD @@ -17,8 +18,8 @@ struct pod_pair { // I'd much rather use std::pair, but it's not a POD Two second; }; -#define STRING_PAIR(x) {llvm::COFF::x, #x} -static const pod_pair +#define STRING_PAIR(x) {COFF::x, #x} +static const pod_pair MachineTypePairs [] = { STRING_PAIR(IMAGE_FILE_MACHINE_UNKNOWN), STRING_PAIR(IMAGE_FILE_MACHINE_AM33), @@ -43,7 +44,7 @@ MachineTypePairs [] = { STRING_PAIR(IMAGE_FILE_MACHINE_WCEMIPSV2) }; -static const pod_pair +static const pod_pair SectionCharacteristicsPairs1 [] = { STRING_PAIR(IMAGE_SCN_TYPE_NO_PAD), STRING_PAIR(IMAGE_SCN_CNT_CODE), @@ -60,7 +61,7 @@ SectionCharacteristicsPairs1 [] = { STRING_PAIR(IMAGE_SCN_MEM_PRELOAD) }; -static const pod_pair +static const pod_pair SectionCharacteristicsPairsAlignment [] = { STRING_PAIR(IMAGE_SCN_ALIGN_1BYTES), STRING_PAIR(IMAGE_SCN_ALIGN_2BYTES), @@ -78,7 +79,7 @@ SectionCharacteristicsPairsAlignment [] = { STRING_PAIR(IMAGE_SCN_ALIGN_8192BYTES) }; -static const pod_pair +static const pod_pair SectionCharacteristicsPairs2 [] = { STRING_PAIR(IMAGE_SCN_LNK_NRELOC_OVFL), STRING_PAIR(IMAGE_SCN_MEM_DISCARDABLE), @@ -89,8 +90,8 @@ SectionCharacteristicsPairs2 [] = { STRING_PAIR(IMAGE_SCN_MEM_READ), STRING_PAIR(IMAGE_SCN_MEM_WRITE) }; - -static const pod_pair + +static const pod_pair SymbolBaseTypePairs [] = { STRING_PAIR(IMAGE_SYM_TYPE_NULL), STRING_PAIR(IMAGE_SYM_TYPE_VOID), @@ -110,15 +111,15 @@ SymbolBaseTypePairs [] = { STRING_PAIR(IMAGE_SYM_TYPE_DWORD) }; -static const pod_pair +static const pod_pair SymbolComplexTypePairs [] = { STRING_PAIR(IMAGE_SYM_DTYPE_NULL), STRING_PAIR(IMAGE_SYM_DTYPE_POINTER), STRING_PAIR(IMAGE_SYM_DTYPE_FUNCTION), STRING_PAIR(IMAGE_SYM_DTYPE_ARRAY), }; - -static const pod_pair + +static const pod_pair SymbolStorageClassPairs [] = { STRING_PAIR(IMAGE_SYM_CLASS_END_OF_FUNCTION), STRING_PAIR(IMAGE_SYM_CLASS_NULL), @@ -149,7 +150,7 @@ SymbolStorageClassPairs [] = { STRING_PAIR(IMAGE_SYM_CLASS_CLR_TOKEN), }; -static const pod_pair +static const pod_pair RelocationTypeX86Pairs [] = { STRING_PAIR(IMAGE_REL_I386_ABSOLUTE), STRING_PAIR(IMAGE_REL_I386_DIR16), @@ -181,7 +182,7 @@ RelocationTypeX86Pairs [] = { STRING_PAIR(IMAGE_REL_AMD64_SSPAN32) }; -static const pod_pair +static const pod_pair RelocationTypesARMPairs [] = { STRING_PAIR(IMAGE_REL_ARM_ABSOLUTE), STRING_PAIR(IMAGE_REL_ARM_ADDR32), @@ -203,8 +204,8 @@ RelocationTypesARMPairs [] = { namespace yaml { // COFF-specific yaml-writing specific routines -static llvm::raw_ostream &writeName(llvm::raw_ostream &Out, - const char *Name, std::size_t NameSize) { +static raw_ostream &writeName(raw_ostream &Out, + const char *Name, std::size_t NameSize) { for (std::size_t i = 0; i < NameSize; ++i) { if (!Name[i]) break; Out << Name[i]; @@ -214,8 +215,9 @@ static llvm::raw_ostream &writeName(llvm::raw_ostream &Out, // Given an array of pod_pair, write all enums that match template -static llvm::raw_ostream &writeBitMask(llvm::raw_ostream &Out, - const pod_pair (&Arr)[N], unsigned long Val) { +static raw_ostream &writeBitMask(raw_ostream &Out, + const pod_pair (&Arr)[N], + unsigned long Val) { for (std::size_t i = 0; i < N; ++i) if (Val & Arr[i].first) Out << Arr[i].second << ", "; @@ -226,8 +228,8 @@ static llvm::raw_ostream &writeBitMask(llvm::raw_ostream &Out, // Given an array of pod_pair, look up a value template -const char *nameLookup(const pod_pair (&Arr)[N], - unsigned long Val, const char *NotFound = NULL) { +const char *nameLookup(const pod_pair (&Arr)[N], + unsigned long Val, const char *NotFound = NULL) { T n = static_cast(Val); for (std::size_t i = 0; i < N; ++i) if (n == Arr[i].first) @@ -236,8 +238,8 @@ const char *nameLookup(const pod_pair (&Arr)[N], } -static llvm::raw_ostream &yamlCOFFHeader( - const llvm::object::coff_file_header *Header,llvm::raw_ostream &Out) { +static raw_ostream &yamlCOFFHeader(const object::coff_file_header *Header, + raw_ostream &Out) { Out << "header: !Header\n"; Out << " Machine: "; @@ -247,94 +249,96 @@ static llvm::raw_ostream &yamlCOFFHeader( } -static llvm::raw_ostream &yamlCOFFSections(llvm::object::COFFObjectFile &Obj, - std::size_t NumSections, llvm::raw_ostream &Out) { - llvm::error_code ec; +static raw_ostream &yamlCOFFSections(object::COFFObjectFile &Obj, + std::size_t NumSections, + raw_ostream &Out) { + error_code ec; Out << "sections:\n"; - for (llvm::object::section_iterator iter = Obj.begin_sections(); - iter != Obj.end_sections(); iter.increment(ec)) { - const llvm::object::coff_section *sect = Obj.getCOFFSection(iter); - + for (object::section_iterator iter = Obj.begin_sections(); + iter != Obj.end_sections(); iter.increment(ec)) { + const object::coff_section *sect = Obj.getCOFFSection(iter); + Out << " - !Section\n"; Out << " Name: "; yaml::writeName(Out, sect->Name, sizeof(sect->Name)) << '\n'; Out << " Characteristics: ["; yaml::writeBitMask(Out, SectionCharacteristicsPairs1, sect->Characteristics); - Out << nameLookup(SectionCharacteristicsPairsAlignment, - sect->Characteristics & 0x00F00000, "# Unrecognized_IMAGE_SCN_ALIGN") + Out << nameLookup(SectionCharacteristicsPairsAlignment, + sect->Characteristics & 0x00F00000, "# Unrecognized_IMAGE_SCN_ALIGN") << ", "; yaml::writeBitMask(Out, SectionCharacteristicsPairs2, sect->Characteristics); Out << "] # "; yaml::writeHexNumber(Out, sect->Characteristics) << '\n'; - llvm::ArrayRef sectionData; - Obj.getSectionContents(sect, sectionData); + ArrayRef sectionData; + Obj.getSectionContents(sect, sectionData); Out << " SectionData: "; yaml::writeHexStream(Out, sectionData) << '\n'; if (iter->begin_relocations() != iter->end_relocations()) Out << " Relocations:\n"; - for (llvm::object::relocation_iterator rIter = iter->begin_relocations(); + for (object::relocation_iterator rIter = iter->begin_relocations(); rIter != iter->end_relocations(); rIter.increment(ec)) { - const llvm::object::coff_relocation *reloc = Obj.getCOFFRelocation(rIter); + const object::coff_relocation *reloc = Obj.getCOFFRelocation(rIter); Out << " - !Relocation\n"; Out << " VirtualAddress: " ; yaml::writeHexNumber(Out, reloc->VirtualAddress) << '\n'; Out << " SymbolTableIndex: " << reloc->SymbolTableIndex << '\n'; - Out << " Type: " + Out << " Type: " << nameLookup(RelocationTypeX86Pairs, reloc->Type) << '\n'; // TODO: Use the correct reloc type for the machine. Out << '\n'; } - } + } return Out; } -static llvm::raw_ostream& yamlCOFFSymbols(llvm::object::COFFObjectFile &Obj, - std::size_t NumSymbols, llvm::raw_ostream &Out) { - llvm::error_code ec; +static raw_ostream& yamlCOFFSymbols(object::COFFObjectFile &Obj, + std::size_t NumSymbols, + raw_ostream &Out) { + error_code ec; Out << "symbols:\n"; - for (llvm::object::symbol_iterator iter = Obj.begin_symbols(); - iter != Obj.end_symbols(); iter.increment(ec)) { + for (object::symbol_iterator iter = Obj.begin_symbols(); + iter != Obj.end_symbols(); iter.increment(ec)) { // Gather all the info that we need - llvm::StringRef str; - const llvm::object::coff_symbol *symbol = Obj.getCOFFSymbol(iter); + StringRef str; + const object::coff_symbol *symbol = Obj.getCOFFSymbol(iter); Obj.getSymbolName(symbol, str); std::size_t simpleType = symbol->getBaseType(); std::size_t complexType = symbol->getComplexType(); std::size_t storageClass = symbol->StorageClass; - + Out << " - !Symbol\n"; - Out << " Name: " << str << '\n'; + Out << " Name: " << str << '\n'; Out << " Value: " << symbol->Value << '\n'; Out << " SectionNumber: " << symbol->SectionNumber << '\n'; - Out << " SimpleType: " - << nameLookup(SymbolBaseTypePairs, simpleType, - "# Unknown_SymbolBaseType") + Out << " SimpleType: " + << nameLookup(SymbolBaseTypePairs, simpleType, + "# Unknown_SymbolBaseType") << " # (" << simpleType << ")\n"; - - Out << " ComplexType: " - << nameLookup(SymbolComplexTypePairs, complexType, - "# Unknown_SymbolComplexType") + + Out << " ComplexType: " + << nameLookup(SymbolComplexTypePairs, complexType, + "# Unknown_SymbolComplexType") << " # (" << complexType << ")\n"; - - Out << " StorageClass: " + + Out << " StorageClass: " << nameLookup(SymbolStorageClassPairs, storageClass, - "# Unknown_StorageClass") + "# Unknown_StorageClass") << " # (" << (int) storageClass << ")\n"; if (symbol->NumberOfAuxSymbols > 0) { - llvm::ArrayRef aux = Obj.getSymbolAuxData(symbol); - Out << " NumberOfAuxSymbols: " + ArrayRef aux = Obj.getSymbolAuxData(symbol); + Out << " NumberOfAuxSymbols: " << (int) symbol->NumberOfAuxSymbols << '\n'; Out << " AuxillaryData: "; yaml::writeHexStream(Out, aux); } - + Out << '\n'; } @@ -342,17 +346,20 @@ static llvm::raw_ostream& yamlCOFFSymbols(llvm::object::COFFObjectFile &Obj, } -llvm::error_code coff2yaml(llvm::raw_ostream &Out, llvm::MemoryBuffer *TheObj) { - llvm::error_code ec; - llvm::object::COFFObjectFile obj(TheObj, ec); - if (!ec) { - const llvm::object::coff_file_header *hd; - ec = obj.getHeader(hd); - if (!ec) { - yamlCOFFHeader(hd, Out); - yamlCOFFSections(obj, hd->NumberOfSections, Out); - yamlCOFFSymbols(obj, hd->NumberOfSymbols, Out); - } - } +error_code coff2yaml(raw_ostream &Out, MemoryBuffer *TheObj) { + error_code ec; + object::COFFObjectFile obj(TheObj, ec); + if (ec) + return ec; + + const object::coff_file_header *hd; + ec = obj.getHeader(hd); + if (ec) + return ec; + + yamlCOFFHeader(hd, Out); + yamlCOFFSections(obj, hd->NumberOfSections, Out); + yamlCOFFSymbols(obj, hd->NumberOfSymbols, Out); + return ec; } -- cgit v1.2.3-18-g5258 From 9e39d0bc2092f97c531591737af8abda48211169 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 20 Apr 2013 03:13:00 +0000 Subject: Remove local namespace yaml to avoid confusion with llvm::yaml. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179921 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/obj2yaml/coff2yaml.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/obj2yaml/coff2yaml.cpp b/tools/obj2yaml/coff2yaml.cpp index 4a8ffbd81e..349d0c1756 100644 --- a/tools/obj2yaml/coff2yaml.cpp +++ b/tools/obj2yaml/coff2yaml.cpp @@ -202,8 +202,6 @@ RelocationTypesARMPairs [] = { }; #undef STRING_PAIR -namespace yaml { // COFF-specific yaml-writing specific routines - static raw_ostream &writeName(raw_ostream &Out, const char *Name, std::size_t NameSize) { for (std::size_t i = 0; i < NameSize; ++i) { @@ -224,8 +222,6 @@ static raw_ostream &writeBitMask(raw_ostream &Out, return Out; } -} // end of yaml namespace - // Given an array of pod_pair, look up a value template const char *nameLookup(const pod_pair (&Arr)[N], @@ -237,9 +233,11 @@ const char *nameLookup(const pod_pair (&Arr)[N], return NotFound; } - static raw_ostream &yamlCOFFHeader(const object::coff_file_header *Header, raw_ostream &Out) { + COFF::header H; + H.Machine = Header->Machine; + H.Characteristics = Header->Characteristics; Out << "header: !Header\n"; Out << " Machine: "; @@ -260,14 +258,14 @@ static raw_ostream &yamlCOFFSections(object::COFFObjectFile &Obj, Out << " - !Section\n"; Out << " Name: "; - yaml::writeName(Out, sect->Name, sizeof(sect->Name)) << '\n'; + writeName(Out, sect->Name, sizeof(sect->Name)) << '\n'; Out << " Characteristics: ["; - yaml::writeBitMask(Out, SectionCharacteristicsPairs1, sect->Characteristics); + writeBitMask(Out, SectionCharacteristicsPairs1, sect->Characteristics); Out << nameLookup(SectionCharacteristicsPairsAlignment, sect->Characteristics & 0x00F00000, "# Unrecognized_IMAGE_SCN_ALIGN") << ", "; - yaml::writeBitMask(Out, SectionCharacteristicsPairs2, sect->Characteristics); + writeBitMask(Out, SectionCharacteristicsPairs2, sect->Characteristics); Out << "] # "; yaml::writeHexNumber(Out, sect->Characteristics) << '\n'; -- cgit v1.2.3-18-g5258 From daf0f44e3161dd065768412544d42de3227c9c3a Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 20 Apr 2013 03:16:59 +0000 Subject: Rename obj2yaml local namespace to avoid conflicts with llvm::yaml. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179922 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/obj2yaml/coff2yaml.cpp | 10 +++++----- tools/obj2yaml/obj2yaml.cpp | 2 +- tools/obj2yaml/obj2yaml.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/obj2yaml/coff2yaml.cpp b/tools/obj2yaml/coff2yaml.cpp index 349d0c1756..203754c11c 100644 --- a/tools/obj2yaml/coff2yaml.cpp +++ b/tools/obj2yaml/coff2yaml.cpp @@ -243,7 +243,7 @@ static raw_ostream &yamlCOFFHeader(const object::coff_file_header *Header, Out << " Machine: "; Out << nameLookup(MachineTypePairs, Header->Machine, "# Unknown_MachineTypes") << " # ("; - return yaml::writeHexNumber(Out, Header->Machine) << ")\n\n"; + return objyaml::writeHexNumber(Out, Header->Machine) << ")\n\n"; } @@ -267,12 +267,12 @@ static raw_ostream &yamlCOFFSections(object::COFFObjectFile &Obj, << ", "; writeBitMask(Out, SectionCharacteristicsPairs2, sect->Characteristics); Out << "] # "; - yaml::writeHexNumber(Out, sect->Characteristics) << '\n'; + objyaml::writeHexNumber(Out, sect->Characteristics) << '\n'; ArrayRef sectionData; Obj.getSectionContents(sect, sectionData); Out << " SectionData: "; - yaml::writeHexStream(Out, sectionData) << '\n'; + objyaml::writeHexStream(Out, sectionData) << '\n'; if (iter->begin_relocations() != iter->end_relocations()) Out << " Relocations:\n"; for (object::relocation_iterator rIter = iter->begin_relocations(); @@ -281,7 +281,7 @@ static raw_ostream &yamlCOFFSections(object::COFFObjectFile &Obj, Out << " - !Relocation\n"; Out << " VirtualAddress: " ; - yaml::writeHexNumber(Out, reloc->VirtualAddress) << '\n'; + objyaml::writeHexNumber(Out, reloc->VirtualAddress) << '\n'; Out << " SymbolTableIndex: " << reloc->SymbolTableIndex << '\n'; Out << " Type: " << nameLookup(RelocationTypeX86Pairs, reloc->Type) << '\n'; @@ -334,7 +334,7 @@ static raw_ostream& yamlCOFFSymbols(object::COFFObjectFile &Obj, Out << " NumberOfAuxSymbols: " << (int) symbol->NumberOfAuxSymbols << '\n'; Out << " AuxillaryData: "; - yaml::writeHexStream(Out, aux); + objyaml::writeHexStream(Out, aux); } Out << '\n'; diff --git a/tools/obj2yaml/obj2yaml.cpp b/tools/obj2yaml/obj2yaml.cpp index f089e0aba5..821c9ac7d3 100644 --- a/tools/obj2yaml/obj2yaml.cpp +++ b/tools/obj2yaml/obj2yaml.cpp @@ -18,7 +18,7 @@ using namespace llvm; -namespace yaml { // generic yaml-writing specific routines +namespace objyaml { // generic yaml-writing specific routines unsigned char printable(unsigned char Ch) { return Ch >= ' ' && Ch <= '~' ? Ch : '.'; diff --git a/tools/obj2yaml/obj2yaml.h b/tools/obj2yaml/obj2yaml.h index b4a012607a..7d52a2d177 100644 --- a/tools/obj2yaml/obj2yaml.h +++ b/tools/obj2yaml/obj2yaml.h @@ -18,7 +18,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" -namespace yaml { // routines for writing YAML +namespace objyaml { // routines for writing YAML // Write a hex stream: // !hex: "" #|\n llvm::raw_ostream &writeHexStream -- cgit v1.2.3-18-g5258 From d0ec6ddc1454a00dd9cf9db813433d2953f4c952 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 20 Apr 2013 03:33:09 +0000 Subject: These can be void. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179923 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/obj2yaml/coff2yaml.cpp | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) (limited to 'tools') diff --git a/tools/obj2yaml/coff2yaml.cpp b/tools/obj2yaml/coff2yaml.cpp index 203754c11c..3098cb5274 100644 --- a/tools/obj2yaml/coff2yaml.cpp +++ b/tools/obj2yaml/coff2yaml.cpp @@ -233,8 +233,8 @@ const char *nameLookup(const pod_pair (&Arr)[N], return NotFound; } -static raw_ostream &yamlCOFFHeader(const object::coff_file_header *Header, - raw_ostream &Out) { +static void yamlCOFFHeader(const object::coff_file_header *Header, + raw_ostream &Out) { COFF::header H; H.Machine = Header->Machine; H.Characteristics = Header->Characteristics; @@ -243,13 +243,12 @@ static raw_ostream &yamlCOFFHeader(const object::coff_file_header *Header, Out << " Machine: "; Out << nameLookup(MachineTypePairs, Header->Machine, "# Unknown_MachineTypes") << " # ("; - return objyaml::writeHexNumber(Out, Header->Machine) << ")\n\n"; + objyaml::writeHexNumber(Out, Header->Machine) << ")\n\n"; } -static raw_ostream &yamlCOFFSections(object::COFFObjectFile &Obj, - std::size_t NumSections, - raw_ostream &Out) { +static void yamlCOFFSections(object::COFFObjectFile &Obj, + std::size_t NumSections, raw_ostream &Out) { error_code ec; Out << "sections:\n"; for (object::section_iterator iter = Obj.begin_sections(); @@ -290,12 +289,10 @@ static raw_ostream &yamlCOFFSections(object::COFFObjectFile &Obj, } } - return Out; } -static raw_ostream& yamlCOFFSymbols(object::COFFObjectFile &Obj, - std::size_t NumSymbols, - raw_ostream &Out) { +static void yamlCOFFSymbols(object::COFFObjectFile &Obj, std::size_t NumSymbols, + raw_ostream &Out) { error_code ec; Out << "symbols:\n"; for (object::symbol_iterator iter = Obj.begin_symbols(); @@ -339,8 +336,6 @@ static raw_ostream& yamlCOFFSymbols(object::COFFObjectFile &Obj, Out << '\n'; } - - return Out; } -- cgit v1.2.3-18-g5258 From 972b26b1d7efbb29a90a0fdd4eda47fd7f7af447 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 20 Apr 2013 11:06:34 +0000 Subject: Remove dead code. This is part of a future patch to use yamlio that incorrectly ended up in a cleanup patch. Thanks to Benjamin Kramer for reporting it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@179938 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/obj2yaml/coff2yaml.cpp | 4 ---- 1 file changed, 4 deletions(-) (limited to 'tools') diff --git a/tools/obj2yaml/coff2yaml.cpp b/tools/obj2yaml/coff2yaml.cpp index 3098cb5274..5106a4a44b 100644 --- a/tools/obj2yaml/coff2yaml.cpp +++ b/tools/obj2yaml/coff2yaml.cpp @@ -235,10 +235,6 @@ const char *nameLookup(const pod_pair (&Arr)[N], static void yamlCOFFHeader(const object::coff_file_header *Header, raw_ostream &Out) { - COFF::header H; - H.Machine = Header->Machine; - H.Characteristics = Header->Characteristics; - Out << "header: !Header\n"; Out << " Machine: "; Out << nameLookup(MachineTypePairs, Header->Machine, "# Unknown_MachineTypes") -- cgit v1.2.3-18-g5258 From 48831939a83915939f759bdbe95404499169bc85 Mon Sep 17 00:00:00 2001 From: Nico Rieck Date: Mon, 22 Apr 2013 08:34:46 +0000 Subject: llvm-readobj: Do not print NULL StringRefs git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180005 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/COFFDumper.cpp | 6 +++--- tools/llvm-readobj/ELFDumper.cpp | 6 +++--- tools/llvm-readobj/MachODumper.cpp | 9 ++++----- 3 files changed, 10 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp index d600bc3fd2..56885c66a8 100644 --- a/tools/llvm-readobj/COFFDumper.cpp +++ b/tools/llvm-readobj/COFFDumper.cpp @@ -726,9 +726,9 @@ void COFFDumper::printSymbol(symbol_iterator SymI) { if (Obj->getSymbolName(Symbol, SymbolName)) SymbolName = ""; - StringRef SectionName; - if (Section && Obj->getSectionName(Section, SectionName)) - SectionName = ""; + StringRef SectionName = ""; + if (Section) + Obj->getSectionName(Section, SectionName); W.printString("Name", SymbolName); W.printNumber("Value", Symbol->Value); diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index 3757b09c39..f771cbdd52 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -643,9 +643,9 @@ void ELFDumper::printSymbol(symbol_iterator SymI, bool IsDynamic) { if (SymI->getName(SymbolName)) SymbolName = ""; - StringRef SectionName; - if (Section && Obj->getSectionName(Section, SectionName)) - SectionName = ""; + StringRef SectionName = ""; + if (Section) + Obj->getSectionName(Section, SectionName); std::string FullSymbolName(SymbolName); if (IsDynamic) { diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index 54de49c310..10e53d91fb 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -406,12 +406,11 @@ void MachODumper::printSymbol(symbol_iterator SymI) { MachOSymbol Symbol; getSymbol(Obj, SymI->getRawDataRefImpl(), Symbol); - StringRef SectionName; + StringRef SectionName = ""; section_iterator SecI(Obj->end_sections()); - if (error(SymI->getSection(SecI)) || - SecI == Obj->end_sections() || - error(SecI->getName(SectionName))) - SectionName = ""; + if (!error(SymI->getSection(SecI)) && + SecI != Obj->end_sections()) + error(SecI->getName(SectionName)); DictScope D(W, "Symbol"); W.printNumber("Name", SymbolName, Symbol.StringIndex); -- cgit v1.2.3-18-g5258 From 92f5e268c9aad68ed58198ad14f4d32fd26c5db6 Mon Sep 17 00:00:00 2001 From: Nico Rieck Date: Mon, 22 Apr 2013 08:34:59 +0000 Subject: llvm-readobj: Check for null section pointer git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180006 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/COFFDumper.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp index 56885c66a8..14f8b72ac7 100644 --- a/tools/llvm-readobj/COFFDumper.cpp +++ b/tools/llvm-readobj/COFFDumper.cpp @@ -799,7 +799,7 @@ void COFFDumper::printSymbol(symbol_iterator SymI) { W.printEnum("Selection", Aux->Selection, makeArrayRef(ImageCOMDATSelect)); W.printBinary("Unused", makeArrayRef(Aux->Unused)); - if (Section->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT + if (Section && Section->Characteristics & COFF::IMAGE_SCN_LNK_COMDAT && Aux->Selection == COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE) { const coff_section *Assoc; StringRef AssocName; -- cgit v1.2.3-18-g5258 From c74142ab15d3d3cdf49214dc65b76cb932a9c1a6 Mon Sep 17 00:00:00 2001 From: Nico Rieck Date: Mon, 22 Apr 2013 08:35:11 +0000 Subject: llvm-readobj: Dump more COFF auxiliary records git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180007 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/COFFDumper.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp index 14f8b72ac7..94aafa7eb1 100644 --- a/tools/llvm-readobj/COFFDumper.cpp +++ b/tools/llvm-readobj/COFFDumper.cpp @@ -785,7 +785,12 @@ void COFFDumper::printSymbol(symbol_iterator SymI) { if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) break; - } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC) { + DictScope AS(W, "AuxFileRecord"); + W.printString("FileName", StringRef(Aux->FileName)); + + } else if (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC || + (Symbol->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL && + Symbol->SectionNumber != COFF::IMAGE_SYM_UNDEFINED)) { const coff_aux_section_definition *Aux; if (error(getSymbolAuxData(Obj, Symbol + I, Aux))) break; -- cgit v1.2.3-18-g5258 From 120cf5743b03d67d9f26ae05c2b79d98cc05f79d Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 23 Apr 2013 15:53:02 +0000 Subject: Write relocations in yaml2obj. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180115 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/yaml2obj/yaml2obj.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'tools') diff --git a/tools/yaml2obj/yaml2obj.cpp b/tools/yaml2obj/yaml2obj.cpp index 5741d95c54..7f8663b824 100644 --- a/tools/yaml2obj/yaml2obj.cpp +++ b/tools/yaml2obj/yaml2obj.cpp @@ -186,6 +186,7 @@ struct COFFParser { errs() << "SectionData must be a collection of pairs of hex bytes"; return false; } + Sec.Relocations = YamlSection.Relocations; Sections.push_back(Sec); } return true; @@ -289,6 +290,12 @@ static bool layoutCOFF(COFFParser &CP) { i->Header.SizeOfRawData = i->Data.size(); i->Header.PointerToRawData = CurrentSectionDataOffset; CurrentSectionDataOffset += i->Header.SizeOfRawData; + if (!i->Relocations.empty()) { + i->Header.PointerToRelocations = CurrentSectionDataOffset; + i->Header.NumberOfRelocations = i->Relocations.size(); + CurrentSectionDataOffset += i->Header.NumberOfRelocations * + COFF::RelocationSize; + } // TODO: Handle alignment. } else { i->Header.SizeOfRawData = 0; @@ -374,6 +381,12 @@ void writeCOFF(COFFParser &CP, raw_ostream &OS) { i != e; ++i) { if (!i->Data.empty()) OS.write(reinterpret_cast(&i->Data[0]), i->Data.size()); + for (unsigned I2 = 0, E2 = i->Relocations.size(); I2 != E2; ++I2) { + const COFF::relocation &R = i->Relocations[I2]; + OS << binary_le(R.VirtualAddress) + << binary_le(R.SymbolTableIndex) + << binary_le(R.Type); + } } // Output symbol table. -- cgit v1.2.3-18-g5258 From c0f15f67038ef3967c2c728d050ad6da0c098f10 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 23 Apr 2013 19:26:43 +0000 Subject: Simplify yaml2obj a bit. The COFFParser now contains only a COFFYAML::Object and the string table (which is recomputed, not serialized). The structs in COFFParser now all begin with a Header field with what is actually on the COFF object. The other fields are things that are semantically part of the struct (relocations in a section for exmaple), but are not actually represented that way in the object file. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180134 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/yaml2obj/yaml2obj.cpp | 217 +++++++++++++++++++++++--------------------- 1 file changed, 112 insertions(+), 105 deletions(-) (limited to 'tools') diff --git a/tools/yaml2obj/yaml2obj.cpp b/tools/yaml2obj/yaml2obj.cpp index 7f8663b824..d132f1cce1 100644 --- a/tools/yaml2obj/yaml2obj.cpp +++ b/tools/yaml2obj/yaml2obj.cpp @@ -115,27 +115,33 @@ static bool hexStringToByteArray(StringRef Str, ContainerOut &Out) { // to use yaml::IO, we use these structures which are closer to the source. namespace COFFYAML { struct Section { - COFF::SectionCharacteristics Characteristics; + COFF::section Header; StringRef SectionData; std::vector Relocations; StringRef Name; + Section() { + memset(&Header, 0, sizeof(COFF::section)); + } }; struct Symbol { + COFF::symbol Header; COFF::SymbolBaseType SimpleType; - uint8_t NumberOfAuxSymbols; - StringRef Name; - COFF::SymbolStorageClass StorageClass; - StringRef AuxillaryData; COFF::SymbolComplexType ComplexType; - uint32_t Value; - uint16_t SectionNumber; + StringRef AuxillaryData; + StringRef Name; + Symbol() { + memset(&Header, 0, sizeof(COFF::symbol)); + } }; struct Object { - COFF::header HeaderData; + COFF::header Header; std::vector
Sections; std::vector Symbols; + Object() { + memset(&Header, 0, sizeof(COFF::header)); + } }; } @@ -143,28 +149,20 @@ namespace COFFYAML { /// See docs/yaml2obj for the yaml scheema. struct COFFParser { COFFParser(COFFYAML::Object &Obj) : Obj(Obj) { - std::memset(&Header, 0, sizeof(Header)); // A COFF string table always starts with a 4 byte size field. Offsets into // it include this size, so allocate it now. StringTable.append(4, 0); } - void parseHeader() { - Header.Machine = Obj.HeaderData.Machine; - Header.Characteristics = Obj.HeaderData.Characteristics; - } - bool parseSections() { for (std::vector::iterator i = Obj.Sections.begin(), e = Obj.Sections.end(); i != e; ++i) { - const COFFYAML::Section &YamlSection = *i; - Section Sec; - std::memset(&Sec.Header, 0, sizeof(Sec.Header)); + COFFYAML::Section &Sec = *i; // If the name is less than 8 bytes, store it in place, otherwise // store it in the string table. - StringRef Name = YamlSection.Name; - std::fill_n(Sec.Header.Name, unsigned(COFF::NameSize), 0); + StringRef Name = Sec.Name; + if (Name.size() <= COFF::NameSize) { std::copy(Name.begin(), Name.end(), Sec.Header.Name); } else { @@ -178,16 +176,6 @@ struct COFFParser { Sec.Header.Name[0] = '/'; std::copy(str.begin(), str.end(), Sec.Header.Name + 1); } - - Sec.Header.Characteristics = YamlSection.Characteristics; - - StringRef Data = YamlSection.SectionData; - if (!hexStringToByteArray(Data, Sec.Data)) { - errs() << "SectionData must be a collection of pairs of hex bytes"; - return false; - } - Sec.Relocations = YamlSection.Relocations; - Sections.push_back(Sec); } return true; } @@ -195,14 +183,11 @@ struct COFFParser { bool parseSymbols() { for (std::vector::iterator i = Obj.Symbols.begin(), e = Obj.Symbols.end(); i != e; ++i) { - COFFYAML::Symbol YamlSymbol = *i; - Symbol Sym; - std::memset(&Sym.Header, 0, sizeof(Sym.Header)); + COFFYAML::Symbol &Sym = *i; // If the name is less than 8 bytes, store it in place, otherwise // store it in the string table. - StringRef Name = YamlSymbol.Name; - std::fill_n(Sym.Header.Name, unsigned(COFF::NameSize), 0); + StringRef Name = Sym.Name; if (Name.size() <= COFF::NameSize) { std::copy(Name.begin(), Name.end(), Sym.Header.Name); } else { @@ -212,24 +197,13 @@ struct COFFParser { Sym.Header.Name + 4) = Index; } - Sym.Header.Value = YamlSymbol.Value; - Sym.Header.Type |= YamlSymbol.SimpleType; - Sym.Header.Type |= YamlSymbol.ComplexType << COFF::SCT_COMPLEX_TYPE_SHIFT; - Sym.Header.StorageClass = YamlSymbol.StorageClass; - Sym.Header.SectionNumber = YamlSymbol.SectionNumber; - - StringRef Data = YamlSymbol.AuxillaryData; - if (!hexStringToByteArray(Data, Sym.AuxSymbols)) { - errs() << "AuxillaryData must be a collection of pairs of hex bytes"; - return false; - } - Symbols.push_back(Sym); + Sym.Header.Type = Sym.SimpleType; + Sym.Header.Type |= Sym.ComplexType << COFF::SCT_COMPLEX_TYPE_SHIFT; } return true; } bool parse() { - parseHeader(); if (!parseSections()) return false; if (!parseSymbols()) @@ -250,21 +224,7 @@ struct COFFParser { } COFFYAML::Object &Obj; - COFF::header Header; - struct Section { - COFF::section Header; - std::vector Data; - std::vector Relocations; - }; - - struct Symbol { - COFF::symbol Header; - std::vector AuxSymbols; - }; - - std::vector
Sections; - std::vector Symbols; StringMap StringTableMap; std::string StringTable; }; @@ -277,17 +237,17 @@ static bool layoutCOFF(COFFParser &CP) { // The section table starts immediately after the header, including the // optional header. - SectionTableStart = sizeof(COFF::header) + CP.Header.SizeOfOptionalHeader; - SectionTableSize = sizeof(COFF::section) * CP.Sections.size(); + SectionTableStart = sizeof(COFF::header) + CP.Obj.Header.SizeOfOptionalHeader; + SectionTableSize = sizeof(COFF::section) * CP.Obj.Sections.size(); uint32_t CurrentSectionDataOffset = SectionTableStart + SectionTableSize; // Assign each section data address consecutively. - for (std::vector::iterator i = CP.Sections.begin(), - e = CP.Sections.end(); - i != e; ++i) { - if (!i->Data.empty()) { - i->Header.SizeOfRawData = i->Data.size(); + for (std::vector::iterator i = CP.Obj.Sections.begin(), + e = CP.Obj.Sections.end(); + i != e; ++i) { + if (!i->SectionData.empty()) { + i->Header.SizeOfRawData = i->SectionData.size()/2; i->Header.PointerToRawData = CurrentSectionDataOffset; CurrentSectionDataOffset += i->Header.SizeOfRawData; if (!i->Relocations.empty()) { @@ -307,21 +267,22 @@ static bool layoutCOFF(COFFParser &CP) { // Calculate number of symbols. uint32_t NumberOfSymbols = 0; - for (std::vector::iterator i = CP.Symbols.begin(), - e = CP.Symbols.end(); - i != e; ++i) { - if (i->AuxSymbols.size() % COFF::SymbolSize != 0) { + for (std::vector::iterator i = CP.Obj.Symbols.begin(), + e = CP.Obj.Symbols.end(); + i != e; ++i) { + unsigned AuxBytes = i->AuxillaryData.size() / 2; + if (AuxBytes % COFF::SymbolSize != 0) { errs() << "AuxillaryData size not a multiple of symbol size!\n"; return false; } - i->Header.NumberOfAuxSymbols = i->AuxSymbols.size() / COFF::SymbolSize; + i->Header.NumberOfAuxSymbols = AuxBytes / COFF::SymbolSize; NumberOfSymbols += 1 + i->Header.NumberOfAuxSymbols; } // Store all the allocated start addresses in the header. - CP.Header.NumberOfSections = CP.Sections.size(); - CP.Header.NumberOfSymbols = NumberOfSymbols; - CP.Header.PointerToSymbolTable = SymbolTableStart; + CP.Obj.Header.NumberOfSections = CP.Obj.Sections.size(); + CP.Obj.Header.NumberOfSymbols = NumberOfSymbols; + CP.Obj.Header.PointerToSymbolTable = SymbolTableStart; *reinterpret_cast(&CP.StringTable[0]) = CP.StringTable.size(); @@ -350,19 +311,19 @@ binary_le_impl binary_le(value_type V) { return binary_le_impl(V); } -void writeCOFF(COFFParser &CP, raw_ostream &OS) { - OS << binary_le(CP.Header.Machine) - << binary_le(CP.Header.NumberOfSections) - << binary_le(CP.Header.TimeDateStamp) - << binary_le(CP.Header.PointerToSymbolTable) - << binary_le(CP.Header.NumberOfSymbols) - << binary_le(CP.Header.SizeOfOptionalHeader) - << binary_le(CP.Header.Characteristics); +bool writeCOFF(COFFParser &CP, raw_ostream &OS) { + OS << binary_le(CP.Obj.Header.Machine) + << binary_le(CP.Obj.Header.NumberOfSections) + << binary_le(CP.Obj.Header.TimeDateStamp) + << binary_le(CP.Obj.Header.PointerToSymbolTable) + << binary_le(CP.Obj.Header.NumberOfSymbols) + << binary_le(CP.Obj.Header.SizeOfOptionalHeader) + << binary_le(CP.Obj.Header.Characteristics); // Output section table. - for (std::vector::const_iterator i = CP.Sections.begin(), - e = CP.Sections.end(); - i != e; ++i) { + for (std::vector::iterator i = CP.Obj.Sections.begin(), + e = CP.Obj.Sections.end(); + i != e; ++i) { OS.write(i->Header.Name, COFF::NameSize); OS << binary_le(i->Header.VirtualSize) << binary_le(i->Header.VirtualAddress) @@ -376,11 +337,18 @@ void writeCOFF(COFFParser &CP, raw_ostream &OS) { } // Output section data. - for (std::vector::const_iterator i = CP.Sections.begin(), - e = CP.Sections.end(); - i != e; ++i) { - if (!i->Data.empty()) - OS.write(reinterpret_cast(&i->Data[0]), i->Data.size()); + for (std::vector::iterator i = CP.Obj.Sections.begin(), + e = CP.Obj.Sections.end(); + i != e; ++i) { + if (!i->SectionData.empty()) { + std::vector Data; + if (!hexStringToByteArray(i->SectionData, Data)) { + errs() << "SectionData must be a collection of pairs of hex bytes"; + return false; + } + + OS.write(reinterpret_cast(&Data[0]), Data.size()); + } for (unsigned I2 = 0, E2 = i->Relocations.size(); I2 != E2; ++I2) { const COFF::relocation &R = i->Relocations[I2]; OS << binary_le(R.VirtualAddress) @@ -391,22 +359,30 @@ void writeCOFF(COFFParser &CP, raw_ostream &OS) { // Output symbol table. - for (std::vector::const_iterator i = CP.Symbols.begin(), - e = CP.Symbols.end(); - i != e; ++i) { + for (std::vector::const_iterator i = CP.Obj.Symbols.begin(), + e = CP.Obj.Symbols.end(); + i != e; ++i) { OS.write(i->Header.Name, COFF::NameSize); OS << binary_le(i->Header.Value) << binary_le(i->Header.SectionNumber) << binary_le(i->Header.Type) << binary_le(i->Header.StorageClass) << binary_le(i->Header.NumberOfAuxSymbols); - if (!i->AuxSymbols.empty()) - OS.write( reinterpret_cast(&i->AuxSymbols[0]) - , i->AuxSymbols.size()); + if (!i->AuxillaryData.empty()) { + std::vector AuxSymbols; + if (!hexStringToByteArray(i->AuxillaryData, AuxSymbols)) { + errs() << "AuxillaryData must be a collection of pairs of hex bytes"; + return false; + } + + OS.write(reinterpret_cast(&AuxSymbols[0]), + AuxSymbols.size()); + } } // Output string table. OS.write(&CP.StringTable[0], CP.StringTable.size()); + return true; } LLVM_YAML_IS_SEQUENCE_VECTOR(COFF::relocation) @@ -627,15 +603,29 @@ struct ScalarEnumerationTraits { template <> struct MappingTraits { + struct NStorageClass { + NStorageClass(IO&) : StorageClass(COFF::SymbolStorageClass(0)) { + } + NStorageClass(IO&, uint8_t S) : StorageClass(COFF::SymbolStorageClass(S)) { + } + uint8_t denormalize(IO &) { + return StorageClass; + } + + COFF::SymbolStorageClass StorageClass; + }; + static void mapping(IO &IO, COFFYAML::Symbol &S) { + MappingNormalization NS(IO, S.Header.StorageClass); + IO.mapRequired("SimpleType", S.SimpleType); - IO.mapOptional("NumberOfAuxSymbols", S.NumberOfAuxSymbols); + IO.mapOptional("NumberOfAuxSymbols", S.Header.NumberOfAuxSymbols); IO.mapRequired("Name", S.Name); - IO.mapRequired("StorageClass", S.StorageClass); + IO.mapRequired("StorageClass", NS->StorageClass); IO.mapOptional("AuxillaryData", S.AuxillaryData); // FIXME: typo IO.mapRequired("ComplexType", S.ComplexType); - IO.mapRequired("Value", S.Value); - IO.mapRequired("SectionNumber", S.SectionNumber); + IO.mapRequired("Value", S.Header.Value); + IO.mapRequired("SectionNumber", S.Header.SectionNumber); } }; @@ -698,10 +688,24 @@ struct MappingTraits { template <> struct MappingTraits { + struct NCharacteristics { + NCharacteristics(IO &) : Characteristics(COFF::SectionCharacteristics(0)) { + } + NCharacteristics(IO &, uint32_t C) : + Characteristics(COFF::SectionCharacteristics(C)) { + } + uint32_t denormalize(IO &) { + return Characteristics; + } + COFF::SectionCharacteristics Characteristics; + }; + static void mapping(IO &IO, COFFYAML::Section &Sec) { + MappingNormalization NC(IO, + Sec.Header.Characteristics); IO.mapOptional("Relocations", Sec.Relocations); IO.mapRequired("SectionData", Sec.SectionData); - IO.mapRequired("Characteristics", Sec.Characteristics); + IO.mapRequired("Characteristics", NC->Characteristics); IO.mapRequired("Name", Sec.Name); } }; @@ -710,7 +714,7 @@ template <> struct MappingTraits { static void mapping(IO &IO, COFFYAML::Object &Obj) { IO.mapRequired("sections", Obj.Sections); - IO.mapRequired("header", Obj.HeaderData); + IO.mapRequired("header", Obj.Header); IO.mapRequired("symbols", Obj.Symbols); } }; @@ -745,5 +749,8 @@ int main(int argc, char **argv) { errs() << "yaml2obj: Failed to layout COFF file!\n"; return 1; } - writeCOFF(CP, outs()); + if (!writeCOFF(CP, outs())) { + errs() << "yaml2obj: Failed to write COFF file!\n"; + return 1; + } } -- cgit v1.2.3-18-g5258 From a0840c4b820f0e946f96cbd56cadccd7d2c83c87 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 23 Apr 2013 19:39:34 +0000 Subject: Fix typo. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180137 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/yaml2obj/yaml2obj.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/yaml2obj/yaml2obj.cpp b/tools/yaml2obj/yaml2obj.cpp index d132f1cce1..2185b4f176 100644 --- a/tools/yaml2obj/yaml2obj.cpp +++ b/tools/yaml2obj/yaml2obj.cpp @@ -128,7 +128,7 @@ namespace COFFYAML { COFF::symbol Header; COFF::SymbolBaseType SimpleType; COFF::SymbolComplexType ComplexType; - StringRef AuxillaryData; + StringRef AuxiliaryData; StringRef Name; Symbol() { memset(&Header, 0, sizeof(COFF::symbol)); @@ -270,9 +270,9 @@ static bool layoutCOFF(COFFParser &CP) { for (std::vector::iterator i = CP.Obj.Symbols.begin(), e = CP.Obj.Symbols.end(); i != e; ++i) { - unsigned AuxBytes = i->AuxillaryData.size() / 2; + unsigned AuxBytes = i->AuxiliaryData.size() / 2; if (AuxBytes % COFF::SymbolSize != 0) { - errs() << "AuxillaryData size not a multiple of symbol size!\n"; + errs() << "AuxiliaryData size not a multiple of symbol size!\n"; return false; } i->Header.NumberOfAuxSymbols = AuxBytes / COFF::SymbolSize; @@ -368,10 +368,10 @@ bool writeCOFF(COFFParser &CP, raw_ostream &OS) { << binary_le(i->Header.Type) << binary_le(i->Header.StorageClass) << binary_le(i->Header.NumberOfAuxSymbols); - if (!i->AuxillaryData.empty()) { + if (!i->AuxiliaryData.empty()) { std::vector AuxSymbols; - if (!hexStringToByteArray(i->AuxillaryData, AuxSymbols)) { - errs() << "AuxillaryData must be a collection of pairs of hex bytes"; + if (!hexStringToByteArray(i->AuxiliaryData, AuxSymbols)) { + errs() << "AuxiliaryData must be a collection of pairs of hex bytes"; return false; } @@ -622,7 +622,7 @@ struct MappingTraits { IO.mapOptional("NumberOfAuxSymbols", S.Header.NumberOfAuxSymbols); IO.mapRequired("Name", S.Name); IO.mapRequired("StorageClass", NS->StorageClass); - IO.mapOptional("AuxillaryData", S.AuxillaryData); // FIXME: typo + IO.mapOptional("AuxiliaryData", S.AuxiliaryData); IO.mapRequired("ComplexType", S.ComplexType); IO.mapRequired("Value", S.Header.Value); IO.mapRequired("SectionNumber", S.Header.SectionNumber); -- cgit v1.2.3-18-g5258 From d4ee3920c928f51e4c4d70b4fae97f4d99be2583 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 24 Apr 2013 17:54:35 +0000 Subject: Don't produce an empty llvm.compiler.used in LTO. LTO was always creating an empty llvm.compiler.used. With this patch we now first check if there is anything to be added first. Unfortunately, there is no good way to test libLTO in isolation as it needs gold or ld64, but there are bots doing LTO builds that found this problem. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180202 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/LTOCodeGenerator.cpp | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) (limited to 'tools') diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index e7c83f94f5..5f5f76f35f 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -287,9 +287,7 @@ static void findUsedValues(GlobalVariable *LLVMUsed, SmallPtrSet &UsedValues) { if (LLVMUsed == 0) return; - ConstantArray *Inits = dyn_cast(LLVMUsed->getInitializer()); - if (Inits == 0) return; - + ConstantArray *Inits = cast(LLVMUsed->getInitializer()); for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) if (GlobalValue *GV = dyn_cast(Inits->getOperand(i)->stripPointerCasts())) @@ -326,24 +324,26 @@ void LTOCodeGenerator::applyScopeRestrictions() { if (LLVMCompilerUsed) LLVMCompilerUsed->eraseFromParent(); - llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(_context); - std::vector asmUsed2; - for (SmallPtrSet::const_iterator i = asmUsed.begin(), - e = asmUsed.end(); i !=e; ++i) { - GlobalValue *GV = *i; - Constant *c = ConstantExpr::getBitCast(GV, i8PTy); - asmUsed2.push_back(c); + if (!asmUsed.empty()) { + llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(_context); + std::vector asmUsed2; + for (SmallPtrSet::const_iterator i = asmUsed.begin(), + e = asmUsed.end(); i !=e; ++i) { + GlobalValue *GV = *i; + Constant *c = ConstantExpr::getBitCast(GV, i8PTy); + asmUsed2.push_back(c); + } + + llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, asmUsed2.size()); + LLVMCompilerUsed = + new llvm::GlobalVariable(*mergedModule, ATy, false, + llvm::GlobalValue::AppendingLinkage, + llvm::ConstantArray::get(ATy, asmUsed2), + "llvm.compiler.used"); + + LLVMCompilerUsed->setSection("llvm.metadata"); } - llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, asmUsed2.size()); - LLVMCompilerUsed = - new llvm::GlobalVariable(*mergedModule, ATy, false, - llvm::GlobalValue::AppendingLinkage, - llvm::ConstantArray::get(ATy, asmUsed2), - "llvm.compiler.used"); - - LLVMCompilerUsed->setSection("llvm.metadata"); - passes.add(createInternalizePass(mustPreserveList)); // apply scope restrictions -- cgit v1.2.3-18-g5258 From 802fe9340d032d20195b00334356cf63b303386c Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 24 Apr 2013 19:47:55 +0000 Subject: Use pointers to iterate over symbols. While here, don't report a dummy symbol for relocations that don't have symbols. We used to says such relocations were for the first defined symbol, but now we return end_symbols(). The llvm-readobj output change agrees with otool. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180214 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/MachODumper.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index 10e53d91fb..31dc5ce24a 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -345,7 +345,9 @@ void MachODumper::printRelocation(const MachOObjectFile *Obj, if (error(RelI->getOffset(Offset))) return; if (error(RelI->getTypeName(RelocName))) return; if (error(RelI->getSymbol(Symbol))) return; - if (error(Symbol.getName(SymbolName))) return; + if (symbol_iterator(Symbol) != Obj->end_symbols() && + error(Symbol.getName(SymbolName))) + return; DataRefImpl DR = RelI->getRawDataRefImpl(); macho::RelocationEntry RE = Obj->getRelocation(DR); -- cgit v1.2.3-18-g5258 From 3d3cc32f5fe815b7a38c2cb558b9d5f40fb0bbb1 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 25 Apr 2013 03:07:42 +0000 Subject: Don't compute a std::vector just to write it out a stream. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180247 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/yaml2obj/yaml2obj.cpp | 100 ++++++++------------------------------------ 1 file changed, 17 insertions(+), 83 deletions(-) (limited to 'tools') diff --git a/tools/yaml2obj/yaml2obj.cpp b/tools/yaml2obj/yaml2obj.cpp index 2185b4f176..32dee54dc5 100644 --- a/tools/yaml2obj/yaml2obj.cpp +++ b/tools/yaml2obj/yaml2obj.cpp @@ -37,80 +37,6 @@ using namespace llvm; static cl::opt Input(cl::Positional, cl::desc(""), cl::init("-")); -template -typename llvm::enable_if_c::is_integer, bool>::type -getAs(const llvm::yaml::ScalarNode *SN, T &Result) { - SmallString<4> Storage; - StringRef Value = SN->getValue(Storage); - if (Value.getAsInteger(0, Result)) - return false; - return true; -} - -// Given a container with begin and end with ::value_type of a character type. -// Iterate through pairs of characters in the the set of [a-fA-F0-9] ignoring -// all other characters. -struct hex_pair_iterator { - StringRef::const_iterator Current, End; - typedef SmallVector value_type; - value_type Pair; - bool IsDone; - - hex_pair_iterator(StringRef C) - : Current(C.begin()), End(C.end()), IsDone(false) { - // Initalize Pair. - ++*this; - } - - // End iterator. - hex_pair_iterator() : Current(), End(), IsDone(true) {} - - value_type operator *() const { - return Pair; - } - - hex_pair_iterator operator ++() { - // We're at the end of the input. - if (Current == End) { - IsDone = true; - return *this; - } - Pair = value_type(); - for (; Current != End && Pair.size() != 2; ++Current) { - // Is a valid hex digit. - if ((*Current >= '0' && *Current <= '9') || - (*Current >= 'a' && *Current <= 'f') || - (*Current >= 'A' && *Current <= 'F')) - Pair.push_back(*Current); - } - // Hit the end without getting 2 hex digits. Pair is invalid. - if (Pair.size() != 2) - IsDone = true; - return *this; - } - - bool operator ==(const hex_pair_iterator Other) { - return (IsDone == Other.IsDone) || - (Current == Other.Current && End == Other.End); - } - - bool operator !=(const hex_pair_iterator Other) { - return !(*this == Other); - } -}; - -template -static bool hexStringToByteArray(StringRef Str, ContainerOut &Out) { - for (hex_pair_iterator I(Str), E; I != E; ++I) { - typename hex_pair_iterator::value_type Pair = *I; - typename ContainerOut::value_type Byte; - if (StringRef(Pair.data(), 2).getAsInteger(16, Byte)) - return false; - Out.push_back(Byte); - } - return true; -} - // The structure of the yaml files is not an exact 1:1 match to COFF. In order // to use yaml::IO, we use these structures which are closer to the source. namespace COFFYAML { @@ -311,6 +237,21 @@ binary_le_impl binary_le(value_type V) { return binary_le_impl(V); } +static bool writeHexData(StringRef Data, raw_ostream &OS) { + unsigned Size = Data.size(); + if (Size % 2) + return false; + + for (unsigned I = 0; I != Size; I += 2) { + uint8_t Byte; + if (Data.substr(I, 2).getAsInteger(16, Byte)) + return false; + OS.write(Byte); + } + + return true; +} + bool writeCOFF(COFFParser &CP, raw_ostream &OS) { OS << binary_le(CP.Obj.Header.Machine) << binary_le(CP.Obj.Header.NumberOfSections) @@ -341,13 +282,10 @@ bool writeCOFF(COFFParser &CP, raw_ostream &OS) { e = CP.Obj.Sections.end(); i != e; ++i) { if (!i->SectionData.empty()) { - std::vector Data; - if (!hexStringToByteArray(i->SectionData, Data)) { + if (!writeHexData(i->SectionData, OS)) { errs() << "SectionData must be a collection of pairs of hex bytes"; return false; } - - OS.write(reinterpret_cast(&Data[0]), Data.size()); } for (unsigned I2 = 0, E2 = i->Relocations.size(); I2 != E2; ++I2) { const COFF::relocation &R = i->Relocations[I2]; @@ -369,14 +307,10 @@ bool writeCOFF(COFFParser &CP, raw_ostream &OS) { << binary_le(i->Header.StorageClass) << binary_le(i->Header.NumberOfAuxSymbols); if (!i->AuxiliaryData.empty()) { - std::vector AuxSymbols; - if (!hexStringToByteArray(i->AuxiliaryData, AuxSymbols)) { + if (!writeHexData(i->AuxiliaryData, OS)) { errs() << "AuxiliaryData must be a collection of pairs of hex bytes"; return false; } - - OS.write(reinterpret_cast(&AuxSymbols[0]), - AuxSymbols.size()); } } -- cgit v1.2.3-18-g5258 From 956ca7265c697107708468b7e1b2fd21f4185bae Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 25 Apr 2013 12:28:45 +0000 Subject: Clarify getRelocationAddress x getRelocationOffset a bit. getRelocationAddress is for dynamic libraries and executables, getRelocationOffset for relocatable objects. Mark the getRelocationAddress of COFF and MachO as not implemented yet. Add a test of ELF's. llvm-readobj -r now prints the same values as readelf -r. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180259 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/MachODump.cpp | 2 +- tools/llvm-objdump/llvm-objdump.cpp | 8 ++++---- tools/llvm-readobj/ELFDumper.cpp | 6 +++++- tools/llvm-readobj/llvm-readobj.cpp | 4 ++-- 4 files changed, 12 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index d78d7f31a6..6797e2dc5b 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -343,7 +343,7 @@ static void DisassembleInputMachO2(StringRef Filename, for (relocation_iterator RI = Sections[SectIdx].begin_relocations(), RE = Sections[SectIdx].end_relocations(); RI != RE; RI.increment(ec)) { uint64_t RelocOffset, SectionAddress; - RI->getAddress(RelocOffset); + RI->getOffset(RelocOffset); Sections[SectIdx].getAddress(SectionAddress); RelocOffset -= SectionAddress; diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 9985599565..247b90f030 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -186,8 +186,8 @@ void llvm::DumpBytes(StringRef bytes) { bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) { uint64_t a_addr, b_addr; - if (error(a.getAddress(a_addr))) return false; - if (error(b.getAddress(b_addr))) return false; + if (error(a.getOffset(a_addr))) return false; + if (error(b.getOffset(b_addr))) return false; return a_addr < b_addr; } @@ -378,7 +378,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { if (error(rel_cur->getHidden(hidden))) goto skip_print_rel; if (hidden) goto skip_print_rel; - if (error(rel_cur->getAddress(addr))) goto skip_print_rel; + if (error(rel_cur->getOffset(addr))) goto skip_print_rel; // Stop when rel_cur's address is past the current instruction. if (addr >= Index + Size) break; if (error(rel_cur->getTypeName(name))) goto skip_print_rel; @@ -417,7 +417,7 @@ static void PrintRelocations(const ObjectFile *o) { if (error(ri->getHidden(hidden))) continue; if (hidden) continue; if (error(ri->getTypeName(relocname))) continue; - if (error(ri->getAddress(address))) continue; + if (error(ri->getOffset(address))) continue; if (error(ri->getValueString(valuestr))) continue; outs() << address << " " << relocname << " " << valuestr << "\n"; } diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index f771cbdd52..ea1b83f32f 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -582,7 +582,11 @@ void ELFDumper::printRelocation(section_iterator Sec, int64_t Info; StringRef SymbolName; SymbolRef Symbol; - if (error(RelI->getOffset(Offset))) return; + if (Obj->getElfHeader()->e_type == ELF::ET_REL){ + if (error(RelI->getOffset(Offset))) return; + } else { + if (error(RelI->getAddress(Offset))) return; + } if (error(RelI->getType(RelocType))) return; if (error(RelI->getTypeName(RelocName))) return; if (error(RelI->getAdditionalInfo(Info))) return; diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index 7a4b4e4431..2e95b6b551 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -143,8 +143,8 @@ bool error(error_code EC) { bool relocAddressLess(RelocationRef a, RelocationRef b) { uint64_t a_addr, b_addr; - if (error(a.getAddress(a_addr))) return false; - if (error(b.getAddress(b_addr))) return false; + if (error(a.getOffset(a_addr))) return false; + if (error(b.getOffset(b_addr))) return false; return a_addr < b_addr; } -- cgit v1.2.3-18-g5258 From 2173e1839c2d00f7f980450dd537047b7b376e6b Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 26 Apr 2013 20:07:33 +0000 Subject: Use llvm/Object/MachO.h in macho-dumper. Drop the old macho parser. For Mach-O there were 2 implementations for parsing object files. A standalone llvm/Object/MachOObject.h and llvm/Object/MachO.h which implements the generic interface in llvm/Object/ObjectFile.h. This patch adds the missing features to MachO.h, moves macho-dump to use MachO.h and removes ObjectFile.h. In addition to making sure that check-all is clean, I checked that the new version produces exactly the same output in all Mach-O files in a llvm+clang build directory (including executables and shared libraries). To test the performance, I ran macho-dump over all the files in a llvm+clang build directory again, but this time redirecting the output to /dev/null. Both the old and new versions take about 4.6 seconds (2.5 user) to finish. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180624 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-rtdyld/llvm-rtdyld.cpp | 2 +- tools/macho-dump/macho-dump.cpp | 424 +++++++++++++++++--------------------- 2 files changed, 192 insertions(+), 234 deletions(-) (limited to 'tools') diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp index 4d8d345894..ead541a5b8 100644 --- a/tools/llvm-rtdyld/llvm-rtdyld.cpp +++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -17,7 +17,7 @@ #include "llvm/ExecutionEngine/ObjectBuffer.h" #include "llvm/ExecutionEngine/ObjectImage.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" -#include "llvm/Object/MachOObject.h" +#include "llvm/Object/MachO.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Memory.h" diff --git a/tools/macho-dump/macho-dump.cpp b/tools/macho-dump/macho-dump.cpp index 3bd3ecc8fd..88fd4529ab 100644 --- a/tools/macho-dump/macho-dump.cpp +++ b/tools/macho-dump/macho-dump.cpp @@ -11,9 +11,10 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Object/MachOObject.h" +#include "llvm/Object/MachO.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/Twine.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Format.h" #include "llvm/Support/ManagedStatic.h" @@ -66,7 +67,8 @@ static void DumpSegmentCommandData(StringRef Name, outs() << " ('flags', " << Flags << ")\n"; } -static int DumpSectionData(MachOObject &Obj, unsigned Index, StringRef Name, +static int DumpSectionData(const MachOObjectFile &Obj, unsigned Index, + StringRef Name, StringRef SegmentName, uint64_t Address, uint64_t Size, uint32_t Offset, uint32_t Align, uint32_t RelocationTableOffset, @@ -92,26 +94,22 @@ static int DumpSectionData(MachOObject &Obj, unsigned Index, StringRef Name, outs() << " ),\n"; // Dump the relocation entries. - int Res = 0; outs() << " ('_relocations', [\n"; - for (unsigned i = 0; i != NumRelocationTableEntries; ++i) { - InMemoryStruct RE; - Obj.ReadRelocationEntry(RelocationTableOffset, i, RE); - if (!RE) { - Res = Error("unable to read relocation table entry '" + Twine(i) + "'"); - break; - } - - outs() << " # Relocation " << i << "\n"; - outs() << " (('word-0', " << format("0x%x", RE->Word0) << "),\n"; - outs() << " ('word-1', " << format("0x%x", RE->Word1) << ")),\n"; + unsigned RelNum = 0; + error_code EC; + for (relocation_iterator I = Obj.getSectionRelBegin(Index), + E = Obj.getSectionRelEnd(Index); I != E; I.increment(EC), ++RelNum) { + macho::RelocationEntry RE = Obj.getRelocation(I->getRawDataRefImpl()); + outs() << " # Relocation " << RelNum << "\n"; + outs() << " (('word-0', " << format("0x%x", RE.Word0) << "),\n"; + outs() << " ('word-1', " << format("0x%x", RE.Word1) << ")),\n"; } outs() << " ])\n"; // Dump the section data, if requested. if (ShowSectionData) { outs() << " ('_section_data', '"; - StringRef Data = Obj.getData(Offset, Size); + StringRef Data = Obj.getData().substr(Offset, Size); for (unsigned i = 0; i != Data.size(); ++i) { if (i && (i % 4) == 0) outs() << ' '; @@ -121,208 +119,162 @@ static int DumpSectionData(MachOObject &Obj, unsigned Index, StringRef Name, outs() << "')\n"; } - return Res; + return 0; } -static int DumpSegmentCommand(MachOObject &Obj, - const MachOObject::LoadCommandInfo &LCI) { - InMemoryStruct SLC; - Obj.ReadSegmentLoadCommand(LCI, SLC); - if (!SLC) - return Error("unable to read segment load command"); +static int DumpSegmentCommand(const MachOObjectFile &Obj, + const MachOObjectFile::LoadCommandInfo &LCI) { + macho::SegmentLoadCommand SLC = Obj.getSegmentLoadCommand(LCI); - DumpSegmentCommandData(StringRef(SLC->Name, 16), SLC->VMAddress, - SLC->VMSize, SLC->FileOffset, SLC->FileSize, - SLC->MaxVMProtection, SLC->InitialVMProtection, - SLC->NumSections, SLC->Flags); + DumpSegmentCommandData(StringRef(SLC.Name, 16), SLC.VMAddress, + SLC.VMSize, SLC.FileOffset, SLC.FileSize, + SLC.MaxVMProtection, SLC.InitialVMProtection, + SLC.NumSections, SLC.Flags); // Dump the sections. - int Res = 0; outs() << " ('sections', [\n"; - for (unsigned i = 0; i != SLC->NumSections; ++i) { - InMemoryStruct Sect; - Obj.ReadSection(LCI, i, Sect); - if (!SLC) { - Res = Error("unable to read section '" + Twine(i) + "'"); - break; - } - - if ((Res = DumpSectionData(Obj, i, StringRef(Sect->Name, 16), - StringRef(Sect->SegmentName, 16), Sect->Address, - Sect->Size, Sect->Offset, Sect->Align, - Sect->RelocationTableOffset, - Sect->NumRelocationTableEntries, Sect->Flags, - Sect->Reserved1, Sect->Reserved2))) - break; + for (unsigned i = 0; i != SLC.NumSections; ++i) { + macho::Section Sect = Obj.getSection(LCI, i); + DumpSectionData(Obj, i, StringRef(Sect.Name, 16), + StringRef(Sect.SegmentName, 16), Sect.Address, + Sect.Size, Sect.Offset, Sect.Align, + Sect.RelocationTableOffset, + Sect.NumRelocationTableEntries, Sect.Flags, + Sect.Reserved1, Sect.Reserved2); } outs() << " ])\n"; - return Res; + return 0; } -static int DumpSegment64Command(MachOObject &Obj, - const MachOObject::LoadCommandInfo &LCI) { - InMemoryStruct SLC; - Obj.ReadSegment64LoadCommand(LCI, SLC); - if (!SLC) - return Error("unable to read segment load command"); - - DumpSegmentCommandData(StringRef(SLC->Name, 16), SLC->VMAddress, - SLC->VMSize, SLC->FileOffset, SLC->FileSize, - SLC->MaxVMProtection, SLC->InitialVMProtection, - SLC->NumSections, SLC->Flags); +static int DumpSegment64Command(const MachOObjectFile &Obj, + const MachOObjectFile::LoadCommandInfo &LCI) { + macho::Segment64LoadCommand SLC = Obj.getSegment64LoadCommand(LCI); + DumpSegmentCommandData(StringRef(SLC.Name, 16), SLC.VMAddress, + SLC.VMSize, SLC.FileOffset, SLC.FileSize, + SLC.MaxVMProtection, SLC.InitialVMProtection, + SLC.NumSections, SLC.Flags); // Dump the sections. - int Res = 0; outs() << " ('sections', [\n"; - for (unsigned i = 0; i != SLC->NumSections; ++i) { - InMemoryStruct Sect; - Obj.ReadSection64(LCI, i, Sect); - if (!SLC) { - Res = Error("unable to read section '" + Twine(i) + "'"); - break; - } - - if ((Res = DumpSectionData(Obj, i, StringRef(Sect->Name, 16), - StringRef(Sect->SegmentName, 16), Sect->Address, - Sect->Size, Sect->Offset, Sect->Align, - Sect->RelocationTableOffset, - Sect->NumRelocationTableEntries, Sect->Flags, - Sect->Reserved1, Sect->Reserved2, - Sect->Reserved3))) - break; + for (unsigned i = 0; i != SLC.NumSections; ++i) { + macho::Section64 Sect = Obj.getSection64(LCI, i); + + DumpSectionData(Obj, i, StringRef(Sect.Name, 16), + StringRef(Sect.SegmentName, 16), Sect.Address, + Sect.Size, Sect.Offset, Sect.Align, + Sect.RelocationTableOffset, + Sect.NumRelocationTableEntries, Sect.Flags, + Sect.Reserved1, Sect.Reserved2, + Sect.Reserved3); } outs() << " ])\n"; - return Res; + return 0; } -static void DumpSymbolTableEntryData(MachOObject &Obj, +static void DumpSymbolTableEntryData(const MachOObjectFile &Obj, unsigned Index, uint32_t StringIndex, uint8_t Type, uint8_t SectionIndex, - uint16_t Flags, uint64_t Value) { + uint16_t Flags, uint64_t Value, + StringRef StringTable) { + const char *Name = &StringTable.data()[StringIndex]; outs() << " # Symbol " << Index << "\n"; outs() << " (('n_strx', " << StringIndex << ")\n"; outs() << " ('n_type', " << format("0x%x", Type) << ")\n"; outs() << " ('n_sect', " << uint32_t(SectionIndex) << ")\n"; outs() << " ('n_desc', " << Flags << ")\n"; outs() << " ('n_value', " << Value << ")\n"; - outs() << " ('_string', '" << Obj.getStringAtIndex(StringIndex) << "')\n"; + outs() << " ('_string', '" << Name << "')\n"; outs() << " ),\n"; } -static int DumpSymtabCommand(MachOObject &Obj, - const MachOObject::LoadCommandInfo &LCI) { - InMemoryStruct SLC; - Obj.ReadSymtabLoadCommand(LCI, SLC); - if (!SLC) - return Error("unable to read segment load command"); - - outs() << " ('symoff', " << SLC->SymbolTableOffset << ")\n"; - outs() << " ('nsyms', " << SLC->NumSymbolTableEntries << ")\n"; - outs() << " ('stroff', " << SLC->StringTableOffset << ")\n"; - outs() << " ('strsize', " << SLC->StringTableSize << ")\n"; +static int DumpSymtabCommand(const MachOObjectFile &Obj) { + macho::SymtabLoadCommand SLC = Obj.getSymtabLoadCommand(); - // Cache the string table data. - Obj.RegisterStringTable(*SLC); + outs() << " ('symoff', " << SLC.SymbolTableOffset << ")\n"; + outs() << " ('nsyms', " << SLC.NumSymbolTableEntries << ")\n"; + outs() << " ('stroff', " << SLC.StringTableOffset << ")\n"; + outs() << " ('strsize', " << SLC.StringTableSize << ")\n"; // Dump the string data. outs() << " ('_string_data', '"; - outs().write_escaped(Obj.getStringTableData(), + StringRef StringTable = Obj.getStringTableData(); + outs().write_escaped(StringTable, /*UseHexEscapes=*/true) << "')\n"; // Dump the symbol table. - int Res = 0; outs() << " ('_symbols', [\n"; - for (unsigned i = 0; i != SLC->NumSymbolTableEntries; ++i) { + error_code EC; + unsigned SymNum = 0; + for (symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols(); I != E; + I.increment(EC), ++SymNum) { + DataRefImpl DRI = I->getRawDataRefImpl(); if (Obj.is64Bit()) { - InMemoryStruct STE; - Obj.ReadSymbol64TableEntry(SLC->SymbolTableOffset, i, STE); - if (!STE) { - Res = Error("unable to read symbol: '" + Twine(i) + "'"); - break; - } - - DumpSymbolTableEntryData(Obj, i, STE->StringIndex, STE->Type, - STE->SectionIndex, STE->Flags, STE->Value); + macho::Symbol64TableEntry STE = Obj.getSymbol64TableEntry(DRI); + DumpSymbolTableEntryData(Obj, SymNum, STE.StringIndex, STE.Type, + STE.SectionIndex, STE.Flags, STE.Value, + StringTable); } else { - InMemoryStruct STE; - Obj.ReadSymbolTableEntry(SLC->SymbolTableOffset, i, STE); - if (!SLC) { - Res = Error("unable to read symbol: '" + Twine(i) + "'"); - break; - } - - DumpSymbolTableEntryData(Obj, i, STE->StringIndex, STE->Type, - STE->SectionIndex, STE->Flags, STE->Value); + macho::SymbolTableEntry STE = Obj.getSymbolTableEntry(DRI); + DumpSymbolTableEntryData(Obj, SymNum, STE.StringIndex, STE.Type, + STE.SectionIndex, STE.Flags, STE.Value, + StringTable); } } outs() << " ])\n"; - return Res; + return 0; } -static int DumpDysymtabCommand(MachOObject &Obj, - const MachOObject::LoadCommandInfo &LCI) { - InMemoryStruct DLC; - Obj.ReadDysymtabLoadCommand(LCI, DLC); - if (!DLC) - return Error("unable to read segment load command"); - - outs() << " ('ilocalsym', " << DLC->LocalSymbolsIndex << ")\n"; - outs() << " ('nlocalsym', " << DLC->NumLocalSymbols << ")\n"; - outs() << " ('iextdefsym', " << DLC->ExternalSymbolsIndex << ")\n"; - outs() << " ('nextdefsym', " << DLC->NumExternalSymbols << ")\n"; - outs() << " ('iundefsym', " << DLC->UndefinedSymbolsIndex << ")\n"; - outs() << " ('nundefsym', " << DLC->NumUndefinedSymbols << ")\n"; - outs() << " ('tocoff', " << DLC->TOCOffset << ")\n"; - outs() << " ('ntoc', " << DLC->NumTOCEntries << ")\n"; - outs() << " ('modtaboff', " << DLC->ModuleTableOffset << ")\n"; - outs() << " ('nmodtab', " << DLC->NumModuleTableEntries << ")\n"; - outs() << " ('extrefsymoff', " << DLC->ReferenceSymbolTableOffset << ")\n"; +static int DumpDysymtabCommand(const MachOObjectFile &Obj) { + macho::DysymtabLoadCommand DLC = Obj.getDysymtabLoadCommand(); + + outs() << " ('ilocalsym', " << DLC.LocalSymbolsIndex << ")\n"; + outs() << " ('nlocalsym', " << DLC.NumLocalSymbols << ")\n"; + outs() << " ('iextdefsym', " << DLC.ExternalSymbolsIndex << ")\n"; + outs() << " ('nextdefsym', " << DLC.NumExternalSymbols << ")\n"; + outs() << " ('iundefsym', " << DLC.UndefinedSymbolsIndex << ")\n"; + outs() << " ('nundefsym', " << DLC.NumUndefinedSymbols << ")\n"; + outs() << " ('tocoff', " << DLC.TOCOffset << ")\n"; + outs() << " ('ntoc', " << DLC.NumTOCEntries << ")\n"; + outs() << " ('modtaboff', " << DLC.ModuleTableOffset << ")\n"; + outs() << " ('nmodtab', " << DLC.NumModuleTableEntries << ")\n"; + outs() << " ('extrefsymoff', " << DLC.ReferenceSymbolTableOffset << ")\n"; outs() << " ('nextrefsyms', " - << DLC->NumReferencedSymbolTableEntries << ")\n"; - outs() << " ('indirectsymoff', " << DLC->IndirectSymbolTableOffset << ")\n"; + << DLC.NumReferencedSymbolTableEntries << ")\n"; + outs() << " ('indirectsymoff', " << DLC.IndirectSymbolTableOffset << ")\n"; outs() << " ('nindirectsyms', " - << DLC->NumIndirectSymbolTableEntries << ")\n"; - outs() << " ('extreloff', " << DLC->ExternalRelocationTableOffset << ")\n"; - outs() << " ('nextrel', " << DLC->NumExternalRelocationTableEntries << ")\n"; - outs() << " ('locreloff', " << DLC->LocalRelocationTableOffset << ")\n"; - outs() << " ('nlocrel', " << DLC->NumLocalRelocationTableEntries << ")\n"; + << DLC.NumIndirectSymbolTableEntries << ")\n"; + outs() << " ('extreloff', " << DLC.ExternalRelocationTableOffset << ")\n"; + outs() << " ('nextrel', " << DLC.NumExternalRelocationTableEntries << ")\n"; + outs() << " ('locreloff', " << DLC.LocalRelocationTableOffset << ")\n"; + outs() << " ('nlocrel', " << DLC.NumLocalRelocationTableEntries << ")\n"; // Dump the indirect symbol table. - int Res = 0; outs() << " ('_indirect_symbols', [\n"; - for (unsigned i = 0; i != DLC->NumIndirectSymbolTableEntries; ++i) { - InMemoryStruct ISTE; - Obj.ReadIndirectSymbolTableEntry(*DLC, i, ISTE); - if (!ISTE) { - Res = Error("unable to read segment load command"); - break; - } - + for (unsigned i = 0; i != DLC.NumIndirectSymbolTableEntries; ++i) { + macho::IndirectSymbolTableEntry ISTE = + Obj.getIndirectSymbolTableEntry(DLC, i); outs() << " # Indirect Symbol " << i << "\n"; outs() << " (('symbol_index', " - << format("0x%x", ISTE->Index) << "),),\n"; + << format("0x%x", ISTE.Index) << "),),\n"; } outs() << " ])\n"; - return Res; + return 0; } -static int DumpLinkeditDataCommand(MachOObject &Obj, - const MachOObject::LoadCommandInfo &LCI) { - InMemoryStruct LLC; - Obj.ReadLinkeditDataLoadCommand(LCI, LLC); - if (!LLC) - return Error("unable to read segment load command"); - - outs() << " ('dataoff', " << LLC->DataOffset << ")\n" - << " ('datasize', " << LLC->DataSize << ")\n" +static int +DumpLinkeditDataCommand(const MachOObjectFile &Obj, + const MachOObjectFile::LoadCommandInfo &LCI) { + macho::LinkeditDataLoadCommand LLC = Obj.getLinkeditDataLoadCommand(LCI); + outs() << " ('dataoff', " << LLC.DataOffset << ")\n" + << " ('datasize', " << LLC.DataSize << ")\n" << " ('_addresses', [\n"; SmallVector Addresses; - Obj.ReadULEB128s(LLC->DataOffset, Addresses); + Obj.ReadULEB128s(LLC.DataOffset, Addresses); for (unsigned i = 0, e = Addresses.size(); i != e; ++i) outs() << " # Address " << i << '\n' << " ('address', " << format("0x%x", Addresses[i]) << "),\n"; @@ -332,28 +284,22 @@ static int DumpLinkeditDataCommand(MachOObject &Obj, return 0; } -static int DumpDataInCodeDataCommand(MachOObject &Obj, - const MachOObject::LoadCommandInfo &LCI) { - InMemoryStruct LLC; - Obj.ReadLinkeditDataLoadCommand(LCI, LLC); - if (!LLC) - return Error("unable to read data-in-code load command"); - - outs() << " ('dataoff', " << LLC->DataOffset << ")\n" - << " ('datasize', " << LLC->DataSize << ")\n" +static int +DumpDataInCodeDataCommand(const MachOObjectFile &Obj, + const MachOObjectFile::LoadCommandInfo &LCI) { + macho::LinkeditDataLoadCommand LLC = Obj.getLinkeditDataLoadCommand(LCI); + outs() << " ('dataoff', " << LLC.DataOffset << ")\n" + << " ('datasize', " << LLC.DataSize << ")\n" << " ('_data_regions', [\n"; - - unsigned NumRegions = LLC->DataSize / 8; + unsigned NumRegions = LLC.DataSize / 8; for (unsigned i = 0; i < NumRegions; ++i) { - InMemoryStruct DICE; - Obj.ReadDataInCodeTableEntry(LLC->DataOffset, i, DICE); - if (!DICE) - return Error("unable to read DataInCodeTableEntry"); + macho::DataInCodeTableEntry DICE = + Obj.getDataInCodeTableEntry(LLC.DataOffset, i); outs() << " # DICE " << i << "\n" - << " ('offset', " << DICE->Offset << ")\n" - << " ('length', " << DICE->Length << ")\n" - << " ('kind', " << DICE->Kind << ")\n"; + << " ('offset', " << DICE.Offset << ")\n" + << " ('length', " << DICE.Length << ")\n" + << " ('kind', " << DICE.Kind << ")\n"; } outs() <<" ])\n"; @@ -361,99 +307,111 @@ static int DumpDataInCodeDataCommand(MachOObject &Obj, return 0; } -static int DumpLinkerOptionsCommand(MachOObject &Obj, - const MachOObject::LoadCommandInfo &LCI) { - InMemoryStruct LOLC; - Obj.ReadLinkerOptionsLoadCommand(LCI, LOLC); - if (!LOLC) - return Error("unable to read linker options load command"); - - outs() << " ('count', " << LOLC->Count << ")\n" - << " ('_strings', [\n"; - - uint64_t DataSize = LOLC->Size - sizeof(macho::LinkerOptionsLoadCommand); - StringRef Data = Obj.getData( - LCI.Offset + sizeof(macho::LinkerOptionsLoadCommand), DataSize); - for (unsigned i = 0; i != LOLC->Count; ++i) { - std::pair Split = Data.split('\0'); - outs() << "\t\""; - outs().write_escaped(Split.first); - outs() << "\",\n"; - Data = Split.second; - } - outs() <<" ])\n"; +static int +DumpLinkerOptionsCommand(const MachOObjectFile &Obj, + const MachOObjectFile::LoadCommandInfo &LCI) { + macho::LinkerOptionsLoadCommand LOLC = Obj.getLinkerOptionsLoadCommand(LCI); + outs() << " ('count', " << LOLC.Count << ")\n" + << " ('_strings', [\n"; + + uint64_t DataSize = LOLC.Size - sizeof(macho::LinkerOptionsLoadCommand); + const char *P = LCI.Ptr + sizeof(macho::LinkerOptionsLoadCommand); + StringRef Data(P, DataSize); + for (unsigned i = 0; i != LOLC.Count; ++i) { + std::pair Split = Data.split('\0'); + outs() << "\t\""; + outs().write_escaped(Split.first); + outs() << "\",\n"; + Data = Split.second; + } + outs() <<" ])\n"; return 0; } - -static int DumpLoadCommand(MachOObject &Obj, unsigned Index) { - const MachOObject::LoadCommandInfo &LCI = Obj.getLoadCommandInfo(Index); - int Res = 0; - - outs() << " # Load Command " << Index << "\n" - << " (('command', " << LCI.Command.Type << ")\n" - << " ('size', " << LCI.Command.Size << ")\n"; - switch (LCI.Command.Type) { +static int DumpLoadCommand(const MachOObjectFile &Obj, + MachOObjectFile::LoadCommandInfo &LCI) { + switch (LCI.C.Type) { case macho::LCT_Segment: - Res = DumpSegmentCommand(Obj, LCI); - break; + return DumpSegmentCommand(Obj, LCI); case macho::LCT_Segment64: - Res = DumpSegment64Command(Obj, LCI); - break; + return DumpSegment64Command(Obj, LCI); case macho::LCT_Symtab: - Res = DumpSymtabCommand(Obj, LCI); - break; + return DumpSymtabCommand(Obj); case macho::LCT_Dysymtab: - Res = DumpDysymtabCommand(Obj, LCI); - break; + return DumpDysymtabCommand(Obj); case macho::LCT_CodeSignature: case macho::LCT_SegmentSplitInfo: case macho::LCT_FunctionStarts: - Res = DumpLinkeditDataCommand(Obj, LCI); - break; + return DumpLinkeditDataCommand(Obj, LCI); case macho::LCT_DataInCode: - Res = DumpDataInCodeDataCommand(Obj, LCI); - break; + return DumpDataInCodeDataCommand(Obj, LCI); case macho::LCT_LinkerOptions: - Res = DumpLinkerOptionsCommand(Obj, LCI); - break; + return DumpLinkerOptionsCommand(Obj, LCI); default: - Warning("unknown load command: " + Twine(LCI.Command.Type)); - break; + Warning("unknown load command: " + Twine(LCI.C.Type)); + return 0; } - outs() << " ),\n"; +} + +static int DumpLoadCommand(const MachOObjectFile &Obj, unsigned Index, + MachOObjectFile::LoadCommandInfo &LCI) { + outs() << " # Load Command " << Index << "\n" + << " (('command', " << LCI.C.Type << ")\n" + << " ('size', " << LCI.C.Size << ")\n"; + int Res = DumpLoadCommand(Obj, LCI); + outs() << " ),\n"; return Res; } +static void printHeader(const MachOObjectFile *Obj, + const macho::Header &Header) { + outs() << "('cputype', " << Header.CPUType << ")\n"; + outs() << "('cpusubtype', " << Header.CPUSubtype << ")\n"; + outs() << "('filetype', " << Header.FileType << ")\n"; + outs() << "('num_load_commands', " << Header.NumLoadCommands << ")\n"; + outs() << "('load_commands_size', " << Header.SizeOfLoadCommands << ")\n"; + outs() << "('flag', " << Header.Flags << ")\n"; + + // Print extended header if 64-bit. + if (Obj->is64Bit()) { + macho::Header64Ext Header64Ext = Obj->getHeader64Ext(); + outs() << "('reserved', " << Header64Ext.Reserved << ")\n"; + } +} + int main(int argc, char **argv) { ProgramName = argv[0]; llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. cl::ParseCommandLineOptions(argc, argv, "llvm Mach-O dumping tool\n"); - // Load the input file. - std::string ErrorStr; - OwningPtr InputBuffer; - if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFile, InputBuffer)) - return Error("unable to read input: '" + ec.message() + "'"); + OwningPtr Binary; + if (error_code EC = createBinary(InputFile, Binary)) + return Error("unable to read input: '" + EC.message() + "'"); - // Construct the Mach-O wrapper object. - OwningPtr InputObject( - MachOObject::LoadFromBuffer(InputBuffer.take(), &ErrorStr)); + const MachOObjectFile *InputObject = dyn_cast(Binary.get()); if (!InputObject) - return Error("unable to load object: '" + ErrorStr + "'"); + return Error("Not a MachO object"); // Print the header - InputObject->printHeader(outs()); + macho::Header Header = InputObject->getHeader(); + printHeader(InputObject, Header); // Print the load commands. int Res = 0; + MachOObjectFile::LoadCommandInfo Command = + InputObject->getFirstLoadCommandInfo(); outs() << "('load_commands', [\n"; - for (unsigned i = 0; i != InputObject->getHeader().NumLoadCommands; ++i) - if ((Res = DumpLoadCommand(*InputObject, i))) + for (unsigned i = 0; ; ++i) { + if (DumpLoadCommand(*InputObject, i, Command)) break; + + if (i == Header.NumLoadCommands - 1) + break; + Command = InputObject->getNextLoadCommandInfo(Command); + } outs() << "])\n"; return Res; -- cgit v1.2.3-18-g5258 From 2900535e65683a74c01659c9776f78a8070798b5 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Thu, 2 May 2013 21:09:03 +0000 Subject: We don't want FP elimination when doing an Apple-style build. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180949 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lto/Makefile b/tools/lto/Makefile index ab2e16e5fa..590b90cdb4 100644 --- a/tools/lto/Makefile +++ b/tools/lto/Makefile @@ -54,6 +54,6 @@ ifeq ($(HOST_OS),Darwin) ifeq ($(RC_XBS),YES) TempFile := $(shell mkdir -p ${OBJROOT}/dSYMs ; mktemp ${OBJROOT}/dSYMs/llvm-lto.XXXXXX) LLVMLibsOptions := $(LLVMLibsOptions) \ - -Wl,-object_path_lto -Wl,$(TempFile) + -Wl,-object_path_lto -Wl,$(TempFile) -Wl,-mllvm,-disable-fp-elim endif endif -- cgit v1.2.3-18-g5258 From 53f1b19c6e0b0b2fe2dfccd543738a20241c8e78 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Thu, 2 May 2013 22:52:47 +0000 Subject: Remove redundant flag. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@180967 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lto/Makefile b/tools/lto/Makefile index 590b90cdb4..ab2e16e5fa 100644 --- a/tools/lto/Makefile +++ b/tools/lto/Makefile @@ -54,6 +54,6 @@ ifeq ($(HOST_OS),Darwin) ifeq ($(RC_XBS),YES) TempFile := $(shell mkdir -p ${OBJROOT}/dSYMs ; mktemp ${OBJROOT}/dSYMs/llvm-lto.XXXXXX) LLVMLibsOptions := $(LLVMLibsOptions) \ - -Wl,-object_path_lto -Wl,$(TempFile) -Wl,-mllvm,-disable-fp-elim + -Wl,-object_path_lto -Wl,$(TempFile) endif endif -- cgit v1.2.3-18-g5258 From 5d446e61d992f105a05aade62d5305fd8a346081 Mon Sep 17 00:00:00 2001 From: Amara Emerson Date: Fri, 3 May 2013 11:36:35 +0000 Subject: Add support for reading ARM ELF build attributes. Build attribute sections can now be read if they exist via ELFObjectFile, and the llvm-readobj tool has been extended with an option to dump this information if requested. Regression tests are also included which exercise these features. Also update the docs with a fixed ARM ABI link and a new link to the Addenda which provides the build attributes specification. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181009 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/ELFDumper.cpp | 63 +++++++++++++++++++++++++++++++++++++ tools/llvm-readobj/ObjDumper.h | 1 + tools/llvm-readobj/llvm-readobj.cpp | 6 ++++ 3 files changed, 70 insertions(+) (limited to 'tools') diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index ea1b83f32f..6fa9026399 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -51,6 +51,7 @@ public: virtual void printDynamicTable() LLVM_OVERRIDE; virtual void printNeededLibraries() LLVM_OVERRIDE; virtual void printProgramHeaders() LLVM_OVERRIDE; + virtual void printARMBuildAttributes() LLVM_OVERRIDE; private: typedef ELFObjectFile ELFO; @@ -858,3 +859,65 @@ void ELFDumper::printProgramHeaders() { W.printNumber("Alignment", PI->p_align); } } + +#define LLVM_READOBJ_ARMATTR_NUMCASE(X) case ARMBuildAttrs::X: \ + W.printNumber(" Tag_" #X, BuildAttrs.Tag_##X); \ + break; \ + +#define LLVM_READOBJ_ARMATTR_STRCASE(X) case ARMBuildAttrs::X: \ + W.printString(" Tag_" #X, BuildAttrs.Tag_##X); \ + break; \ + +template +void ELFDumper::printARMBuildAttributes() { + if (Obj->getArch() != Triple::arm || !Obj->hasARMBuildAttributes()) + return; + ARMBuildAttrs::ARMGenericBuildAttrInfo BuildAttrs; + SmallVector AttrsRead; + error_code EC = Obj->readARMBuildAttributes(BuildAttrs, AttrsRead); + if (error(EC)) + return; + + DictScope D(W, "ARMBuildAttributes"); + + for (SmallVector::iterator I = AttrsRead.begin(), + E = AttrsRead.end(); I != E; ++I) { + switch (*I) { + LLVM_READOBJ_ARMATTR_STRCASE(CPU_name) + LLVM_READOBJ_ARMATTR_STRCASE(CPU_raw_name) + LLVM_READOBJ_ARMATTR_NUMCASE(CPU_arch) + LLVM_READOBJ_ARMATTR_NUMCASE(CPU_arch_profile) + LLVM_READOBJ_ARMATTR_NUMCASE(ARM_ISA_use) + LLVM_READOBJ_ARMATTR_NUMCASE(THUMB_ISA_use) + LLVM_READOBJ_ARMATTR_NUMCASE(FP_arch) + LLVM_READOBJ_ARMATTR_NUMCASE(WMMX_arch) + LLVM_READOBJ_ARMATTR_NUMCASE(Advanced_SIMD_arch) + LLVM_READOBJ_ARMATTR_NUMCASE(PCS_config) + LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_R9_use) + LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_RW_data) + LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_RO_data) + LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_GOT_use) + LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_wchar_t) + LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_rounding) + LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_denormal) + LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_exceptions) + LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_user_exceptions) + LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_number_model) + LLVM_READOBJ_ARMATTR_NUMCASE(ABI_align8_needed) + LLVM_READOBJ_ARMATTR_NUMCASE(ABI_align8_preserved) + LLVM_READOBJ_ARMATTR_NUMCASE(ABI_enum_size) + LLVM_READOBJ_ARMATTR_NUMCASE(ABI_HardFP_use) + LLVM_READOBJ_ARMATTR_NUMCASE(ABI_VFP_args) + LLVM_READOBJ_ARMATTR_NUMCASE(CPU_unaligned_access) + LLVM_READOBJ_ARMATTR_NUMCASE(FP_HP_extension) + LLVM_READOBJ_ARMATTR_NUMCASE(MPextension_use) + LLVM_READOBJ_ARMATTR_NUMCASE(DIV_use) + LLVM_READOBJ_ARMATTR_NUMCASE(T2EE_use) + LLVM_READOBJ_ARMATTR_NUMCASE(Virtualization_use) + LLVM_READOBJ_ARMATTR_NUMCASE(ABI_optimization_goals) + LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_optimization_goals) + default: + break; + } + } +} diff --git a/tools/llvm-readobj/ObjDumper.h b/tools/llvm-readobj/ObjDumper.h index 6918e28cb9..9a8f0c157a 100644 --- a/tools/llvm-readobj/ObjDumper.h +++ b/tools/llvm-readobj/ObjDumper.h @@ -39,6 +39,7 @@ public: virtual void printDynamicTable() { } virtual void printNeededLibraries() { } virtual void printProgramHeaders() { } + virtual void printARMBuildAttributes() { } protected: StreamWriter& W; diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index 2e95b6b551..d5eb85429c 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -128,6 +128,10 @@ namespace opts { // -expand-relocs cl::opt ExpandRelocs("expand-relocs", cl::desc("Expand each shown relocation to multiple lines")); + + // -arm-buildattrs + cl::opt ArmBuildAttrs("arm-buildattrs", + cl::desc("Display ARM ELF build attributes")); } // namespace opts namespace llvm { @@ -221,6 +225,8 @@ static void dumpObject(const ObjectFile *Obj) { Dumper->printNeededLibraries(); if (opts::ProgramHeaders) Dumper->printProgramHeaders(); + if (opts::ArmBuildAttrs) + Dumper->printARMBuildAttributes(); } -- cgit v1.2.3-18-g5258 From 1aef163a6815e7bff675f83ddec8b063d6082e86 Mon Sep 17 00:00:00 2001 From: Amara Emerson Date: Fri, 3 May 2013 23:57:17 +0000 Subject: Revert r181009. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181079 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/ELFDumper.cpp | 63 ------------------------------------- tools/llvm-readobj/ObjDumper.h | 1 - tools/llvm-readobj/llvm-readobj.cpp | 6 ---- 3 files changed, 70 deletions(-) (limited to 'tools') diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index 6fa9026399..ea1b83f32f 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -51,7 +51,6 @@ public: virtual void printDynamicTable() LLVM_OVERRIDE; virtual void printNeededLibraries() LLVM_OVERRIDE; virtual void printProgramHeaders() LLVM_OVERRIDE; - virtual void printARMBuildAttributes() LLVM_OVERRIDE; private: typedef ELFObjectFile ELFO; @@ -859,65 +858,3 @@ void ELFDumper::printProgramHeaders() { W.printNumber("Alignment", PI->p_align); } } - -#define LLVM_READOBJ_ARMATTR_NUMCASE(X) case ARMBuildAttrs::X: \ - W.printNumber(" Tag_" #X, BuildAttrs.Tag_##X); \ - break; \ - -#define LLVM_READOBJ_ARMATTR_STRCASE(X) case ARMBuildAttrs::X: \ - W.printString(" Tag_" #X, BuildAttrs.Tag_##X); \ - break; \ - -template -void ELFDumper::printARMBuildAttributes() { - if (Obj->getArch() != Triple::arm || !Obj->hasARMBuildAttributes()) - return; - ARMBuildAttrs::ARMGenericBuildAttrInfo BuildAttrs; - SmallVector AttrsRead; - error_code EC = Obj->readARMBuildAttributes(BuildAttrs, AttrsRead); - if (error(EC)) - return; - - DictScope D(W, "ARMBuildAttributes"); - - for (SmallVector::iterator I = AttrsRead.begin(), - E = AttrsRead.end(); I != E; ++I) { - switch (*I) { - LLVM_READOBJ_ARMATTR_STRCASE(CPU_name) - LLVM_READOBJ_ARMATTR_STRCASE(CPU_raw_name) - LLVM_READOBJ_ARMATTR_NUMCASE(CPU_arch) - LLVM_READOBJ_ARMATTR_NUMCASE(CPU_arch_profile) - LLVM_READOBJ_ARMATTR_NUMCASE(ARM_ISA_use) - LLVM_READOBJ_ARMATTR_NUMCASE(THUMB_ISA_use) - LLVM_READOBJ_ARMATTR_NUMCASE(FP_arch) - LLVM_READOBJ_ARMATTR_NUMCASE(WMMX_arch) - LLVM_READOBJ_ARMATTR_NUMCASE(Advanced_SIMD_arch) - LLVM_READOBJ_ARMATTR_NUMCASE(PCS_config) - LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_R9_use) - LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_RW_data) - LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_RO_data) - LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_GOT_use) - LLVM_READOBJ_ARMATTR_NUMCASE(ABI_PCS_wchar_t) - LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_rounding) - LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_denormal) - LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_exceptions) - LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_user_exceptions) - LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_number_model) - LLVM_READOBJ_ARMATTR_NUMCASE(ABI_align8_needed) - LLVM_READOBJ_ARMATTR_NUMCASE(ABI_align8_preserved) - LLVM_READOBJ_ARMATTR_NUMCASE(ABI_enum_size) - LLVM_READOBJ_ARMATTR_NUMCASE(ABI_HardFP_use) - LLVM_READOBJ_ARMATTR_NUMCASE(ABI_VFP_args) - LLVM_READOBJ_ARMATTR_NUMCASE(CPU_unaligned_access) - LLVM_READOBJ_ARMATTR_NUMCASE(FP_HP_extension) - LLVM_READOBJ_ARMATTR_NUMCASE(MPextension_use) - LLVM_READOBJ_ARMATTR_NUMCASE(DIV_use) - LLVM_READOBJ_ARMATTR_NUMCASE(T2EE_use) - LLVM_READOBJ_ARMATTR_NUMCASE(Virtualization_use) - LLVM_READOBJ_ARMATTR_NUMCASE(ABI_optimization_goals) - LLVM_READOBJ_ARMATTR_NUMCASE(ABI_FP_optimization_goals) - default: - break; - } - } -} diff --git a/tools/llvm-readobj/ObjDumper.h b/tools/llvm-readobj/ObjDumper.h index 9a8f0c157a..6918e28cb9 100644 --- a/tools/llvm-readobj/ObjDumper.h +++ b/tools/llvm-readobj/ObjDumper.h @@ -39,7 +39,6 @@ public: virtual void printDynamicTable() { } virtual void printNeededLibraries() { } virtual void printProgramHeaders() { } - virtual void printARMBuildAttributes() { } protected: StreamWriter& W; diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index d5eb85429c..2e95b6b551 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -128,10 +128,6 @@ namespace opts { // -expand-relocs cl::opt ExpandRelocs("expand-relocs", cl::desc("Expand each shown relocation to multiple lines")); - - // -arm-buildattrs - cl::opt ArmBuildAttrs("arm-buildattrs", - cl::desc("Display ARM ELF build attributes")); } // namespace opts namespace llvm { @@ -225,8 +221,6 @@ static void dumpObject(const ObjectFile *Obj) { Dumper->printNeededLibraries(); if (opts::ProgramHeaders) Dumper->printProgramHeaders(); - if (opts::ArmBuildAttrs) - Dumper->printARMBuildAttributes(); } -- cgit v1.2.3-18-g5258 From b00b4bed57af9d6c8f2a4ee138ca471fd06b0750 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 4 May 2013 02:21:46 +0000 Subject: Add missing header. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181095 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/LTOCodeGenerator.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/lto/LTOCodeGenerator.h b/tools/lto/LTOCodeGenerator.h index 601dbfa044..a4ade9fd26 100644 --- a/tools/lto/LTOCodeGenerator.h +++ b/tools/lto/LTOCodeGenerator.h @@ -19,6 +19,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/Linker.h" #include +#include namespace llvm { class LLVMContext; -- cgit v1.2.3-18-g5258 From ae8f1f3fde1d9618bfcf8f629ffd68c26015f921 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 4 May 2013 02:28:57 +0000 Subject: Remove unused members and constructor arguments. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181096 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/LTOCodeGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index 5f5f76f35f..683a480d3f 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -69,7 +69,7 @@ const char* LTOCodeGenerator::getVersionString() { LTOCodeGenerator::LTOCodeGenerator() : _context(getGlobalContext()), - _linker("LinkTimeOptimizer", "ld-temp.o", _context), _target(NULL), + _linker("ld-temp.o", _context), _target(NULL), _emitDwarfDebugInfo(false), _scopeRestrictionsDone(false), _codeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC), _nativeObjectFile(NULL) { -- cgit v1.2.3-18-g5258 From 105193772d84057493968310c1d1c6dd0f1ae735 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 4 May 2013 02:43:00 +0000 Subject: Don't construct or delete a module on the Linker. The linker is now responsible only for actually linking the modules, it is up to the clients to create and destroy them. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181098 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/LTOCodeGenerator.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index 683a480d3f..de2c1fd4b8 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -69,7 +69,7 @@ const char* LTOCodeGenerator::getVersionString() { LTOCodeGenerator::LTOCodeGenerator() : _context(getGlobalContext()), - _linker("ld-temp.o", _context), _target(NULL), + _linker(new Module("ld-temp.o", _context)), _target(NULL), _emitDwarfDebugInfo(false), _scopeRestrictionsDone(false), _codeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC), _nativeObjectFile(NULL) { @@ -81,6 +81,7 @@ LTOCodeGenerator::LTOCodeGenerator() LTOCodeGenerator::~LTOCodeGenerator() { delete _target; delete _nativeObjectFile; + delete _linker.getModule(); for (std::vector::iterator I = _codegenOptions.begin(), E = _codegenOptions.end(); I != E; ++I) -- cgit v1.2.3-18-g5258 From fca88631650af3e862f7df012f34d9c724a9ed7c Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 4 May 2013 03:06:50 +0000 Subject: Last batch of cleanups to Linker.h. Update comments, fix * placement, fix method names that are not used in clang, add a linkInModule that takes a Mode and put it in Linker.cpp. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181099 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/LTOCodeGenerator.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index de2c1fd4b8..57e7a2d07f 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -89,7 +89,7 @@ LTOCodeGenerator::~LTOCodeGenerator() { } bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg) { - bool ret = _linker.LinkInModule(mod->getLLVVMModule(), &errMsg); + bool ret = _linker.linkInModule(mod->getLLVVMModule(), &errMsg); const std::vector &undefs = mod->getAsmUndefinedRefs(); for (int i = 0, e = undefs.size(); i != e; ++i) -- cgit v1.2.3-18-g5258 From c1685b3a5052de377735f69e53e50741dbe5b52a Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 4 May 2013 05:30:49 +0000 Subject: Optimize llvm-link too. This takes the linking of almost all modules in a clang build from 6:32 to 0:19. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181105 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-link/llvm-link.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp index 3a2d84a533..01a61c672c 100644 --- a/tools/llvm-link/llvm-link.cpp +++ b/tools/llvm-link/llvm-link.cpp @@ -93,6 +93,7 @@ int main(int argc, char **argv) { return 1; } + Linker L(Composite.get()); for (unsigned i = BaseArg+1; i < InputFilenames.size(); ++i) { OwningPtr M(LoadFile(argv[0], InputFilenames[i], Context)); if (M.get() == 0) { @@ -102,8 +103,7 @@ int main(int argc, char **argv) { if (Verbose) errs() << "Linking in '" << InputFilenames[i] << "'\n"; - if (Linker::LinkModules(Composite.get(), M.get(), Linker::DestroySource, - &ErrorMessage)) { + if (L.linkInModule(M.get(), &ErrorMessage)) { errs() << argv[0] << ": link error in '" << InputFilenames[i] << "': " << ErrorMessage << "\n"; return 1; -- cgit v1.2.3-18-g5258 From 730d718b73d73f5aefb9495f62699d3974e8a550 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 6 May 2013 18:19:24 +0000 Subject: Remove some redundant includes in llvm-mc.cpp. Patch by Jun Koi! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181231 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-mc/llvm-mc.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'tools') diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index 243899bb88..4b01c33504 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -16,7 +16,6 @@ #include "llvm/ADT/OwningPtr.h" #include "llvm/MC/MCAsmBackend.h" #include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCInstPrinter.h" #include "llvm/MC/MCInstrInfo.h" @@ -27,7 +26,6 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MC/MCTargetAsmParser.h" -#include "llvm/MC/SubtargetFeature.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileUtilities.h" #include "llvm/Support/FormattedStream.h" @@ -40,7 +38,6 @@ #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/ToolOutputFile.h" -#include "llvm/Support/system_error.h" using namespace llvm; static cl::opt -- cgit v1.2.3-18-g5258 From 7098ae2fee5d89a6e95ff391a9efa78c4a6c8703 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 6 May 2013 20:11:21 +0000 Subject: Split Alignment out of the Section Characteristics. The alignment is just a byte in the middle of Characteristics, not an independent flag. Making it an independent field in the yaml representation makes it more yamlio friendly. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@181243 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/yaml2obj/yaml2obj.cpp | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/yaml2obj/yaml2obj.cpp b/tools/yaml2obj/yaml2obj.cpp index 32dee54dc5..707b6b4d5c 100644 --- a/tools/yaml2obj/yaml2obj.cpp +++ b/tools/yaml2obj/yaml2obj.cpp @@ -42,6 +42,7 @@ static cl::opt namespace COFFYAML { struct Section { COFF::section Header; + unsigned Alignment; StringRef SectionData; std::vector Relocations; StringRef Name; @@ -102,6 +103,8 @@ struct COFFParser { Sec.Header.Name[0] = '/'; std::copy(str.begin(), str.end(), Sec.Header.Name + 1); } + + Sec.Header.Characteristics |= (Log2_32(Sec.Alignment) + 1) << 20; } return true; } @@ -358,20 +361,6 @@ struct ScalarBitSetTraits { BCase(IMAGE_SCN_MEM_16BIT); BCase(IMAGE_SCN_MEM_LOCKED); BCase(IMAGE_SCN_MEM_PRELOAD); - BCase(IMAGE_SCN_ALIGN_1BYTES); - BCase(IMAGE_SCN_ALIGN_2BYTES); - BCase(IMAGE_SCN_ALIGN_4BYTES); - BCase(IMAGE_SCN_ALIGN_8BYTES); - BCase(IMAGE_SCN_ALIGN_16BYTES); - BCase(IMAGE_SCN_ALIGN_32BYTES); - BCase(IMAGE_SCN_ALIGN_64BYTES); - BCase(IMAGE_SCN_ALIGN_128BYTES); - BCase(IMAGE_SCN_ALIGN_256BYTES); - BCase(IMAGE_SCN_ALIGN_512BYTES); - BCase(IMAGE_SCN_ALIGN_1024BYTES); - BCase(IMAGE_SCN_ALIGN_2048BYTES); - BCase(IMAGE_SCN_ALIGN_4096BYTES); - BCase(IMAGE_SCN_ALIGN_8192BYTES); BCase(IMAGE_SCN_LNK_NRELOC_OVFL); BCase(IMAGE_SCN_MEM_DISCARDABLE); BCase(IMAGE_SCN_MEM_NOT_CACHED); @@ -641,6 +630,7 @@ struct MappingTraits { IO.mapRequired("SectionData", Sec.SectionData); IO.mapRequired("Characteristics", NC->Characteristics); IO.mapRequired("Name", Sec.Name); + IO.mapOptional("Alignment", Sec.Alignment); } }; -- cgit v1.2.3-18-g5258