diff options
author | Alexander Kornienko <alexfh@google.com> | 2013-03-14 10:51:38 +0000 |
---|---|---|
committer | Alexander Kornienko <alexfh@google.com> | 2013-03-14 10:51:38 +0000 |
commit | 647735c781c5b37061ee03d6e9e6c7dda92218e2 (patch) | |
tree | 5a5e56606d41060263048b5a5586b3d2380898ba /tools | |
parent | 6aed25d93d1cfcde5809a73ffa7dc1b0d6396f66 (diff) | |
parent | f635ef401786c84df32090251a8cf45981ecca33 (diff) |
Updating branches/google/stable to r176857
git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/google/stable@177040 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools')
70 files changed, 1418 insertions, 876 deletions
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) diff --git a/tools/bugpoint-passes/CMakeLists.txt b/tools/bugpoint-passes/CMakeLists.txt index b2f1bb5d13..05f190a2a5 100644 --- a/tools/bugpoint-passes/CMakeLists.txt +++ b/tools/bugpoint-passes/CMakeLists.txt @@ -1,3 +1,7 @@ +if( NOT LLVM_BUILD_TOOLS ) + set(EXCLUDE_FROM_ALL ON) +endif() + add_llvm_loadable_module( BugpointPasses TestPasses.cpp ) diff --git a/tools/bugpoint-passes/TestPasses.cpp b/tools/bugpoint-passes/TestPasses.cpp index 835c397b51..118c98a459 100644 --- a/tools/bugpoint-passes/TestPasses.cpp +++ b/tools/bugpoint-passes/TestPasses.cpp @@ -12,12 +12,12 @@ // //===----------------------------------------------------------------------===// -#include "llvm/BasicBlock.h" -#include "llvm/Constant.h" +#include "llvm/IR/BasicBlock.h" +#include "llvm/IR/Constant.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Type.h" #include "llvm/InstVisitor.h" -#include "llvm/Instructions.h" #include "llvm/Pass.h" -#include "llvm/Type.h" using namespace llvm; diff --git a/tools/bugpoint/BugDriver.cpp b/tools/bugpoint/BugDriver.cpp index d396f7f5ad..cede4ac3ae 100644 --- a/tools/bugpoint/BugDriver.cpp +++ b/tools/bugpoint/BugDriver.cpp @@ -15,8 +15,8 @@ #include "BugDriver.h" #include "ToolRunner.h" +#include "llvm/IR/Module.h" #include "llvm/Linker.h" -#include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileUtilities.h" diff --git a/tools/bugpoint/CMakeLists.txt b/tools/bugpoint/CMakeLists.txt index ee2235bf42..3c5e64fdab 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) + linker bitreader bitwriter vectorize objcarcopts) add_llvm_tool(bugpoint BugDriver.cpp diff --git a/tools/bugpoint/CrashDebugger.cpp b/tools/bugpoint/CrashDebugger.cpp index 80e746c518..ed211a6008 100644 --- a/tools/bugpoint/CrashDebugger.cpp +++ b/tools/bugpoint/CrashDebugger.cpp @@ -16,10 +16,11 @@ #include "ToolRunner.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Analysis/Verifier.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/ValueSymbolTable.h" #include "llvm/Pass.h" #include "llvm/PassManager.h" #include "llvm/Support/CFG.h" @@ -27,7 +28,6 @@ #include "llvm/Support/FileUtilities.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils/Cloning.h" -#include "llvm/ValueSymbolTable.h" #include <set> using namespace llvm; diff --git a/tools/bugpoint/ExecutionDriver.cpp b/tools/bugpoint/ExecutionDriver.cpp index 218a559d21..da360453ec 100644 --- a/tools/bugpoint/ExecutionDriver.cpp +++ b/tools/bugpoint/ExecutionDriver.cpp @@ -230,7 +230,7 @@ bool BugDriver::initializeExecutionEnvironment() { } if (!SafeInterpreter) { SafeInterpreterSel = AutoPick; - Message = "Sorry, I can't automatically select an interpreter!\n"; + Message = "Sorry, I can't automatically select a safe interpreter!\n"; } break; case RunLLC: diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp index 805e019c9b..bb27767fa4 100644 --- a/tools/bugpoint/ExtractFunction.cpp +++ b/tools/bugpoint/ExtractFunction.cpp @@ -15,11 +15,11 @@ #include "BugDriver.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Assembly/Writer.h" -#include "llvm/Constants.h" -#include "llvm/DataLayout.h" -#include "llvm/DerivedTypes.h" -#include "llvm/LLVMContext.h" -#include "llvm/Module.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" #include "llvm/Pass.h" #include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" diff --git a/tools/bugpoint/LLVMBuild.txt b/tools/bugpoint/LLVMBuild.txt index 549d9d0233..e03c594bf9 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 +required_libraries = AsmParser BitReader BitWriter IPO Instrumentation Linker Scalar ObjCARC diff --git a/tools/bugpoint/Makefile b/tools/bugpoint/Makefile index 34f4bddb01..65ffc13022 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 + bitwriter vectorize objcarcopts include $(LEVEL)/Makefile.common diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp index 7b3d709c05..c676a05cb6 100644 --- a/tools/bugpoint/Miscompilation.cpp +++ b/tools/bugpoint/Miscompilation.cpp @@ -17,11 +17,11 @@ #include "ToolRunner.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Config/config.h" // for HAVE_LINK_R -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#include "llvm/Instructions.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" #include "llvm/Linker.h" -#include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileUtilities.h" diff --git a/tools/bugpoint/OptimizerDriver.cpp b/tools/bugpoint/OptimizerDriver.cpp index 3d65886398..87dc9f332c 100644 --- a/tools/bugpoint/OptimizerDriver.cpp +++ b/tools/bugpoint/OptimizerDriver.cpp @@ -18,8 +18,8 @@ #include "BugDriver.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/DataLayout.h" -#include "llvm/Module.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Module.h" #include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" diff --git a/tools/bugpoint/ToolRunner.cpp b/tools/bugpoint/ToolRunner.cpp index e7d3978e26..735061d8bc 100644 --- a/tools/bugpoint/ToolRunner.cpp +++ b/tools/bugpoint/ToolRunner.cpp @@ -531,12 +531,12 @@ LLC *AbstractInterpreter::createLLC(const char *Argv0, return 0; } - Message = "Found llc: " + LLCPath + "\n"; GCC *gcc = GCC::create(Message, GCCBinary, GCCArgs); if (!gcc) { errs() << Message << "\n"; exit(1); } + Message = "Found llc: " + LLCPath + "\n"; return new LLC(LLCPath, gcc, Args, UseIntegratedAssembler); } diff --git a/tools/bugpoint/bugpoint.cpp b/tools/bugpoint/bugpoint.cpp index efc656553b..5e8fdd145e 100644 --- a/tools/bugpoint/bugpoint.cpp +++ b/tools/bugpoint/bugpoint.cpp @@ -15,9 +15,9 @@ #include "BugDriver.h" #include "ToolRunner.h" -#include "llvm/LLVMContext.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/LinkAllIR.h" #include "llvm/LinkAllPasses.h" -#include "llvm/LinkAllVMCore.h" #include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ManagedStatic.h" @@ -120,6 +120,7 @@ int main(int argc, char **argv) { PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); initializeScalarOpts(Registry); + initializeObjCARCOpts(Registry); initializeVectorization(Registry); initializeIPO(Registry); initializeAnalysis(Registry); diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index 4e9c9c0683..aa65223473 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -13,15 +13,15 @@ // //===----------------------------------------------------------------------===// -#include "llvm/LLVMContext.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/ADT/Triple.h" #include "llvm/Assembly/PrintModulePass.h" #include "llvm/CodeGen/CommandFlags.h" #include "llvm/CodeGen/LinkAllAsmWriterComponents.h" #include "llvm/CodeGen/LinkAllCodegenComponents.h" -#include "llvm/DataLayout.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Module.h" #include "llvm/MC/SubtargetFeature.h" -#include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" @@ -319,10 +319,8 @@ static int compileModule(char **argv, LLVMContext &Context) { TLI->disableAllFunctions(); PM.add(TLI); - if (target.get()) { - PM.add(new TargetTransformInfo(target->getScalarTargetTransformInfo(), - target->getVectorTargetTransformInfo())); - } + // Add intenal analysis passes from the target machine. + Target.addAnalysisPasses(PM); // Add the target data from the target machine, if it exists, or the module. if (const DataLayout *TD = Target.getDataLayout()) diff --git a/tools/lli/CMakeLists.txt b/tools/lli/CMakeLists.txt index ed479f5323..356233f397 100644 --- a/tools/lli/CMakeLists.txt +++ b/tools/lli/CMakeLists.txt @@ -11,7 +11,9 @@ endif( LLVM_USE_OPROFILE ) if( LLVM_USE_INTEL_JITEVENTS ) set(LLVM_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS} + DebugInfo IntelJITEvents + Object ) endif( LLVM_USE_INTEL_JITEVENTS ) diff --git a/tools/lli/Makefile b/tools/lli/Makefile index 31f3ab8a1e..85ac6b46bb 100644 --- a/tools/lli/Makefile +++ b/tools/lli/Makefile @@ -17,7 +17,7 @@ LINK_COMPONENTS := mcjit jit interpreter nativecodegen bitreader asmparser selec # If Intel JIT Events support is confiured, link against the LLVM Intel JIT # Events interface library ifeq ($(USE_INTEL_JITEVENTS), 1) - LINK_COMPONENTS += inteljitevents + LINK_COMPONENTS += debuginfo inteljitevents object endif # If oprofile support is confiured, link against the LLVM oprofile interface diff --git a/tools/lli/RecordingMemoryManager.cpp b/tools/lli/RecordingMemoryManager.cpp index 75cb978130..e4d992d3d4 100644 --- a/tools/lli/RecordingMemoryManager.cpp +++ b/tools/lli/RecordingMemoryManager.cpp @@ -15,16 +15,26 @@ #include "RecordingMemoryManager.h" using namespace llvm; +RecordingMemoryManager::~RecordingMemoryManager() { + for (SmallVectorImpl<Allocation>::iterator + I = AllocatedCodeMem.begin(), E = AllocatedCodeMem.end(); + I != E; ++I) + sys::Memory::releaseMappedMemory(I->first); + for (SmallVectorImpl<Allocation>::iterator + I = AllocatedDataMem.begin(), E = AllocatedDataMem.end(); + I != E; ++I) + sys::Memory::releaseMappedMemory(I->first); +} + uint8_t *RecordingMemoryManager:: allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) { // The recording memory manager is just a local copy of the remote target. // The alignment requirement is just stored here for later use. Regular - // heap storage is sufficient here. - void *Addr = malloc(Size); - assert(Addr && "malloc() failure!"); - sys::MemoryBlock Block(Addr, Size); + // heap storage is sufficient here, but we're using mapped memory to work + // around a bug in MCJIT. + sys::MemoryBlock Block = allocateSection(Size); AllocatedCodeMem.push_back(Allocation(Block, Alignment)); - return (uint8_t*)Addr; + return (uint8_t*)Block.base(); } uint8_t *RecordingMemoryManager:: @@ -32,13 +42,30 @@ allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, bool IsReadOnly) { // The recording memory manager is just a local copy of the remote target. // The alignment requirement is just stored here for later use. Regular - // heap storage is sufficient here. - void *Addr = malloc(Size); - assert(Addr && "malloc() failure!"); - sys::MemoryBlock Block(Addr, Size); + // heap storage is sufficient here, but we're using mapped memory to work + // around a bug in MCJIT. + sys::MemoryBlock Block = allocateSection(Size); AllocatedDataMem.push_back(Allocation(Block, Alignment)); - return (uint8_t*)Addr; + return (uint8_t*)Block.base(); +} + +sys::MemoryBlock RecordingMemoryManager::allocateSection(uintptr_t Size) { + error_code ec; + sys::MemoryBlock MB = sys::Memory::allocateMappedMemory(Size, + &Near, + sys::Memory::MF_READ | + sys::Memory::MF_WRITE, + ec); + assert(!ec && MB.base()); + + // FIXME: This is part of a work around to keep sections near one another + // when MCJIT performs relocations after code emission but before + // the generated code is moved to the remote target. + // Save this address as the basis for our next request + Near = MB; + return MB; } + void RecordingMemoryManager::setMemoryWritable() { llvm_unreachable("Unexpected!"); } void RecordingMemoryManager::setMemoryExecutable() { llvm_unreachable("Unexpected!"); } void RecordingMemoryManager::setPoisonMemory(bool poison) { llvm_unreachable("Unexpected!"); } diff --git a/tools/lli/RecordingMemoryManager.h b/tools/lli/RecordingMemoryManager.h index 20fd0c2e6e..991f535fd4 100644 --- a/tools/lli/RecordingMemoryManager.h +++ b/tools/lli/RecordingMemoryManager.h @@ -31,9 +31,15 @@ private: SmallVector<Allocation, 16> AllocatedDataMem; SmallVector<Allocation, 16> AllocatedCodeMem; + // FIXME: This is part of a work around to keep sections near one another + // when MCJIT performs relocations after code emission but before + // the generated code is moved to the remote target. + sys::MemoryBlock Near; + sys::MemoryBlock allocateSection(uintptr_t Size); + public: RecordingMemoryManager() {} - virtual ~RecordingMemoryManager() {} + virtual ~RecordingMemoryManager(); typedef SmallVectorImpl<Allocation>::const_iterator const_data_iterator; typedef SmallVectorImpl<Allocation>::const_iterator const_code_iterator; diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index 5135d5041f..332660fc1e 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -14,7 +14,7 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "lli" -#include "llvm/LLVMContext.h" +#include "llvm/IR/LLVMContext.h" #include "RecordingMemoryManager.h" #include "RemoteTarget.h" #include "llvm/ADT/Triple.h" @@ -27,7 +27,8 @@ #include "llvm/ExecutionEngine/JITMemoryManager.h" #include "llvm/ExecutionEngine/MCJIT.h" #include "llvm/ExecutionEngine/SectionMemoryManager.h" -#include "llvm/Module.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Type.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/DynamicLibrary.h" @@ -43,7 +44,6 @@ #include "llvm/Support/Signals.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Type.h" #include <cerrno> #ifdef __CYGWIN__ diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp index c66c89f6ed..86eb8e272f 100644 --- a/tools/llvm-ar/llvm-ar.cpp +++ b/tools/llvm-ar/llvm-ar.cpp @@ -12,9 +12,9 @@ // //===----------------------------------------------------------------------===// -#include "llvm/LLVMContext.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/Bitcode/Archive.h" -#include "llvm/Module.h" +#include "llvm/IR/Module.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" diff --git a/tools/llvm-as/llvm-as.cpp b/tools/llvm-as/llvm-as.cpp index 2aa57d6760..273c4274b5 100644 --- a/tools/llvm-as/llvm-as.cpp +++ b/tools/llvm-as/llvm-as.cpp @@ -15,11 +15,11 @@ // //===----------------------------------------------------------------------===// -#include "llvm/LLVMContext.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Assembly/Parser.h" #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/Module.h" +#include "llvm/IR/Module.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/PrettyStackTrace.h" diff --git a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp index 46b687e1c2..99479a46a8 100644 --- a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp +++ b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp @@ -98,16 +98,17 @@ static const char *GetBlockName(unsigned BlockID, if (CurStreamType != LLVMIRBitstream) return 0; switch (BlockID) { - default: return 0; - case bitc::MODULE_BLOCK_ID: return "MODULE_BLOCK"; - case bitc::PARAMATTR_BLOCK_ID: return "PARAMATTR_BLOCK"; - case bitc::TYPE_BLOCK_ID_NEW: return "TYPE_BLOCK_ID"; - case bitc::CONSTANTS_BLOCK_ID: return "CONSTANTS_BLOCK"; - case bitc::FUNCTION_BLOCK_ID: return "FUNCTION_BLOCK"; - case bitc::VALUE_SYMTAB_BLOCK_ID: return "VALUE_SYMTAB"; - case bitc::METADATA_BLOCK_ID: return "METADATA_BLOCK"; - case bitc::METADATA_ATTACHMENT_ID: return "METADATA_ATTACHMENT_BLOCK"; - case bitc::USELIST_BLOCK_ID: return "USELIST_BLOCK_ID"; + default: return 0; + case bitc::MODULE_BLOCK_ID: return "MODULE_BLOCK"; + case bitc::PARAMATTR_BLOCK_ID: return "PARAMATTR_BLOCK"; + case bitc::PARAMATTR_GROUP_BLOCK_ID: return "PARAMATTR_GROUP_BLOCK_ID"; + case bitc::TYPE_BLOCK_ID_NEW: return "TYPE_BLOCK_ID"; + case bitc::CONSTANTS_BLOCK_ID: return "CONSTANTS_BLOCK"; + case bitc::FUNCTION_BLOCK_ID: return "FUNCTION_BLOCK"; + case bitc::VALUE_SYMTAB_BLOCK_ID: return "VALUE_SYMTAB"; + case bitc::METADATA_BLOCK_ID: return "METADATA_BLOCK"; + case bitc::METADATA_ATTACHMENT_ID: return "METADATA_ATTACHMENT_BLOCK"; + case bitc::USELIST_BLOCK_ID: return "USELIST_BLOCK_ID"; } } @@ -159,7 +160,9 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID, case bitc::PARAMATTR_BLOCK_ID: switch (CodeID) { default: return 0; - case bitc::PARAMATTR_CODE_ENTRY: return "ENTRY"; + case bitc::PARAMATTR_CODE_ENTRY_OLD: return "ENTRY"; + case bitc::PARAMATTR_CODE_ENTRY: return "ENTRY"; + case bitc::PARAMATTR_GRP_CODE_ENTRY: return "ENTRY"; } case bitc::TYPE_BLOCK_ID_NEW: switch (CodeID) { @@ -318,10 +321,10 @@ static bool Error(const std::string &Err) { } /// ParseBlock - Read a block, updating statistics, etc. -static bool ParseBlock(BitstreamCursor &Stream, unsigned IndentLevel) { +static bool ParseBlock(BitstreamCursor &Stream, unsigned BlockID, + unsigned IndentLevel) { std::string Indent(IndentLevel*2, ' '); uint64_t BlockBitStart = Stream.GetCurrentBitNo(); - unsigned BlockID = Stream.ReadSubBlockID(); // Get the statistics for this BlockID. PerBlockIDStats &BlockStats = BlockIDStats[BlockID]; @@ -354,7 +357,7 @@ static bool ParseBlock(BitstreamCursor &Stream, unsigned IndentLevel) { outs() << " BlockID=" << BlockID; outs() << " NumWords=" << NumWords - << " BlockCodeSize=" << Stream.GetAbbrevIDWidth() << ">\n"; + << " BlockCodeSize=" << Stream.getAbbrevIDWidth() << ">\n"; } SmallVector<uint64_t, 64> Record; @@ -366,12 +369,13 @@ static bool ParseBlock(BitstreamCursor &Stream, unsigned IndentLevel) { uint64_t RecordStartBit = Stream.GetCurrentBitNo(); - // Read the code for this record. - unsigned AbbrevID = Stream.ReadCode(); - switch (AbbrevID) { - case bitc::END_BLOCK: { - if (Stream.ReadBlockEnd()) - return Error("Error at end of block"); + BitstreamEntry Entry = + Stream.advance(BitstreamCursor::AF_DontAutoprocessAbbrevs); + + switch (Entry.Kind) { + case BitstreamEntry::Error: + return Error("malformed bitcode file"); + case BitstreamEntry::EndBlock: { uint64_t BlockBitEnd = Stream.GetCurrentBitNo(); BlockStats.NumBits += BlockBitEnd-BlockBitStart; if (Dump) { @@ -383,80 +387,81 @@ static bool ParseBlock(BitstreamCursor &Stream, unsigned IndentLevel) { } return false; } - case bitc::ENTER_SUBBLOCK: { + + case BitstreamEntry::SubBlock: { uint64_t SubBlockBitStart = Stream.GetCurrentBitNo(); - if (ParseBlock(Stream, IndentLevel+1)) + if (ParseBlock(Stream, Entry.ID, IndentLevel+1)) return true; ++BlockStats.NumSubBlocks; uint64_t SubBlockBitEnd = Stream.GetCurrentBitNo(); - + // Don't include subblock sizes in the size of this block. BlockBitStart += SubBlockBitEnd-SubBlockBitStart; + continue; + } + case BitstreamEntry::Record: + // The interesting case. break; } - case bitc::DEFINE_ABBREV: + + if (Entry.ID == bitc::DEFINE_ABBREV) { Stream.ReadAbbrevRecord(); ++BlockStats.NumAbbrevs; - break; - default: - Record.clear(); - - ++BlockStats.NumRecords; - if (AbbrevID != bitc::UNABBREV_RECORD) - ++BlockStats.NumAbbreviatedRecords; - - const char *BlobStart = 0; - unsigned BlobLen = 0; - unsigned Code = Stream.ReadRecord(AbbrevID, Record, BlobStart, BlobLen); - - - - // Increment the # occurrences of this code. - if (BlockStats.CodeFreq.size() <= Code) - BlockStats.CodeFreq.resize(Code+1); - BlockStats.CodeFreq[Code].NumInstances++; - BlockStats.CodeFreq[Code].TotalBits += - Stream.GetCurrentBitNo()-RecordStartBit; - if (AbbrevID != bitc::UNABBREV_RECORD) - BlockStats.CodeFreq[Code].NumAbbrev++; + continue; + } + + Record.clear(); + + ++BlockStats.NumRecords; + + StringRef Blob; + unsigned Code = Stream.readRecord(Entry.ID, Record, &Blob); + + // Increment the # occurrences of this code. + if (BlockStats.CodeFreq.size() <= Code) + BlockStats.CodeFreq.resize(Code+1); + BlockStats.CodeFreq[Code].NumInstances++; + BlockStats.CodeFreq[Code].TotalBits += + Stream.GetCurrentBitNo()-RecordStartBit; + if (Entry.ID != bitc::UNABBREV_RECORD) { + BlockStats.CodeFreq[Code].NumAbbrev++; + ++BlockStats.NumAbbreviatedRecords; + } - if (Dump) { - outs() << Indent << " <"; - if (const char *CodeName = - GetCodeName(Code, BlockID, *Stream.getBitStreamReader())) - outs() << CodeName; - else - outs() << "UnknownCode" << Code; - if (NonSymbolic && + if (Dump) { + outs() << Indent << " <"; + if (const char *CodeName = GetCodeName(Code, BlockID, *Stream.getBitStreamReader())) - outs() << " codeid=" << Code; - if (AbbrevID != bitc::UNABBREV_RECORD) - outs() << " abbrevid=" << AbbrevID; - - for (unsigned i = 0, e = Record.size(); i != e; ++i) - outs() << " op" << i << "=" << (int64_t)Record[i]; - - outs() << "/>"; - - if (BlobStart) { - outs() << " blob data = "; - bool BlobIsPrintable = true; - for (unsigned i = 0; i != BlobLen; ++i) - if (!isprint(BlobStart[i])) { - BlobIsPrintable = false; - break; - } - - if (BlobIsPrintable) - outs() << "'" << std::string(BlobStart, BlobStart+BlobLen) <<"'"; - else - outs() << "unprintable, " << BlobLen << " bytes."; - } - - outs() << "\n"; + outs() << CodeName; + else + outs() << "UnknownCode" << Code; + if (NonSymbolic && + GetCodeName(Code, BlockID, *Stream.getBitStreamReader())) + outs() << " codeid=" << Code; + if (Entry.ID != bitc::UNABBREV_RECORD) + outs() << " abbrevid=" << Entry.ID; + + for (unsigned i = 0, e = Record.size(); i != e; ++i) + outs() << " op" << i << "=" << (int64_t)Record[i]; + + outs() << "/>"; + + if (Blob.data()) { + outs() << " blob data = "; + bool BlobIsPrintable = true; + for (unsigned i = 0, e = Blob.size(); i != e; ++i) + if (!isprint(static_cast<unsigned char>(Blob[i]))) { + BlobIsPrintable = false; + break; + } + + if (BlobIsPrintable) + outs() << "'" << Blob << "'"; + else + outs() << "unprintable, " << Blob.size() << " bytes."; } - break; + outs() << "\n"; } } } @@ -519,7 +524,9 @@ static int AnalyzeBitcode() { if (Code != bitc::ENTER_SUBBLOCK) return Error("Invalid record at top-level"); - if (ParseBlock(Stream, 0)) + unsigned BlockID = Stream.ReadSubBlockID(); + + if (ParseBlock(Stream, BlockID, 0)) return true; ++NumTopBlocks; } diff --git a/tools/llvm-diff/DiffConsumer.cpp b/tools/llvm-diff/DiffConsumer.cpp index 592ae702fa..9078013c1c 100644 --- a/tools/llvm-diff/DiffConsumer.cpp +++ b/tools/llvm-diff/DiffConsumer.cpp @@ -12,8 +12,8 @@ //===----------------------------------------------------------------------===// #include "DiffConsumer.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" #include "llvm/Support/ErrorHandling.h" using namespace llvm; diff --git a/tools/llvm-diff/DiffLog.cpp b/tools/llvm-diff/DiffLog.cpp index 5f06a1614b..caf779bb40 100644 --- a/tools/llvm-diff/DiffLog.cpp +++ b/tools/llvm-diff/DiffLog.cpp @@ -15,7 +15,7 @@ #include "DiffConsumer.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" -#include "llvm/Instructions.h" +#include "llvm/IR/Instructions.h" using namespace llvm; diff --git a/tools/llvm-diff/DifferenceEngine.cpp b/tools/llvm-diff/DifferenceEngine.cpp index 9cf1f12715..4b11315b08 100644 --- a/tools/llvm-diff/DifferenceEngine.cpp +++ b/tools/llvm-diff/DifferenceEngine.cpp @@ -18,10 +18,10 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSet.h" -#include "llvm/Constants.h" -#include "llvm/Function.h" -#include "llvm/Instructions.h" -#include "llvm/Module.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Instructions.h" +#include "llvm/IR/Module.h" #include "llvm/Support/CFG.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/ErrorHandling.h" diff --git a/tools/llvm-diff/llvm-diff.cpp b/tools/llvm-diff/llvm-diff.cpp index f381dae630..0b9e92b1b8 100644 --- a/tools/llvm-diff/llvm-diff.cpp +++ b/tools/llvm-diff/llvm-diff.cpp @@ -16,14 +16,14 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" -#include "llvm/LLVMContext.h" -#include "llvm/Module.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Type.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" -#include "llvm/Type.h" #include <string> #include <utility> diff --git a/tools/llvm-dis/llvm-dis.cpp b/tools/llvm-dis/llvm-dis.cpp index cea6219a30..2baa91da50 100644 --- a/tools/llvm-dis/llvm-dis.cpp +++ b/tools/llvm-dis/llvm-dis.cpp @@ -16,12 +16,13 @@ // //===----------------------------------------------------------------------===// -#include "llvm/LLVMContext.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/Assembly/AssemblyAnnotationWriter.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/DebugInfo.h" -#include "llvm/IntrinsicInst.h" -#include "llvm/Module.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/Type.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/DataStream.h" #include "llvm/Support/FormattedStream.h" @@ -31,7 +32,6 @@ #include "llvm/Support/Signals.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/Support/system_error.h" -#include "llvm/Type.h" using namespace llvm; static cl::opt<std::string> diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index 34302fa745..80948560ca 100644 --- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -52,6 +52,25 @@ static cl::opt<bool> PrintInlining("inlining", cl::init(false), cl::desc("Print all inlined frames for a given address")); +static cl::opt<DIDumpType> +DumpType("debug-dump", cl::init(DIDT_All), + cl::desc("Dump of debug sections:"), + cl::values( + clEnumValN(DIDT_All, "all", "Dump all debug sections"), + clEnumValN(DIDT_Abbrev, "abbrev", ".debug_abbrev"), + clEnumValN(DIDT_AbbrevDwo, "abbrev.dwo", ".debug_abbrev.dwo"), + clEnumValN(DIDT_Aranges, "aranges", ".debug_aranges"), + clEnumValN(DIDT_Info, "info", ".debug_info"), + clEnumValN(DIDT_InfoDwo, "info.dwo", ".debug_info.dwo"), + clEnumValN(DIDT_Line, "line", ".debug_line"), + clEnumValN(DIDT_Frames, "frames", ".debug_frame"), + clEnumValN(DIDT_Ranges, "ranges", ".debug_ranges"), + clEnumValN(DIDT_Pubnames, "pubnames", ".debug_pubnames"), + clEnumValN(DIDT_Str, "str", ".debug_str"), + clEnumValN(DIDT_StrDwo, "str.dwo", ".debug_str.dwo"), + clEnumValN(DIDT_StrOffsetsDwo, "str_offsets.dwo", ".debug_str_offsets.dwo"), + clEnumValEnd)); + static void PrintDILineInfo(DILineInfo dli) { if (PrintFunctions) outs() << (dli.getFunctionName() ? dli.getFunctionName() : "<unknown>") @@ -69,13 +88,18 @@ static void DumpInput(const StringRef &Filename) { } OwningPtr<ObjectFile> Obj(ObjectFile::createObjectFile(Buff.take())); - OwningPtr<DIContext> dictx(DIContext::getDWARFContext(Obj.get())); + if (!Obj) { + errs() << Filename << ": Unknown object file format\n"; + return; + } + + OwningPtr<DIContext> DICtx(DIContext::getDWARFContext(Obj.get())); if (Address == -1ULL) { outs() << Filename << ":\tfile format " << Obj->getFileFormatName() << "\n\n"; // Dump the complete DWARF structure. - dictx->dump(outs()); + DICtx->dump(outs(), DumpType); } else { // Print line info for the specified address. int SpecFlags = DILineInfoSpecifier::FileLineInfo | @@ -84,7 +108,7 @@ static void DumpInput(const StringRef &Filename) { SpecFlags |= DILineInfoSpecifier::FunctionName; if (PrintInlining) { DIInliningInfo InliningInfo = - dictx->getInliningInfoForAddress(Address, SpecFlags); + DICtx->getInliningInfoForAddress(Address, SpecFlags); uint32_t n = InliningInfo.getNumberOfFrames(); if (n == 0) { // Print one empty debug line info in any case. @@ -96,7 +120,7 @@ static void DumpInput(const StringRef &Filename) { } } } else { - DILineInfo dli = dictx->getLineInfoForAddress(Address, SpecFlags); + DILineInfo dli = DICtx->getLineInfoForAddress(Address, SpecFlags); PrintDILineInfo(dli); } } diff --git a/tools/llvm-extract/llvm-extract.cpp b/tools/llvm-extract/llvm-extract.cpp index c45749b15e..85a921118a 100644 --- a/tools/llvm-extract/llvm-extract.cpp +++ b/tools/llvm-extract/llvm-extract.cpp @@ -12,13 +12,13 @@ // //===----------------------------------------------------------------------===// -#include "llvm/LLVMContext.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/Assembly/PrintModulePass.h" #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/DataLayout.h" -#include "llvm/Module.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Module.h" #include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/IRReader.h" diff --git a/tools/llvm-jitlistener/CMakeLists.txt b/tools/llvm-jitlistener/CMakeLists.txt index 57a4a0cbe1..d429af928f 100644 --- a/tools/llvm-jitlistener/CMakeLists.txt +++ b/tools/llvm-jitlistener/CMakeLists.txt @@ -6,6 +6,7 @@ include_directories( ${LLVM_INTEL_JITEVENTS_INCDIR} ) set(LLVM_LINK_COMPONENTS
asmparser
bitreader
+ debuginfo
inteljitevents
interpreter
jit
diff --git a/tools/llvm-jitlistener/Makefile b/tools/llvm-jitlistener/Makefile index 0971e6a252..30182355c9 100644 --- a/tools/llvm-jitlistener/Makefile +++ b/tools/llvm-jitlistener/Makefile @@ -18,7 +18,7 @@ LINK_COMPONENTS := mcjit jit interpreter nativecodegen bitreader asmparser selec # Events interface library. If not, this tool will do nothing useful, but it
# will build correctly.
ifeq ($(USE_INTEL_JITEVENTS), 1)
- LINK_COMPONENTS += inteljitevents
+ LINK_COMPONENTS += debuginfo inteljitevents
endif
# This tool has no plugins, optimize startup time.
diff --git a/tools/llvm-jitlistener/llvm-jitlistener.cpp b/tools/llvm-jitlistener/llvm-jitlistener.cpp index 0be525a13e..d6f5032d6e 100644 --- a/tools/llvm-jitlistener/llvm-jitlistener.cpp +++ b/tools/llvm-jitlistener/llvm-jitlistener.cpp @@ -13,7 +13,7 @@ // //===----------------------------------------------------------------------===// -#include "llvm/LLVMContext.h" +#include "llvm/IR/LLVMContext.h" #include "../../lib/ExecutionEngine/IntelJITEvents/IntelJITEventsWrapper.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/Triple.h" @@ -21,7 +21,7 @@ #include "llvm/ExecutionEngine/JITMemoryManager.h" #include "llvm/ExecutionEngine/MCJIT.h" #include "llvm/ExecutionEngine/ObjectImage.h" -#include "llvm/Module.h" +#include "llvm/IR/Module.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Host.h" #include "llvm/Support/IRReader.h" @@ -137,7 +137,7 @@ protected: // Override the triple to generate ELF on Windows since that's supported Triple Tuple(TheModule->getTargetTriple()); if (Tuple.getTriple().empty()) - Tuple.setTriple(LLVM_HOSTTRIPLE); + Tuple.setTriple(sys::getProcessTriple()); if (Tuple.isOSWindows() && Triple::ELF != Tuple.getEnvironment()) { Tuple.setEnvironment(Triple::ELF); diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp index d02fca2ece..f6c9f11a5e 100644 --- a/tools/llvm-link/llvm-link.cpp +++ b/tools/llvm-link/llvm-link.cpp @@ -15,8 +15,8 @@ #include "llvm/Linker.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/LLVMContext.h" -#include "llvm/Module.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/IRReader.h" #include "llvm/Support/ManagedStatic.h" diff --git a/tools/llvm-mc/Disassembler.cpp b/tools/llvm-mc/Disassembler.cpp index 54cf4e2edc..06c7721d7e 100644 --- a/tools/llvm-mc/Disassembler.cpp +++ b/tools/llvm-mc/Disassembler.cpp @@ -13,10 +13,6 @@ //===----------------------------------------------------------------------===// #include "Disassembler.h" -#include "../../lib/MC/MCDisassembler/EDDisassembler.h" -#include "../../lib/MC/MCDisassembler/EDInst.h" -#include "../../lib/MC/MCDisassembler/EDOperand.h" -#include "../../lib/MC/MCDisassembler/EDToken.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/Triple.h" #include "llvm/MC/MCDisassembler.h" @@ -169,175 +165,3 @@ int Disassembler::disassemble(const Target &T, return ErrorOccurred; } - -static int byteArrayReader(uint8_t *B, uint64_t A, void *Arg) { - ByteArrayTy &ByteArray = *((ByteArrayTy*)Arg); - - if (A >= ByteArray.size()) - return -1; - - *B = ByteArray[A].first; - - return 0; -} - -static int verboseEvaluator(uint64_t *V, unsigned R, void *Arg) { - EDDisassembler &disassembler = *(EDDisassembler *)((void **)Arg)[0]; - raw_ostream &Out = *(raw_ostream *)((void **)Arg)[1]; - - if (const char *regName = disassembler.nameWithRegisterID(R)) - Out << "[" << regName << "/" << R << "]"; - - if (disassembler.registerIsStackPointer(R)) - Out << "(sp)"; - if (disassembler.registerIsProgramCounter(R)) - Out << "(pc)"; - - *V = 0; - return 0; -} - -int Disassembler::disassembleEnhanced(const std::string &TS, - MemoryBuffer &Buffer, - SourceMgr &SM, - raw_ostream &Out) { - ByteArrayTy ByteArray; - StringRef Str = Buffer.getBuffer(); - - if (ByteArrayFromString(ByteArray, Str, SM)) { - return -1; - } - - Triple T(TS); - EDDisassembler::AssemblySyntax AS; - - switch (T.getArch()) { - default: - errs() << "error: no default assembly syntax for " << TS.c_str() << "\n"; - return -1; - case Triple::arm: - case Triple::thumb: - AS = EDDisassembler::kEDAssemblySyntaxARMUAL; - break; - case Triple::x86: - case Triple::x86_64: - AS = EDDisassembler::kEDAssemblySyntaxX86ATT; - break; - } - - OwningPtr<EDDisassembler> - disassembler(EDDisassembler::getDisassembler(TS.c_str(), AS)); - - if (disassembler == 0) { - errs() << "error: couldn't get disassembler for " << TS << '\n'; - return -1; - } - - while (ByteArray.size()) { - OwningPtr<EDInst> - inst(disassembler->createInst(byteArrayReader, 0, &ByteArray)); - - if (inst == 0) { - errs() << "error: Didn't get an instruction\n"; - return -1; - } - - ByteArray.erase (ByteArray.begin(), ByteArray.begin() + inst->byteSize()); - - unsigned numTokens = inst->numTokens(); - if ((int)numTokens < 0) { - errs() << "error: couldn't count the instruction's tokens\n"; - return -1; - } - - for (unsigned tokenIndex = 0; tokenIndex != numTokens; ++tokenIndex) { - EDToken *token; - - if (inst->getToken(token, tokenIndex)) { - errs() << "error: Couldn't get token\n"; - return -1; - } - - const char *buf; - if (token->getString(buf)) { - errs() << "error: Couldn't get string for token\n"; - return -1; - } - - Out << '['; - int operandIndex = token->operandID(); - - if (operandIndex >= 0) - Out << operandIndex << "-"; - - switch (token->type()) { - case EDToken::kTokenWhitespace: Out << "w"; break; - case EDToken::kTokenPunctuation: Out << "p"; break; - case EDToken::kTokenOpcode: Out << "o"; break; - case EDToken::kTokenLiteral: Out << "l"; break; - case EDToken::kTokenRegister: Out << "r"; break; - } - - Out << ":" << buf; - - if (token->type() == EDToken::kTokenLiteral) { - Out << "="; - if (token->literalSign()) - Out << "-"; - uint64_t absoluteValue; - if (token->literalAbsoluteValue(absoluteValue)) { - errs() << "error: Couldn't get the value of a literal token\n"; - return -1; - } - Out << absoluteValue; - } else if (token->type() == EDToken::kTokenRegister) { - Out << "="; - unsigned regID; - if (token->registerID(regID)) { - errs() << "error: Couldn't get the ID of a register token\n"; - return -1; - } - Out << "r" << regID; - } - - Out << "]"; - } - - Out << " "; - - if (inst->isBranch()) - Out << "<br> "; - if (inst->isMove()) - Out << "<mov> "; - - unsigned numOperands = inst->numOperands(); - - if ((int)numOperands < 0) { - errs() << "error: Couldn't count operands\n"; - return -1; - } - - for (unsigned operandIndex = 0; operandIndex != numOperands; - ++operandIndex) { - Out << operandIndex << ":"; - - EDOperand *operand; - if (inst->getOperand(operand, operandIndex)) { - errs() << "error: couldn't get operand\n"; - return -1; - } - - uint64_t evaluatedResult; - void *Arg[] = { disassembler.get(), &Out }; - if (operand->evaluate(evaluatedResult, verboseEvaluator, Arg)) { - errs() << "error: Couldn't evaluate an operand\n"; - return -1; - } - Out << "=" << evaluatedResult << " "; - } - - Out << '\n'; - } - - return 0; -} diff --git a/tools/llvm-mc/Disassembler.h b/tools/llvm-mc/Disassembler.h index 17d622f1d9..5615da8d3d 100644 --- a/tools/llvm-mc/Disassembler.h +++ b/tools/llvm-mc/Disassembler.h @@ -35,11 +35,6 @@ public: MemoryBuffer &Buffer, SourceMgr &SM, raw_ostream &Out); - - static int disassembleEnhanced(const std::string &tripleString, - MemoryBuffer &buffer, - SourceMgr &SM, - raw_ostream &Out); }; } // namespace llvm diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index 15cacfabeb..243899bb88 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -22,7 +22,6 @@ #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCParser/AsmLexer.h" -#include "llvm/MC/MCParser/MCAsmLexer.h" #include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCStreamer.h" @@ -157,11 +156,18 @@ static cl::opt<bool> GenDwarfForAssembly("g", cl::desc("Generate dwarf debugging info for assembly " "source files")); +static cl::opt<std::string> +DebugCompilationDir("fdebug-compilation-dir", + cl::desc("Specifies the debug info's compilation dir")); + +static cl::opt<std::string> +MainFileName("main-file-name", + cl::desc("Specifies the name we should consider the input file")); + enum ActionType { AC_AsLex, AC_Assemble, AC_Disassemble, - AC_EDisassemble, AC_MDisassemble, AC_HDisassemble }; @@ -175,8 +181,6 @@ Action(cl::desc("Action to perform:"), "Assemble a .s file (default)"), clEnumValN(AC_Disassemble, "disassemble", "Disassemble strings of hex bytes"), - clEnumValN(AC_EDisassemble, "edis", - "Enhanced disassembly of strings of hex bytes"), clEnumValN(AC_MDisassemble, "mdis", "Marked up disassembly of strings of hex bytes"), clEnumValN(AC_HDisassemble, "hdis", @@ -231,6 +235,13 @@ static void setDwarfDebugFlags(int argc, char **argv) { } } +static std::string DwarfDebugProducer; +static void setDwarfDebugProducer(void) { + if(!getenv("DEBUG_PRODUCER")) + return; + DwarfDebugProducer += getenv("DEBUG_PRODUCER"); +} + static int AsLexInput(SourceMgr &SrcMgr, MCAsmInfo &MAI, tool_output_file *Out) { AsmLexer Lexer(MAI); @@ -258,9 +269,6 @@ static int AsLexInput(SourceMgr &SrcMgr, MCAsmInfo &MAI, tool_output_file *Out) case AsmToken::Real: Out->os() << "real: " << Lexer.getTok().getString(); break; - case AsmToken::Register: - Out->os() << "register: " << Lexer.getTok().getRegVal(); - break; case AsmToken::String: Out->os() << "string: " << Lexer.getTok().getString(); break; @@ -351,6 +359,8 @@ int main(int argc, char **argv) { TripleName = Triple::normalize(TripleName); setDwarfDebugFlags(argc, argv); + setDwarfDebugProducer(); + const char *ProgName = argv[0]; const Target *TheTarget = GetTarget(ProgName); if (!TheTarget) @@ -372,7 +382,6 @@ int main(int argc, char **argv) { // it later. SrcMgr.setIncludeDirs(IncludeDirs); - llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(TripleName)); assert(MAI && "Unable to create target asm info!"); @@ -389,8 +398,14 @@ int main(int argc, char **argv) { Ctx.setAllowTemporaryLabels(false); Ctx.setGenDwarfForAssembly(GenDwarfForAssembly); - if (!DwarfDebugFlags.empty()) + if (!DwarfDebugFlags.empty()) Ctx.setDwarfDebugFlags(StringRef(DwarfDebugFlags)); + if (!DwarfDebugProducer.empty()) + Ctx.setDwarfDebugProducer(StringRef(DwarfDebugProducer)); + if (!DebugCompilationDir.empty()) + Ctx.setCompilationDir(DebugCompilationDir); + if (!MainFileName.empty()) + Ctx.setMainFileName(MainFileName); // Package up features to be passed to target/subtarget std::string FeaturesStr; @@ -412,7 +427,7 @@ int main(int argc, char **argv) { OwningPtr<MCSubtargetInfo> STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr)); - MCInstPrinter *IP; + MCInstPrinter *IP = NULL; if (FileType == OFT_AssemblyFile) { IP = TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MCII, *MRI, *STI); @@ -450,19 +465,18 @@ int main(int argc, char **argv) { Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI); break; case AC_MDisassemble: + assert(IP && "Expected assembly output"); IP->setUseMarkup(1); disassemble = true; break; case AC_HDisassemble: + assert(IP && "Expected assembly output"); IP->setPrintImmHex(1); disassemble = true; break; case AC_Disassemble: disassemble = true; break; - case AC_EDisassemble: - Res = Disassembler::disassembleEnhanced(TripleName, *Buffer, SrcMgr, Out->os()); - break; } if (disassemble) Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str, diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index 83cf1d3815..a24aae6061 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -16,10 +16,10 @@ // //===----------------------------------------------------------------------===// -#include "llvm/LLVMContext.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/Bitcode/Archive.h" #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/Module.h" +#include "llvm/IR/Module.h" #include "llvm/Object/Archive.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/CommandLine.h" @@ -384,7 +384,9 @@ static void DumpSymbolNamesFromFile(std::string &Filename) { OwningPtr<Binary> child; if (i->getAsBinary(child)) { // Try opening it as a bitcode file. - OwningPtr<MemoryBuffer> buff(i->getBuffer()); + OwningPtr<MemoryBuffer> buff; + if (error(i->getMemoryBuffer(buff))) + return; Module *Result = 0; if (buff) Result = ParseBitcodeFile(buff.get(), Context, &ErrorMessage); diff --git a/tools/llvm-objdump/CMakeLists.txt b/tools/llvm-objdump/CMakeLists.txt index 5001435e83..0c49d0b457 100644 --- a/tools/llvm-objdump/CMakeLists.txt +++ b/tools/llvm-objdump/CMakeLists.txt @@ -10,6 +10,7 @@ set(LLVM_LINK_COMPONENTS add_llvm_tool(llvm-objdump llvm-objdump.cpp COFFDump.cpp + ELFDump.cpp MachODump.cpp MCFunction.cpp ) diff --git a/tools/llvm-objdump/COFFDump.cpp b/tools/llvm-objdump/COFFDump.cpp index 30faecbb19..2ada683f2d 100644 --- a/tools/llvm-objdump/COFFDump.cpp +++ b/tools/llvm-objdump/COFFDump.cpp @@ -20,9 +20,9 @@ #include "llvm/Object/ObjectFile.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 "llvm/Support/Win64EH.h" #include <algorithm> #include <cstring> diff --git a/tools/llvm-objdump/ELFDump.cpp b/tools/llvm-objdump/ELFDump.cpp new file mode 100644 index 0000000000..bd1523133f --- /dev/null +++ b/tools/llvm-objdump/ELFDump.cpp @@ -0,0 +1,100 @@ +//===-- ELFDump.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-objdump. +/// +//===----------------------------------------------------------------------===// + +#include "llvm-objdump.h" +#include "llvm/Object/ELF.h" +#include "llvm/Support/Format.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; +using namespace llvm::object; + +template<class ELFT> +void printProgramHeaders( + const ELFObjectFile<ELFT> *o) { + typedef ELFObjectFile<ELFT> ELFO; + outs() << "Program Header:\n"; + for (typename ELFO::Elf_Phdr_Iter pi = o->begin_program_headers(), + pe = o->end_program_headers(); + pi != pe; ++pi) { + switch (pi->p_type) { + case ELF::PT_LOAD: + outs() << " LOAD "; + break; + case ELF::PT_GNU_STACK: + outs() << " STACK "; + break; + case ELF::PT_GNU_EH_FRAME: + outs() << "EH_FRAME "; + break; + case ELF::PT_INTERP: + outs() << " INTERP "; + break; + case ELF::PT_DYNAMIC: + outs() << " DYNAMIC "; + break; + case ELF::PT_PHDR: + outs() << " PHDR "; + break; + case ELF::PT_TLS: + outs() << " TLS "; + break; + default: + outs() << " UNKNOWN "; + } + + const char *Fmt = ELFT::Is64Bits ? "0x%016" PRIx64 " " : "0x%08" PRIx64 " "; + + outs() << "off " + << format(Fmt, (uint64_t)pi->p_offset) + << "vaddr " + << format(Fmt, (uint64_t)pi->p_vaddr) + << "paddr " + << format(Fmt, (uint64_t)pi->p_paddr) + << format("align 2**%u\n", CountTrailingZeros_64(pi->p_align)) + << " filesz " + << format(Fmt, (uint64_t)pi->p_filesz) + << "memsz " + << format(Fmt, (uint64_t)pi->p_memsz) + << "flags " + << ((pi->p_flags & ELF::PF_R) ? "r" : "-") + << ((pi->p_flags & ELF::PF_W) ? "w" : "-") + << ((pi->p_flags & ELF::PF_X) ? "x" : "-") + << "\n"; + } + outs() << "\n"; +} + +void llvm::printELFFileHeader(const object::ObjectFile *Obj) { + // Little-endian 32-bit + if (const ELFObjectFile<ELFType<support::little, 4, false> > *ELFObj = + dyn_cast<ELFObjectFile<ELFType<support::little, 4, false> > >(Obj)) + printProgramHeaders(ELFObj); + + // Big-endian 32-bit + if (const ELFObjectFile<ELFType<support::big, 4, false> > *ELFObj = + dyn_cast<ELFObjectFile<ELFType<support::big, 4, false> > >(Obj)) + printProgramHeaders(ELFObj); + + // Little-endian 64-bit + if (const ELFObjectFile<ELFType<support::little, 8, true> > *ELFObj = + dyn_cast<ELFObjectFile<ELFType<support::little, 8, true> > >(Obj)) + printProgramHeaders(ELFObj); + + // Big-endian 64-bit + if (const ELFObjectFile<ELFType<support::big, 8, true> > *ELFObj = + dyn_cast<ELFObjectFile<ELFType<support::big, 8, true> > >(Obj)) + printProgramHeaders(ELFObj); +} diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 3a350382ae..c324ff13a6 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -334,9 +334,15 @@ void llvm::DisassembleInputMachO(StringRef Filename) { for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) { StringRef SectName; if (Sections[SectIdx].getName(SectName) || - SectName.compare("__TEXT,__text")) + SectName != "__text") continue; // Skip non-text sections + StringRef SegmentName; + DataRefImpl DR = Sections[SectIdx].getRawDataRefImpl(); + if (MachOOF->getSectionFinalSegmentName(DR, SegmentName) || + SegmentName != "__TEXT") + continue; + // Insert the functions from the function starts segment into our map. uint64_t VMAddr; Sections[SectIdx].getAddress(VMAddr); diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 2838a2a2b3..322bd21b28 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -11,6 +11,9 @@ // dumps out a plethora of information about an object file depending on the // flags. // +// The flags and output of this program should be near identical to those of +// binutils objdump. +// //===----------------------------------------------------------------------===// #include "llvm-objdump.h" @@ -28,6 +31,7 @@ #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/Object/Archive.h" #include "llvm/Object/COFF.h" +#include "llvm/Object/MachO.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" @@ -72,9 +76,9 @@ static cl::opt<bool> SymbolTable("t", cl::desc("Display the symbol table")); static cl::opt<bool> -MachO("macho", cl::desc("Use MachO specific object file parser")); +MachOOpt("macho", cl::desc("Use MachO specific object file parser")); static cl::alias -MachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachO)); +MachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachOOpt)); cl::opt<std::string> llvm::TripleName("triple", cl::desc("Target triple to disassemble for, " @@ -111,6 +115,14 @@ static cl::alias UnwindInfoShort("u", cl::desc("Alias for --unwind-info"), cl::aliasopt(UnwindInfo)); +static cl::opt<bool> +PrivateHeaders("private-headers", + cl::desc("Display format specific file headers")); + +static cl::alias +PrivateHeadersShort("p", cl::desc("Alias for --private-headers"), + cl::aliasopt(PrivateHeaders)); + static StringRef ToolName; bool llvm::error(error_code ec) { @@ -241,9 +253,18 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { // Sort relocations by address. std::sort(Rels.begin(), Rels.end(), RelocAddressLess); + StringRef SegmentName = ""; + if (const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(Obj)) { + DataRefImpl DR = i->getRawDataRefImpl(); + if (error(MachO->getSectionFinalSegmentName(DR, SegmentName))) + break; + } StringRef name; if (error(i->getName(name))) break; - outs() << "Disassembly of section " << name << ':'; + outs() << "Disassembly of section "; + if (!SegmentName.empty()) + outs() << SegmentName << ","; + outs() << name << ':'; // If the section has no symbols just insert a dummy one and disassemble // the whole section. @@ -423,7 +444,7 @@ static void PrintSectionHeaders(const ObjectFile *o) { if (error(si->isBSS(BSS))) return; std::string Type = (std::string(Text ? "TEXT " : "") + (Data ? "DATA " : "") + (BSS ? "BSS" : "")); - outs() << format("%3d %-13s %09" PRIx64 " %017" PRIx64 " %s\n", + outs() << format("%3d %-13s %08" PRIx64 " %016" PRIx64 " %s\n", i, Name.str().c_str(), Size, Address, Type.c_str()); ++i; } @@ -460,7 +481,7 @@ static void PrintSectionContents(const ObjectFile *o) { // Print ascii. outs() << " "; for (std::size_t i = 0; i < 16 && addr + i < end; ++i) { - if (std::isprint(Contents[addr + i] & 0xFF)) + if (std::isprint(static_cast<unsigned char>(Contents[addr + i]) & 0xFF)) outs() << Contents[addr + i]; else outs() << "."; @@ -553,7 +574,10 @@ static void PrintSymbolTable(const ObjectFile *o) { else if (Type == SymbolRef::ST_Function) FileFunc = 'F'; - outs() << format("%08" PRIx64, Address) << " " + const char *Fmt = o->getBytesInAddress() > 4 ? "%016" PRIx64 : + "%08" PRIx64; + + outs() << format(Fmt, Address) << " " << GlobLoc // Local -> 'l', Global -> 'g', Neither -> ' ' << (Weak ? 'w' : ' ') // Weak? << ' ' // Constructor. Not supported yet. @@ -567,6 +591,13 @@ static void PrintSymbolTable(const ObjectFile *o) { else if (Section == o->end_sections()) outs() << "*UND*"; else { + if (const MachOObjectFile *MachO = dyn_cast<const MachOObjectFile>(o)) { + StringRef SegmentName; + DataRefImpl DR = Section->getRawDataRefImpl(); + if (error(MachO->getSectionFinalSegmentName(DR, SegmentName))) + SegmentName = ""; + outs() << SegmentName << ","; + } StringRef SectionName; if (error(Section->getName(SectionName))) SectionName = ""; @@ -610,6 +641,8 @@ static void DumpObject(const ObjectFile *o) { PrintSymbolTable(o); if (UnwindInfo) PrintUnwindInfo(o); + if (PrivateHeaders && o->isELF()) + printELFFileHeader(o); } /// @brief Dump each object file in \a a; @@ -640,7 +673,7 @@ static void DumpInput(StringRef file) { return; } - if (MachO && Disassemble) { + if (MachOOpt && Disassemble) { DisassembleInputMachO(file); return; } @@ -689,7 +722,8 @@ int main(int argc, char **argv) { && !SectionHeaders && !SectionContents && !SymbolTable - && !UnwindInfo) { + && !UnwindInfo + && !PrivateHeaders) { cl::PrintHelpMessage(); return 2; } diff --git a/tools/llvm-objdump/llvm-objdump.h b/tools/llvm-objdump/llvm-objdump.h index 9f5a8c3db9..ca7bced635 100644 --- a/tools/llvm-objdump/llvm-objdump.h +++ b/tools/llvm-objdump/llvm-objdump.h @@ -19,6 +19,7 @@ namespace llvm { namespace object { class COFFObjectFile; + class ObjectFile; class RelocationRef; } class error_code; @@ -32,6 +33,7 @@ bool RelocAddressLess(object::RelocationRef a, object::RelocationRef b); void DumpBytes(StringRef bytes); void DisassembleInputMachO(StringRef Filename); void printCOFFUnwindInfo(const object::COFFObjectFile* o); +void printELFFileHeader(const object::ObjectFile *o); class StringRefMemoryObject : public MemoryObject { virtual void anchor(); diff --git a/tools/llvm-prof/llvm-prof.cpp b/tools/llvm-prof/llvm-prof.cpp index a2bfae6e8d..b2c3f06169 100644 --- a/tools/llvm-prof/llvm-prof.cpp +++ b/tools/llvm-prof/llvm-prof.cpp @@ -13,14 +13,14 @@ // //===----------------------------------------------------------------------===// -#include "llvm/LLVMContext.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/Analysis/Passes.h" #include "llvm/Analysis/ProfileInfo.h" #include "llvm/Analysis/ProfileInfoLoader.h" #include "llvm/Assembly/AssemblyAnnotationWriter.h" #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/InstrTypes.h" -#include "llvm/Module.h" +#include "llvm/IR/InstrTypes.h" +#include "llvm/IR/Module.h" #include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Format.h" diff --git a/tools/llvm-ranlib/llvm-ranlib.cpp b/tools/llvm-ranlib/llvm-ranlib.cpp index 7755628777..fe9d3e2954 100644 --- a/tools/llvm-ranlib/llvm-ranlib.cpp +++ b/tools/llvm-ranlib/llvm-ranlib.cpp @@ -11,9 +11,9 @@ // //===----------------------------------------------------------------------===// -#include "llvm/LLVMContext.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/Bitcode/Archive.h" -#include "llvm/Module.h" +#include "llvm/IR/Module.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" diff --git a/tools/llvm-readobj/CMakeLists.txt b/tools/llvm-readobj/CMakeLists.txt index be80469f28..676c23d7ae 100644 --- a/tools/llvm-readobj/CMakeLists.txt +++ b/tools/llvm-readobj/CMakeLists.txt @@ -1,5 +1,6 @@ set(LLVM_LINK_COMPONENTS archive bitreader object) add_llvm_tool(llvm-readobj + ELF.cpp llvm-readobj.cpp ) diff --git a/tools/llvm-readobj/ELF.cpp b/tools/llvm-readobj/ELF.cpp new file mode 100644 index 0000000000..07f15b3a6d --- /dev/null +++ b/tools/llvm-readobj/ELF.cpp @@ -0,0 +1,196 @@ +//===- 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 <class ELFT> +void printValue(const ELFObjectFile<ELFT> *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 <class ELFT> +ErrorOr<void> dumpDynamicTable(const ELFObjectFile<ELFT> *O, raw_ostream &OS) { + typedef ELFObjectFile<ELFT> 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<void> dumpELFDynamicTable(ObjectFile *O, raw_ostream &OS) { + // Little-endian 32-bit + if (const ELFObjectFile<ELFType<support::little, 4, false> > *ELFObj = + dyn_cast<ELFObjectFile<ELFType<support::little, 4, false> > >(O)) + return dumpDynamicTable(ELFObj, OS); + + // Big-endian 32-bit + if (const ELFObjectFile<ELFType<support::big, 4, false> > *ELFObj = + dyn_cast<ELFObjectFile<ELFType<support::big, 4, false> > >(O)) + return dumpDynamicTable(ELFObj, OS); + + // Little-endian 64-bit + if (const ELFObjectFile<ELFType<support::little, 8, true> > *ELFObj = + dyn_cast<ELFObjectFile<ELFType<support::little, 8, true> > >(O)) + return dumpDynamicTable(ELFObj, OS); + + // Big-endian 64-bit + if (const ELFObjectFile<ELFType<support::big, 8, true> > *ELFObj = + dyn_cast<ELFObjectFile<ELFType<support::big, 8, true> > >(O)) + return dumpDynamicTable(ELFObj, OS); + return error_code(object_error::invalid_file_type); +} +} // end namespace llvm diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index 40e3b8c933..8f0917fc91 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -7,15 +7,20 @@ // //===----------------------------------------------------------------------===// // -// This program is a utility that works like traditional Unix "readelf", -// except that it can handle any type of object file recognized by lib/Object. +// This is a tool similar to readelf, except it works on multiple object file +// formats. The main purpose of this tool is to provide detailed output suitable +// for FileCheck. // -// It makes use of the generic ObjectFile interface. +// Flags should be similar to readelf where supported, but the output format +// does not need to be identical. The point is to not make users learn yet +// another set of flags. // -// Caution: This utility is new, experimental, unsupported, and incomplete. +// Output should be specialized for each format where appropriate. // //===----------------------------------------------------------------------===// +#include "llvm-readobj.h" + #include "llvm/ADT/Triple.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Object/ELF.h" @@ -33,7 +38,7 @@ using namespace llvm::object; static cl::opt<std::string> InputFilename(cl::Positional, cl::desc("<input object>"), cl::init("")); -void DumpSymbolHeader() { +static void dumpSymbolHeader() { outs() << format(" %-32s", (const char*)"Name") << format(" %-4s", (const char*)"Type") << format(" %-16s", (const char*)"Address") @@ -43,7 +48,16 @@ void DumpSymbolHeader() { << "\n"; } -const char *GetTypeStr(SymbolRef::Type Type) { +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"; +} + +static const char *getTypeStr(SymbolRef::Type Type) { switch (Type) { case SymbolRef::ST_Unknown: return "?"; case SymbolRef::ST_Data: return "DATA"; @@ -55,7 +69,7 @@ const char *GetTypeStr(SymbolRef::Type Type) { return "INV"; } -std::string GetFlagStr(uint32_t Flags) { +static std::string getSymbolFlagStr(uint32_t Flags) { std::string result; if (Flags & SymbolRef::SF_Undefined) result += "undef,"; @@ -79,102 +93,126 @@ std::string GetFlagStr(uint32_t Flags) { return result; } -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; - Sym.getName(Name); - Sym.getAddress(Address); - Sym.getSize(Size); - Sym.getFileOffset(FileOffset); - Sym.getType(Type); - Sym.getFlags(Flags); - std::string FullName = Name; - - // 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; - } - } - - // 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) - << " " << GetFlagStr(Flags) - << "\n"; +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" }}; -// Iterate through the normal symbols in the ObjectFile -void DumpSymbols(const ObjectFile *obj) { - error_code ec; - uint32_t count = 0; - outs() << "Symbols:\n"; - symbol_iterator it = obj->begin_symbols(); - symbol_iterator ie = obj->end_symbols(); - while (it != ie) { - DumpSymbol(*it, obj, false); - it.increment(ec); - if (ec) - report_fatal_error("Symbol iteration failed"); - ++count; + 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; } - outs() << " Total: " << count << "\n\n"; + + // Remove trailing comma + if (result.size() > 0) { + result.erase(result.size() - 1); + } + return result; } -// Iterate through the dynamic symbols in the ObjectFile. -void DumpDynamicSymbols(const ObjectFile *obj) { - error_code ec; - uint32_t count = 0; - outs() << "Dynamic Symbols:\n"; - symbol_iterator it = obj->begin_dynamic_symbols(); - symbol_iterator ie = obj->end_dynamic_symbols(); - while (it != ie) { - DumpSymbol(*it, obj, true); - it.increment(ec); - if (ec) - report_fatal_error("Symbol iteration failed"); - ++count; +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; + + // 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; + } } - outs() << " Total: " << count << "\n\n"; + + // 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"; +} + +static void dumpStaticSymbol(const SymbolRef &Sym, const ObjectFile *obj) { + return dumpSymbol(Sym, obj, false); } -void DumpLibrary(const LibraryRef &lib) { +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"; } -// Iterate through needed libraries -void DumpLibrariesNeeded(const ObjectFile *obj) { +template<typename Iterator, typename Func> +static void dump(const ObjectFile *obj, Func f, Iterator begin, Iterator end, + const char *errStr) { error_code ec; uint32_t count = 0; - library_iterator it = obj->begin_libraries_needed(); - library_iterator ie = obj->end_libraries_needed(); - outs() << "Libraries needed:\n"; + Iterator it = begin, ie = end; while (it != ie) { - DumpLibrary(*it); + f(*it, obj); it.increment(ec); if (ec) - report_fatal_error("Needed libraries iteration failed"); + report_fatal_error(errStr); ++count; } outs() << " Total: " << count << "\n\n"; } -void DumpHeaders(const ObjectFile *obj) { +static void dumpHeaders(const ObjectFile *obj) { outs() << "File Format : " << obj->getFileFormatName() << "\n"; outs() << "Arch : " << Triple::getArchTypeName((llvm::Triple::ArchType)obj->getArch()) @@ -204,15 +242,40 @@ int main(int argc, char** argv) { return 1; } - ObjectFile *obj = ObjectFile::createObjectFile(File.take()); + OwningPtr<ObjectFile> o(ObjectFile::createObjectFile(File.take())); + ObjectFile *obj = o.get(); if (!obj) { errs() << InputFilename << ": Object type not recognized\n"; } - DumpHeaders(obj); - DumpSymbols(obj); - DumpDynamicSymbols(obj); - DumpLibrariesNeeded(obj); + dumpHeaders(obj); + + 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"); + + outs() << "Sections:\n"; + dumpSectionHeader(); + dump(obj, &dumpSection, obj->begin_sections(), obj->end_sections(), + "Section iteration failed"); + + if (obj->isELF()) { + if (ErrorOr<void> e = dumpELFDynamicTable(obj, outs())) + ; + else + errs() << "InputFilename" << ": " << error_code(e).message() << "\n"; + } + + outs() << "Libraries needed:\n"; + dump(obj, &dumpLibrary, obj->begin_libraries_needed(), + obj->end_libraries_needed(), "Needed libraries iteration failed"); + return 0; } diff --git a/tools/llvm-readobj/llvm-readobj.h b/tools/llvm-readobj/llvm-readobj.h new file mode 100644 index 0000000000..cf492b2a8d --- /dev/null +++ b/tools/llvm-readobj/llvm-readobj.h @@ -0,0 +1,22 @@ +//===- llvm-readobj.h - Dump contents of an Object File -------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_READ_OBJ_H +#define LLVM_TOOLS_READ_OBJ_H + +#include "llvm/Support/ErrorOr.h" + +namespace llvm { +namespace object { class ObjectFile; } +class raw_ostream; + +ErrorOr<void> dumpELFDynamicTable(object::ObjectFile *O, raw_ostream &OS); +} // end namespace llvm + +#endif diff --git a/tools/llvm-rtdyld/CMakeLists.txt b/tools/llvm-rtdyld/CMakeLists.txt index 17e2c3e2d5..8d161d366d 100644 --- a/tools/llvm-rtdyld/CMakeLists.txt +++ b/tools/llvm-rtdyld/CMakeLists.txt @@ -1,4 +1,4 @@ -set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support MC object RuntimeDyld JIT) +set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} support MC object RuntimeDyld JIT debuginfo) add_llvm_tool(llvm-rtdyld llvm-rtdyld.cpp diff --git a/tools/llvm-rtdyld/Makefile b/tools/llvm-rtdyld/Makefile index 30fbee0979..fabdd683a9 100644 --- a/tools/llvm-rtdyld/Makefile +++ b/tools/llvm-rtdyld/Makefile @@ -9,7 +9,7 @@ LEVEL := ../.. TOOLNAME := llvm-rtdyld -LINK_COMPONENTS := all-targets support MC object RuntimeDyld JIT +LINK_COMPONENTS := all-targets support MC object RuntimeDyld JIT debuginfo # This tool has no plugins, optimize startup time. TOOL_NO_EXPORTS := 1 diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp index ec63c9b56c..4d8d345894 100644 --- a/tools/llvm-rtdyld/llvm-rtdyld.cpp +++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -13,6 +13,7 @@ #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringMap.h" +#include "llvm/DebugInfo/DIContext.h" #include "llvm/ExecutionEngine/ObjectBuffer.h" #include "llvm/ExecutionEngine/ObjectImage.h" #include "llvm/ExecutionEngine/RuntimeDyld.h" @@ -31,7 +32,8 @@ InputFileList(cl::Positional, cl::ZeroOrMore, cl::desc("<input file>")); enum ActionType { - AC_Execute + AC_Execute, + AC_PrintLineInfo }; static cl::opt<ActionType> @@ -39,6 +41,8 @@ Action(cl::desc("Action to perform:"), cl::init(AC_Execute), cl::values(clEnumValN(AC_Execute, "execute", "Load, link, and execute the inputs."), + clEnumValN(AC_PrintLineInfo, "printline", + "Load, link, and print line information for each function."), clEnumValEnd)); static cl::opt<std::string> @@ -114,6 +118,66 @@ static int Error(const Twine &Msg) { /* *** */ +static int printLineInfoForInput() { + // If we don't have any input files, read from stdin. + if (!InputFileList.size()) + InputFileList.push_back("-"); + for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) { + // Instantiate a dynamic linker. + TrivialMemoryManager *MemMgr = new TrivialMemoryManager; + RuntimeDyld Dyld(MemMgr); + + // Load the input memory buffer. + OwningPtr<MemoryBuffer> InputBuffer; + OwningPtr<ObjectImage> LoadedObject; + if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFileList[i], + InputBuffer)) + return Error("unable to read input: '" + ec.message() + "'"); + + // Load the object file + LoadedObject.reset(Dyld.loadObject(new ObjectBuffer(InputBuffer.take()))); + if (!LoadedObject) { + return Error(Dyld.getErrorString()); + } + + // Resolve all the relocations we can. + Dyld.resolveRelocations(); + + OwningPtr<DIContext> Context(DIContext::getDWARFContext(LoadedObject->getObjectFile())); + + // Use symbol info to iterate functions in the object. + error_code ec; + for (object::symbol_iterator I = LoadedObject->begin_symbols(), + E = LoadedObject->end_symbols(); + I != E && !ec; + I.increment(ec)) { + object::SymbolRef::Type SymType; + if (I->getType(SymType)) continue; + if (SymType == object::SymbolRef::ST_Function) { + StringRef Name; + uint64_t Addr; + uint64_t Size; + if (I->getName(Name)) continue; + if (I->getAddress(Addr)) continue; + if (I->getSize(Size)) continue; + + outs() << "Function: " << Name << ", Size = " << Size << "\n"; + + DILineInfoTable Lines = Context->getLineInfoForAddressRange(Addr, Size); + DILineInfoTable::iterator Begin = Lines.begin(); + DILineInfoTable::iterator End = Lines.end(); + for (DILineInfoTable::iterator It = Begin; It != End; ++It) { + outs() << " Line info @ " << It->first - Addr << ": " + << It->second.getFileName() + << ", line:" << It->second.getLine() << "\n"; + } + } + } + } + + return 0; +} + static int executeInput() { // Instantiate a dynamic linker. TrivialMemoryManager *MemMgr = new TrivialMemoryManager; @@ -180,5 +244,7 @@ int main(int argc, char **argv) { switch (Action) { case AC_Execute: return executeInput(); + case AC_PrintLineInfo: + return printLineInfoForInput(); } } diff --git a/tools/llvm-stress/llvm-stress.cpp b/tools/llvm-stress/llvm-stress.cpp index ce798f7b2e..fbda1b7b67 100644 --- a/tools/llvm-stress/llvm-stress.cpp +++ b/tools/llvm-stress/llvm-stress.cpp @@ -11,13 +11,14 @@ // different components in LLVM. // //===----------------------------------------------------------------------===// -#include "llvm/LLVMContext.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/ADT/OwningPtr.h" +#include "llvm/Analysis/CallGraphSCCPass.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Assembly/PrintModulePass.h" -#include "llvm/CallGraphSCCPass.h" -#include "llvm/Constants.h" -#include "llvm/Instruction.h" -#include "llvm/Module.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/Instruction.h" +#include "llvm/IR/Module.h" #include "llvm/PassManager.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ManagedStatic.h" @@ -26,7 +27,6 @@ #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/ToolOutputFile.h" #include <algorithm> -#include <memory> #include <set> #include <sstream> #include <vector> @@ -379,9 +379,7 @@ struct ConstModifier: public Modifier { RandomBits[i] = Ran->Rand64(); APInt RandomInt(Ty->getPrimitiveSizeInBits(), makeArrayRef(RandomBits)); - - bool isIEEE = !Ty->isX86_FP80Ty() && !Ty->isPPC_FP128Ty(); - APFloat RandomFloat(RandomInt, isIEEE); + APFloat RandomFloat(Ty->getFltSemantics(), RandomInt); if (Ran->Rand() & 1) return PT->push_back(ConstantFP::getNullValue(Ty)); @@ -624,15 +622,15 @@ void FillFunction(Function *F, Random &R) { // List of modifiers which add new random instructions. std::vector<Modifier*> Modifiers; - std::auto_ptr<Modifier> LM(new LoadModifier(BB, &PT, &R)); - std::auto_ptr<Modifier> SM(new StoreModifier(BB, &PT, &R)); - std::auto_ptr<Modifier> EE(new ExtractElementModifier(BB, &PT, &R)); - std::auto_ptr<Modifier> SHM(new ShuffModifier(BB, &PT, &R)); - std::auto_ptr<Modifier> IE(new InsertElementModifier(BB, &PT, &R)); - std::auto_ptr<Modifier> BM(new BinModifier(BB, &PT, &R)); - std::auto_ptr<Modifier> CM(new CastModifier(BB, &PT, &R)); - std::auto_ptr<Modifier> SLM(new SelectModifier(BB, &PT, &R)); - std::auto_ptr<Modifier> PM(new CmpModifier(BB, &PT, &R)); + OwningPtr<Modifier> LM(new LoadModifier(BB, &PT, &R)); + OwningPtr<Modifier> SM(new StoreModifier(BB, &PT, &R)); + OwningPtr<Modifier> EE(new ExtractElementModifier(BB, &PT, &R)); + OwningPtr<Modifier> SHM(new ShuffModifier(BB, &PT, &R)); + OwningPtr<Modifier> IE(new InsertElementModifier(BB, &PT, &R)); + OwningPtr<Modifier> BM(new BinModifier(BB, &PT, &R)); + OwningPtr<Modifier> CM(new CastModifier(BB, &PT, &R)); + OwningPtr<Modifier> SLM(new SelectModifier(BB, &PT, &R)); + OwningPtr<Modifier> PM(new CmpModifier(BB, &PT, &R)); Modifiers.push_back(LM.get()); Modifiers.push_back(SM.get()); Modifiers.push_back(EE.get()); @@ -686,7 +684,7 @@ int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, "llvm codegen stress-tester\n"); llvm_shutdown_obj Y; - std::auto_ptr<Module> M(new Module("/tmp/autogen.bc", getGlobalContext())); + OwningPtr<Module> M(new Module("/tmp/autogen.bc", getGlobalContext())); Function *F = GenEmptyFunction(M.get()); // Pick an initial seed value diff --git a/tools/llvm-symbolizer/CMakeLists.txt b/tools/llvm-symbolizer/CMakeLists.txt index 5e274630c8..5967b891f4 100644 --- a/tools/llvm-symbolizer/CMakeLists.txt +++ b/tools/llvm-symbolizer/CMakeLists.txt @@ -9,5 +9,6 @@ set(LLVM_LINK_COMPONENTS ) add_llvm_tool(llvm-symbolizer + LLVMSymbolize.cpp llvm-symbolizer.cpp ) diff --git a/tools/llvm-symbolizer/LLVMSymbolize.cpp b/tools/llvm-symbolizer/LLVMSymbolize.cpp new file mode 100644 index 0000000000..86ea34bff6 --- /dev/null +++ b/tools/llvm-symbolizer/LLVMSymbolize.cpp @@ -0,0 +1,287 @@ +//===-- LLVMSymbolize.cpp -------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Implementation for LLVM symbolization library. +// +//===----------------------------------------------------------------------===// + +#include "LLVMSymbolize.h" +#include "llvm/Object/MachO.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Path.h" + +#include <sstream> + +namespace llvm { +namespace symbolize { + +static bool error(error_code ec) { + if (!ec) + return false; + errs() << "LLVMSymbolizer: error reading file: " << ec.message() << ".\n"; + return true; +} + +static uint32_t +getDILineInfoSpecifierFlags(const LLVMSymbolizer::Options &Opts) { + uint32_t Flags = llvm::DILineInfoSpecifier::FileLineInfo | + llvm::DILineInfoSpecifier::AbsoluteFilePath; + if (Opts.PrintFunctions) + Flags |= llvm::DILineInfoSpecifier::FunctionName; + return Flags; +} + +static void patchFunctionNameInDILineInfo(const std::string &NewFunctionName, + DILineInfo &LineInfo) { + std::string FileName = LineInfo.getFileName(); + LineInfo = DILineInfo(StringRef(FileName), StringRef(NewFunctionName), + LineInfo.getLine(), LineInfo.getColumn()); +} + +ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx) + : Module(Obj), DebugInfoContext(DICtx) { + error_code ec; + for (symbol_iterator si = Module->begin_symbols(), se = Module->end_symbols(); + si != se; si.increment(ec)) { + if (error(ec)) + return; + SymbolRef::Type SymbolType; + if (error(si->getType(SymbolType))) + continue; + if (SymbolType != SymbolRef::ST_Function && + SymbolType != SymbolRef::ST_Data) + continue; + uint64_t SymbolAddress; + if (error(si->getAddress(SymbolAddress)) || + SymbolAddress == UnknownAddressOrSize) + continue; + uint64_t SymbolSize; + if (error(si->getSize(SymbolSize)) || SymbolSize == UnknownAddressOrSize) + continue; + StringRef SymbolName; + if (error(si->getName(SymbolName))) + continue; + // FIXME: If a function has alias, there are two entries in symbol table + // with same address size. Make sure we choose the correct one. + SymbolMapTy &M = SymbolType == SymbolRef::ST_Function ? Functions : Objects; + SymbolDesc SD = { SymbolAddress, SymbolAddress + SymbolSize }; + M.insert(std::make_pair(SD, SymbolName)); + } +} + +bool ModuleInfo::getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address, + std::string &Name, uint64_t &Addr, + uint64_t &Size) const { + const SymbolMapTy &M = Type == SymbolRef::ST_Function ? Functions : Objects; + SymbolDesc SD = { Address, Address + 1 }; + SymbolMapTy::const_iterator it = M.find(SD); + if (it == M.end()) + return false; + if (Address < it->first.Addr || Address >= it->first.AddrEnd) + return false; + Name = it->second.str(); + Addr = it->first.Addr; + Size = it->first.AddrEnd - it->first.Addr; + return true; +} + +DILineInfo ModuleInfo::symbolizeCode( + uint64_t ModuleOffset, const LLVMSymbolizer::Options &Opts) const { + DILineInfo LineInfo; + if (DebugInfoContext) { + LineInfo = DebugInfoContext->getLineInfoForAddress( + ModuleOffset, getDILineInfoSpecifierFlags(Opts)); + } + // Override function name from symbol table if necessary. + if (Opts.PrintFunctions && Opts.UseSymbolTable) { + std::string FunctionName; + uint64_t Start, Size; + if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset, + FunctionName, Start, Size)) { + patchFunctionNameInDILineInfo(FunctionName, LineInfo); + } + } + return LineInfo; +} + +DIInliningInfo ModuleInfo::symbolizeInlinedCode( + uint64_t ModuleOffset, const LLVMSymbolizer::Options &Opts) const { + DIInliningInfo InlinedContext; + if (DebugInfoContext) { + InlinedContext = DebugInfoContext->getInliningInfoForAddress( + ModuleOffset, getDILineInfoSpecifierFlags(Opts)); + } + // Make sure there is at least one frame in context. + if (InlinedContext.getNumberOfFrames() == 0) { + InlinedContext.addFrame(DILineInfo()); + } + // Override the function name in lower frame with name from symbol table. + if (Opts.PrintFunctions && Opts.UseSymbolTable) { + DIInliningInfo PatchedInlinedContext; + for (uint32_t i = 0, n = InlinedContext.getNumberOfFrames(); i < n; i++) { + DILineInfo LineInfo = InlinedContext.getFrame(i); + if (i == n - 1) { + std::string FunctionName; + uint64_t Start, Size; + if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset, + FunctionName, Start, Size)) { + patchFunctionNameInDILineInfo(FunctionName, LineInfo); + } + } + PatchedInlinedContext.addFrame(LineInfo); + } + InlinedContext = PatchedInlinedContext; + } + return InlinedContext; +} + +bool ModuleInfo::symbolizeData(uint64_t ModuleOffset, std::string &Name, + uint64_t &Start, uint64_t &Size) const { + return getNameFromSymbolTable(SymbolRef::ST_Data, ModuleOffset, Name, Start, + Size); +} + +const char LLVMSymbolizer::kBadString[] = "??"; + +std::string LLVMSymbolizer::symbolizeCode(const std::string &ModuleName, + uint64_t ModuleOffset) { + ModuleInfo *Info = getOrCreateModuleInfo(ModuleName); + if (Info == 0) + return printDILineInfo(DILineInfo()); + if (Opts.PrintInlining) { + DIInliningInfo InlinedContext = + Info->symbolizeInlinedCode(ModuleOffset, Opts); + uint32_t FramesNum = InlinedContext.getNumberOfFrames(); + assert(FramesNum > 0); + std::string Result; + for (uint32_t i = 0; i < FramesNum; i++) { + DILineInfo LineInfo = InlinedContext.getFrame(i); + Result += printDILineInfo(LineInfo); + } + return Result; + } + DILineInfo LineInfo = Info->symbolizeCode(ModuleOffset, Opts); + return printDILineInfo(LineInfo); +} + +std::string LLVMSymbolizer::symbolizeData(const std::string &ModuleName, + uint64_t ModuleOffset) { + std::string Name = kBadString; + uint64_t Start = 0; + uint64_t Size = 0; + if (Opts.UseSymbolTable) { + if (ModuleInfo *Info = getOrCreateModuleInfo(ModuleName)) { + if (Info->symbolizeData(ModuleOffset, Name, Start, Size)) + DemangleName(Name); + } + } + std::stringstream ss; + ss << Name << "\n" << Start << " " << Size << "\n"; + return ss.str(); +} + +// 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. + IsLittleEndian = true; + return true; +} + +static ObjectFile *getObjectFile(const std::string &Path) { + OwningPtr<MemoryBuffer> Buff; + if (error_code ec = MemoryBuffer::getFile(Path, Buff)) + error(ec); + return ObjectFile::createObjectFile(Buff.take()); +} + +static std::string getDarwinDWARFResourceForModule(const std::string &Path) { + StringRef Basename = sys::path::filename(Path); + const std::string &DSymDirectory = Path + ".dSYM"; + SmallString<16> ResourceName = StringRef(DSymDirectory); + sys::path::append(ResourceName, "Contents", "Resources", "DWARF"); + sys::path::append(ResourceName, Basename); + return ResourceName.str(); +} + +ModuleInfo * +LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) { + ModuleMapTy::iterator I = Modules.find(ModuleName); + if (I != Modules.end()) + return I->second; + + ObjectFile *Obj = getObjectFile(ModuleName); + if (Obj == 0) { + // Module name doesn't point to a valid object file. + Modules.insert(make_pair(ModuleName, (ModuleInfo *)0)); + return 0; + } + + DIContext *Context = 0; + bool IsLittleEndian; + if (getObjectEndianness(Obj, IsLittleEndian)) { + // On Darwin we may find DWARF in separate object file in + // resource directory. + ObjectFile *DbgObj = Obj; + if (isa<MachOObjectFile>(Obj)) { + const std::string &ResourceName = + getDarwinDWARFResourceForModule(ModuleName); + ObjectFile *ResourceObj = getObjectFile(ResourceName); + if (ResourceObj != 0) + DbgObj = ResourceObj; + } + Context = DIContext::getDWARFContext(DbgObj); + assert(Context); + } + + ModuleInfo *Info = new ModuleInfo(Obj, Context); + Modules.insert(make_pair(ModuleName, Info)); + return Info; +} + +std::string LLVMSymbolizer::printDILineInfo(DILineInfo LineInfo) const { + // By default, DILineInfo contains "<invalid>" for function/filename it + // cannot fetch. We replace it to "??" to make our output closer to addr2line. + static const std::string kDILineInfoBadString = "<invalid>"; + std::stringstream Result; + if (Opts.PrintFunctions) { + std::string FunctionName = LineInfo.getFunctionName(); + if (FunctionName == kDILineInfoBadString) + FunctionName = kBadString; + DemangleName(FunctionName); + Result << FunctionName << "\n"; + } + std::string Filename = LineInfo.getFileName(); + if (Filename == kDILineInfoBadString) + Filename = kBadString; + Result << Filename << ":" << LineInfo.getLine() << ":" << LineInfo.getColumn() + << "\n"; + return Result.str(); +} + +#if !defined(_MSC_VER) +// Assume that __cxa_demangle is provided by libcxxabi (except for Windows). +extern "C" char *__cxa_demangle(const char *mangled_name, char *output_buffer, + size_t *length, int *status); +#endif + +void LLVMSymbolizer::DemangleName(std::string &Name) const { +#if !defined(_MSC_VER) + if (!Opts.Demangle) + return; + int status = 0; + char *DemangledName = __cxa_demangle(Name.c_str(), 0, 0, &status); + if (status != 0) + return; + Name = DemangledName; + free(DemangledName); +#endif +} + +} // namespace symbolize +} // namespace llvm diff --git a/tools/llvm-symbolizer/LLVMSymbolize.h b/tools/llvm-symbolizer/LLVMSymbolize.h new file mode 100644 index 0000000000..e6220aa4ce --- /dev/null +++ b/tools/llvm-symbolizer/LLVMSymbolize.h @@ -0,0 +1,97 @@ +//===-- LLVMSymbolize.h ----------------------------------------- C++ -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Header for LLVM symbolization library. +// +//===----------------------------------------------------------------------===// +#ifndef LLVM_SYMBOLIZE_H +#define LLVM_SYMBOLIZE_H + +#include "llvm/ADT/OwningPtr.h" +#include "llvm/DebugInfo/DIContext.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Support/MemoryBuffer.h" +#include <map> +#include <string> + +namespace llvm { + +using namespace object; + +namespace symbolize { + +class ModuleInfo; + +class LLVMSymbolizer { +public: + struct Options { + bool UseSymbolTable : 1; + bool PrintFunctions : 1; + bool PrintInlining : 1; + bool Demangle : 1; + Options(bool UseSymbolTable = true, bool PrintFunctions = true, + bool PrintInlining = true, bool Demangle = true) + : UseSymbolTable(UseSymbolTable), PrintFunctions(PrintFunctions), + PrintInlining(PrintInlining), Demangle(Demangle) { + } + }; + + LLVMSymbolizer(const Options &Opts = Options()) : Opts(Opts) {} + + // Returns the result of symbolization for module name/offset as + // a string (possibly containing newlines). + std::string + symbolizeCode(const std::string &ModuleName, uint64_t ModuleOffset); + std::string + symbolizeData(const std::string &ModuleName, uint64_t ModuleOffset); +private: + ModuleInfo *getOrCreateModuleInfo(const std::string &ModuleName); + std::string printDILineInfo(DILineInfo LineInfo) const; + void DemangleName(std::string &Name) const; + + typedef std::map<std::string, ModuleInfo *> ModuleMapTy; + ModuleMapTy Modules; + Options Opts; + static const char kBadString[]; +}; + +class ModuleInfo { +public: + ModuleInfo(ObjectFile *Obj, DIContext *DICtx); + + DILineInfo symbolizeCode(uint64_t ModuleOffset, + const LLVMSymbolizer::Options &Opts) const; + DIInliningInfo symbolizeInlinedCode( + uint64_t ModuleOffset, const LLVMSymbolizer::Options &Opts) const; + bool symbolizeData(uint64_t ModuleOffset, std::string &Name, uint64_t &Start, + uint64_t &Size) const; + +private: + bool getNameFromSymbolTable(SymbolRef::Type Type, uint64_t Address, + std::string &Name, uint64_t &Addr, + uint64_t &Size) const; + OwningPtr<ObjectFile> Module; + OwningPtr<DIContext> DebugInfoContext; + + struct SymbolDesc { + uint64_t Addr; + uint64_t AddrEnd; + friend bool operator<(const SymbolDesc &s1, const SymbolDesc &s2) { + return s1.AddrEnd <= s2.Addr; + } + }; + typedef std::map<SymbolDesc, StringRef> SymbolMapTy; + SymbolMapTy Functions; + SymbolMapTy Objects; +}; + +} // namespace symbolize +} // namespace llvm + +#endif // LLVM_SYMBOLIZE_H diff --git a/tools/llvm-symbolizer/llvm-symbolizer.cpp b/tools/llvm-symbolizer/llvm-symbolizer.cpp index 6a5eb4a662..d039ec691f 100644 --- a/tools/llvm-symbolizer/llvm-symbolizer.cpp +++ b/tools/llvm-symbolizer/llvm-symbolizer.cpp @@ -15,292 +15,69 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/OwningPtr.h" +#include "LLVMSymbolize.h" #include "llvm/ADT/StringRef.h" -#include "llvm/DebugInfo/DIContext.h" -#include "llvm/Object/MachO.h" -#include "llvm/Object/ObjectFile.h" -#include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Path.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" #include "llvm/Support/raw_ostream.h" #include <cstdio> #include <cstring> -#include <map> #include <string> using namespace llvm; -using namespace object; +using namespace symbolize; static cl::opt<bool> -UseSymbolTable("use-symbol-table", cl::init(true), - cl::desc("Prefer names in symbol table to names " - "in debug info")); +ClUseSymbolTable("use-symbol-table", cl::init(true), + cl::desc("Prefer names in symbol table to names " + "in debug info")); static cl::opt<bool> -PrintFunctions("functions", cl::init(true), - cl::desc("Print function names as well as line " - "information for a given address")); +ClPrintFunctions("functions", cl::init(true), + cl::desc("Print function names as well as line " + "information for a given address")); static cl::opt<bool> -PrintInlining("inlining", cl::init(true), - cl::desc("Print all inlined frames for a given address")); +ClPrintInlining("inlining", cl::init(true), + cl::desc("Print all inlined frames for a given address")); static cl::opt<bool> -Demangle("demangle", cl::init(true), - cl::desc("Demangle function names")); - -static StringRef ToolInvocationPath; - -static bool error(error_code ec) { - if (!ec) return false; - errs() << ToolInvocationPath << ": error reading file: " - << ec.message() << ".\n"; - return true; -} - -static uint32_t getDILineInfoSpecifierFlags() { - uint32_t Flags = llvm::DILineInfoSpecifier::FileLineInfo | - llvm::DILineInfoSpecifier::AbsoluteFilePath; - if (PrintFunctions) - Flags |= llvm::DILineInfoSpecifier::FunctionName; - return Flags; -} - -static void patchFunctionNameInDILineInfo(const std::string &NewFunctionName, - DILineInfo &LineInfo) { - std::string FileName = LineInfo.getFileName(); - LineInfo = DILineInfo(StringRef(FileName), StringRef(NewFunctionName), - LineInfo.getLine(), LineInfo.getColumn()); -} - -namespace { -class ModuleInfo { - OwningPtr<ObjectFile> Module; - OwningPtr<DIContext> DebugInfoContext; - public: - ModuleInfo(ObjectFile *Obj, DIContext *DICtx) - : Module(Obj), DebugInfoContext(DICtx) {} - - DILineInfo symbolizeCode(uint64_t ModuleOffset) const { - DILineInfo LineInfo; - if (DebugInfoContext) { - LineInfo = DebugInfoContext->getLineInfoForAddress( - ModuleOffset, getDILineInfoSpecifierFlags()); - } - // Override function name from symbol table if necessary. - if (PrintFunctions && UseSymbolTable) { - std::string Function; - if (getFunctionNameFromSymbolTable(ModuleOffset, Function)) { - patchFunctionNameInDILineInfo(Function, LineInfo); - } - } - return LineInfo; - } - - DIInliningInfo symbolizeInlinedCode(uint64_t ModuleOffset) const { - DIInliningInfo InlinedContext; - if (DebugInfoContext) { - InlinedContext = DebugInfoContext->getInliningInfoForAddress( - ModuleOffset, getDILineInfoSpecifierFlags()); - } - // Make sure there is at least one frame in context. - if (InlinedContext.getNumberOfFrames() == 0) { - InlinedContext.addFrame(DILineInfo()); - } - // Override the function name in lower frame with name from symbol table. - if (PrintFunctions && UseSymbolTable) { - DIInliningInfo PatchedInlinedContext; - for (uint32_t i = 0, n = InlinedContext.getNumberOfFrames(); - i != n; i++) { - DILineInfo LineInfo = InlinedContext.getFrame(i); - if (i == n - 1) { - std::string Function; - if (getFunctionNameFromSymbolTable(ModuleOffset, Function)) { - patchFunctionNameInDILineInfo(Function, LineInfo); - } - } - PatchedInlinedContext.addFrame(LineInfo); - } - InlinedContext = PatchedInlinedContext; - } - return InlinedContext; - } - - private: - bool getFunctionNameFromSymbolTable(uint64_t Address, - std::string &FunctionName) const { - assert(Module); - error_code ec; - for (symbol_iterator si = Module->begin_symbols(), - se = Module->end_symbols(); - si != se; si.increment(ec)) { - if (error(ec)) return false; - uint64_t SymbolAddress; - uint64_t SymbolSize; - SymbolRef::Type SymbolType; - if (error(si->getAddress(SymbolAddress)) || - SymbolAddress == UnknownAddressOrSize) continue; - if (error(si->getSize(SymbolSize)) || - SymbolSize == UnknownAddressOrSize) continue; - if (error(si->getType(SymbolType))) continue; - // FIXME: If a function has alias, there are two entries in symbol table - // with same address size. Make sure we choose the correct one. - if (SymbolAddress <= Address && Address < SymbolAddress + SymbolSize && - SymbolType == SymbolRef::ST_Function) { - StringRef Name; - if (error(si->getName(Name))) continue; - FunctionName = Name.str(); - return true; - } - } - return false; - } -}; - -typedef std::map<std::string, ModuleInfo*> ModuleMapTy; -typedef ModuleMapTy::iterator ModuleMapIter; -} // namespace - -static ModuleMapTy Modules; - -// 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. - IsLittleEndian = true; - return true; -} - -static ObjectFile *getObjectFile(const std::string &Path) { - OwningPtr<MemoryBuffer> Buff; - MemoryBuffer::getFile(Path, Buff); - return ObjectFile::createObjectFile(Buff.take()); -} - -static std::string getDarwinDWARFResourceForModule(const std::string &Path) { - StringRef Basename = sys::path::filename(Path); - const std::string &DSymDirectory = Path + ".dSYM"; - SmallString<16> ResourceName = StringRef(DSymDirectory); - sys::path::append(ResourceName, "Contents", "Resources", "DWARF"); - sys::path::append(ResourceName, Basename); - return ResourceName.str(); -} - -static ModuleInfo *getOrCreateModuleInfo(const std::string &ModuleName) { - ModuleMapIter I = Modules.find(ModuleName); - if (I != Modules.end()) - return I->second; - - ObjectFile *Obj = getObjectFile(ModuleName); - ObjectFile *DbgObj = Obj; - if (Obj == 0) { - // Module name doesn't point to a valid object file. - Modules.insert(make_pair(ModuleName, (ModuleInfo*)0)); - return 0; - } - - DIContext *Context = 0; - bool IsLittleEndian; - if (getObjectEndianness(Obj, IsLittleEndian)) { - // On Darwin we may find DWARF in separate object file in - // resource directory. - if (isa<MachOObjectFile>(Obj)) { - const std::string &ResourceName = getDarwinDWARFResourceForModule( - ModuleName); - ObjectFile *ResourceObj = getObjectFile(ResourceName); - if (ResourceObj != 0) - DbgObj = ResourceObj; - } - Context = DIContext::getDWARFContext(DbgObj); - assert(Context); - } - - ModuleInfo *Info = new ModuleInfo(Obj, Context); - Modules.insert(make_pair(ModuleName, Info)); - return Info; -} - -#if !defined(_MSC_VER) -// Assume that __cxa_demangle is provided by libcxxabi (except for Windows). -extern "C" char *__cxa_demangle(const char *mangled_name, char *output_buffer, - size_t *length, int *status); -#endif - -static void printDILineInfo(DILineInfo LineInfo) { - // By default, DILineInfo contains "<invalid>" for function/filename it - // cannot fetch. We replace it to "??" to make our output closer to addr2line. - static const std::string kDILineInfoBadString = "<invalid>"; - static const std::string kSymbolizerBadString = "??"; - if (PrintFunctions) { - std::string FunctionName = LineInfo.getFunctionName(); - if (FunctionName == kDILineInfoBadString) - FunctionName = kSymbolizerBadString; -#if !defined(_MSC_VER) - if (Demangle) { - int status = 0; - char *DemangledName = __cxa_demangle( - FunctionName.c_str(), 0, 0, &status); - if (status == 0) { - FunctionName = DemangledName; - free(DemangledName); - } - } -#endif - outs() << FunctionName << "\n"; - } - std::string Filename = LineInfo.getFileName(); - if (Filename == kDILineInfoBadString) - Filename = kSymbolizerBadString; - outs() << Filename << - ":" << LineInfo.getLine() << - ":" << LineInfo.getColumn() << - "\n"; -} - -static void symbolize(std::string ModuleName, std::string ModuleOffsetStr) { - ModuleInfo *Info = getOrCreateModuleInfo(ModuleName); - uint64_t Offset = 0; - if (Info == 0 || - StringRef(ModuleOffsetStr).getAsInteger(0, Offset)) { - printDILineInfo(DILineInfo()); - } else if (PrintInlining) { - DIInliningInfo InlinedContext = Info->symbolizeInlinedCode(Offset); - uint32_t FramesNum = InlinedContext.getNumberOfFrames(); - assert(FramesNum > 0); - for (uint32_t i = 0; i < FramesNum; i++) { - DILineInfo LineInfo = InlinedContext.getFrame(i); - printDILineInfo(LineInfo); - } - } else { - DILineInfo LineInfo = Info->symbolizeCode(Offset); - printDILineInfo(LineInfo); - } - - outs() << "\n"; // Print extra empty line to mark the end of output. - outs().flush(); -} - -static bool parseModuleNameAndOffset(std::string &ModuleName, - std::string &ModuleOffsetStr) { - static const int kMaxInputStringLength = 1024; - static const char kDelimiters[] = " \n"; +ClDemangle("demangle", cl::init(true), cl::desc("Demangle function names")); + +static bool parseCommand(bool &IsData, std::string &ModuleName, + uint64_t &ModuleOffset) { + const char *kDataCmd = "DATA "; + const char *kCodeCmd = "CODE "; + const int kMaxInputStringLength = 1024; + const char kDelimiters[] = " \n"; char InputString[kMaxInputStringLength]; if (!fgets(InputString, sizeof(InputString), stdin)) return false; + IsData = false; ModuleName = ""; - ModuleOffsetStr = ""; + std::string ModuleOffsetStr = ""; + char *pos = InputString; + if (strncmp(pos, kDataCmd, strlen(kDataCmd)) == 0) { + IsData = true; + pos += strlen(kDataCmd); + } else if (strncmp(pos, kCodeCmd, strlen(kCodeCmd)) == 0) { + IsData = false; + pos += strlen(kCodeCmd); + } else { + // If no cmd, assume it's CODE. + IsData = false; + } // FIXME: Handle case when filename is given in quotes. - if (char *FilePath = strtok(InputString, kDelimiters)) { + if (char *FilePath = strtok(pos, kDelimiters)) { ModuleName = FilePath; - if (char *OffsetStr = strtok((char*)0, kDelimiters)) + if (char *OffsetStr = strtok((char *)0, kDelimiters)) ModuleOffsetStr = OffsetStr; } + if (StringRef(ModuleOffsetStr).getAsInteger(0, ModuleOffset)) + return false; return true; } @@ -308,15 +85,22 @@ int main(int argc, char **argv) { // Print stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); - llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. cl::ParseCommandLineOptions(argc, argv, "llvm symbolizer for compiler-rt\n"); - ToolInvocationPath = argv[0]; + LLVMSymbolizer::Options Opts(ClUseSymbolTable, ClPrintFunctions, + ClPrintInlining, ClDemangle); + LLVMSymbolizer Symbolizer(Opts); + bool IsData = false; std::string ModuleName; - std::string ModuleOffsetStr; - while (parseModuleNameAndOffset(ModuleName, ModuleOffsetStr)) { - symbolize(ModuleName, ModuleOffsetStr); + uint64_t ModuleOffset; + while (parseCommand(IsData, ModuleName, ModuleOffset)) { + std::string Result = + IsData ? Symbolizer.symbolizeData(ModuleName, ModuleOffset) + : Symbolizer.symbolizeCode(ModuleName, ModuleOffset); + outs() << Result << "\n"; + outs().flush(); } return 0; } diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index cfaaf863b2..75705154e4 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -19,15 +19,15 @@ #include "llvm/Analysis/Verifier.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/Config/config.h" -#include "llvm/Constants.h" -#include "llvm/DataLayout.h" -#include "llvm/DerivedTypes.h" -#include "llvm/LLVMContext.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/DerivedTypes.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" #include "llvm/Linker.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/SubtargetFeature.h" -#include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FormattedStream.h" @@ -47,6 +47,10 @@ using namespace llvm; static cl::opt<bool> +DisableOpt("disable-opt", cl::init(false), + cl::desc("Do not run any optimization passes")); + +static cl::opt<bool> DisableInline("disable-inlining", cl::init(false), cl::desc("Do not run the inliner pass")); @@ -371,16 +375,17 @@ bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, // Add an appropriate DataLayout instance for this module... passes.add(new DataLayout(*_target->getDataLayout())); - passes.add(new TargetTransformInfo(_target->getScalarTargetTransformInfo(), - _target->getVectorTargetTransformInfo())); + _target->addAnalysisPasses(passes); // 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()); @@ -388,6 +393,7 @@ bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, FunctionPassManager *codeGenPasses = new FunctionPassManager(mergedModule); codeGenPasses->add(new DataLayout(*_target->getDataLayout())); + _target->addAnalysisPasses(*codeGenPasses); formatted_raw_ostream Out(out); diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp index 5a388cbad6..ff67769192 100644 --- a/tools/lto/LTOModule.cpp +++ b/tools/lto/LTOModule.cpp @@ -16,8 +16,9 @@ #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/Triple.h" #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/Constants.h" -#include "llvm/LLVMContext.h" +#include "llvm/IR/Constants.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCParser/MCAsmParser.h" @@ -26,7 +27,6 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCTargetAsmParser.h" #include "llvm/MC/SubtargetFeature.h" -#include "llvm/Module.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Host.h" #include "llvm/Support/MemoryBuffer.h" @@ -320,8 +320,9 @@ MemoryBuffer *LTOModule::makeBuffer(const void *mem, size_t length) { } /// objcClassNameFromExpression - Get string that the data pointer points to. -bool LTOModule::objcClassNameFromExpression(Constant *c, std::string &name) { - if (ConstantExpr *ce = dyn_cast<ConstantExpr>(c)) { +bool +LTOModule::objcClassNameFromExpression(const Constant *c, std::string &name) { + if (const ConstantExpr *ce = dyn_cast<ConstantExpr>(c)) { Constant *op = ce->getOperand(0); if (GlobalVariable *gvn = dyn_cast<GlobalVariable>(op)) { Constant *cn = gvn->getInitializer(); @@ -337,8 +338,8 @@ bool LTOModule::objcClassNameFromExpression(Constant *c, std::string &name) { } /// addObjCClass - Parse i386/ppc ObjC class data structure. -void LTOModule::addObjCClass(GlobalVariable *clgv) { - ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer()); +void LTOModule::addObjCClass(const GlobalVariable *clgv) { + const ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer()); if (!c) return; // second slot in __OBJC,__class is pointer to superclass name @@ -374,8 +375,8 @@ void LTOModule::addObjCClass(GlobalVariable *clgv) { } /// addObjCCategory - Parse i386/ppc ObjC category data structure. -void LTOModule::addObjCCategory(GlobalVariable *clgv) { - ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer()); +void LTOModule::addObjCCategory(const GlobalVariable *clgv) { + const ConstantStruct *c = dyn_cast<ConstantStruct>(clgv->getInitializer()); if (!c) return; // second slot in __OBJC,__category is pointer to target class name @@ -399,7 +400,7 @@ void LTOModule::addObjCCategory(GlobalVariable *clgv) { } /// addObjCClassRef - Parse i386/ppc ObjC class list data structure. -void LTOModule::addObjCClassRef(GlobalVariable *clgv) { +void LTOModule::addObjCClassRef(const GlobalVariable *clgv) { std::string targetclassName; if (!objcClassNameFromExpression(clgv->getInitializer(), targetclassName)) return; @@ -419,7 +420,7 @@ void LTOModule::addObjCClassRef(GlobalVariable *clgv) { } /// addDefinedDataSymbol - Add a data symbol as defined to the list. -void LTOModule::addDefinedDataSymbol(GlobalValue *v) { +void LTOModule::addDefinedDataSymbol(const GlobalValue *v) { // Add to list of defined symbols. addDefinedSymbol(v, false); @@ -448,34 +449,34 @@ void LTOModule::addDefinedDataSymbol(GlobalValue *v) { // special case if this data blob is an ObjC class definition if (v->getSection().compare(0, 15, "__OBJC,__class,") == 0) { - if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { + if (const GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { addObjCClass(gv); } } // special case if this data blob is an ObjC category definition else if (v->getSection().compare(0, 18, "__OBJC,__category,") == 0) { - if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { + if (const GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { addObjCCategory(gv); } } // special case if this data blob is the list of referenced classes else if (v->getSection().compare(0, 18, "__OBJC,__cls_refs,") == 0) { - if (GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { + if (const GlobalVariable *gv = dyn_cast<GlobalVariable>(v)) { addObjCClassRef(gv); } } } /// addDefinedFunctionSymbol - Add a function symbol as defined to the list. -void LTOModule::addDefinedFunctionSymbol(Function *f) { +void LTOModule::addDefinedFunctionSymbol(const Function *f) { // add to list of defined symbols addDefinedSymbol(f, true); } /// addDefinedSymbol - Add a defined symbol to the list. -void LTOModule::addDefinedSymbol(GlobalValue *def, bool isFunction) { +void LTOModule::addDefinedSymbol(const GlobalValue *def, bool isFunction) { // ignore all llvm.* symbols if (def->getName().startswith("llvm.")) return; @@ -492,7 +493,7 @@ void LTOModule::addDefinedSymbol(GlobalValue *def, bool isFunction) { if (isFunction) { attr |= LTO_SYMBOL_PERMISSIONS_CODE; } else { - GlobalVariable *gv = dyn_cast<GlobalVariable>(def); + const GlobalVariable *gv = dyn_cast<GlobalVariable>(def); if (gv && gv->isConstant()) attr |= LTO_SYMBOL_PERMISSIONS_RODATA; else @@ -607,7 +608,8 @@ void LTOModule::addAsmGlobalSymbolUndef(const char *name) { /// addPotentialUndefinedSymbol - Add a symbol which isn't defined just yet to a /// list to be resolved later. -void LTOModule::addPotentialUndefinedSymbol(GlobalValue *decl, bool isFunc) { +void +LTOModule::addPotentialUndefinedSymbol(const GlobalValue *decl, bool isFunc) { // ignore all llvm.* symbols if (decl->getName().startswith("llvm.")) return; @@ -731,7 +733,8 @@ namespace { return Symbols.end(); } - RecordStreamer(MCContext &Context) : MCStreamer(Context) {} + RecordStreamer(MCContext &Context) + : MCStreamer(SK_RecordStreamer, Context) {} virtual void EmitInstruction(const MCInst &Inst) { // Scan for values. @@ -743,6 +746,9 @@ namespace { Symbol->setSection(*getCurrentSection()); markDefined(*Symbol); } + virtual void EmitDebugLabel(MCSymbol *Symbol) { + EmitLabel(Symbol); + } virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { // FIXME: should we handle aliases? markDefined(*Symbol); @@ -760,8 +766,13 @@ namespace { markDefined(*Symbol); } + virtual void EmitBundleAlignMode(unsigned AlignPow2) {} + virtual void EmitBundleLock(bool AlignToEnd) {} + virtual void EmitBundleUnlock() {} + // Noop calls. virtual void ChangeSection(const MCSection *Section) {} + virtual void InitToTextSection() {} virtual void InitSections() {} virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {} virtual void EmitThumbFunc(MCSymbol *Func) {} @@ -794,6 +805,10 @@ namespace { const MCSymbol *Label, unsigned PointerSize) {} virtual void FinishImpl() {} + + static bool classof(const MCStreamer *S) { + return S->getKind() == SK_RecordStreamer; + } }; } // end anonymous namespace diff --git a/tools/lto/LTOModule.h b/tools/lto/LTOModule.h index eca97c43c6..83f3a7def1 100644 --- a/tools/lto/LTOModule.h +++ b/tools/lto/LTOModule.h @@ -17,8 +17,8 @@ #include "llvm-c/lto.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/StringMap.h" +#include "llvm/IR/Module.h" #include "llvm/MC/MCContext.h" -#include "llvm/Module.h" #include "llvm/Target/Mangler.h" #include "llvm/Target/TargetMachine.h" #include <string> @@ -44,7 +44,7 @@ private: const char *name; uint32_t attributes; bool isFunction; - llvm::GlobalValue *symbol; + const llvm::GlobalValue *symbol; }; llvm::OwningPtr<llvm::Module> _module; @@ -138,16 +138,16 @@ private: /// addPotentialUndefinedSymbol - Add a symbol which isn't defined just yet /// to a list to be resolved later. - void addPotentialUndefinedSymbol(llvm::GlobalValue *dcl, bool isFunc); + void addPotentialUndefinedSymbol(const llvm::GlobalValue *dcl, bool isFunc); /// addDefinedSymbol - Add a defined symbol to the list. - void addDefinedSymbol(llvm::GlobalValue *def, bool isFunction); + void addDefinedSymbol(const llvm::GlobalValue *def, bool isFunction); /// addDefinedFunctionSymbol - Add a function symbol as defined to the list. - void addDefinedFunctionSymbol(llvm::Function *f); + void addDefinedFunctionSymbol(const llvm::Function *f); /// addDefinedDataSymbol - Add a data symbol as defined to the list. - void addDefinedDataSymbol(llvm::GlobalValue *v); + void addDefinedDataSymbol(const llvm::GlobalValue *v); /// addAsmGlobalSymbols - Add global symbols from module-level ASM to the /// defined or undefined lists. @@ -162,17 +162,17 @@ private: void addAsmGlobalSymbolUndef(const char *); /// addObjCClass - Parse i386/ppc ObjC class data structure. - void addObjCClass(llvm::GlobalVariable *clgv); + void addObjCClass(const llvm::GlobalVariable *clgv); /// addObjCCategory - Parse i386/ppc ObjC category data structure. - void addObjCCategory(llvm::GlobalVariable *clgv); + void addObjCCategory(const llvm::GlobalVariable *clgv); /// addObjCClassRef - Parse i386/ppc ObjC class list data structure. - void addObjCClassRef(llvm::GlobalVariable *clgv); + void addObjCClassRef(const llvm::GlobalVariable *clgv); /// objcClassNameFromExpression - Get string that the data pointer points /// to. - bool objcClassNameFromExpression(llvm::Constant* c, std::string &name); + bool objcClassNameFromExpression(const llvm::Constant* c, std::string &name); /// isTargetMatch - Returns 'true' if the memory buffer is for the specified /// target triple. diff --git a/tools/lto/Makefile b/tools/lto/Makefile index 3610fed03b..ab2e16e5fa 100644 --- a/tools/lto/Makefile +++ b/tools/lto/Makefile @@ -51,7 +51,7 @@ ifeq ($(HOST_OS),Darwin) endif # If we're doing an Apple-style build, add the LTO object path. - ifeq ($(RC_BUILDIT),YES) + ifeq ($(RC_XBS),YES) TempFile := $(shell mkdir -p ${OBJROOT}/dSYMs ; mktemp ${OBJROOT}/dSYMs/llvm-lto.XXXXXX) LLVMLibsOptions := $(LLVMLibsOptions) \ -Wl,-object_path_lto -Wl,$(TempFile) diff --git a/tools/macho-dump/macho-dump.cpp b/tools/macho-dump/macho-dump.cpp index 20deda9a0c..3bd3ecc8fd 100644 --- a/tools/macho-dump/macho-dump.cpp +++ b/tools/macho-dump/macho-dump.cpp @@ -337,7 +337,7 @@ static int DumpDataInCodeDataCommand(MachOObject &Obj, InMemoryStruct<macho::LinkeditDataLoadCommand> LLC; Obj.ReadLinkeditDataLoadCommand(LCI, LLC); if (!LLC) - return Error("unable to read segment load command"); + return Error("unable to read data-in-code load command"); outs() << " ('dataoff', " << LLC->DataOffset << ")\n" << " ('datasize', " << LLC->DataSize << ")\n" @@ -361,6 +361,31 @@ static int DumpDataInCodeDataCommand(MachOObject &Obj, return 0; } +static int DumpLinkerOptionsCommand(MachOObject &Obj, + const MachOObject::LoadCommandInfo &LCI) { + InMemoryStruct<macho::LinkerOptionsLoadCommand> 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<StringRef,StringRef> 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); @@ -390,6 +415,9 @@ static int DumpLoadCommand(MachOObject &Obj, unsigned Index) { case macho::LCT_DataInCode: Res = DumpDataInCodeDataCommand(Obj, LCI); break; + case macho::LCT_LinkerOptions: + Res = DumpLinkerOptionsCommand(Obj, LCI); + break; default: Warning("unknown load command: " + Twine(LCI.Command.Type)); break; diff --git a/tools/opt/AnalysisWrappers.cpp b/tools/opt/AnalysisWrappers.cpp index 6ba0fb00f6..55f544ff5e 100644 --- a/tools/opt/AnalysisWrappers.cpp +++ b/tools/opt/AnalysisWrappers.cpp @@ -18,7 +18,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Analysis/CallGraph.h" -#include "llvm/Module.h" +#include "llvm/IR/Module.h" #include "llvm/Pass.h" #include "llvm/Support/CallSite.h" #include "llvm/Support/raw_ostream.h" diff --git a/tools/opt/CMakeLists.txt b/tools/opt/CMakeLists.txt index 32de6d4060..cf5e5a83cf 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 ipo vectorize) +set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} bitreader asmparser bitwriter instrumentation scalaropts objcarcopts ipo vectorize) add_llvm_tool(opt AnalysisWrappers.cpp diff --git a/tools/opt/GraphPrinters.cpp b/tools/opt/GraphPrinters.cpp index 472fe07f21..f271966d10 100644 --- a/tools/opt/GraphPrinters.cpp +++ b/tools/opt/GraphPrinters.cpp @@ -14,81 +14,10 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/Dominators.h" #include "llvm/Pass.h" -#include "llvm/Support/GraphWriter.h" -#include "llvm/Support/ToolOutputFile.h" -#include "llvm/Value.h" -using namespace llvm; - -template<typename GraphType> -static void WriteGraphToFile(raw_ostream &O, const std::string &GraphName, - const GraphType >) { - std::string Filename = GraphName + ".dot"; - O << "Writing '" << Filename << "'..."; - std::string ErrInfo; - tool_output_file F(Filename.c_str(), ErrInfo); - - if (ErrInfo.empty()) { - WriteGraph(F.os(), GT); - F.os().close(); - if (!F.os().has_error()) { - O << "\n"; - F.keep(); - return; - } - } - O << " error opening file for writing!\n"; - F.os().clear_error(); -} - - -//===----------------------------------------------------------------------===// -// Call Graph Printer -//===----------------------------------------------------------------------===// - -namespace llvm { - template<> - struct DOTGraphTraits<CallGraph*> : public DefaultDOTGraphTraits { - - DOTGraphTraits (bool isSimple=false) : DefaultDOTGraphTraits(isSimple) {} - - static std::string getGraphName(CallGraph *F) { - return "Call Graph"; - } - static std::string getNodeLabel(CallGraphNode *Node, CallGraph *Graph) { - if (Node->getFunction()) - return ((Value*)Node->getFunction())->getName(); - return "external node"; - } - }; -} - - -namespace { - struct CallGraphPrinter : public ModulePass { - static char ID; // Pass ID, replacement for typeid - CallGraphPrinter() : ModulePass(ID) {} - - virtual bool runOnModule(Module &M) { - WriteGraphToFile(llvm::errs(), "callgraph", &getAnalysis<CallGraph>()); - return false; - } - - void print(raw_ostream &OS, const llvm::Module*) const {} - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.addRequired<CallGraph>(); - AU.setPreservesAll(); - } - }; -} - -char CallGraphPrinter::ID = 0; -static RegisterPass<CallGraphPrinter> P2("dot-callgraph", - "Print Call Graph to 'dot' file"); +using namespace llvm; //===----------------------------------------------------------------------===// // DomInfoPrinter Pass diff --git a/tools/opt/LLVMBuild.txt b/tools/opt/LLVMBuild.txt index b174431e04..a866d12a26 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 all-targets +required_libraries = AsmParser BitReader BitWriter IPO Instrumentation Scalar ObjCARC all-targets diff --git a/tools/opt/Makefile b/tools/opt/Makefile index ee7e1cf796..79ed815dce 100644 --- a/tools/opt/Makefile +++ b/tools/opt/Makefile @@ -9,6 +9,6 @@ LEVEL := ../.. TOOLNAME := opt -LINK_COMPONENTS := bitreader bitwriter asmparser instrumentation scalaropts ipo vectorize all-targets +LINK_COMPONENTS := bitreader bitwriter asmparser instrumentation scalaropts objcarcopts ipo vectorize all-targets include $(LEVEL)/Makefile.common diff --git a/tools/opt/PrintSCC.cpp b/tools/opt/PrintSCC.cpp index be45ac1e4d..a502fa743c 100644 --- a/tools/opt/PrintSCC.cpp +++ b/tools/opt/PrintSCC.cpp @@ -27,7 +27,7 @@ #include "llvm/ADT/SCCIterator.h" #include "llvm/Analysis/CallGraph.h" -#include "llvm/Module.h" +#include "llvm/IR/Module.h" #include "llvm/Pass.h" #include "llvm/Support/CFG.h" #include "llvm/Support/raw_ostream.h" diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 8e88e3aee2..81a2de2d55 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -12,23 +12,23 @@ // //===----------------------------------------------------------------------===// -#include "llvm/LLVMContext.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/ADT/StringSet.h" #include "llvm/ADT/Triple.h" #include "llvm/Analysis/CallGraph.h" +#include "llvm/Analysis/CallGraphSCCPass.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/RegionPass.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Assembly/PrintModulePass.h" #include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/CallGraphSCCPass.h" #include "llvm/CodeGen/CommandFlags.h" -#include "llvm/DataLayout.h" #include "llvm/DebugInfo.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/IR/Module.h" +#include "llvm/LinkAllIR.h" #include "llvm/LinkAllPasses.h" -#include "llvm/LinkAllVMCore.h" #include "llvm/MC/SubtargetFeature.h" -#include "llvm/Module.h" #include "llvm/PassManager.h" #include "llvm/Support/Debug.h" #include "llvm/Support/IRReader.h" @@ -523,16 +523,11 @@ CodeGenOpt::Level GetCodeGenOptLevel() { } // Returns the TargetMachine instance or zero if no triple is provided. -static TargetMachine* GetTargetMachine(std::string TripleStr) { - if (TripleStr.empty()) - return 0; - - // Get the target specific parser. +static TargetMachine* GetTargetMachine(Triple TheTriple) { std::string Error; - Triple TheTriple(Triple::normalize(TargetTriple)); - const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, Error); + // Some modules don't specify a triple, and this is okay. if (!TheTarget) { return 0; } @@ -572,6 +567,7 @@ int main(int argc, char **argv) { PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); initializeScalarOpts(Registry); + initializeObjCARCOpts(Registry); initializeVectorization(Registry); initializeIPO(Registry); initializeAnalysis(Registry); @@ -655,11 +651,15 @@ int main(int argc, char **argv) { if (TD) Passes.add(TD); - std::auto_ptr<TargetMachine> TM(GetTargetMachine(TargetTriple)); - if (TM.get()) { - Passes.add(new TargetTransformInfo(TM->getScalarTargetTransformInfo(), - TM->getVectorTargetTransformInfo())); - } + Triple ModuleTriple(M->getTargetTriple()); + TargetMachine *Machine = 0; + if (ModuleTriple.getArch()) + Machine = GetTargetMachine(Triple(ModuleTriple)); + std::auto_ptr<TargetMachine> TM(Machine); + + // Add internal analysis passes from the target machine. + if (TM.get()) + TM->addAnalysisPasses(Passes); OwningPtr<FunctionPassManager> FPasses; if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { |