aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/CMakeLists.txt6
-rw-r--r--tools/LLVMBuild.txt2
-rw-r--r--tools/Makefile8
-rw-r--r--tools/bugpoint-passes/TestPasses.cpp10
-rw-r--r--tools/bugpoint/BugDriver.cpp6
-rw-r--r--tools/bugpoint/BugDriver.h2
-rw-r--r--tools/bugpoint/CrashDebugger.cpp20
-rw-r--r--tools/bugpoint/ExtractFunction.cpp24
-rw-r--r--tools/bugpoint/ListReducer.h6
-rw-r--r--tools/bugpoint/Miscompilation.cpp14
-rw-r--r--tools/bugpoint/OptimizerDriver.cpp12
-rw-r--r--tools/bugpoint/ToolRunner.cpp4
-rw-r--r--tools/bugpoint/ToolRunner.h2
-rw-r--r--tools/bugpoint/bugpoint.cpp6
-rw-r--r--tools/gold/gold-plugin.cpp19
-rw-r--r--tools/llc/llc.cpp249
-rw-r--r--tools/lli/CMakeLists.txt4
-rw-r--r--tools/lli/LLVMBuild.txt2
-rw-r--r--tools/lli/Makefile2
-rw-r--r--tools/lli/RecordingMemoryManager.cpp16
-rw-r--r--tools/lli/RecordingMemoryManager.h5
-rw-r--r--tools/lli/RemoteTarget.cpp10
-rw-r--r--tools/lli/RemoteTarget.h8
-rw-r--r--tools/lli/lli.cpp271
-rw-r--r--tools/llvm-ar/CMakeLists.txt1
-rw-r--r--tools/llvm-ar/Makefile1
-rw-r--r--tools/llvm-ar/llvm-ar.cpp213
-rw-r--r--tools/llvm-as/CMakeLists.txt1
-rw-r--r--tools/llvm-as/llvm-as.cpp8
-rw-r--r--tools/llvm-bcanalyzer/CMakeLists.txt1
-rw-r--r--tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp7
-rw-r--r--tools/llvm-config/Makefile2
-rw-r--r--tools/llvm-diff/DiffConsumer.cpp5
-rw-r--r--tools/llvm-diff/DiffConsumer.h5
-rw-r--r--tools/llvm-diff/DiffLog.cpp3
-rw-r--r--tools/llvm-diff/DifferenceEngine.cpp12
-rw-r--r--tools/llvm-diff/DifferenceEngine.h5
-rw-r--r--tools/llvm-diff/llvm-diff.cpp10
-rw-r--r--tools/llvm-dis/CMakeLists.txt1
-rw-r--r--tools/llvm-dis/llvm-dis.cpp14
-rw-r--r--tools/llvm-dwarfdump/llvm-dwarfdump.cpp55
-rw-r--r--tools/llvm-extract/llvm-extract.cpp69
-rw-r--r--tools/llvm-jitlistener/CMakeLists.txt20
-rw-r--r--tools/llvm-jitlistener/LLVMBuild.txt22
-rw-r--r--tools/llvm-jitlistener/Makefile27
-rw-r--r--tools/llvm-jitlistener/llvm-jitlistener.cpp207
-rw-r--r--tools/llvm-link/llvm-link.cpp12
-rw-r--r--tools/llvm-mc/Disassembler.cpp180
-rw-r--r--tools/llvm-mc/Disassembler.h5
-rw-r--r--tools/llvm-mc/llvm-mc.cpp74
-rw-r--r--tools/llvm-mcmarkup/CMakeLists.txt5
-rw-r--r--tools/llvm-mcmarkup/LLVMBuild.txt22
-rw-r--r--tools/llvm-mcmarkup/Makefile17
-rw-r--r--tools/llvm-mcmarkup/llvm-mcmarkup.cpp225
-rw-r--r--tools/llvm-nm/llvm-nm.cpp53
-rw-r--r--tools/llvm-objdump/CMakeLists.txt2
-rw-r--r--tools/llvm-objdump/COFFDump.cpp355
-rw-r--r--tools/llvm-objdump/ELFDump.cpp89
-rw-r--r--tools/llvm-objdump/MachODump.cpp59
-rw-r--r--tools/llvm-objdump/llvm-objdump.cpp85
-rw-r--r--tools/llvm-objdump/llvm-objdump.h11
-rw-r--r--tools/llvm-prof/llvm-prof.cpp16
-rw-r--r--tools/llvm-ranlib/CMakeLists.txt1
-rw-r--r--tools/llvm-ranlib/Makefile1
-rw-r--r--tools/llvm-ranlib/llvm-ranlib.cpp67
-rw-r--r--tools/llvm-readobj/llvm-readobj.cpp220
-rw-r--r--tools/llvm-rtdyld/llvm-rtdyld.cpp17
-rw-r--r--tools/llvm-size/llvm-size.cpp2
-rw-r--r--tools/llvm-stress/llvm-stress.cpp24
-rw-r--r--tools/llvm-symbolizer/CMakeLists.txt13
-rw-r--r--tools/llvm-symbolizer/Makefile17
-rw-r--r--tools/llvm-symbolizer/llvm-symbolizer.cpp322
-rw-r--r--tools/lto/CMakeLists.txt3
-rw-r--r--tools/lto/LTOCodeGenerator.cpp64
-rw-r--r--tools/lto/LTOCodeGenerator.h6
-rw-r--r--tools/lto/LTODisassembler.cpp26
-rw-r--r--tools/lto/LTOModule.cpp75
-rw-r--r--tools/lto/LTOModule.h28
-rw-r--r--tools/lto/Makefile7
-rw-r--r--tools/lto/lto.cpp5
-rw-r--r--tools/lto/lto.exports3
-rw-r--r--tools/opt/AnalysisWrappers.cpp4
-rw-r--r--tools/opt/CMakeLists.txt2
-rw-r--r--tools/opt/GraphPrinters.cpp6
-rw-r--r--tools/opt/LLVMBuild.txt2
-rw-r--r--tools/opt/Makefile2
-rw-r--r--tools/opt/PrintSCC.cpp6
-rw-r--r--tools/opt/opt.cpp129
88 files changed, 2401 insertions, 1258 deletions
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 1bfc2fe..144e8ec 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -31,11 +31,17 @@ add_subdirectory(llvm-objdump)
add_subdirectory(llvm-readobj)
add_subdirectory(llvm-rtdyld)
add_subdirectory(llvm-dwarfdump)
+if( LLVM_USE_INTEL_JITEVENTS )
+ add_subdirectory(llvm-jitlistener)
+endif( LLVM_USE_INTEL_JITEVENTS )
add_subdirectory(bugpoint)
add_subdirectory(bugpoint-passes)
add_subdirectory(llvm-bcanalyzer)
add_subdirectory(llvm-stress)
+add_subdirectory(llvm-mcmarkup)
+
+add_subdirectory(llvm-symbolizer)
if( NOT WIN32 )
add_subdirectory(lto)
diff --git a/tools/LLVMBuild.txt b/tools/LLVMBuild.txt
index df4aa9f..25aa177 100644
--- a/tools/LLVMBuild.txt
+++ b/tools/LLVMBuild.txt
@@ -16,7 +16,7 @@
;===------------------------------------------------------------------------===;
[common]
-subdirectories = bugpoint llc lli llvm-ar llvm-as llvm-bcanalyzer llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-link llvm-mc llvm-nm llvm-objdump llvm-prof llvm-ranlib llvm-rtdyld llvm-size macho-dump opt
+subdirectories = bugpoint llc lli llvm-ar llvm-as llvm-bcanalyzer llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-jitlistener llvm-link llvm-mc llvm-nm llvm-objdump llvm-prof llvm-ranlib llvm-rtdyld llvm-size macho-dump opt llvm-mcmarkup
[component_0]
type = Group
diff --git a/tools/Makefile b/tools/Makefile
index 2b4b9b7..c405868 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -34,7 +34,13 @@ PARALLEL_DIRS := opt llvm-as llvm-dis \
bugpoint llvm-bcanalyzer \
llvm-diff macho-dump llvm-objdump llvm-readobj \
llvm-rtdyld llvm-dwarfdump llvm-cov \
- llvm-size llvm-stress
+ llvm-size llvm-stress llvm-mcmarkup \
+ llvm-symbolizer
+
+# If Intel JIT Events support is configured, build an extra tool to test it.
+ifeq ($(USE_INTEL_JITEVENTS), 1)
+ PARALLEL_DIRS += llvm-jitlistener
+endif
# Let users override the set of tools to build from the command line.
ifdef ONLY_TOOLS
diff --git a/tools/bugpoint-passes/TestPasses.cpp b/tools/bugpoint-passes/TestPasses.cpp
index 1535b03..118c98a 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/Instructions.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/Pass.h"
-#include "llvm/Type.h"
-#include "llvm/Support/InstVisitor.h"
using namespace llvm;
diff --git a/tools/bugpoint/BugDriver.cpp b/tools/bugpoint/BugDriver.cpp
index 21636ea..cede4ac 100644
--- a/tools/bugpoint/BugDriver.cpp
+++ b/tools/bugpoint/BugDriver.cpp
@@ -15,15 +15,15 @@
#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/IRReader.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/IRReader.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Host.h"
#include <memory>
using namespace llvm;
diff --git a/tools/bugpoint/BugDriver.h b/tools/bugpoint/BugDriver.h
index cc78489..2b621ec 100644
--- a/tools/bugpoint/BugDriver.h
+++ b/tools/bugpoint/BugDriver.h
@@ -18,8 +18,8 @@
#include "llvm/ADT/ValueMap.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
-#include <vector>
#include <string>
+#include <vector>
namespace llvm {
diff --git a/tools/bugpoint/CrashDebugger.cpp b/tools/bugpoint/CrashDebugger.cpp
index aed16f4..ed211a6 100644
--- a/tools/bugpoint/CrashDebugger.cpp
+++ b/tools/bugpoint/CrashDebugger.cpp
@@ -12,22 +12,22 @@
//===----------------------------------------------------------------------===//
#include "BugDriver.h"
-#include "ToolRunner.h"
#include "ListReducer.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
-#include "llvm/Pass.h"
-#include "llvm/PassManager.h"
-#include "llvm/ValueSymbolTable.h"
+#include "ToolRunner.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/Analysis/Verifier.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"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileUtilities.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Cloning.h"
-#include "llvm/Support/FileUtilities.h"
-#include "llvm/Support/CommandLine.h"
#include <set>
using namespace llvm;
diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp
index 888d2c8..bb27767 100644
--- a/tools/bugpoint/ExtractFunction.cpp
+++ b/tools/bugpoint/ExtractFunction.cpp
@@ -13,25 +13,25 @@
//===----------------------------------------------------------------------===//
#include "BugDriver.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
-#include "llvm/PassManager.h"
-#include "llvm/Pass.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Assembly/Writer.h"
-#include "llvm/Transforms/IPO.h"
-#include "llvm/Transforms/Scalar.h"
-#include "llvm/Transforms/Utils/Cloning.h"
-#include "llvm/Transforms/Utils/CodeExtractor.h"
-#include "llvm/Target/TargetData.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"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileUtilities.h"
-#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Transforms/Utils/CodeExtractor.h"
#include <set>
using namespace llvm;
diff --git a/tools/bugpoint/ListReducer.h b/tools/bugpoint/ListReducer.h
index bd1c5da..8083e2d 100644
--- a/tools/bugpoint/ListReducer.h
+++ b/tools/bugpoint/ListReducer.h
@@ -15,11 +15,11 @@
#ifndef BUGPOINT_LIST_REDUCER_H
#define BUGPOINT_LIST_REDUCER_H
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/ErrorHandling.h"
-#include <vector>
-#include <cstdlib>
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
+#include <cstdlib>
+#include <vector>
namespace llvm {
diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp
index 82a3a86..c676a05 100644
--- a/tools/bugpoint/Miscompilation.cpp
+++ b/tools/bugpoint/Miscompilation.cpp
@@ -15,17 +15,17 @@
#include "BugDriver.h"
#include "ListReducer.h"
#include "ToolRunner.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Instructions.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Config/config.h" // for HAVE_LINK_R
+#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/Analysis/Verifier.h"
-#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileUtilities.h"
-#include "llvm/Config/config.h" // for HAVE_LINK_R
+#include "llvm/Transforms/Utils/Cloning.h"
using namespace llvm;
namespace llvm {
diff --git a/tools/bugpoint/OptimizerDriver.cpp b/tools/bugpoint/OptimizerDriver.cpp
index fb090ee..87dc9f3 100644
--- a/tools/bugpoint/OptimizerDriver.cpp
+++ b/tools/bugpoint/OptimizerDriver.cpp
@@ -16,18 +16,18 @@
//===----------------------------------------------------------------------===//
#include "BugDriver.h"
-#include "llvm/Module.h"
-#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Bitcode/ReaderWriter.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Support/FileUtilities.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Module.h"
+#include "llvm/PassManager.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
+#include "llvm/Support/SystemUtils.h"
+#include "llvm/Support/ToolOutputFile.h"
#define DONT_GET_PLUGIN_LOADER_OPTION
#include "llvm/Support/PluginLoader.h"
diff --git a/tools/bugpoint/ToolRunner.cpp b/tools/bugpoint/ToolRunner.cpp
index d975d68..e7d3978 100644
--- a/tools/bugpoint/ToolRunner.cpp
+++ b/tools/bugpoint/ToolRunner.cpp
@@ -13,12 +13,12 @@
#define DEBUG_TYPE "toolrunner"
#include "ToolRunner.h"
-#include "llvm/Support/Program.h"
+#include "llvm/Config/config.h" // for HAVE_LINK_R
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FileUtilities.h"
+#include "llvm/Support/Program.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Config/config.h" // for HAVE_LINK_R
#include <fstream>
#include <sstream>
using namespace llvm;
diff --git a/tools/bugpoint/ToolRunner.h b/tools/bugpoint/ToolRunner.h
index 7b93394..bb83ce4 100644
--- a/tools/bugpoint/ToolRunner.h
+++ b/tools/bugpoint/ToolRunner.h
@@ -20,8 +20,8 @@
#include "llvm/ADT/Triple.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/SystemUtils.h"
#include <exception>
#include <vector>
diff --git a/tools/bugpoint/bugpoint.cpp b/tools/bugpoint/bugpoint.cpp
index 8f15b02..3049421 100644
--- a/tools/bugpoint/bugpoint.cpp
+++ b/tools/bugpoint/bugpoint.cpp
@@ -15,18 +15,18 @@
#include "BugDriver.h"
#include "ToolRunner.h"
+#include "llvm/IR/LLVMContext.h"
#include "llvm/LinkAllPasses.h"
-#include "llvm/LLVMContext.h"
+#include "llvm/LinkAllVMCore.h"
#include "llvm/PassManager.h"
-#include "llvm/Support/PassNameParser.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/PassNameParser.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/Valgrind.h"
-#include "llvm/LinkAllVMCore.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
//Enable this macro to debug bugpoint itself.
diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp
index 9c17da6..40f5fd6 100644
--- a/tools/gold/gold-plugin.cpp
+++ b/tools/gold/gold-plugin.cpp
@@ -14,17 +14,14 @@
#include "llvm/Config/config.h" // plugin-api.h requires HAVE_STDINT_H
#include "plugin-api.h"
-
#include "llvm-c/lto.h"
-
#include "llvm/ADT/OwningPtr.h"
-#include "llvm/Support/system_error.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/Errno.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
-
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Support/system_error.h"
#include <cerrno>
#include <cstdlib>
#include <cstring>
@@ -378,9 +375,6 @@ static ld_plugin_status all_symbols_read_hook(void) {
}
}
- // If we don't preserve any symbols, libLTO will assume that all symbols are
- // needed. Keep all symbols unless we're producing a final executable.
- bool anySymbolsPreserved = false;
for (std::list<claimed_file>::iterator I = Modules.begin(),
E = Modules.end(); I != E; ++I) {
if (I->syms.empty())
@@ -389,7 +383,6 @@ static ld_plugin_status all_symbols_read_hook(void) {
for (unsigned i = 0, e = I->syms.size(); i != e; i++) {
if (I->syms[i].resolution == LDPR_PREVAILING_DEF) {
lto_codegen_add_must_preserve_symbol(code_gen, I->syms[i].name);
- anySymbolsPreserved = true;
if (options::generate_api_file)
api_file << I->syms[i].name << "\n";
@@ -400,12 +393,6 @@ static ld_plugin_status all_symbols_read_hook(void) {
if (options::generate_api_file)
api_file.close();
- if (!anySymbolsPreserved) {
- // All of the IL is unnecessary!
- lto_codegen_dispose(code_gen);
- return LDPS_OK;
- }
-
lto_codegen_set_pic_model(code_gen, output_type);
lto_codegen_set_debug_model(code_gen, LTO_DEBUG_MODEL_DWARF);
if (!options::mcpu.empty())
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp
index 81f297f..aa65223 100644
--- a/tools/llc/llc.cpp
+++ b/tools/llc/llc.cpp
@@ -13,28 +13,29 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
-#include "llvm/PassManager.h"
-#include "llvm/Pass.h"
+#include "llvm/IR/LLVMContext.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Assembly/PrintModulePass.h"
-#include "llvm/Support/IRReader.h"
+#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
#include "llvm/CodeGen/LinkAllCodegenComponents.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Module.h"
#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/Pass.h"
+#include "llvm/PassManager.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/IRReader.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/Support/Host.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
-#include "llvm/Target/TargetData.h"
+#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Target/TargetLibraryInfo.h"
#include "llvm/Target/TargetMachine.h"
#include <memory>
@@ -50,6 +51,11 @@ InputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
static cl::opt<std::string>
OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));
+static cl::opt<unsigned>
+TimeCompilations("time-compilations", cl::Hidden, cl::init(1u),
+ cl::value_desc("N"),
+ cl::desc("Repeat compilation N times for timing"));
+
// Determine optimization level.
static cl::opt<char>
OptLevel("O",
@@ -62,216 +68,15 @@ OptLevel("O",
static cl::opt<std::string>
TargetTriple("mtriple", cl::desc("Override target triple for module"));
-static cl::opt<std::string>
-MArch("march", cl::desc("Architecture to generate code for (see --version)"));
-
-static cl::opt<std::string>
-MCPU("mcpu",
- cl::desc("Target a specific cpu type (-mcpu=help for details)"),
- cl::value_desc("cpu-name"),
- cl::init(""));
-
-static cl::list<std::string>
-MAttrs("mattr",
- cl::CommaSeparated,
- cl::desc("Target specific attributes (-mattr=help for details)"),
- cl::value_desc("a1,+a2,-a3,..."));
-
-static cl::opt<Reloc::Model>
-RelocModel("relocation-model",
- cl::desc("Choose relocation model"),
- cl::init(Reloc::Default),
- cl::values(
- clEnumValN(Reloc::Default, "default",
- "Target default relocation model"),
- clEnumValN(Reloc::Static, "static",
- "Non-relocatable code"),
- clEnumValN(Reloc::PIC_, "pic",
- "Fully relocatable, position independent code"),
- clEnumValN(Reloc::DynamicNoPIC, "dynamic-no-pic",
- "Relocatable external references, non-relocatable code"),
- clEnumValEnd));
-
-static cl::opt<llvm::CodeModel::Model>
-CMModel("code-model",
- cl::desc("Choose code model"),
- cl::init(CodeModel::Default),
- cl::values(clEnumValN(CodeModel::Default, "default",
- "Target default code model"),
- clEnumValN(CodeModel::Small, "small",
- "Small code model"),
- clEnumValN(CodeModel::Kernel, "kernel",
- "Kernel code model"),
- clEnumValN(CodeModel::Medium, "medium",
- "Medium code model"),
- clEnumValN(CodeModel::Large, "large",
- "Large code model"),
- clEnumValEnd));
-
-static cl::opt<bool>
-RelaxAll("mc-relax-all",
- cl::desc("When used with filetype=obj, "
- "relax all fixups in the emitted object file"));
-
-cl::opt<TargetMachine::CodeGenFileType>
-FileType("filetype", cl::init(TargetMachine::CGFT_AssemblyFile),
- cl::desc("Choose a file type (not all types are supported by all targets):"),
- cl::values(
- clEnumValN(TargetMachine::CGFT_AssemblyFile, "asm",
- "Emit an assembly ('.s') file"),
- clEnumValN(TargetMachine::CGFT_ObjectFile, "obj",
- "Emit a native object ('.o') file"),
- clEnumValN(TargetMachine::CGFT_Null, "null",
- "Emit nothing, for performance testing"),
- clEnumValEnd));
-
cl::opt<bool> NoVerify("disable-verify", cl::Hidden,
cl::desc("Do not verify input module"));
-cl::opt<bool> DisableDotLoc("disable-dot-loc", cl::Hidden,
- cl::desc("Do not use .loc entries"));
-
-cl::opt<bool> DisableCFI("disable-cfi", cl::Hidden,
- cl::desc("Do not use .cfi_* directives"));
-
-cl::opt<bool> EnableDwarfDirectory("enable-dwarf-directory", cl::Hidden,
- cl::desc("Use .file directives with an explicit directory."));
-
-static cl::opt<bool>
-DisableRedZone("disable-red-zone",
- cl::desc("Do not emit code that uses the red zone."),
- cl::init(false));
-
-static cl::opt<bool>
-EnableFPMAD("enable-fp-mad",
- cl::desc("Enable less precise MAD instructions to be generated"),
- cl::init(false));
-
-static cl::opt<bool>
-DisableFPElim("disable-fp-elim",
- cl::desc("Disable frame pointer elimination optimization"),
- cl::init(false));
-
-static cl::opt<bool>
-DisableFPElimNonLeaf("disable-non-leaf-fp-elim",
- cl::desc("Disable frame pointer elimination optimization for non-leaf funcs"),
- cl::init(false));
-
-static cl::opt<bool>
-EnableUnsafeFPMath("enable-unsafe-fp-math",
- cl::desc("Enable optimizations that may decrease FP precision"),
- cl::init(false));
-
-static cl::opt<bool>
-EnableNoInfsFPMath("enable-no-infs-fp-math",
- cl::desc("Enable FP math optimizations that assume no +-Infs"),
- cl::init(false));
-
-static cl::opt<bool>
-EnableNoNaNsFPMath("enable-no-nans-fp-math",
- cl::desc("Enable FP math optimizations that assume no NaNs"),
- cl::init(false));
-
-static cl::opt<bool>
-EnableHonorSignDependentRoundingFPMath("enable-sign-dependent-rounding-fp-math",
- cl::Hidden,
- cl::desc("Force codegen to assume rounding mode can change dynamically"),
- cl::init(false));
-
-static cl::opt<bool>
-GenerateSoftFloatCalls("soft-float",
- cl::desc("Generate software floating point library calls"),
- cl::init(false));
-
-static cl::opt<llvm::FloatABI::ABIType>
-FloatABIForCalls("float-abi",
- cl::desc("Choose float ABI type"),
- cl::init(FloatABI::Default),
- cl::values(
- clEnumValN(FloatABI::Default, "default",
- "Target default float ABI type"),
- clEnumValN(FloatABI::Soft, "soft",
- "Soft float ABI (implied by -soft-float)"),
- clEnumValN(FloatABI::Hard, "hard",
- "Hard float ABI (uses FP registers)"),
- clEnumValEnd));
-
-static cl::opt<llvm::FPOpFusion::FPOpFusionMode>
-FuseFPOps("fp-contract",
- cl::desc("Enable aggresive formation of fused FP ops"),
- cl::init(FPOpFusion::Standard),
- cl::values(
- clEnumValN(FPOpFusion::Fast, "fast",
- "Fuse FP ops whenever profitable"),
- clEnumValN(FPOpFusion::Standard, "on",
- "Only fuse 'blessed' FP ops."),
- clEnumValN(FPOpFusion::Strict, "off",
- "Only fuse FP ops when the result won't be effected."),
- clEnumValEnd));
-
-static cl::opt<bool>
-DontPlaceZerosInBSS("nozero-initialized-in-bss",
- cl::desc("Don't place zero-initialized symbols into bss section"),
- cl::init(false));
-
-static cl::opt<bool>
+cl::opt<bool>
DisableSimplifyLibCalls("disable-simplify-libcalls",
- cl::desc("Disable simplify-libcalls"),
- cl::init(false));
-
-static cl::opt<bool>
-EnableGuaranteedTailCallOpt("tailcallopt",
- cl::desc("Turn fastcc calls into tail calls by (potentially) changing ABI."),
- cl::init(false));
-
-static cl::opt<bool>
-DisableTailCalls("disable-tail-calls",
- cl::desc("Never emit tail calls"),
- cl::init(false));
-
-static cl::opt<unsigned>
-OverrideStackAlignment("stack-alignment",
- cl::desc("Override default stack alignment"),
- cl::init(0));
-
-static cl::opt<bool>
-EnableRealignStack("realign-stack",
- cl::desc("Realign stack if needed"),
- cl::init(true));
+ cl::desc("Disable simplify-libcalls"),
+ cl::init(false));
-static cl::opt<std::string>
-TrapFuncName("trap-func", cl::Hidden,
- cl::desc("Emit a call to trap function rather than a trap instruction"),
- cl::init(""));
-
-static cl::opt<bool>
-EnablePIE("enable-pie",
- cl::desc("Assume the creation of a position independent executable."),
- cl::init(false));
-
-static cl::opt<bool>
-SegmentedStacks("segmented-stacks",
- cl::desc("Use segmented stacks if possible."),
- cl::init(false));
-
-static cl::opt<bool>
-UseInitArray("use-init-array",
- cl::desc("Use .init_array instead of .ctors."),
- cl::init(false));
-
-static cl::opt<std::string> StopAfter("stop-after",
- cl::desc("Stop compilation after a specific pass"),
- cl::value_desc("pass-name"),
- cl::init(""));
-static cl::opt<std::string> StartAfter("start-after",
- cl::desc("Resume compilation after a specific pass"),
- cl::value_desc("pass-name"),
- cl::init(""));
-
-static cl::opt<unsigned>
-SSPBufferSize("stack-protector-buffer-size", cl::init(8),
- cl::desc("Lower bound for a buffer to be considered for "
- "stack protection"));
+static int compileModule(char**, LLVMContext&);
// GetFileNameRoot - Helper function to get the basename of a filename.
static inline std::string
@@ -383,6 +188,15 @@ int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");
+ // Compile the module TimeCompilations times to give better compile time
+ // metrics.
+ for (unsigned I = TimeCompilations; I; --I)
+ if (int RetVal = compileModule(argv, Context))
+ return RetVal;
+ return 0;
+}
+
+static int compileModule(char **argv, LLVMContext &Context) {
// Load the module to be compiled...
SMDiagnostic Err;
std::auto_ptr<Module> M;
@@ -505,11 +319,14 @@ int main(int argc, char **argv) {
TLI->disableAllFunctions();
PM.add(TLI);
+ // 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 TargetData *TD = Target.getTargetData())
- PM.add(new TargetData(*TD));
+ if (const DataLayout *TD = Target.getDataLayout())
+ PM.add(new DataLayout(*TD));
else
- PM.add(new TargetData(mod));
+ PM.add(new DataLayout(mod));
// Override default to generate verbose assembly.
Target.setAsmVerbosityDefault(true);
diff --git a/tools/lli/CMakeLists.txt b/tools/lli/CMakeLists.txt
index 68cb921..ed479f5 100644
--- a/tools/lli/CMakeLists.txt
+++ b/tools/lli/CMakeLists.txt
@@ -1,7 +1,5 @@
-link_directories( ${LLVM_INTEL_JITEVENTS_LIBDIR} )
-
-set(LLVM_LINK_COMPONENTS mcjit jit interpreter nativecodegen bitreader asmparser selectiondag)
+set(LLVM_LINK_COMPONENTS mcjit jit interpreter nativecodegen bitreader asmparser selectiondag native)
if( LLVM_USE_OPROFILE )
set(LLVM_LINK_COMPONENTS
diff --git a/tools/lli/LLVMBuild.txt b/tools/lli/LLVMBuild.txt
index 4eb82bd..36ceb39 100644
--- a/tools/lli/LLVMBuild.txt
+++ b/tools/lli/LLVMBuild.txt
@@ -19,4 +19,4 @@
type = Tool
name = lli
parent = Tools
-required_libraries = AsmParser BitReader Interpreter JIT MCJIT NativeCodeGen SelectionDAG
+required_libraries = AsmParser BitReader Interpreter JIT MCJIT NativeCodeGen SelectionDAG Native
diff --git a/tools/lli/Makefile b/tools/lli/Makefile
index 100fc2e..31f3ab8 100644
--- a/tools/lli/Makefile
+++ b/tools/lli/Makefile
@@ -12,7 +12,7 @@ TOOLNAME := lli
include $(LEVEL)/Makefile.config
-LINK_COMPONENTS := mcjit jit interpreter nativecodegen bitreader asmparser selectiondag
+LINK_COMPONENTS := mcjit jit interpreter nativecodegen bitreader asmparser selectiondag native
# If Intel JIT Events support is confiured, link against the LLVM Intel JIT
# Events interface library
diff --git a/tools/lli/RecordingMemoryManager.cpp b/tools/lli/RecordingMemoryManager.cpp
index 9e1cff5..75cb978 100644
--- a/tools/lli/RecordingMemoryManager.cpp
+++ b/tools/lli/RecordingMemoryManager.cpp
@@ -28,7 +28,8 @@ allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) {
}
uint8_t *RecordingMemoryManager::
-allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) {
+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.
@@ -81,7 +82,20 @@ void RecordingMemoryManager::endExceptionTable(const Function *F, uint8_t *Table
void RecordingMemoryManager::deallocateExceptionTable(void *ET) {
llvm_unreachable("Unexpected!");
}
+
+static int jit_noop() {
+ return 0;
+}
+
void *RecordingMemoryManager::getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure) {
+ // We should not invoke parent's ctors/dtors from generated main()!
+ // On Mingw and Cygwin, the symbol __main is resolved to
+ // callee's(eg. tools/lli) one, to invoke wrong duplicated ctors
+ // (and register wrong callee's dtors with atexit(3)).
+ // We expect ExecutionEngine::runStaticConstructorsDestructors()
+ // is called before ExecutionEngine::runFunctionAsMain() is called.
+ if (Name == "__main") return (void*)(intptr_t)&jit_noop;
+
return NULL;
}
diff --git a/tools/lli/RecordingMemoryManager.h b/tools/lli/RecordingMemoryManager.h
index 1590235..20fd0c2 100644
--- a/tools/lli/RecordingMemoryManager.h
+++ b/tools/lli/RecordingMemoryManager.h
@@ -47,10 +47,13 @@ public:
unsigned SectionID);
uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID);
+ unsigned SectionID, bool IsReadOnly);
void *getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure = true);
+
+ bool applyPermissions(std::string *ErrMsg) { return false; }
+
// The following obsolete JITMemoryManager calls are stubbed out for
// this model.
void setMemoryWritable();
diff --git a/tools/lli/RemoteTarget.cpp b/tools/lli/RemoteTarget.cpp
index 918f157..212bdfd 100644
--- a/tools/lli/RemoteTarget.cpp
+++ b/tools/lli/RemoteTarget.cpp
@@ -13,9 +13,9 @@
//===----------------------------------------------------------------------===//
#include "RemoteTarget.h"
-#include <llvm/ADT/StringRef.h>
-#include <llvm/Support/DataTypes.h>
-#include <llvm/Support/Memory.h>
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Memory.h"
#include <stdlib.h>
#include <string>
using namespace llvm;
@@ -36,13 +36,13 @@ bool RemoteTarget::allocateSpace(size_t Size, unsigned Alignment,
bool RemoteTarget::loadData(uint64_t Address, const void *Data, size_t Size) {
memcpy ((void*)Address, Data, Size);
- sys::MemoryBlock Mem((void*)Address, Size);
- sys::Memory::setExecutable(Mem, &ErrorMsg);
return false;
}
bool RemoteTarget::loadCode(uint64_t Address, const void *Data, size_t Size) {
memcpy ((void*)Address, Data, Size);
+ sys::MemoryBlock Mem((void*)Address, Size);
+ sys::Memory::setExecutable(Mem, &ErrorMsg);
return false;
}
diff --git a/tools/lli/RemoteTarget.h b/tools/lli/RemoteTarget.h
index c584526..b2a6d0e 100644
--- a/tools/lli/RemoteTarget.h
+++ b/tools/lli/RemoteTarget.h
@@ -15,10 +15,10 @@
#ifndef REMOTEPROCESS_H
#define REMOTEPROCESS_H
-#include <llvm/ADT/StringRef.h>
-#include <llvm/ADT/SmallVector.h>
-#include <llvm/Support/DataTypes.h>
-#include <llvm/Support/Memory.h>
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/Memory.h"
#include <stdlib.h>
#include <string>
diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp
index 4004b6c..332660f 100644
--- a/tools/lli/lli.cpp
+++ b/tools/lli/lli.cpp
@@ -14,11 +14,9 @@
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "lli"
+#include "llvm/IR/LLVMContext.h"
#include "RecordingMemoryManager.h"
#include "RemoteTarget.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
-#include "llvm/Type.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/CodeGen/LinkAllCodegenComponents.h"
@@ -28,32 +26,26 @@
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/ExecutionEngine/JITMemoryManager.h"
#include "llvm/ExecutionEngine/MCJIT.h"
+#include "llvm/ExecutionEngine/SectionMemoryManager.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"
+#include "llvm/Support/Format.h"
#include "llvm/Support/IRReader.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MathExtras.h"
+#include "llvm/Support/Memory.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Format.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
-#include "llvm/Support/Debug.h"
-#include "llvm/Support/DynamicLibrary.h"
-#include "llvm/Support/Memory.h"
+#include "llvm/Support/raw_ostream.h"
#include <cerrno>
-#ifdef __linux__
-// These includes used by LLIMCJITMemoryManager::getPointerToNamedFunction()
-// for Glibc trickery. Look comments in this function for more information.
-#ifdef HAVE_SYS_STAT_H
-#include <sys/stat.h>
-#endif
-#include <fcntl.h>
-#include <unistd.h>
-#endif
-
#ifdef __CYGWIN__
#include <cygwin/version.h>
#if defined(CYGWIN_VERSION_DLL_MAJOR) && CYGWIN_VERSION_DLL_MAJOR<1007
@@ -171,6 +163,23 @@ namespace {
cl::init(false));
cl::opt<bool>
+ GenerateSoftFloatCalls("soft-float",
+ cl::desc("Generate software floating point library calls"),
+ cl::init(false));
+
+ cl::opt<llvm::FloatABI::ABIType>
+ FloatABIForCalls("float-abi",
+ cl::desc("Choose float ABI type"),
+ cl::init(FloatABI::Default),
+ cl::values(
+ clEnumValN(FloatABI::Default, "default",
+ "Target default float ABI type"),
+ clEnumValN(FloatABI::Soft, "soft",
+ "Soft float ABI (implied by -soft-float)"),
+ clEnumValN(FloatABI::Hard, "hard",
+ "Hard float ABI (uses FP registers)"),
+ clEnumValEnd));
+ cl::opt<bool>
// In debug builds, make this default to true.
#ifdef NDEBUG
#define EMIT_DEBUG false
@@ -199,192 +208,6 @@ static void do_shutdown() {
#endif
}
-// Memory manager for MCJIT
-class LLIMCJITMemoryManager : public JITMemoryManager {
-public:
- SmallVector<sys::MemoryBlock, 16> AllocatedDataMem;
- SmallVector<sys::MemoryBlock, 16> AllocatedCodeMem;
- SmallVector<sys::MemoryBlock, 16> FreeCodeMem;
-
- LLIMCJITMemoryManager() { }
- ~LLIMCJITMemoryManager();
-
- virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID);
-
- virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID);
-
- virtual void *getPointerToNamedFunction(const std::string &Name,
- bool AbortOnFailure = true);
-
- // Invalidate instruction cache for code sections. Some platforms with
- // separate data cache and instruction cache require explicit cache flush,
- // otherwise JIT code manipulations (like resolved relocations) will get to
- // the data cache but not to the instruction cache.
- virtual void invalidateInstructionCache();
-
- // The MCJITMemoryManager doesn't use the following functions, so we don't
- // need implement them.
- virtual void setMemoryWritable() {
- llvm_unreachable("Unexpected call!");
- }
- virtual void setMemoryExecutable() {
- llvm_unreachable("Unexpected call!");
- }
- virtual void setPoisonMemory(bool poison) {
- llvm_unreachable("Unexpected call!");
- }
- virtual void AllocateGOT() {
- llvm_unreachable("Unexpected call!");
- }
- virtual uint8_t *getGOTBase() const {
- llvm_unreachable("Unexpected call!");
- return 0;
- }
- virtual uint8_t *startFunctionBody(const Function *F,
- uintptr_t &ActualSize){
- llvm_unreachable("Unexpected call!");
- return 0;
- }
- virtual uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize,
- unsigned Alignment) {
- llvm_unreachable("Unexpected call!");
- return 0;
- }
- virtual void endFunctionBody(const Function *F, uint8_t *FunctionStart,
- uint8_t *FunctionEnd) {
- llvm_unreachable("Unexpected call!");
- }
- virtual uint8_t *allocateSpace(intptr_t Size, unsigned Alignment) {
- llvm_unreachable("Unexpected call!");
- return 0;
- }
- virtual uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment) {
- llvm_unreachable("Unexpected call!");
- return 0;
- }
- virtual void deallocateFunctionBody(void *Body) {
- llvm_unreachable("Unexpected call!");
- }
- virtual uint8_t* startExceptionTable(const Function* F,
- uintptr_t &ActualSize) {
- llvm_unreachable("Unexpected call!");
- return 0;
- }
- virtual void endExceptionTable(const Function *F, uint8_t *TableStart,
- uint8_t *TableEnd, uint8_t* FrameRegister) {
- llvm_unreachable("Unexpected call!");
- }
- virtual void deallocateExceptionTable(void *ET) {
- llvm_unreachable("Unexpected call!");
- }
-};
-
-uint8_t *LLIMCJITMemoryManager::allocateDataSection(uintptr_t Size,
- unsigned Alignment,
- unsigned SectionID) {
- if (!Alignment)
- Alignment = 16;
- uint8_t *Addr = (uint8_t*)calloc((Size + Alignment - 1)/Alignment, Alignment);
- AllocatedDataMem.push_back(sys::MemoryBlock(Addr, Size));
- return Addr;
-}
-
-uint8_t *LLIMCJITMemoryManager::allocateCodeSection(uintptr_t Size,
- unsigned Alignment,
- unsigned SectionID) {
- if (!Alignment)
- Alignment = 16;
- unsigned NeedAllocate = Alignment * ((Size + Alignment - 1)/Alignment + 1);
- uintptr_t Addr = 0;
- // Look in the list of free code memory regions and use a block there if one
- // is available.
- for (int i = 0, e = FreeCodeMem.size(); i != e; ++i) {
- sys::MemoryBlock &MB = FreeCodeMem[i];
- if (MB.size() >= NeedAllocate) {
- Addr = (uintptr_t)MB.base();
- uintptr_t EndOfBlock = Addr + MB.size();
- // Align the address.
- Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1);
- // Store cutted free memory block.
- FreeCodeMem[i] = sys::MemoryBlock((void*)(Addr + Size),
- EndOfBlock - Addr - Size);
- return (uint8_t*)Addr;
- }
- }
-
- // No pre-allocated free block was large enough. Allocate a new memory region.
- sys::MemoryBlock MB = sys::Memory::AllocateRWX(NeedAllocate, 0, 0);
-
- AllocatedCodeMem.push_back(MB);
- Addr = (uintptr_t)MB.base();
- uintptr_t EndOfBlock = Addr + MB.size();
- // Align the address.
- Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1);
- // The AllocateRWX may allocate much more memory than we need. In this case,
- // we store the unused memory as a free memory block.
- unsigned FreeSize = EndOfBlock-Addr-Size;
- if (FreeSize > 16)
- FreeCodeMem.push_back(sys::MemoryBlock((void*)(Addr + Size), FreeSize));
-
- // Return aligned address
- return (uint8_t*)Addr;
-}
-
-void LLIMCJITMemoryManager::invalidateInstructionCache() {
- for (int i = 0, e = AllocatedCodeMem.size(); i != e; ++i)
- sys::Memory::InvalidateInstructionCache(AllocatedCodeMem[i].base(),
- AllocatedCodeMem[i].size());
-}
-
-void *LLIMCJITMemoryManager::getPointerToNamedFunction(const std::string &Name,
- bool AbortOnFailure) {
-#if defined(__linux__)
- //===--------------------------------------------------------------------===//
- // Function stubs that are invoked instead of certain library calls
- //
- // Force the following functions to be linked in to anything that uses the
- // JIT. This is a hack designed to work around the all-too-clever Glibc
- // strategy of making these functions work differently when inlined vs. when
- // not inlined, and hiding their real definitions in a separate archive file
- // that the dynamic linker can't see. For more info, search for
- // 'libc_nonshared.a' on Google, or read http://llvm.org/PR274.
- if (Name == "stat") return (void*)(intptr_t)&stat;
- if (Name == "fstat") return (void*)(intptr_t)&fstat;
- if (Name == "lstat") return (void*)(intptr_t)&lstat;
- if (Name == "stat64") return (void*)(intptr_t)&stat64;
- if (Name == "fstat64") return (void*)(intptr_t)&fstat64;
- if (Name == "lstat64") return (void*)(intptr_t)&lstat64;
- if (Name == "atexit") return (void*)(intptr_t)&atexit;
- if (Name == "mknod") return (void*)(intptr_t)&mknod;
-#endif // __linux__
-
- const char *NameStr = Name.c_str();
- void *Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr);
- if (Ptr) return Ptr;
-
- // If it wasn't found and if it starts with an underscore ('_') character,
- // try again without the underscore.
- if (NameStr[0] == '_') {
- Ptr = sys::DynamicLibrary::SearchForAddressOfSymbol(NameStr+1);
- if (Ptr) return Ptr;
- }
-
- if (AbortOnFailure)
- report_fatal_error("Program used external function '" + Name +
- "' which could not be resolved!");
- return 0;
-}
-
-LLIMCJITMemoryManager::~LLIMCJITMemoryManager() {
- for (unsigned i = 0, e = AllocatedCodeMem.size(); i != e; ++i)
- sys::Memory::ReleaseRWX(AllocatedCodeMem[i]);
- for (unsigned i = 0, e = AllocatedDataMem.size(); i != e; ++i)
- free(AllocatedDataMem[i].base());
-}
-
-
void layoutRemoteTargetMemory(RemoteTarget *T, RecordingMemoryManager *JMM) {
// Lay out our sections in order, with all the code sections first, then
// all the data sections.
@@ -435,9 +258,13 @@ void layoutRemoteTargetMemory(RemoteTarget *T, RecordingMemoryManager *JMM) {
EE->mapSectionAddress(const_cast<void*>(Offsets[i].first), Addr);
DEBUG(dbgs() << " Mapping local: " << Offsets[i].first
- << " to remote: " << format("%#018x", Addr) << "\n");
+ << " to remote: " << format("%p", Addr) << "\n");
}
+
+ // Trigger application of relocations
+ EE->finalizeObject();
+
// Now load it all to the target.
for (unsigned i = 0, e = Offsets.size(); i != e; ++i) {
uint64_t Addr = RemoteAddr + Offsets[i].second;
@@ -446,12 +273,12 @@ void layoutRemoteTargetMemory(RemoteTarget *T, RecordingMemoryManager *JMM) {
T->loadCode(Addr, Offsets[i].first, Sizes[i]);
DEBUG(dbgs() << " loading code: " << Offsets[i].first
- << " to remote: " << format("%#018x", Addr) << "\n");
+ << " to remote: " << format("%p", Addr) << "\n");
} else {
T->loadData(Addr, Offsets[i].first, Sizes[i]);
DEBUG(dbgs() << " loading data: " << Offsets[i].first
- << " to remote: " << format("%#018x", Addr) << "\n");
+ << " to remote: " << format("%p", Addr) << "\n");
}
}
@@ -471,6 +298,7 @@ int main(int argc, char **argv, char * const *envp) {
// usable by the JIT.
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
+ InitializeNativeTargetAsmParser();
cl::ParseCommandLineOptions(argc, argv,
"llvm interpreter & dynamic compiler\n");
@@ -519,7 +347,7 @@ int main(int argc, char **argv, char * const *envp) {
if (RemoteMCJIT)
JMM = new RecordingMemoryManager();
else
- JMM = new LLIMCJITMemoryManager();
+ JMM = new SectionMemoryManager();
builder.setJITMemoryManager(JMM);
} else {
if (RemoteMCJIT) {
@@ -543,15 +371,22 @@ int main(int argc, char **argv, char * const *envp) {
}
builder.setOptLevel(OLvl);
+ TargetOptions Options;
+ Options.UseSoftFloat = GenerateSoftFloatCalls;
+ if (FloatABIForCalls != FloatABI::Default)
+ Options.FloatABIType = FloatABIForCalls;
+ if (GenerateSoftFloatCalls)
+ FloatABIForCalls = FloatABI::Soft;
+
// Remote target execution doesn't handle EH or debug registration.
if (!RemoteMCJIT) {
- TargetOptions Options;
Options.JITExceptionHandling = EnableJITExceptionHandling;
Options.JITEmitDebugInfo = EmitJitDebugInfo;
Options.JITEmitDebugInfoToDisk = EmitJitDebugInfoToDisk;
- builder.setTargetOptions(Options);
}
+ builder.setTargetOptions(Options);
+
EE = builder.create();
if (!EE) {
if (!ErrorMsg.empty())
@@ -613,8 +448,13 @@ int main(int argc, char **argv, char * const *envp) {
// MCJIT itself. FIXME.
//
// Run static constructors.
- if (!RemoteMCJIT)
- EE->runStaticConstructorsDestructors(false);
+ if (!RemoteMCJIT) {
+ if (UseMCJIT && !ForceInterpreter) {
+ // Give MCJIT a chance to apply relocations and set page permissions.
+ EE->finalizeObject();
+ }
+ EE->runStaticConstructorsDestructors(false);
+ }
if (NoLazyCompilation) {
for (Module::iterator I = Mod->begin(), E = Mod->end(); I != E; ++I) {
@@ -649,16 +489,19 @@ int main(int argc, char **argv, char * const *envp) {
uint64_t Entry = (uint64_t)EE->getPointerToFunction(EntryFn);
DEBUG(dbgs() << "Executing '" << EntryFn->getName() << "' at "
- << format("%#18x", Entry) << "\n");
+ << format("%p", Entry) << "\n");
if (Target.executeCode(Entry, Result))
errs() << "ERROR: " << Target.getErrorMsg() << "\n";
Target.stop();
} else {
+ // Trigger compilation separately so code regions that need to be
+ // invalidated will be known.
+ (void)EE->getPointerToFunction(EntryFn);
// Clear instruction cache before code will be executed.
if (JMM)
- static_cast<LLIMCJITMemoryManager*>(JMM)->invalidateInstructionCache();
+ static_cast<SectionMemoryManager*>(JMM)->invalidateInstructionCache();
// Run main.
Result = EE->runFunctionAsMain(EntryFn, InputArgv, envp);
diff --git a/tools/llvm-ar/CMakeLists.txt b/tools/llvm-ar/CMakeLists.txt
index c8b0b72..70eb760 100644
--- a/tools/llvm-ar/CMakeLists.txt
+++ b/tools/llvm-ar/CMakeLists.txt
@@ -1,5 +1,4 @@
set(LLVM_LINK_COMPONENTS archive)
-set(LLVM_REQUIRES_EH 1)
add_llvm_tool(llvm-ar
llvm-ar.cpp
diff --git a/tools/llvm-ar/Makefile b/tools/llvm-ar/Makefile
index 6ee6f34..fafb14b 100644
--- a/tools/llvm-ar/Makefile
+++ b/tools/llvm-ar/Makefile
@@ -10,7 +10,6 @@
LEVEL := ../..
TOOLNAME := llvm-ar
LINK_COMPONENTS := archive
-REQUIRES_EH := 1
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS := 1
diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp
index 7c53701..86eb8e2 100644
--- a/tools/llvm-ar/llvm-ar.cpp
+++ b/tools/llvm-ar/llvm-ar.cpp
@@ -12,19 +12,20 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
+#include "llvm/IR/LLVMContext.h"
#include "llvm/Bitcode/Archive.h"
+#include "llvm/IR/Module.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/raw_ostream.h"
#include <algorithm>
-#include <memory>
+#include <cstdlib>
#include <fstream>
+#include <memory>
using namespace llvm;
// Option for compatibility with AIX, not used but must allow it to be present.
@@ -126,40 +127,57 @@ std::set<sys::Path> Paths;
// The Archive object to which all the editing operations will be sent.
Archive* TheArchive = 0;
+// The name this program was invoked as.
+static const char *program_name;
+
+// show_help - Show the error message, the help message and exit.
+LLVM_ATTRIBUTE_NORETURN static void
+show_help(const std::string &msg) {
+ errs() << program_name << ": " << msg << "\n\n";
+ cl::PrintHelpMessage();
+ if (TheArchive)
+ delete TheArchive;
+ std::exit(1);
+}
+
+// fail - Show the error message and exit.
+LLVM_ATTRIBUTE_NORETURN static void
+fail(const std::string &msg) {
+ errs() << program_name << ": " << msg << "\n\n";
+ if (TheArchive)
+ delete TheArchive;
+ std::exit(1);
+}
+
// getRelPos - Extract the member filename from the command line for
// the [relpos] argument associated with a, b, and i modifiers
void getRelPos() {
- if(RestOfArgs.size() > 0) {
- RelPos = RestOfArgs[0];
- RestOfArgs.erase(RestOfArgs.begin());
- }
- else
- throw "Expected [relpos] for a, b, or i modifier";
+ if(RestOfArgs.size() == 0)
+ show_help("Expected [relpos] for a, b, or i modifier");
+ RelPos = RestOfArgs[0];
+ RestOfArgs.erase(RestOfArgs.begin());
}
// getCount - Extract the [count] argument associated with the N modifier
// from the command line and check its value.
void getCount() {
- if(RestOfArgs.size() > 0) {
- Count = atoi(RestOfArgs[0].c_str());
- RestOfArgs.erase(RestOfArgs.begin());
- }
- else
- throw "Expected [count] value with N modifier";
+ if(RestOfArgs.size() == 0)
+ show_help("Expected [count] value with N modifier");
+
+ Count = atoi(RestOfArgs[0].c_str());
+ RestOfArgs.erase(RestOfArgs.begin());
// Non-positive counts are not allowed
if (Count < 1)
- throw "Invalid [count] value (not a positive integer)";
+ show_help("Invalid [count] value (not a positive integer)");
}
// getArchive - Get the archive file name from the command line
void getArchive() {
- if(RestOfArgs.size() > 0) {
- ArchiveName = RestOfArgs[0];
- RestOfArgs.erase(RestOfArgs.begin());
- }
- else
- throw "An archive name must be specified.";
+ if(RestOfArgs.size() == 0)
+ show_help("An archive name must be specified");
+ ArchiveName = RestOfArgs[0];
+ RestOfArgs.erase(RestOfArgs.begin());
}
// getMembers - Copy over remaining items in RestOfArgs to our Members vector
@@ -240,25 +258,27 @@ ArchiveOperation parseCommandLine() {
// Perform various checks on the operation/modifier specification
// to make sure we are dealing with a legal request.
if (NumOperations == 0)
- throw "You must specify at least one of the operations";
+ show_help("You must specify at least one of the operations");
if (NumOperations > 1)
- throw "Only one operation may be specified";
+ show_help("Only one operation may be specified");
if (NumPositional > 1)
- throw "You may only specify one of a, b, and i modifiers";
- if (AddAfter || AddBefore || InsertBefore)
+ show_help("You may only specify one of a, b, and i modifiers");
+ if (AddAfter || AddBefore || InsertBefore) {
if (Operation != Move && Operation != ReplaceOrInsert)
- throw "The 'a', 'b' and 'i' modifiers can only be specified with "
- "the 'm' or 'r' operations";
+ show_help("The 'a', 'b' and 'i' modifiers can only be specified with "
+ "the 'm' or 'r' operations");
+ }
if (RecurseDirectories && Operation != ReplaceOrInsert)
- throw "The 'R' modifiers is only applicabe to the 'r' operation";
+ show_help("The 'R' modifiers is only applicabe to the 'r' operation");
if (OriginalDates && Operation != Extract)
- throw "The 'o' modifier is only applicable to the 'x' operation";
+ show_help("The 'o' modifier is only applicable to the 'x' operation");
if (TruncateNames && Operation!=QuickAppend && Operation!=ReplaceOrInsert)
- throw "The 'f' modifier is only applicable to the 'q' and 'r' operations";
+ show_help("The 'f' modifier is only applicable to the 'q' and 'r' "
+ "operations");
if (OnlyUpdate && Operation != ReplaceOrInsert)
- throw "The 'u' modifier is only applicable to the 'r' operation";
+ show_help("The 'u' modifier is only applicable to the 'r' operation");
if (Count > 1 && Members.size() > 1)
- throw "Only one member name may be specified with the 'N' modifier";
+ show_help("Only one member name may be specified with the 'N' modifier");
// Return the parsed operation to the caller
return Operation;
@@ -304,16 +324,16 @@ bool buildPaths(bool checkExistence, std::string* ErrMsg) {
for (unsigned i = 0; i < Members.size(); i++) {
sys::Path aPath;
if (!aPath.set(Members[i]))
- throw std::string("File member name invalid: ") + Members[i];
+ fail(std::string("File member name invalid: ") + Members[i]);
if (checkExistence) {
bool Exists;
if (sys::fs::exists(aPath.str(), Exists) || !Exists)
- throw std::string("File does not exist: ") + Members[i];
+ fail(std::string("File does not exist: ") + Members[i]);
std::string Err;
sys::PathWithStatus PwS(aPath);
const sys::FileStatus *si = PwS.getFileStatus(false, &Err);
if (!si)
- throw Err;
+ fail(Err);
if (si->isDir) {
std::set<sys::Path> dirpaths;
if (recurseDirectories(aPath, dirpaths, ErrMsg))
@@ -683,6 +703,7 @@ doReplaceOrInsert(std::string* ErrMsg) {
// main - main program for llvm-ar .. see comments in the code
int main(int argc, char **argv) {
+ program_name = argv[0];
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
PrettyStackTraceProgram X(argc, argv);
@@ -698,77 +719,61 @@ int main(int argc, char **argv) {
int exitCode = 0;
- // Make sure we don't exit with "unhandled exception".
- try {
- // Do our own parsing of the command line because the CommandLine utility
- // can't handle the grouped positional parameters without a dash.
- ArchiveOperation Operation = parseCommandLine();
-
- // Check the path name of the archive
- sys::Path ArchivePath;
- if (!ArchivePath.set(ArchiveName))
- throw std::string("Archive name invalid: ") + ArchiveName;
-
- // Create or open the archive object.
- bool Exists;
- if (llvm::sys::fs::exists(ArchivePath.str(), Exists) || !Exists) {
- // Produce a warning if we should and we're creating the archive
- if (!Create)
- errs() << argv[0] << ": creating " << ArchivePath.str() << "\n";
- TheArchive = Archive::CreateEmpty(ArchivePath, Context);
- TheArchive->writeToDisk();
- } else {
- std::string Error;
- TheArchive = Archive::OpenAndLoad(ArchivePath, Context, &Error);
- if (TheArchive == 0) {
- errs() << argv[0] << ": error loading '" << ArchivePath.str() << "': "
- << Error << "!\n";
- return 1;
- }
- }
+ // Do our own parsing of the command line because the CommandLine utility
+ // can't handle the grouped positional parameters without a dash.
+ ArchiveOperation Operation = parseCommandLine();
- // Make sure we're not fooling ourselves.
- assert(TheArchive && "Unable to instantiate the archive");
-
- // Make sure we clean up the archive even on failure.
- std::auto_ptr<Archive> AutoArchive(TheArchive);
-
- // Perform the operation
- std::string ErrMsg;
- bool haveError = false;
- switch (Operation) {
- case Print: haveError = doPrint(&ErrMsg); break;
- case Delete: haveError = doDelete(&ErrMsg); break;
- case Move: haveError = doMove(&ErrMsg); break;
- case QuickAppend: haveError = doQuickAppend(&ErrMsg); break;
- case ReplaceOrInsert: haveError = doReplaceOrInsert(&ErrMsg); break;
- case DisplayTable: haveError = doDisplayTable(&ErrMsg); break;
- case Extract: haveError = doExtract(&ErrMsg); break;
- case NoOperation:
- errs() << argv[0] << ": No operation was selected.\n";
- break;
- }
- if (haveError) {
- errs() << argv[0] << ": " << ErrMsg << "\n";
+ // Check the path name of the archive
+ sys::Path ArchivePath;
+ if (!ArchivePath.set(ArchiveName)) {
+ errs() << argv[0] << ": Archive name invalid: " << ArchiveName << "\n";
+ return 1;
+ }
+
+ // Create or open the archive object.
+ bool Exists;
+ if (llvm::sys::fs::exists(ArchivePath.str(), Exists) || !Exists) {
+ // Produce a warning if we should and we're creating the archive
+ if (!Create)
+ errs() << argv[0] << ": creating " << ArchivePath.str() << "\n";
+ TheArchive = Archive::CreateEmpty(ArchivePath, Context);
+ TheArchive->writeToDisk();
+ } else {
+ std::string Error;
+ TheArchive = Archive::OpenAndLoad(ArchivePath, Context, &Error);
+ if (TheArchive == 0) {
+ errs() << argv[0] << ": error loading '" << ArchivePath.str() << "': "
+ << Error << "!\n";
return 1;
}
- } catch (const char*msg) {
- // These errors are usage errors, thrown only by the various checks in the
- // code above.
- errs() << argv[0] << ": " << msg << "\n\n";
- cl::PrintHelpMessage();
- exitCode = 1;
- } catch (const std::string& msg) {
- // These errors are thrown by LLVM libraries (e.g. lib System) and represent
- // a more serious error so we bump the exitCode and don't print the usage.
- errs() << argv[0] << ": " << msg << "\n";
- exitCode = 2;
- } catch (...) {
- // This really shouldn't happen, but just in case ....
- errs() << argv[0] << ": An unexpected unknown exception occurred.\n";
- exitCode = 3;
}
+ // Make sure we're not fooling ourselves.
+ assert(TheArchive && "Unable to instantiate the archive");
+
+ // Perform the operation
+ std::string ErrMsg;
+ bool haveError = false;
+ switch (Operation) {
+ case Print: haveError = doPrint(&ErrMsg); break;
+ case Delete: haveError = doDelete(&ErrMsg); break;
+ case Move: haveError = doMove(&ErrMsg); break;
+ case QuickAppend: haveError = doQuickAppend(&ErrMsg); break;
+ case ReplaceOrInsert: haveError = doReplaceOrInsert(&ErrMsg); break;
+ case DisplayTable: haveError = doDisplayTable(&ErrMsg); break;
+ case Extract: haveError = doExtract(&ErrMsg); break;
+ case NoOperation:
+ errs() << argv[0] << ": No operation was selected.\n";
+ break;
+ }
+ if (haveError) {
+ errs() << argv[0] << ": " << ErrMsg << "\n";
+ return 1;
+ }
+
+ delete TheArchive;
+ TheArchive = 0;
+
// Return result code back to operating system.
return exitCode;
}
diff --git a/tools/llvm-as/CMakeLists.txt b/tools/llvm-as/CMakeLists.txt
index eef4a13..d5620e7 100644
--- a/tools/llvm-as/CMakeLists.txt
+++ b/tools/llvm-as/CMakeLists.txt
@@ -1,5 +1,4 @@
set(LLVM_LINK_COMPONENTS asmparser bitwriter)
-set(LLVM_REQUIRES_EH 1)
add_llvm_tool(llvm-as
llvm-as.cpp
diff --git a/tools/llvm-as/llvm-as.cpp b/tools/llvm-as/llvm-as.cpp
index 1def9a4..273c427 100644
--- a/tools/llvm-as/llvm-as.cpp
+++ b/tools/llvm-as/llvm-as.cpp
@@ -15,18 +15,18 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
-#include "llvm/Assembly/Parser.h"
+#include "llvm/IR/LLVMContext.h"
#include "llvm/Analysis/Verifier.h"
+#include "llvm/Assembly/Parser.h"
#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/IR/Module.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/Support/Signals.h"
#include <memory>
using namespace llvm;
diff --git a/tools/llvm-bcanalyzer/CMakeLists.txt b/tools/llvm-bcanalyzer/CMakeLists.txt
index 732bc32..0151ea9 100644
--- a/tools/llvm-bcanalyzer/CMakeLists.txt
+++ b/tools/llvm-bcanalyzer/CMakeLists.txt
@@ -1,5 +1,4 @@
set(LLVM_LINK_COMPONENTS bitreader)
-set(LLVM_REQUIRES_EH 1)
add_llvm_tool(llvm-bcanalyzer
llvm-bcanalyzer.cpp
diff --git a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
index 8109ca4..46b687e 100644
--- a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
+++ b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
@@ -37,12 +37,11 @@
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
-
-#include <map>
#include <algorithm>
+#include <map>
using namespace llvm;
static cl::opt<std::string>
@@ -150,7 +149,7 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
case bitc::MODULE_CODE_DATALAYOUT: return "DATALAYOUT";
case bitc::MODULE_CODE_ASM: return "ASM";
case bitc::MODULE_CODE_SECTIONNAME: return "SECTIONNAME";
- case bitc::MODULE_CODE_DEPLIB: return "DEPLIB";
+ case bitc::MODULE_CODE_DEPLIB: return "DEPLIB"; // FIXME: Remove in 4.0
case bitc::MODULE_CODE_GLOBALVAR: return "GLOBALVAR";
case bitc::MODULE_CODE_FUNCTION: return "FUNCTION";
case bitc::MODULE_CODE_ALIAS: return "ALIAS";
diff --git a/tools/llvm-config/Makefile b/tools/llvm-config/Makefile
index e8c8692..b20b6bf 100644
--- a/tools/llvm-config/Makefile
+++ b/tools/llvm-config/Makefile
@@ -63,5 +63,5 @@ ifeq ($(LLVM_CROSS_COMPILING),1)
install:: $(DESTDIR)$(PROJ_bindir)
$(Echo) Installing llvm-config-host
$(Verb) $(ProgInstall) $(BuildLLVMToolDir)/llvm-config \
- $(DESTDIR)$(PROJ_bindir)/llvm-config-host
+ $(DESTDIR)$(PROJ_bindir)/$(program_prefix)llvm-config-host
endif
diff --git a/tools/llvm-diff/DiffConsumer.cpp b/tools/llvm-diff/DiffConsumer.cpp
index 91c1699..9078013 100644
--- a/tools/llvm-diff/DiffConsumer.cpp
+++ b/tools/llvm-diff/DiffConsumer.cpp
@@ -12,9 +12,8 @@
//===----------------------------------------------------------------------===//
#include "DiffConsumer.h"
-
-#include "llvm/Module.h"
-#include "llvm/Instructions.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/DiffConsumer.h b/tools/llvm-diff/DiffConsumer.h
index 98e369b..6c2209f 100644
--- a/tools/llvm-diff/DiffConsumer.h
+++ b/tools/llvm-diff/DiffConsumer.h
@@ -15,12 +15,11 @@
#define _LLVM_DIFFCONSUMER_H_
#include "DiffLog.h"
-
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Casting.h"
+#include "llvm/Support/raw_ostream.h"
namespace llvm {
class Module;
diff --git a/tools/llvm-diff/DiffLog.cpp b/tools/llvm-diff/DiffLog.cpp
index 9cc0c88..caf779b 100644
--- a/tools/llvm-diff/DiffLog.cpp
+++ b/tools/llvm-diff/DiffLog.cpp
@@ -13,10 +13,9 @@
#include "DiffLog.h"
#include "DiffConsumer.h"
-
-#include "llvm/Instructions.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/IR/Instructions.h"
using namespace llvm;
diff --git a/tools/llvm-diff/DifferenceEngine.cpp b/tools/llvm-diff/DifferenceEngine.cpp
index 0c1e30c..4b11315 100644
--- a/tools/llvm-diff/DifferenceEngine.cpp
+++ b/tools/llvm-diff/DifferenceEngine.cpp
@@ -13,22 +13,20 @@
//===----------------------------------------------------------------------===//
#include "DifferenceEngine.h"
-
-#include "llvm/Constants.h"
-#include "llvm/Function.h"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
-#include "llvm/Support/CallSite.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"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/type_traits.h"
-
#include <utility>
using namespace llvm;
diff --git a/tools/llvm-diff/DifferenceEngine.h b/tools/llvm-diff/DifferenceEngine.h
index 0246d8f..73bf6eb 100644
--- a/tools/llvm-diff/DifferenceEngine.h
+++ b/tools/llvm-diff/DifferenceEngine.h
@@ -15,11 +15,10 @@
#ifndef _LLVM_DIFFERENCE_ENGINE_H_
#define _LLVM_DIFFERENCE_ENGINE_H_
+#include "DiffConsumer.h"
+#include "DiffLog.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
-#include "DiffLog.h"
-#include "DiffConsumer.h"
-
#include <utility>
namespace llvm {
diff --git a/tools/llvm-diff/llvm-diff.cpp b/tools/llvm-diff/llvm-diff.cpp
index 45957b3..0b9e92b 100644
--- a/tools/llvm-diff/llvm-diff.cpp
+++ b/tools/llvm-diff/llvm-diff.cpp
@@ -13,19 +13,17 @@
#include "DiffLog.h"
#include "DifferenceEngine.h"
-
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
-#include "llvm/Type.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.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/raw_ostream.h"
#include "llvm/Support/SourceMgr.h"
-
+#include "llvm/Support/raw_ostream.h"
#include <string>
#include <utility>
diff --git a/tools/llvm-dis/CMakeLists.txt b/tools/llvm-dis/CMakeLists.txt
index 3125f8a..9f12ecb 100644
--- a/tools/llvm-dis/CMakeLists.txt
+++ b/tools/llvm-dis/CMakeLists.txt
@@ -1,5 +1,4 @@
set(LLVM_LINK_COMPONENTS bitreader analysis)
-set(LLVM_REQUIRES_EH 1)
add_llvm_tool(llvm-dis
llvm-dis.cpp
diff --git a/tools/llvm-dis/llvm-dis.cpp b/tools/llvm-dis/llvm-dis.cpp
index 41f023d..2baa91d 100644
--- a/tools/llvm-dis/llvm-dis.cpp
+++ b/tools/llvm-dis/llvm-dis.cpp
@@ -16,21 +16,21 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/LLVMContext.h"
-#include "llvm/DebugInfo.h"
-#include "llvm/Module.h"
-#include "llvm/Type.h"
-#include "llvm/IntrinsicInst.h"
-#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/IR/LLVMContext.h"
#include "llvm/Assembly/AssemblyAnnotationWriter.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/DebugInfo.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"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/system_error.h"
using namespace llvm;
diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index 38c3a1e..34302fa 100644
--- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -1,4 +1,4 @@
-//===-- llvm-dwarfdump.cpp - Debug info dumping utility for llvm -----------===//
+//===-- llvm-dwarfdump.cpp - Debug info dumping utility for llvm ----------===//
//
// The LLVM Compiler Infrastructure
//
@@ -12,10 +12,11 @@
//===----------------------------------------------------------------------===//
#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/ADT/STLExtras.h"
-#include "llvm/Object/ObjectFile.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/RelocVisitor.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
@@ -28,6 +29,9 @@
#include "llvm/Support/system_error.h"
#include <algorithm>
#include <cstring>
+#include <list>
+#include <string>
+
using namespace llvm;
using namespace object;
@@ -65,47 +69,8 @@ static void DumpInput(const StringRef &Filename) {
}
OwningPtr<ObjectFile> Obj(ObjectFile::createObjectFile(Buff.take()));
+ OwningPtr<DIContext> dictx(DIContext::getDWARFContext(Obj.get()));
- StringRef DebugInfoSection;
- StringRef DebugAbbrevSection;
- StringRef DebugLineSection;
- StringRef DebugArangesSection;
- StringRef DebugStringSection;
- StringRef DebugRangesSection;
-
- error_code ec;
- for (section_iterator i = Obj->begin_sections(),
- e = Obj->end_sections();
- i != e; i.increment(ec)) {
- StringRef name;
- i->getName(name);
- StringRef data;
- i->getContents(data);
-
- if (name.startswith("__DWARF,"))
- name = name.substr(8); // Skip "__DWARF," prefix.
- name = name.substr(name.find_first_not_of("._")); // Skip . and _ prefixes.
- if (name == "debug_info")
- DebugInfoSection = data;
- else if (name == "debug_abbrev")
- DebugAbbrevSection = data;
- else if (name == "debug_line")
- DebugLineSection = data;
- else if (name == "debug_aranges")
- DebugArangesSection = data;
- else if (name == "debug_str")
- DebugStringSection = data;
- else if (name == "debug_ranges")
- DebugRangesSection = data;
- }
-
- OwningPtr<DIContext> dictx(DIContext::getDWARFContext(/*FIXME*/true,
- DebugInfoSection,
- DebugAbbrevSection,
- DebugArangesSection,
- DebugLineSection,
- DebugStringSection,
- DebugRangesSection));
if (Address == -1ULL) {
outs() << Filename
<< ":\tfile format " << Obj->getFileFormatName() << "\n\n";
@@ -118,8 +83,8 @@ static void DumpInput(const StringRef &Filename) {
if (PrintFunctions)
SpecFlags |= DILineInfoSpecifier::FunctionName;
if (PrintInlining) {
- DIInliningInfo InliningInfo = dictx->getInliningInfoForAddress(
- Address, SpecFlags);
+ DIInliningInfo InliningInfo =
+ dictx->getInliningInfoForAddress(Address, SpecFlags);
uint32_t n = InliningInfo.getNumberOfFrames();
if (n == 0) {
// Print one empty debug line info in any case.
diff --git a/tools/llvm-extract/llvm-extract.cpp b/tools/llvm-extract/llvm-extract.cpp
index 2ed11c5..85a9211 100644
--- a/tools/llvm-extract/llvm-extract.cpp
+++ b/tools/llvm-extract/llvm-extract.cpp
@@ -12,23 +12,23 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
-#include "llvm/PassManager.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/Transforms/IPO.h"
-#include "llvm/Target/TargetData.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"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/Support/SystemUtils.h"
-#include "llvm/Support/Signals.h"
#include "llvm/Support/Regex.h"
-#include "llvm/ADT/SmallPtrSet.h"
-#include "llvm/ADT/SetVector.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/SystemUtils.h"
+#include "llvm/Support/ToolOutputFile.h"
+#include "llvm/Transforms/IPO.h"
#include <memory>
using namespace llvm;
@@ -59,6 +59,19 @@ ExtractRegExpFuncs("rfunc", cl::desc("Specify function(s) to extract using a "
"regular expression"),
cl::ZeroOrMore, cl::value_desc("rfunction"));
+// ExtractAlias - The alias to extract from the module.
+static cl::list<std::string>
+ExtractAliases("alias", cl::desc("Specify alias to extract"),
+ cl::ZeroOrMore, cl::value_desc("alias"));
+
+
+// ExtractRegExpAliases - The aliases, matched via regular expression, to
+// extract from the module.
+static cl::list<std::string>
+ExtractRegExpAliases("ralias", cl::desc("Specify alias(es) to extract using a "
+ "regular expression"),
+ cl::ZeroOrMore, cl::value_desc("ralias"));
+
// ExtractGlobals - The globals to extract from the module.
static cl::list<std::string>
ExtractGlobals("glob", cl::desc("Specify global to extract"),
@@ -97,6 +110,40 @@ int main(int argc, char **argv) {
// Use SetVector to avoid duplicates.
SetVector<GlobalValue *> GVs;
+ // Figure out which aliases we should extract.
+ for (size_t i = 0, e = ExtractAliases.size(); i != e; ++i) {
+ GlobalAlias *GA = M->getNamedAlias(ExtractAliases[i]);
+ if (!GA) {
+ errs() << argv[0] << ": program doesn't contain alias named '"
+ << ExtractAliases[i] << "'!\n";
+ return 1;
+ }
+ GVs.insert(GA);
+ }
+
+ // Extract aliases via regular expression matching.
+ for (size_t i = 0, e = ExtractRegExpAliases.size(); i != e; ++i) {
+ std::string Error;
+ Regex RegEx(ExtractRegExpAliases[i]);
+ if (!RegEx.isValid(Error)) {
+ errs() << argv[0] << ": '" << ExtractRegExpAliases[i] << "' "
+ "invalid regex: " << Error;
+ }
+ bool match = false;
+ for (Module::alias_iterator GA = M->alias_begin(), E = M->alias_end();
+ GA != E; GA++) {
+ if (RegEx.match(GA->getName())) {
+ GVs.insert(&*GA);
+ match = true;
+ }
+ }
+ if (!match) {
+ errs() << argv[0] << ": program doesn't contain global named '"
+ << ExtractRegExpAliases[i] << "'!\n";
+ return 1;
+ }
+ }
+
// Figure out which globals we should extract.
for (size_t i = 0, e = ExtractGlobals.size(); i != e; ++i) {
GlobalValue *GV = M->getNamedGlobal(ExtractGlobals[i]);
@@ -206,7 +253,7 @@ int main(int argc, char **argv) {
// In addition to deleting all other functions, we also want to spiff it
// up a little bit. Do this now.
PassManager Passes;
- Passes.add(new TargetData(M.get())); // Use correct TargetData
+ Passes.add(new DataLayout(M.get())); // Use correct DataLayout
std::vector<GlobalValue*> Gvs(GVs.begin(), GVs.end());
diff --git a/tools/llvm-jitlistener/CMakeLists.txt b/tools/llvm-jitlistener/CMakeLists.txt
new file mode 100644
index 0000000..57a4a0c
--- /dev/null
+++ b/tools/llvm-jitlistener/CMakeLists.txt
@@ -0,0 +1,20 @@
+# This tool is excluded from the CMake build if Intel JIT events are disabled.
+
+link_directories( ${LLVM_INTEL_JITEVENTS_LIBDIR} )
+include_directories( ${LLVM_INTEL_JITEVENTS_INCDIR} )
+
+set(LLVM_LINK_COMPONENTS
+ asmparser
+ bitreader
+ inteljitevents
+ interpreter
+ jit
+ mcjit
+ nativecodegen
+ object
+ selectiondag
+ )
+
+add_llvm_tool(llvm-jitlistener
+ llvm-jitlistener.cpp
+ )
diff --git a/tools/llvm-jitlistener/LLVMBuild.txt b/tools/llvm-jitlistener/LLVMBuild.txt
new file mode 100644
index 0000000..c436dd9
--- /dev/null
+++ b/tools/llvm-jitlistener/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-jitlistener/LLVMBuild.txt -------------------*- Conf -*--===;
+;
+; The LLVM Compiler Infrastructure
+;
+; This file is distributed under the University of Illinois Open Source
+; License. See LICENSE.TXT for details.
+;
+;===------------------------------------------------------------------------===;
+;
+; This is an LLVMBuild description file for the components in this subdirectory.
+;
+; For more information on the LLVMBuild system, please see:
+;
+; http://llvm.org/docs/LLVMBuild.html
+;
+;===------------------------------------------------------------------------===;
+
+[component_0]
+type = Tool
+name = llvm-jitlistener
+parent = Tools
+required_libraries = AsmParser BitReader Interpreter JIT MCJIT NativeCodeGen Object SelectionDAG Native
diff --git a/tools/llvm-jitlistener/Makefile b/tools/llvm-jitlistener/Makefile
new file mode 100644
index 0000000..0971e6a
--- /dev/null
+++ b/tools/llvm-jitlistener/Makefile
@@ -0,0 +1,27 @@
+##===- tools/llvm-jitlistener/Makefile ---------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../..
+TOOLNAME := llvm-jitlistener
+
+include $(LEVEL)/Makefile.config
+
+LINK_COMPONENTS := mcjit jit interpreter nativecodegen bitreader asmparser selectiondag Object
+
+# If Intel JIT Events support is configured, link against the LLVM Intel JIT
+# Events interface library. If not, this tool will do nothing useful, but it
+# will build correctly.
+ifeq ($(USE_INTEL_JITEVENTS), 1)
+ LINK_COMPONENTS += inteljitevents
+endif
+
+# This tool has no plugins, optimize startup time.
+TOOL_NO_EXPORTS := 1
+
+include $(LLVM_SRC_ROOT)/Makefile.rules
diff --git a/tools/llvm-jitlistener/llvm-jitlistener.cpp b/tools/llvm-jitlistener/llvm-jitlistener.cpp
new file mode 100644
index 0000000..2f72e42
--- /dev/null
+++ b/tools/llvm-jitlistener/llvm-jitlistener.cpp
@@ -0,0 +1,207 @@
+//===-- llvm-jitlistener.cpp - Utility for testing MCJIT event listener ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This program is a used by lit tests to verify the MCJIT JITEventListener
+// interface. It registers a mock JIT event listener, generates a module from
+// an input IR file and dumps the reported event information to stdout.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/IR/LLVMContext.h"
+#include "../../lib/ExecutionEngine/IntelJITEvents/IntelJITEventsWrapper.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ExecutionEngine/JITEventListener.h"
+#include "llvm/ExecutionEngine/JITMemoryManager.h"
+#include "llvm/ExecutionEngine/MCJIT.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/IRReader.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetSelect.h"
+#include <string>
+
+using namespace llvm;
+
+namespace {
+
+typedef std::vector<std::pair<std::string, unsigned int> > SourceLocations;
+typedef std::map<uint64_t, SourceLocations> NativeCodeMap;
+
+NativeCodeMap ReportedDebugFuncs;
+
+int NotifyEvent(iJIT_JVM_EVENT EventType, void *EventSpecificData) {
+ switch (EventType) {
+ case iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED: {
+ if (!EventSpecificData) {
+ errs() <<
+ "Error: The JIT event listener did not provide a event data.";
+ return -1;
+ }
+ iJIT_Method_Load* msg = static_cast<iJIT_Method_Load*>(EventSpecificData);
+
+ ReportedDebugFuncs[msg->method_id];
+
+ outs() << "Method load [" << msg->method_id << "]: " << msg->method_name
+ << ", Size = " << msg->method_size << "\n";
+
+ for(unsigned int i = 0; i < msg->line_number_size; ++i) {
+ if (!msg->line_number_table) {
+ errs() << "A function with a non-zero line count had no line table.";
+ return -1;
+ }
+ std::pair<std::string, unsigned int> loc(
+ std::string(msg->source_file_name),
+ msg->line_number_table[i].LineNumber);
+ ReportedDebugFuncs[msg->method_id].push_back(loc);
+ outs() << " Line info @ " << msg->line_number_table[i].Offset
+ << ": " << msg->source_file_name
+ << ", line " << msg->line_number_table[i].LineNumber << "\n";
+ }
+ outs() << "\n";
+ }
+ break;
+ case iJVM_EVENT_TYPE_METHOD_UNLOAD_START: {
+ if (!EventSpecificData) {
+ errs() <<
+ "Error: The JIT event listener did not provide a event data.";
+ return -1;
+ }
+ unsigned int UnloadId
+ = *reinterpret_cast<unsigned int*>(EventSpecificData);
+ assert(1 == ReportedDebugFuncs.erase(UnloadId));
+ outs() << "Method unload [" << UnloadId << "]\n";
+ }
+ break;
+ default:
+ break;
+ }
+ return 0;
+}
+
+iJIT_IsProfilingActiveFlags IsProfilingActive(void) {
+ // for testing, pretend we have an Intel Parallel Amplifier XE 2011
+ // instance attached
+ return iJIT_SAMPLING_ON;
+}
+
+unsigned int GetNewMethodID(void) {
+ static unsigned int id = 0;
+ return ++id;
+}
+
+class JitEventListenerTest {
+protected:
+ void InitEE(const std::string &IRFile) {
+ LLVMContext &Context = getGlobalContext();
+
+ // If we have a native target, initialize it to ensure it is linked in and
+ // usable by the JIT.
+ InitializeNativeTarget();
+ InitializeNativeTargetAsmPrinter();
+
+ // Parse the bitcode...
+ SMDiagnostic Err;
+ TheModule = ParseIRFile(IRFile, Err, Context);
+ if (!TheModule) {
+ errs() << Err.getMessage();
+ return;
+ }
+
+ // FIXME: This is using the default legacy JITMemoryManager because it
+ // supports poison memory. At some point, we'll need to update this to
+ // use an MCJIT-specific memory manager. It might be nice to have the
+ // poison memory option there too.
+ JITMemoryManager *MemMgr = JITMemoryManager::CreateDefaultMemManager();
+ if (!MemMgr) {
+ errs() << "Unable to create memory manager.";
+ return;
+ }
+
+ // Tell the memory manager to poison freed memory so that accessing freed
+ // memory is more easily tested.
+ MemMgr->setPoisonMemory(true);
+
+ // Override the triple to generate ELF on Windows since that's supported
+ Triple Tuple(TheModule->getTargetTriple());
+ if (Tuple.getTriple().empty())
+ Tuple.setTriple(LLVM_HOSTTRIPLE);
+
+ if (Tuple.isOSWindows() && Triple::ELF != Tuple.getEnvironment()) {
+ Tuple.setEnvironment(Triple::ELF);
+ TheModule->setTargetTriple(Tuple.getTriple());
+ }
+
+ // Compile the IR
+ std::string Error;
+ TheJIT.reset(EngineBuilder(TheModule)
+ .setEngineKind(EngineKind::JIT)
+ .setErrorStr(&Error)
+ .setJITMemoryManager(MemMgr)
+ .setUseMCJIT(true)
+ .create());
+ if (Error.empty() == false)
+ errs() << Error;
+ }
+
+ void DestroyEE() {
+ TheJIT.reset();
+ }
+
+ LLVMContext Context; // Global ownership
+ Module *TheModule; // Owned by ExecutionEngine.
+ JITMemoryManager *JMM; // Owned by ExecutionEngine.
+ OwningPtr<ExecutionEngine> TheJIT;
+
+public:
+ void ProcessInput(const std::string &Filename) {
+ InitEE(Filename);
+
+ llvm::OwningPtr<llvm::JITEventListener> Listener(JITEventListener::createIntelJITEventListener(
+ new IntelJITEventsWrapper(NotifyEvent, 0,
+ IsProfilingActive, 0, 0,
+ GetNewMethodID)));
+
+ TheJIT->RegisterJITEventListener(Listener.get());
+
+ TheJIT->finalizeObject();
+
+ // Destroy the JIT engine instead of unregistering to get unload events.
+ DestroyEE();
+ }
+};
+
+
+
+} // end anonymous namespace
+
+static cl::opt<std::string>
+InputFilename(cl::Positional, cl::desc("<input IR file>"),
+ cl::Required);
+
+int main(int argc, char **argv) {
+ // Print a stack trace if we signal out.
+ sys::PrintStackTraceOnErrorSignal();
+ PrettyStackTraceProgram X(argc, argv);
+ llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
+
+ cl::ParseCommandLineOptions(argc, argv, "llvm jit event listener test utility\n");
+
+ JitEventListenerTest Test;
+
+ Test.ProcessInput(InputFilename);
+
+ return 0;
+}
diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp
index 378a833..f6c9f11 100644
--- a/tools/llvm-link/llvm-link.cpp
+++ b/tools/llvm-link/llvm-link.cpp
@@ -13,18 +13,18 @@
//===----------------------------------------------------------------------===//
#include "llvm/Linker.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Bitcode/ReaderWriter.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"
+#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/Support/SystemUtils.h"
-#include "llvm/Support/IRReader.h"
#include "llvm/Support/Signals.h"
-#include "llvm/Support/Path.h"
+#include "llvm/Support/SystemUtils.h"
+#include "llvm/Support/ToolOutputFile.h"
#include <memory>
using namespace llvm;
diff --git a/tools/llvm-mc/Disassembler.cpp b/tools/llvm-mc/Disassembler.cpp
index 5f2fdb8..06c7721 100644
--- a/tools/llvm-mc/Disassembler.cpp
+++ b/tools/llvm-mc/Disassembler.cpp
@@ -13,16 +13,12 @@
//===----------------------------------------------------------------------===//
#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"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MemoryObject.h"
#include "llvm/Support/SourceMgr.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 17d622f..5615da8 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 3bceb14..e77f27e 100644
--- a/tools/llvm-mc/llvm-mc.cpp
+++ b/tools/llvm-mc/llvm-mc.cpp
@@ -12,36 +12,36 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/MC/MCParser/AsmLexer.h"
-#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "Disassembler.h"
+#include "llvm/ADT/OwningPtr.h"
#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCAsmInfo.h"
-#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCCodeEmitter.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCInstPrinter.h"
#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"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/MC/SubtargetFeature.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/SourceMgr.h"
-#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/Support/Host.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/system_error.h"
-#include "Disassembler.h"
using namespace llvm;
static cl::opt<std::string>
@@ -69,6 +69,9 @@ static cl::opt<bool>
RelaxAll("mc-relax-all", cl::desc("Relax all fixups"));
static cl::opt<bool>
+DisableCFI("disable-cfi", cl::desc("Do not use .cfi_* directives"));
+
+static cl::opt<bool>
NoExecStack("mc-no-exec-stack", cl::desc("File doesn't need an exec stack"));
enum OutputFileType {
@@ -154,11 +157,20 @@ 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
};
static cl::opt<ActionType>
@@ -170,8 +182,11 @@ 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",
+ "Disassemble strings of hex bytes printing "
+ "immediates as hex"),
clEnumValEnd));
static const Target *GetTarget(const char *ProgName) {
@@ -248,9 +263,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;
@@ -379,8 +391,12 @@ int main(int argc, char **argv) {
Ctx.setAllowTemporaryLabels(false);
Ctx.setGenDwarfForAssembly(GenDwarfForAssembly);
- if (!DwarfDebugFlags.empty())
+ if (!DwarfDebugFlags.empty())
Ctx.setDwarfDebugFlags(StringRef(DwarfDebugFlags));
+ if (!DebugCompilationDir.empty())
+ Ctx.setCompilationDir(DebugCompilationDir);
+ if (!MainFileName.empty())
+ Ctx.setMainFileName(MainFileName);
// Package up features to be passed to target/subtarget
std::string FeaturesStr;
@@ -402,18 +418,20 @@ int main(int argc, char **argv) {
OwningPtr<MCSubtargetInfo>
STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
+ MCInstPrinter *IP;
if (FileType == OFT_AssemblyFile) {
- MCInstPrinter *IP =
+ IP =
TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MCII, *MRI, *STI);
MCCodeEmitter *CE = 0;
MCAsmBackend *MAB = 0;
if (ShowEncoding) {
CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
- MAB = TheTarget->createMCAsmBackend(TripleName);
+ MAB = TheTarget->createMCAsmBackend(TripleName, MCPU);
}
+ bool UseCFI = !DisableCFI;
Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/true,
/*useLoc*/ true,
- /*useCFI*/ true,
+ UseCFI,
/*useDwarfDirectory*/ true,
IP, CE, MAB, ShowInst));
@@ -422,13 +440,14 @@ int main(int argc, char **argv) {
} else {
assert(FileType == OFT_ObjectFile && "Invalid file type!");
MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
- MCAsmBackend *MAB = TheTarget->createMCAsmBackend(TripleName);
+ MCAsmBackend *MAB = TheTarget->createMCAsmBackend(TripleName, MCPU);
Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB,
FOS, CE, RelaxAll,
NoExecStack));
}
int Res = 1;
+ bool disassemble = false;
switch (Action) {
case AC_AsLex:
Res = AsLexInput(SrcMgr, *MAI, Out.get());
@@ -436,14 +455,21 @@ int main(int argc, char **argv) {
case AC_Assemble:
Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI);
break;
- case AC_Disassemble:
- Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str,
- *Buffer, SrcMgr, Out->os());
+ case AC_MDisassemble:
+ IP->setUseMarkup(1);
+ disassemble = true;
break;
- case AC_EDisassemble:
- Res = Disassembler::disassembleEnhanced(TripleName, *Buffer, SrcMgr, Out->os());
+ case AC_HDisassemble:
+ IP->setPrintImmHex(1);
+ disassemble = true;
+ break;
+ case AC_Disassemble:
+ disassemble = true;
break;
}
+ if (disassemble)
+ Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str,
+ *Buffer, SrcMgr, Out->os());
// Keep output if no errors.
if (Res == 0) Out->keep();
diff --git a/tools/llvm-mcmarkup/CMakeLists.txt b/tools/llvm-mcmarkup/CMakeLists.txt
new file mode 100644
index 0000000..0a51e99
--- /dev/null
+++ b/tools/llvm-mcmarkup/CMakeLists.txt
@@ -0,0 +1,5 @@
+set(LLVM_LINK_COMPONENTS support)
+
+add_llvm_tool(llvm-mcmarkup
+ llvm-mcmarkup.cpp
+ )
diff --git a/tools/llvm-mcmarkup/LLVMBuild.txt b/tools/llvm-mcmarkup/LLVMBuild.txt
new file mode 100644
index 0000000..6423493
--- /dev/null
+++ b/tools/llvm-mcmarkup/LLVMBuild.txt
@@ -0,0 +1,22 @@
+;===- ./tools/llvm-mcmarkup/LLVMBuild.txt ----------------------*- Conf -*--===;
+;
+; The LLVM Compiler Infrastructure
+;
+; This file is distributed under the University of Illinois Open Source
+; License. See LICENSE.TXT for details.
+;
+;===------------------------------------------------------------------------===;
+;
+; This is an LLVMBuild description file for the components in this subdirectory.
+;
+; For more information on the LLVMBuild system, please see:
+;
+; http://llvm.org/docs/LLVMBuild.html
+;
+;===------------------------------------------------------------------------===;
+
+[component_0]
+type = Tool
+name = llvm-mcmarkup
+parent = Tools
+required_libraries = Support
diff --git a/tools/llvm-mcmarkup/Makefile b/tools/llvm-mcmarkup/Makefile
new file mode 100644
index 0000000..5633a9c
--- /dev/null
+++ b/tools/llvm-mcmarkup/Makefile
@@ -0,0 +1,17 @@
+##===- tools/llvm-mcmarkup/Makefile ------------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../..
+TOOLNAME := llvm-mcmarkup
+LINK_COMPONENTS := support
+
+# This tool has no plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-mcmarkup/llvm-mcmarkup.cpp b/tools/llvm-mcmarkup/llvm-mcmarkup.cpp
new file mode 100644
index 0000000..888761f
--- /dev/null
+++ b/tools/llvm-mcmarkup/llvm-mcmarkup.cpp
@@ -0,0 +1,225 @@
+//===-- llvm-mcmarkup.cpp - Parse the MC assembly markup tags -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Example simple parser implementation for the MC assembly markup language.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/system_error.h"
+using namespace llvm;
+
+static cl::list<std::string>
+ InputFilenames(cl::Positional, cl::desc("<input files>"),
+ cl::ZeroOrMore);
+static cl::opt<bool>
+DumpTags("dump-tags", cl::desc("List all tags encountered in input"));
+
+static StringRef ToolName;
+
+/// Trivial lexer for the markup parser. Input is always handled a character
+/// at a time. The lexer just encapsulates EOF and lookahead handling.
+class MarkupLexer {
+ StringRef::const_iterator Start;
+ StringRef::const_iterator CurPtr;
+ StringRef::const_iterator End;
+public:
+ MarkupLexer(StringRef Source)
+ : Start(Source.begin()), CurPtr(Source.begin()), End(Source.end()) {}
+ // When processing non-markup, input is consumed a character at a time.
+ bool isEOF() { return CurPtr == End; }
+ int getNextChar() {
+ if (CurPtr == End) return EOF;
+ return *CurPtr++;
+ }
+ int peekNextChar() {
+ if (CurPtr == End) return EOF;
+ return *CurPtr;
+ }
+ StringRef::const_iterator getPosition() const { return CurPtr; }
+};
+
+/// A markup tag is a name and a (usually empty) list of modifiers.
+class MarkupTag {
+ StringRef Name;
+ StringRef Modifiers;
+ SMLoc StartLoc;
+public:
+ MarkupTag(StringRef n, StringRef m, SMLoc Loc)
+ : Name(n), Modifiers(m), StartLoc(Loc) {}
+ StringRef getName() const { return Name; }
+ StringRef getModifiers() const { return Modifiers; }
+ SMLoc getLoc() const { return StartLoc; }
+};
+
+/// A simple parser implementation for creating MarkupTags from input text.
+class MarkupParser {
+ MarkupLexer &Lex;
+ SourceMgr &SM;
+public:
+ MarkupParser(MarkupLexer &lex, SourceMgr &SrcMgr) : Lex(lex), SM(SrcMgr) {}
+ /// Create a MarkupTag from the current position in the MarkupLexer.
+ /// The parseTag() method should be called when the lexer has processed
+ /// the opening '<' character. Input will be consumed up to and including
+ /// the ':' which terminates the tag open.
+ MarkupTag parseTag();
+ /// Issue a diagnostic and terminate program execution.
+ void FatalError(SMLoc Loc, StringRef Msg);
+};
+
+void MarkupParser::FatalError(SMLoc Loc, StringRef Msg) {
+ SM.PrintMessage(Loc, SourceMgr::DK_Error, Msg);
+ exit(1);
+}
+
+// Example handler for when a tag is recognized.
+static void processStartTag(MarkupTag &Tag) {
+ // If we're just printing the tags, do that, otherwise do some simple
+ // colorization.
+ if (DumpTags) {
+ outs() << Tag.getName();
+ if (Tag.getModifiers().size())
+ outs() << " " << Tag.getModifiers();
+ outs() << "\n";
+ return;
+ }
+
+ if (!outs().has_colors())
+ return;
+ // Color registers as red and immediates as cyan. Those don't have nested
+ // tags, so don't bother keeping a stack of colors to reset to.
+ if (Tag.getName() == "reg")
+ outs().changeColor(raw_ostream::RED);
+ else if (Tag.getName() == "imm")
+ outs().changeColor(raw_ostream::CYAN);
+}
+
+// Example handler for when the end of a tag is recognized.
+static void processEndTag(MarkupTag &Tag) {
+ // If we're printing the tags, there's nothing more to do here. Otherwise,
+ // set the color back the normal.
+ if (DumpTags)
+ return;
+ if (!outs().has_colors())
+ return;
+ // Just reset to basic white.
+ outs().changeColor(raw_ostream::WHITE, false);
+}
+
+MarkupTag MarkupParser::parseTag() {
+ // First off, extract the tag into it's own StringRef so we can look at it
+ // outside of the context of consuming input.
+ StringRef::const_iterator Start = Lex.getPosition();
+ SMLoc Loc = SMLoc::getFromPointer(Start - 1);
+ while(Lex.getNextChar() != ':') {
+ // EOF is an error.
+ if (Lex.isEOF())
+ FatalError(SMLoc::getFromPointer(Start), "unterminated markup tag");
+ }
+ StringRef RawTag(Start, Lex.getPosition() - Start - 1);
+ std::pair<StringRef, StringRef> SplitTag = RawTag.split(' ');
+ return MarkupTag(SplitTag.first, SplitTag.second, Loc);
+}
+
+static void parseMCMarkup(StringRef Filename) {
+ OwningPtr<MemoryBuffer> BufferPtr;
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, BufferPtr)) {
+ errs() << ToolName << ": " << ec.message() << '\n';
+ return;
+ }
+ MemoryBuffer *Buffer = BufferPtr.take();
+
+ SourceMgr SrcMgr;
+
+ // Tell SrcMgr about this buffer, which is what the parser will pick up.
+ SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
+
+ StringRef InputSource = Buffer->getBuffer();
+ MarkupLexer Lex(InputSource);
+ MarkupParser Parser(Lex, SrcMgr);
+
+ SmallVector<MarkupTag, 4> TagStack;
+
+ for (int CurChar = Lex.getNextChar();
+ CurChar != EOF;
+ CurChar = Lex.getNextChar()) {
+ switch (CurChar) {
+ case '<': {
+ // A "<<" is output as a literal '<' and does not start a markup tag.
+ if (Lex.peekNextChar() == '<') {
+ (void)Lex.getNextChar();
+ break;
+ }
+ // Parse the markup entry.
+ TagStack.push_back(Parser.parseTag());
+
+ // Do any special handling for the start of a tag.
+ processStartTag(TagStack.back());
+ continue;
+ }
+ case '>': {
+ SMLoc Loc = SMLoc::getFromPointer(Lex.getPosition() - 1);
+ // A ">>" is output as a literal '>' and does not end a markup tag.
+ if (Lex.peekNextChar() == '>') {
+ (void)Lex.getNextChar();
+ break;
+ }
+ // Close out the innermost tag.
+ if (TagStack.empty())
+ Parser.FatalError(Loc, "'>' without matching '<'");
+
+ // Do any special handling for the end of a tag.
+ processEndTag(TagStack.back());
+
+ TagStack.pop_back();
+ continue;
+ }
+ default:
+ break;
+ }
+ // For anything else, just echo the character back out.
+ if (!DumpTags && CurChar != EOF)
+ outs() << (char)CurChar;
+ }
+
+ // If there are any unterminated markup tags, issue diagnostics for them.
+ while (!TagStack.empty()) {
+ MarkupTag &Tag = TagStack.back();
+ SrcMgr.PrintMessage(Tag.getLoc(), SourceMgr::DK_Error,
+ "unterminated markup tag");
+ TagStack.pop_back();
+ }
+}
+
+int main(int argc, char **argv) {
+ // Print a stack trace if we signal out.
+ sys::PrintStackTraceOnErrorSignal();
+ PrettyStackTraceProgram X(argc, argv);
+
+ llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
+ cl::ParseCommandLineOptions(argc, argv, "llvm MC markup parser\n");
+
+ ToolName = argv[0];
+
+ // If no input files specified, read from stdin.
+ if (InputFilenames.size() == 0)
+ InputFilenames.push_back("-");
+
+ std::for_each(InputFilenames.begin(), InputFilenames.end(),
+ parseMCMarkup);
+ return 0;
+}
diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp
index eb52acc..056fd35 100644
--- a/tools/llvm-nm/llvm-nm.cpp
+++ b/tools/llvm-nm/llvm-nm.cpp
@@ -16,21 +16,21 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
-#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/IR/LLVMContext.h"
#include "llvm/Bitcode/Archive.h"
+#include "llvm/Bitcode/ReaderWriter.h"
+#include "llvm/IR/Module.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Program.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Signals.h"
-#include "llvm/Support/Format.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
#include <algorithm>
#include <cctype>
@@ -110,6 +110,13 @@ namespace {
cl::opt<bool> SizeSort("size-sort", cl::desc("Sort symbols by size"));
+ cl::opt<bool> WithoutAliases("without-aliases", cl::Hidden,
+ cl::desc("Exclude aliases from output"));
+
+ cl::opt<bool> ArchiveMap("print-armap",
+ cl::desc("Print the archive map"));
+ cl::alias ArchiveMaps("s", cl::desc("Alias for --print-armap"),
+ cl::aliasopt(ArchiveMap));
bool PrintAddress = true;
bool MultipleFiles = false;
@@ -143,6 +150,8 @@ namespace {
return true;
else if (a.Address == b.Address && a.Name < b.Name)
return true;
+ else if (a.Address == b.Address && a.Name == b.Name && a.Size < b.Size)
+ return true;
else
return false;
@@ -153,12 +162,21 @@ namespace {
return true;
else if (a.Size == b.Size && a.Name < b.Name)
return true;
+ else if (a.Size == b.Size && a.Name == b.Name && a.Address < b.Address)
+ return true;
else
return false;
}
static bool CompareSymbolName(const NMSymbol &a, const NMSymbol &b) {
- return a.Name < b.Name;
+ if (a.Name < b.Name)
+ return true;
+ else if (a.Name == b.Name && a.Size < b.Size)
+ return true;
+ else if (a.Name == b.Name && a.Size == b.Size && a.Address < b.Address)
+ return true;
+ else
+ return false;
}
StringRef CurrentFilename;
@@ -275,8 +293,9 @@ static void DumpSymbolNamesFromModule(Module *M) {
std::for_each (M->begin(), M->end(), DumpSymbolNameForGlobalValue);
std::for_each (M->global_begin(), M->global_end(),
DumpSymbolNameForGlobalValue);
- std::for_each (M->alias_begin(), M->alias_end(),
- DumpSymbolNameForGlobalValue);
+ if (!WithoutAliases)
+ std::for_each (M->alias_begin(), M->alias_end(),
+ DumpSymbolNameForGlobalValue);
SortAndPrintSymbolList();
}
@@ -342,6 +361,24 @@ static void DumpSymbolNamesFromFile(std::string &Filename) {
return;
if (object::Archive *a = dyn_cast<object::Archive>(arch.get())) {
+ if (ArchiveMap) {
+ outs() << "Archive map" << "\n";
+ for (object::Archive::symbol_iterator i = a->begin_symbols(),
+ e = a->end_symbols(); i != e; ++i) {
+ object::Archive::child_iterator c;
+ StringRef symname;
+ StringRef filename;
+ if (error(i->getMember(c)))
+ return;
+ if (error(i->getName(symname)))
+ return;
+ if (error(c->getName(filename)))
+ return;
+ outs() << symname << " in " << filename << "\n";
+ }
+ outs() << "\n";
+ }
+
for (object::Archive::child_iterator i = a->begin_children(),
e = a->end_children(); i != e; ++i) {
OwningPtr<Binary> child;
diff --git a/tools/llvm-objdump/CMakeLists.txt b/tools/llvm-objdump/CMakeLists.txt
index f3b2e1f..0c49d0b 100644
--- a/tools/llvm-objdump/CMakeLists.txt
+++ b/tools/llvm-objdump/CMakeLists.txt
@@ -9,6 +9,8 @@ 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
new file mode 100644
index 0000000..2ada683
--- /dev/null
+++ b/tools/llvm-objdump/COFFDump.cpp
@@ -0,0 +1,355 @@
+//===-- COFFDump.cpp - COFF-specific dumper ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief This file implements the COFF-specific dumper for llvm-objdump.
+/// It outputs the Win64 EH data structures as plain text.
+/// The encoding of the unwind codes is decribed in MSDN:
+/// http://msdn.microsoft.com/en-us/library/ck9asaa9.aspx
+///
+//===----------------------------------------------------------------------===//
+
+#include "llvm-objdump.h"
+#include "llvm/Object/COFF.h"
+#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 <algorithm>
+#include <cstring>
+
+using namespace llvm;
+using namespace object;
+using namespace llvm::Win64EH;
+
+// Returns the name of the unwind code.
+static StringRef getUnwindCodeTypeName(uint8_t Code) {
+ switch(Code) {
+ default: llvm_unreachable("Invalid unwind code");
+ case UOP_PushNonVol: return "UOP_PushNonVol";
+ case UOP_AllocLarge: return "UOP_AllocLarge";
+ case UOP_AllocSmall: return "UOP_AllocSmall";
+ case UOP_SetFPReg: return "UOP_SetFPReg";
+ case UOP_SaveNonVol: return "UOP_SaveNonVol";
+ case UOP_SaveNonVolBig: return "UOP_SaveNonVolBig";
+ case UOP_SaveXMM128: return "UOP_SaveXMM128";
+ case UOP_SaveXMM128Big: return "UOP_SaveXMM128Big";
+ case UOP_PushMachFrame: return "UOP_PushMachFrame";
+ }
+}
+
+// Returns the name of a referenced register.
+static StringRef getUnwindRegisterName(uint8_t Reg) {
+ switch(Reg) {
+ default: llvm_unreachable("Invalid register");
+ case 0: return "RAX";
+ case 1: return "RCX";
+ case 2: return "RDX";
+ case 3: return "RBX";
+ case 4: return "RSP";
+ case 5: return "RBP";
+ case 6: return "RSI";
+ case 7: return "RDI";
+ case 8: return "R8";
+ case 9: return "R9";
+ case 10: return "R10";
+ case 11: return "R11";
+ case 12: return "R12";
+ case 13: return "R13";
+ case 14: return "R14";
+ case 15: return "R15";
+ }
+}
+
+// Calculates the number of array slots required for the unwind code.
+static unsigned getNumUsedSlots(const UnwindCode &UnwindCode) {
+ switch (UnwindCode.getUnwindOp()) {
+ default: llvm_unreachable("Invalid unwind code");
+ case UOP_PushNonVol:
+ case UOP_AllocSmall:
+ case UOP_SetFPReg:
+ case UOP_PushMachFrame:
+ return 1;
+ case UOP_SaveNonVol:
+ case UOP_SaveXMM128:
+ return 2;
+ case UOP_SaveNonVolBig:
+ case UOP_SaveXMM128Big:
+ return 3;
+ case UOP_AllocLarge:
+ return (UnwindCode.getOpInfo() == 0) ? 2 : 3;
+ }
+}
+
+// Prints one unwind code. Because an unwind code can occupy up to 3 slots in
+// the unwind codes array, this function requires that the correct number of
+// slots is provided.
+static void printUnwindCode(ArrayRef<UnwindCode> UCs) {
+ assert(UCs.size() >= getNumUsedSlots(UCs[0]));
+ outs() << format(" 0x%02x: ", unsigned(UCs[0].u.CodeOffset))
+ << getUnwindCodeTypeName(UCs[0].getUnwindOp());
+ switch (UCs[0].getUnwindOp()) {
+ case UOP_PushNonVol:
+ outs() << " " << getUnwindRegisterName(UCs[0].getOpInfo());
+ break;
+ case UOP_AllocLarge:
+ if (UCs[0].getOpInfo() == 0) {
+ outs() << " " << UCs[1].FrameOffset;
+ } else {
+ outs() << " " << UCs[1].FrameOffset
+ + (static_cast<uint32_t>(UCs[2].FrameOffset) << 16);
+ }
+ break;
+ case UOP_AllocSmall:
+ outs() << " " << ((UCs[0].getOpInfo() + 1) * 8);
+ break;
+ case UOP_SetFPReg:
+ outs() << " ";
+ break;
+ case UOP_SaveNonVol:
+ outs() << " " << getUnwindRegisterName(UCs[0].getOpInfo())
+ << format(" [0x%04x]", 8 * UCs[1].FrameOffset);
+ break;
+ case UOP_SaveNonVolBig:
+ outs() << " " << getUnwindRegisterName(UCs[0].getOpInfo())
+ << format(" [0x%08x]", UCs[1].FrameOffset
+ + (static_cast<uint32_t>(UCs[2].FrameOffset) << 16));
+ break;
+ case UOP_SaveXMM128:
+ outs() << " XMM" << static_cast<uint32_t>(UCs[0].getOpInfo())
+ << format(" [0x%04x]", 16 * UCs[1].FrameOffset);
+ break;
+ case UOP_SaveXMM128Big:
+ outs() << " XMM" << UCs[0].getOpInfo()
+ << format(" [0x%08x]", UCs[1].FrameOffset
+ + (static_cast<uint32_t>(UCs[2].FrameOffset) << 16));
+ break;
+ case UOP_PushMachFrame:
+ outs() << " " << (UCs[0].getOpInfo() ? "w/o" : "w")
+ << " error code";
+ break;
+ }
+ outs() << "\n";
+}
+
+static void printAllUnwindCodes(ArrayRef<UnwindCode> UCs) {
+ for (const UnwindCode *I = UCs.begin(), *E = UCs.end(); I < E; ) {
+ unsigned UsedSlots = getNumUsedSlots(*I);
+ if (UsedSlots > UCs.size()) {
+ outs() << "Unwind data corrupted: Encountered unwind op "
+ << getUnwindCodeTypeName((*I).getUnwindOp())
+ << " which requires " << UsedSlots
+ << " slots, but only " << UCs.size()
+ << " remaining in buffer";
+ return ;
+ }
+ printUnwindCode(ArrayRef<UnwindCode>(I, E));
+ I += UsedSlots;
+ }
+}
+
+// Given a symbol sym this functions returns the address and section of it.
+static error_code resolveSectionAndAddress(const COFFObjectFile *Obj,
+ const SymbolRef &Sym,
+ const coff_section *&ResolvedSection,
+ uint64_t &ResolvedAddr) {
+ if (error_code ec = Sym.getAddress(ResolvedAddr)) return ec;
+ section_iterator iter(Obj->begin_sections());
+ if (error_code ec = Sym.getSection(iter)) return ec;
+ ResolvedSection = Obj->getCOFFSection(iter);
+ return object_error::success;
+}
+
+// Given a vector of relocations for a section and an offset into this section
+// the function returns the symbol used for the relocation at the offset.
+static error_code resolveSymbol(const std::vector<RelocationRef> &Rels,
+ uint64_t Offset, SymbolRef &Sym) {
+ for (std::vector<RelocationRef>::const_iterator I = Rels.begin(),
+ E = Rels.end();
+ I != E; ++I) {
+ uint64_t Ofs;
+ if (error_code ec = I->getOffset(Ofs)) return ec;
+ if (Ofs == Offset) {
+ if (error_code ec = I->getSymbol(Sym)) return ec;
+ break;
+ }
+ }
+ return object_error::success;
+}
+
+// Given a vector of relocations for a section and an offset into this section
+// the function resolves the symbol used for the relocation at the offset and
+// returns the section content and the address inside the content pointed to
+// by the symbol.
+static error_code getSectionContents(const COFFObjectFile *Obj,
+ const std::vector<RelocationRef> &Rels,
+ uint64_t Offset,
+ ArrayRef<uint8_t> &Contents,
+ uint64_t &Addr) {
+ SymbolRef Sym;
+ if (error_code ec = resolveSymbol(Rels, Offset, Sym)) return ec;
+ const coff_section *Section;
+ if (error_code ec = resolveSectionAndAddress(Obj, Sym, Section, Addr))
+ return ec;
+ if (error_code ec = Obj->getSectionContents(Section, Contents)) return ec;
+ return object_error::success;
+}
+
+// Given a vector of relocations for a section and an offset into this section
+// the function returns the name of the symbol used for the relocation at the
+// offset.
+static error_code resolveSymbolName(const std::vector<RelocationRef> &Rels,
+ uint64_t Offset, StringRef &Name) {
+ SymbolRef Sym;
+ if (error_code ec = resolveSymbol(Rels, Offset, Sym)) return ec;
+ if (error_code ec = Sym.getName(Name)) return ec;
+ return object_error::success;
+}
+
+static void printCOFFSymbolAddress(llvm::raw_ostream &Out,
+ const std::vector<RelocationRef> &Rels,
+ uint64_t Offset, uint32_t Disp) {
+ StringRef Sym;
+ if (error_code ec = resolveSymbolName(Rels, Offset, Sym)) {
+ error(ec);
+ return ;
+ }
+ Out << Sym;
+ if (Disp > 0)
+ Out << format(" + 0x%04x", Disp);
+}
+
+void llvm::printCOFFUnwindInfo(const COFFObjectFile *Obj) {
+ const coff_file_header *Header;
+ if (error(Obj->getHeader(Header))) return;
+
+ if (Header->Machine != COFF::IMAGE_FILE_MACHINE_AMD64) {
+ errs() << "Unsupported image machine type "
+ "(currently only AMD64 is supported).\n";
+ return;
+ }
+
+ const coff_section *Pdata = 0;
+
+ error_code ec;
+ for (section_iterator SI = Obj->begin_sections(),
+ SE = Obj->end_sections();
+ SI != SE; SI.increment(ec)) {
+ if (error(ec)) return;
+
+ StringRef Name;
+ if (error(SI->getName(Name))) continue;
+
+ if (Name != ".pdata") continue;
+
+ Pdata = Obj->getCOFFSection(SI);
+ std::vector<RelocationRef> Rels;
+ for (relocation_iterator RI = SI->begin_relocations(),
+ RE = SI->end_relocations();
+ RI != RE; RI.increment(ec)) {
+ if (error(ec)) break;
+ Rels.push_back(*RI);
+ }
+
+ // Sort relocations by address.
+ std::sort(Rels.begin(), Rels.end(), RelocAddressLess);
+
+ ArrayRef<uint8_t> Contents;
+ if (error(Obj->getSectionContents(Pdata, Contents))) continue;
+ if (Contents.empty()) continue;
+
+ ArrayRef<RuntimeFunction> RFs(
+ reinterpret_cast<const RuntimeFunction *>(Contents.data()),
+ Contents.size() / sizeof(RuntimeFunction));
+ for (const RuntimeFunction *I = RFs.begin(), *E = RFs.end(); I < E; ++I) {
+ const uint64_t SectionOffset = std::distance(RFs.begin(), I)
+ * sizeof(RuntimeFunction);
+
+ outs() << "Function Table:\n";
+
+ outs() << " Start Address: ";
+ printCOFFSymbolAddress(outs(), Rels, SectionOffset +
+ /*offsetof(RuntimeFunction, StartAddress)*/ 0,
+ I->StartAddress);
+ outs() << "\n";
+
+ outs() << " End Address: ";
+ printCOFFSymbolAddress(outs(), Rels, SectionOffset +
+ /*offsetof(RuntimeFunction, EndAddress)*/ 4,
+ I->EndAddress);
+ outs() << "\n";
+
+ outs() << " Unwind Info Address: ";
+ printCOFFSymbolAddress(outs(), Rels, SectionOffset +
+ /*offsetof(RuntimeFunction, UnwindInfoOffset)*/ 8,
+ I->UnwindInfoOffset);
+ outs() << "\n";
+
+ ArrayRef<uint8_t> XContents;
+ uint64_t UnwindInfoOffset = 0;
+ if (error(getSectionContents(Obj, Rels, SectionOffset +
+ /*offsetof(RuntimeFunction, UnwindInfoOffset)*/ 8,
+ XContents, UnwindInfoOffset))) continue;
+ if (XContents.empty()) continue;
+
+ UnwindInfoOffset += I->UnwindInfoOffset;
+ if (UnwindInfoOffset > XContents.size()) continue;
+
+ const Win64EH::UnwindInfo *UI =
+ reinterpret_cast<const Win64EH::UnwindInfo *>
+ (XContents.data() + UnwindInfoOffset);
+
+ // The casts to int are required in order to output the value as number.
+ // Without the casts the value would be interpreted as char data (which
+ // results in garbage output).
+ outs() << " Version: " << static_cast<int>(UI->getVersion()) << "\n";
+ outs() << " Flags: " << static_cast<int>(UI->getFlags());
+ if (UI->getFlags()) {
+ if (UI->getFlags() & UNW_ExceptionHandler)
+ outs() << " UNW_ExceptionHandler";
+ if (UI->getFlags() & UNW_TerminateHandler)
+ outs() << " UNW_TerminateHandler";
+ if (UI->getFlags() & UNW_ChainInfo)
+ outs() << " UNW_ChainInfo";
+ }
+ outs() << "\n";
+ outs() << " Size of prolog: "
+ << static_cast<int>(UI->PrologSize) << "\n";
+ outs() << " Number of Codes: "
+ << static_cast<int>(UI->NumCodes) << "\n";
+ // Maybe this should move to output of UOP_SetFPReg?
+ if (UI->getFrameRegister()) {
+ outs() << " Frame register: "
+ << getUnwindRegisterName(UI->getFrameRegister())
+ << "\n";
+ outs() << " Frame offset: "
+ << 16 * UI->getFrameOffset()
+ << "\n";
+ } else {
+ outs() << " No frame pointer used\n";
+ }
+ if (UI->getFlags() & (UNW_ExceptionHandler | UNW_TerminateHandler)) {
+ // FIXME: Output exception handler data
+ } else if (UI->getFlags() & UNW_ChainInfo) {
+ // FIXME: Output chained unwind info
+ }
+
+ if (UI->NumCodes)
+ outs() << " Unwind Codes:\n";
+
+ printAllUnwindCodes(ArrayRef<UnwindCode>(&UI->UnwindCodes[0],
+ UI->NumCodes));
+
+ outs() << "\n\n";
+ outs().flush();
+ }
+ }
+}
diff --git a/tools/llvm-objdump/ELFDump.cpp b/tools/llvm-objdump/ELFDump.cpp
new file mode 100644
index 0000000..a635fef
--- /dev/null
+++ b/tools/llvm-objdump/ELFDump.cpp
@@ -0,0 +1,89 @@
+//===-- 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<endianness target_endianness, std::size_t max_alignment, bool is64Bits>
+void printProgramHeaders(
+ const ELFObjectFile<target_endianness, max_alignment, is64Bits> *o) {
+ typedef ELFObjectFile<target_endianness, max_alignment, is64Bits> 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;
+ default:
+ outs() << " UNKNOWN ";
+ }
+
+ const char *Fmt = 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<support::little, 4, false> *ELFObj =
+ dyn_cast<ELFObjectFile<support::little, 4, false> >(Obj))
+ printProgramHeaders(ELFObj);
+
+ // Big-endian 32-bit
+ if (const ELFObjectFile<support::big, 4, false> *ELFObj =
+ dyn_cast<ELFObjectFile<support::big, 4, false> >(Obj))
+ printProgramHeaders(ELFObj);
+
+ // Little-endian 64-bit
+ if (const ELFObjectFile<support::little, 8, true> *ELFObj =
+ dyn_cast<ELFObjectFile<support::little, 8, true> >(Obj))
+ printProgramHeaders(ELFObj);
+
+ // Big-endian 64-bit
+ if (const ELFObjectFile<support::big, 8, true> *ELFObj =
+ dyn_cast<ELFObjectFile<support::big, 8, true> >(Obj))
+ printProgramHeaders(ELFObj);
+}
diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp
index 1feea42..c324ff1 100644
--- a/tools/llvm-objdump/MachODump.cpp
+++ b/tools/llvm-objdump/MachODump.cpp
@@ -13,11 +13,9 @@
#include "llvm-objdump.h"
#include "MCFunction.h"
-#include "llvm/Support/MachO.h"
-#include "llvm/Object/MachO.h"
#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/Triple.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCDisassembler.h"
@@ -28,10 +26,12 @@
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Object/MachO.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/GraphWriter.h"
+#include "llvm/Support/MachO.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
@@ -309,16 +309,10 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
raw_ostream &DebugOut = nulls();
#endif
- StringRef DebugAbbrevSection, DebugInfoSection, DebugArangesSection,
- DebugLineSection, DebugStrSection;
OwningPtr<DIContext> diContext;
- OwningPtr<MachOObjectFile> DSYMObj;
- MachOObject *DbgInfoObj = MachOObj;
+ ObjectFile *DbgObj = MachOOF.get();
// Try to find debug info and set up the DIContext for it.
if (UseDbg) {
- ArrayRef<SectionRef> DebugSections = Sections;
- std::vector<SectionRef> DSYMSections;
-
// A separate DSym file path was specified, parse it as a macho file,
// get the sections and supply it to the section name parsing machinery.
if (!DSYMFile.empty()) {
@@ -327,42 +321,11 @@ void llvm::DisassembleInputMachO(StringRef Filename) {
errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n';
return;
}
- DSYMObj.reset(static_cast<MachOObjectFile*>(
- ObjectFile::createMachOObjectFile(Buf.take())));
- const macho::Header &Header = DSYMObj->getObject()->getHeader();
-
- std::vector<SymbolRef> Symbols;
- SmallVector<uint64_t, 8> FoundFns;
- getSectionsAndSymbols(Header, DSYMObj.get(), 0, DSYMSections, Symbols,
- FoundFns);
- DebugSections = DSYMSections;
- DbgInfoObj = DSYMObj.get()->getObject();
- }
-
- // Find the named debug info sections.
- for (unsigned SectIdx = 0; SectIdx != DebugSections.size(); SectIdx++) {
- StringRef SectName;
- if (!DebugSections[SectIdx].getName(SectName)) {
- if (SectName.equals("__DWARF,__debug_abbrev"))
- DebugSections[SectIdx].getContents(DebugAbbrevSection);
- else if (SectName.equals("__DWARF,__debug_info"))
- DebugSections[SectIdx].getContents(DebugInfoSection);
- else if (SectName.equals("__DWARF,__debug_aranges"))
- DebugSections[SectIdx].getContents(DebugArangesSection);
- else if (SectName.equals("__DWARF,__debug_line"))
- DebugSections[SectIdx].getContents(DebugLineSection);
- else if (SectName.equals("__DWARF,__debug_str"))
- DebugSections[SectIdx].getContents(DebugStrSection);
- }
+ DbgObj = ObjectFile::createMachOObjectFile(Buf.take());
}
- // Setup the DIContext.
- diContext.reset(DIContext::getDWARFContext(DbgInfoObj->isLittleEndian(),
- DebugInfoSection,
- DebugAbbrevSection,
- DebugArangesSection,
- DebugLineSection,
- DebugStrSection));
+ // Setup the DIContext
+ diContext.reset(DIContext::getDWARFContext(DbgObj));
}
FunctionMapTy FunctionMap;
@@ -371,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 13ea4e3..9958dad 100644
--- a/tools/llvm-objdump/llvm-objdump.cpp
+++ b/tools/llvm-objdump/llvm-objdump.cpp
@@ -15,13 +15,10 @@
#include "llvm-objdump.h"
#include "MCFunction.h"
-#include "llvm/Object/Archive.h"
-#include "llvm/Object/COFF.h"
-#include "llvm/Object/ObjectFile.h"
#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Triple.h"
-#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
@@ -29,6 +26,11 @@
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Object/Archive.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Object/ELF.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"
@@ -72,9 +74,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, "
@@ -100,9 +102,28 @@ MAttrs("mattr",
cl::desc("Target specific attributes"),
cl::value_desc("a1,+a2,-a3,..."));
+static cl::opt<bool>
+NoShowRawInsn("no-show-raw-insn", cl::desc("When disassembling instructions, "
+ "do not print the instruction bytes."));
+
+static cl::opt<bool>
+UnwindInfo("unwind-info", cl::desc("Display unwind information"));
+
+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;
-static bool error(error_code ec) {
+bool llvm::error(error_code ec) {
if (!ec) return false;
outs() << ToolName << ": error reading file: " << ec.message() << ".\n";
@@ -161,7 +182,7 @@ void llvm::DumpBytes(StringRef bytes) {
outs() << output;
}
-static bool RelocAddressLess(RelocationRef a, RelocationRef b) {
+bool llvm::RelocAddressLess(RelocationRef a, RelocationRef b) {
uint64_t a_addr, b_addr;
if (error(a.getAddress(a_addr))) return false;
if (error(b.getAddress(b_addr))) return false;
@@ -230,9 +251,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.
@@ -321,8 +351,11 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
DebugOut, nulls())) {
- outs() << format("%8" PRIx64 ":\t", SectionAddr + Index);
- DumpBytes(StringRef(Bytes.data() + Index, Size));
+ outs() << format("%8" PRIx64 ":", SectionAddr + Index);
+ if (!NoShowRawInsn) {
+ outs() << "\t";
+ DumpBytes(StringRef(Bytes.data() + Index, Size));
+ }
IP->printInst(&Inst, outs(), "");
outs() << "\n";
} else {
@@ -553,6 +586,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 = "";
@@ -566,6 +606,19 @@ static void PrintSymbolTable(const ObjectFile *o) {
}
}
+static void PrintUnwindInfo(const ObjectFile *o) {
+ outs() << "Unwind info:\n\n";
+
+ if (const COFFObjectFile *coff = dyn_cast<COFFObjectFile>(o)) {
+ printCOFFUnwindInfo(coff);
+ } else {
+ // TODO: Extract DWARF dump tool to objdump.
+ errs() << "This operation is only currently supported "
+ "for COFF object files.\n";
+ return;
+ }
+}
+
static void DumpObject(const ObjectFile *o) {
outs() << '\n';
outs() << o->getFileName()
@@ -581,6 +634,10 @@ static void DumpObject(const ObjectFile *o) {
PrintSectionContents(o);
if (SymbolTable)
PrintSymbolTable(o);
+ if (UnwindInfo)
+ PrintUnwindInfo(o);
+ if (PrivateHeaders && o->isELF())
+ printELFFileHeader(o);
}
/// @brief Dump each object file in \a a;
@@ -611,7 +668,7 @@ static void DumpInput(StringRef file) {
return;
}
- if (MachO && Disassemble) {
+ if (MachOOpt && Disassemble) {
DisassembleInputMachO(file);
return;
}
@@ -659,7 +716,9 @@ int main(int argc, char **argv) {
&& !Relocations
&& !SectionHeaders
&& !SectionContents
- && !SymbolTable) {
+ && !SymbolTable
+ && !UnwindInfo
+ && !PrivateHeaders) {
cl::PrintHelpMessage();
return 2;
}
diff --git a/tools/llvm-objdump/llvm-objdump.h b/tools/llvm-objdump/llvm-objdump.h
index aa71b77..ca7bced 100644
--- a/tools/llvm-objdump/llvm-objdump.h
+++ b/tools/llvm-objdump/llvm-objdump.h
@@ -17,12 +17,23 @@
namespace llvm {
+namespace object {
+ class COFFObjectFile;
+ class ObjectFile;
+ class RelocationRef;
+}
+class error_code;
+
extern cl::opt<std::string> TripleName;
extern cl::opt<std::string> ArchName;
// Various helper functions.
+bool error(error_code ec);
+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 81e9503..b2c3f06 100644
--- a/tools/llvm-prof/llvm-prof.cpp
+++ b/tools/llvm-prof/llvm-prof.cpp
@@ -13,23 +13,23 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/InstrTypes.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
-#include "llvm/PassManager.h"
-#include "llvm/Assembly/AssemblyAnnotationWriter.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/ProfileInfo.h"
#include "llvm/Analysis/ProfileInfoLoader.h"
-#include "llvm/Analysis/Passes.h"
+#include "llvm/Assembly/AssemblyAnnotationWriter.h"
#include "llvm/Bitcode/ReaderWriter.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"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Support/Format.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
#include <algorithm>
#include <iomanip>
diff --git a/tools/llvm-ranlib/CMakeLists.txt b/tools/llvm-ranlib/CMakeLists.txt
index 3116d2e..2d7defe 100644
--- a/tools/llvm-ranlib/CMakeLists.txt
+++ b/tools/llvm-ranlib/CMakeLists.txt
@@ -1,5 +1,4 @@
set(LLVM_LINK_COMPONENTS archive)
-set(LLVM_REQUIRES_EH 1)
add_llvm_tool(llvm-ranlib
llvm-ranlib.cpp
diff --git a/tools/llvm-ranlib/Makefile b/tools/llvm-ranlib/Makefile
index 36195f4..cca9501 100644
--- a/tools/llvm-ranlib/Makefile
+++ b/tools/llvm-ranlib/Makefile
@@ -10,7 +10,6 @@
LEVEL := ../..
TOOLNAME := llvm-ranlib
LINK_COMPONENTS := archive
-REQUIRES_EH := 1
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS := 1
diff --git a/tools/llvm-ranlib/llvm-ranlib.cpp b/tools/llvm-ranlib/llvm-ranlib.cpp
index 4006765..fe9d3e2 100644
--- a/tools/llvm-ranlib/llvm-ranlib.cpp
+++ b/tools/llvm-ranlib/llvm-ranlib.cpp
@@ -11,16 +11,16 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
+#include "llvm/IR/LLVMContext.h"
#include "llvm/Bitcode/Archive.h"
+#include "llvm/IR/Module.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/Format.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/raw_ostream.h"
#include <memory>
using namespace llvm;
@@ -61,41 +61,38 @@ int main(int argc, char **argv) {
int exitCode = 0;
- // Make sure we don't exit with "unhandled exception".
- try {
-
- // Check the path name of the archive
- sys::Path ArchivePath;
- if (!ArchivePath.set(ArchiveName))
- throw std::string("Archive name invalid: ") + ArchiveName;
+ // Check the path name of the archive
+ sys::Path ArchivePath;
+ if (!ArchivePath.set(ArchiveName)) {
+ errs() << argv[0] << ": " << "Archive name invalid: " << ArchiveName <<
+ "\n";
+ return 1;
+ }
- // Make sure it exists, we don't create empty archives
- bool Exists;
- if (llvm::sys::fs::exists(ArchivePath.str(), Exists) || !Exists)
- throw std::string("Archive file does not exist");
+ // Make sure it exists, we don't create empty archives
+ bool Exists;
+ if (llvm::sys::fs::exists(ArchivePath.str(), Exists) || !Exists) {
+ errs() << argv[0] << ": " << "Archive file does not exist" <<
+ ArchivePath.str() << "\n";
+ return 1;
+ }
- std::string err_msg;
- std::auto_ptr<Archive>
- AutoArchive(Archive::OpenAndLoad(ArchivePath, Context, &err_msg));
- Archive* TheArchive = AutoArchive.get();
- if (!TheArchive)
- throw err_msg;
+ std::string err_msg;
+ std::auto_ptr<Archive>
+ AutoArchive(Archive::OpenAndLoad(ArchivePath, Context, &err_msg));
+ Archive* TheArchive = AutoArchive.get();
+ if (!TheArchive) {
+ errs() << argv[0] << ": " << err_msg << "\n";
+ return 1;
+ }
- if (TheArchive->writeToDisk(true, false, &err_msg ))
- throw err_msg;
+ if (TheArchive->writeToDisk(true, false, &err_msg )) {
+ errs() << argv[0] << ": " << err_msg << "\n";
+ return 1;
+ }
- if (Verbose)
- printSymbolTable(TheArchive);
+ if (Verbose)
+ printSymbolTable(TheArchive);
- } catch (const char* msg) {
- errs() << argv[0] << ": " << msg << "\n\n";
- exitCode = 1;
- } catch (const std::string& msg) {
- errs() << argv[0] << ": " << msg << "\n";
- exitCode = 2;
- } catch (...) {
- errs() << argv[0] << ": An unexpected unknown exception occurred.\n";
- exitCode = 3;
- }
return exitCode;
}
diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp
index 3be1289..d22ecd1 100644
--- a/tools/llvm-readobj/llvm-readobj.cpp
+++ b/tools/llvm-readobj/llvm-readobj.cpp
@@ -16,16 +16,16 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Object/ObjectFile.h"
-#include "llvm/Object/ELF.h"
-#include "llvm/Analysis/Verifier.h"
#include "llvm/ADT/Triple.h"
-#include "llvm/Support/Format.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Object/ELF.h"
+#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Debug.h"
-#include "llvm/Support/Signals.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/FormattedStream.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Signals.h"
using namespace llvm;
using namespace llvm::object;
@@ -33,7 +33,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 +43,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 +64,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 +88,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";
}
-void DumpLibrary(const LibraryRef &lib) {
+static void dumpStaticSymbol(const SymbolRef &Sym, const ObjectFile *obj) {
+ return dumpSymbol(Sym, obj, false);
+}
+
+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())
@@ -209,10 +242,27 @@ int main(int argc, char** argv) {
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");
+
+ 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-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp
index 95de8d8..ec63c9b 100644
--- a/tools/llvm-rtdyld/llvm-rtdyld.cpp
+++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp
@@ -11,8 +11,10 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/ExecutionEngine/ObjectBuffer.h"
+#include "llvm/ExecutionEngine/ObjectImage.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/Object/MachOObject.h"
#include "llvm/Support/CommandLine.h"
@@ -56,13 +58,15 @@ public:
uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
unsigned SectionID);
uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment,
- unsigned SectionID);
+ unsigned SectionID, bool IsReadOnly);
virtual void *getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure = true) {
return 0;
}
+ bool applyPermissions(std::string *ErrMsg) { return false; }
+
// Invalidate instruction cache for sections with execute permissions.
// Some platforms with separate data cache and instruction cache require
// explicit cache flush, otherwise JIT code manipulations (like resolved
@@ -80,7 +84,8 @@ uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size,
uint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size,
unsigned Alignment,
- unsigned SectionID) {
+ unsigned SectionID,
+ bool IsReadOnly) {
sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, 0, 0);
DataMemory.push_back(MB);
return (uint8_t*)MB.base();
@@ -120,12 +125,14 @@ static int executeInput() {
for(unsigned i = 0, e = InputFileList.size(); i != e; ++i) {
// 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 into it.
- if (Dyld.loadObject(InputBuffer.take())) {
+ // Load the object file
+ LoadedObject.reset(Dyld.loadObject(new ObjectBuffer(InputBuffer.take())));
+ if (!LoadedObject) {
return Error(Dyld.getErrorString());
}
}
diff --git a/tools/llvm-size/llvm-size.cpp b/tools/llvm-size/llvm-size.cpp
index 462da40..3de6605 100644
--- a/tools/llvm-size/llvm-size.cpp
+++ b/tools/llvm-size/llvm-size.cpp
@@ -23,8 +23,8 @@
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
#include <algorithm>
#include <string>
diff --git a/tools/llvm-stress/llvm-stress.cpp b/tools/llvm-stress/llvm-stress.cpp
index 31252dd..bb15c6b 100644
--- a/tools/llvm-stress/llvm-stress.cpp
+++ b/tools/llvm-stress/llvm-stress.cpp
@@ -11,25 +11,25 @@
// different components in LLVM.
//
//===----------------------------------------------------------------------===//
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
-#include "llvm/PassManager.h"
-#include "llvm/Constants.h"
-#include "llvm/Instruction.h"
-#include "llvm/CallGraphSCCPass.h"
-#include "llvm/Assembly/PrintModulePass.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/Analysis/CallGraphSCCPass.h"
#include "llvm/Analysis/Verifier.h"
-#include "llvm/Support/PassNameParser.h"
+#include "llvm/Assembly/PrintModulePass.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"
+#include "llvm/Support/PassNameParser.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/ToolOutputFile.h"
+#include <algorithm>
#include <memory>
-#include <sstream>
#include <set>
+#include <sstream>
#include <vector>
-#include <algorithm>
using namespace llvm;
static cl::opt<unsigned> SeedCL("seed",
@@ -126,6 +126,10 @@ public:
/// C'tor
Modifier(BasicBlock *Block, PieceTable *PT, Random *R):
BB(Block),PT(PT),Ran(R),Context(BB->getContext()) {}
+
+ /// virtual D'tor to silence warnings.
+ virtual ~Modifier() {}
+
/// Add a new instruction.
virtual void Act() = 0;
/// Add N new instructions,
diff --git a/tools/llvm-symbolizer/CMakeLists.txt b/tools/llvm-symbolizer/CMakeLists.txt
new file mode 100644
index 0000000..5e27463
--- /dev/null
+++ b/tools/llvm-symbolizer/CMakeLists.txt
@@ -0,0 +1,13 @@
+# FIXME: As we plan to execute llvm-symbolizer binary from compiler-rt
+# libraries, it has to be compiled for all supported targets (x86_64, i386 etc).
+# This means that we need LLVM libraries to be compiled for these
+# targets as well. Currently, there is no support for such a build strategy.
+
+set(LLVM_LINK_COMPONENTS
+ DebugInfo
+ Object
+ )
+
+add_llvm_tool(llvm-symbolizer
+ llvm-symbolizer.cpp
+ )
diff --git a/tools/llvm-symbolizer/Makefile b/tools/llvm-symbolizer/Makefile
new file mode 100644
index 0000000..5ac83a5
--- /dev/null
+++ b/tools/llvm-symbolizer/Makefile
@@ -0,0 +1,17 @@
+##===- tools/llvm-symbolizer/Makefile ----------------------*- Makefile -*-===##
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL := ../..
+TOOLNAME := llvm-symbolizer
+LINK_COMPONENTS := DebugInfo Object
+
+# This tool has no plugins, optimize startup time.
+TOOL_NO_EXPORTS := 1
+
+include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-symbolizer/llvm-symbolizer.cpp b/tools/llvm-symbolizer/llvm-symbolizer.cpp
new file mode 100644
index 0000000..6a5eb4a
--- /dev/null
+++ b/tools/llvm-symbolizer/llvm-symbolizer.cpp
@@ -0,0 +1,322 @@
+//===-- llvm-symbolizer.cpp - Simple addr2line-like symbolizer ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This utility works much like "addr2line". It is able of transforming
+// tuples (module name, module offset) to code locations (function name,
+// file, line number, column number). It is targeted for compiler-rt tools
+// (especially AddressSanitizer and ThreadSanitizer) that can use it
+// to symbolize stack traces in their error reports.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/OwningPtr.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;
+
+static cl::opt<bool>
+UseSymbolTable("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"));
+
+static cl::opt<bool>
+PrintInlining("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";
+ char InputString[kMaxInputStringLength];
+ if (!fgets(InputString, sizeof(InputString), stdin))
+ return false;
+ ModuleName = "";
+ ModuleOffsetStr = "";
+ // FIXME: Handle case when filename is given in quotes.
+ if (char *FilePath = strtok(InputString, kDelimiters)) {
+ ModuleName = FilePath;
+ if (char *OffsetStr = strtok((char*)0, kDelimiters))
+ ModuleOffsetStr = OffsetStr;
+ }
+ return true;
+}
+
+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.
+
+ cl::ParseCommandLineOptions(argc, argv, "llvm symbolizer for compiler-rt\n");
+ ToolInvocationPath = argv[0];
+
+ std::string ModuleName;
+ std::string ModuleOffsetStr;
+ while (parseModuleNameAndOffset(ModuleName, ModuleOffsetStr)) {
+ symbolize(ModuleName, ModuleOffsetStr);
+ }
+ return 0;
+}
diff --git a/tools/lto/CMakeLists.txt b/tools/lto/CMakeLists.txt
index 9112976..5820b14 100644
--- a/tools/lto/CMakeLists.txt
+++ b/tools/lto/CMakeLists.txt
@@ -6,10 +6,13 @@ add_definitions( -DLLVM_VERSION_INFO=\"${PACKAGE_VERSION}\" )
set(SOURCES
LTOCodeGenerator.cpp
+ LTODisassembler.cpp
lto.cpp
LTOModule.cpp
)
+set(LLVM_COMMON_DEPENDS intrinsics_gen)
+
if( NOT WIN32 AND LLVM_ENABLE_PIC )
set(bsl ${BUILD_SHARED_LIBS})
set(BUILD_SHARED_LIBS ON)
diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp
index f8b07b2..e87b378 100644
--- a/tools/lto/LTOCodeGenerator.cpp
+++ b/tools/lto/LTOCodeGenerator.cpp
@@ -14,36 +14,36 @@
#include "LTOCodeGenerator.h"
#include "LTOModule.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Linker.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
-#include "llvm/PassManager.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/Analysis/Passes.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Config/config.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/Target/Mangler.h"
-#include "llvm/Target/TargetOptions.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegisterInfo.h"
-#include "llvm/Transforms/IPO.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#include "llvm/PassManager.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
-#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/Host.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/system_error.h"
-#include "llvm/ADT/StringExtras.h"
+#include "llvm/Target/Mangler.h"
+#include "llvm/Target/TargetMachine.h"
+#include "llvm/Target/TargetOptions.h"
+#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
using namespace llvm;
static cl::opt<bool>
@@ -218,12 +218,13 @@ bool LTOCodeGenerator::determineTarget(std::string& errMsg) {
if (_target != NULL)
return false;
- std::string Triple = _linker.getModule()->getTargetTriple();
- if (Triple.empty())
- Triple = sys::getDefaultTargetTriple();
+ std::string TripleStr = _linker.getModule()->getTargetTriple();
+ if (TripleStr.empty())
+ TripleStr = sys::getDefaultTargetTriple();
+ llvm::Triple Triple(TripleStr);
// create target machine from info for merged modules
- const Target *march = TargetRegistry::lookupTarget(Triple, errMsg);
+ const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg);
if (march == NULL)
return true;
@@ -244,11 +245,18 @@ bool LTOCodeGenerator::determineTarget(std::string& errMsg) {
// construct LTOModule, hand over ownership of module and target
SubtargetFeatures Features;
- Features.getDefaultSubtargetFeatures(llvm::Triple(Triple));
+ Features.getDefaultSubtargetFeatures(Triple);
std::string FeatureStr = Features.getString();
+ // Set a default CPU for Darwin triples.
+ if (_mCpu.empty() && Triple.isOSDarwin()) {
+ if (Triple.getArch() == llvm::Triple::x86_64)
+ _mCpu = "core2";
+ else if (Triple.getArch() == llvm::Triple::x86)
+ _mCpu = "yonah";
+ }
TargetOptions Options;
LTOModule::getTargetOptions(Options);
- _target = march->createTargetMachine(Triple, _mCpu, FeatureStr, Options,
+ _target = march->createTargetMachine(TripleStr, _mCpu, FeatureStr, Options,
RelocModel, CodeModel::Default,
CodeGenOpt::Aggressive);
return false;
@@ -293,7 +301,7 @@ void LTOCodeGenerator::applyScopeRestrictions() {
// mark which symbols can not be internalized
MCContext Context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(),NULL);
- Mangler mangler(Context, *_target->getTargetData());
+ Mangler mangler(Context, *_target->getDataLayout());
std::vector<const char*> mustPreserveList;
SmallPtrSet<GlobalValue*, 8> asmUsed;
@@ -361,13 +369,15 @@ bool LTOCodeGenerator::generateObjectFile(raw_ostream &out,
// Start off with a verification pass.
passes.add(createVerifierPass());
- // Add an appropriate TargetData instance for this module...
- passes.add(new TargetData(*_target->getTargetData()));
+ // Add an appropriate DataLayout instance for this module...
+ passes.add(new DataLayout(*_target->getDataLayout()));
+ _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, /*Internalize=*/false,
+ PassManagerBuilder().populateLTOPassManager(passes,
+ /*Internalize=*/false,
!DisableInline,
DisableGVNLoadPRE);
@@ -376,7 +386,7 @@ bool LTOCodeGenerator::generateObjectFile(raw_ostream &out,
FunctionPassManager *codeGenPasses = new FunctionPassManager(mergedModule);
- codeGenPasses->add(new TargetData(*_target->getTargetData()));
+ codeGenPasses->add(new DataLayout(*_target->getDataLayout()));
formatted_raw_ostream Out(out);
diff --git a/tools/lto/LTOCodeGenerator.h b/tools/lto/LTOCodeGenerator.h
index 3081b7d..601dbfa 100644
--- a/tools/lto/LTOCodeGenerator.h
+++ b/tools/lto/LTOCodeGenerator.h
@@ -14,10 +14,10 @@
#ifndef LTO_CODE_GENERATOR_H
#define LTO_CODE_GENERATOR_H
-#include "llvm/Linker.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/SmallPtrSet.h"
#include "llvm-c/lto.h"
+#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/ADT/StringMap.h"
+#include "llvm/Linker.h"
#include <string>
namespace llvm {
diff --git a/tools/lto/LTODisassembler.cpp b/tools/lto/LTODisassembler.cpp
new file mode 100644
index 0000000..186aceb
--- /dev/null
+++ b/tools/lto/LTODisassembler.cpp
@@ -0,0 +1,26 @@
+//===-- LTODisassembler.cpp - LTO Disassembler interface ------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This function provides utility methods used by clients of libLTO that want
+// to use the disassembler.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm-c/lto.h"
+#include "llvm/Support/TargetSelect.h"
+
+using namespace llvm;
+
+void lto_initialize_disassembler() {
+ // Initialize targets and assembly printers/parsers.
+ llvm::InitializeAllTargetInfos();
+ llvm::InitializeAllTargetMCs();
+ llvm::InitializeAllAsmParsers();
+ llvm::InitializeAllDisassemblers();
+}
diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp
index b98bfab..23a8fb4 100644
--- a/tools/lto/LTOModule.cpp
+++ b/tools/lto/LTOModule.cpp
@@ -13,19 +13,20 @@
//===----------------------------------------------------------------------===//
#include "LTOModule.h"
-#include "llvm/Constants.h"
-#include "llvm/LLVMContext.h"
-#include "llvm/Module.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/Triple.h"
#include "llvm/Bitcode/ReaderWriter.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"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/MC/SubtargetFeature.h"
-#include "llvm/MC/MCParser/MCAsmParser.h"
-#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -34,8 +35,7 @@
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/system_error.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/Triple.h"
+#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
static cl::opt<bool>
@@ -158,7 +158,7 @@ SSPBufferSize("stack-protector-buffer-size", cl::init(8),
LTOModule::LTOModule(llvm::Module *m, llvm::TargetMachine *t)
: _module(m), _target(t),
_context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(), NULL),
- _mangler(_context, *_target->getTargetData()) {}
+ _mangler(_context, *_target->getDataLayout()) {}
/// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM
/// bitcode.
@@ -278,23 +278,31 @@ LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer,
return NULL;
}
- std::string Triple = m->getTargetTriple();
- if (Triple.empty())
- Triple = sys::getDefaultTargetTriple();
+ std::string TripleStr = m->getTargetTriple();
+ if (TripleStr.empty())
+ TripleStr = sys::getDefaultTargetTriple();
+ llvm::Triple Triple(TripleStr);
// find machine architecture for this module
- const Target *march = TargetRegistry::lookupTarget(Triple, errMsg);
+ const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg);
if (!march)
return NULL;
// construct LTOModule, hand over ownership of module and target
SubtargetFeatures Features;
- Features.getDefaultSubtargetFeatures(llvm::Triple(Triple));
+ Features.getDefaultSubtargetFeatures(Triple);
std::string FeatureStr = Features.getString();
+ // Set a default CPU for Darwin triples.
std::string CPU;
+ if (Triple.isOSDarwin()) {
+ if (Triple.getArch() == llvm::Triple::x86_64)
+ CPU = "core2";
+ else if (Triple.getArch() == llvm::Triple::x86)
+ CPU = "yonah";
+ }
TargetOptions Options;
getTargetOptions(Options);
- TargetMachine *target = march->createTargetMachine(Triple, CPU, FeatureStr,
+ TargetMachine *target = march->createTargetMachine(TripleStr, CPU, FeatureStr,
Options);
LTOModule *Ret = new LTOModule(m.take(), target);
if (Ret->parseSymbols(errMsg)) {
@@ -312,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();
@@ -329,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
@@ -366,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
@@ -391,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;
@@ -411,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);
@@ -440,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;
@@ -484,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
@@ -599,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;
@@ -735,6 +745,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);
@@ -752,6 +765,10 @@ 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 InitSections() {}
diff --git a/tools/lto/LTOModule.h b/tools/lto/LTOModule.h
index 8e52206..83f3a7d 100644
--- a/tools/lto/LTOModule.h
+++ b/tools/lto/LTOModule.h
@@ -14,15 +14,15 @@
#ifndef LTO_MODULE_H
#define LTO_MODULE_H
-#include "llvm/Module.h"
+#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/Target/Mangler.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/ADT/OwningPtr.h"
-#include "llvm/ADT/StringMap.h"
-#include "llvm-c/lto.h"
-#include <vector>
#include <string>
+#include <vector>
// Forward references to llvm classes.
namespace llvm {
@@ -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 153fa03..3610fed 100644
--- a/tools/lto/Makefile
+++ b/tools/lto/Makefile
@@ -49,4 +49,11 @@ ifeq ($(HOST_OS),Darwin)
-Wl,-install_name \
-Wl,"@executable_path/../lib/lib$(LIBRARYNAME)$(SHLIBEXT)"
endif
+
+ # If we're doing an Apple-style build, add the LTO object path.
+ ifeq ($(RC_BUILDIT),YES)
+ TempFile := $(shell mkdir -p ${OBJROOT}/dSYMs ; mktemp ${OBJROOT}/dSYMs/llvm-lto.XXXXXX)
+ LLVMLibsOptions := $(LLVMLibsOptions) \
+ -Wl,-object_path_lto -Wl,$(TempFile)
+ endif
endif
diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp
index a7e633d..11ad532 100644
--- a/tools/lto/lto.cpp
+++ b/tools/lto/lto.cpp
@@ -13,10 +13,9 @@
//===----------------------------------------------------------------------===//
#include "llvm-c/lto.h"
-#include "llvm-c/Core.h"
-
-#include "LTOModule.h"
#include "LTOCodeGenerator.h"
+#include "LTOModule.h"
+#include "llvm-c/Core.h"
// Holds most recent error string.
diff --git a/tools/lto/lto.exports b/tools/lto/lto.exports
index b900bfb..46d0d74 100644
--- a/tools/lto/lto.exports
+++ b/tools/lto/lto.exports
@@ -1,5 +1,6 @@
lto_get_error_message
lto_get_version
+lto_initialize_disassembler
lto_module_create
lto_module_create_from_fd
lto_module_create_from_fd_at_offset
@@ -28,5 +29,7 @@ lto_codegen_set_assembler_path
lto_codegen_set_cpu
lto_codegen_compile_to_file
LLVMCreateDisasm
+LLVMCreateDisasmCPU
LLVMDisasmDispose
LLVMDisasmInstruction
+LLVMSetDisasmOptions
diff --git a/tools/opt/AnalysisWrappers.cpp b/tools/opt/AnalysisWrappers.cpp
index a2b57bb..55f544f 100644
--- a/tools/opt/AnalysisWrappers.cpp
+++ b/tools/opt/AnalysisWrappers.cpp
@@ -17,10 +17,10 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Module.h"
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/Support/CallSite.h"
-#include "llvm/Analysis/CallGraph.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
diff --git a/tools/opt/CMakeLists.txt b/tools/opt/CMakeLists.txt
index 7daf22a..32de6d4 100644
--- a/tools/opt/CMakeLists.txt
+++ b/tools/opt/CMakeLists.txt
@@ -1,4 +1,4 @@
-set(LLVM_LINK_COMPONENTS bitreader asmparser bitwriter instrumentation scalaropts ipo vectorize)
+set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} bitreader asmparser bitwriter instrumentation scalaropts ipo vectorize)
add_llvm_tool(opt
AnalysisWrappers.cpp
diff --git a/tools/opt/GraphPrinters.cpp b/tools/opt/GraphPrinters.cpp
index 30361f5..c7481e5 100644
--- a/tools/opt/GraphPrinters.cpp
+++ b/tools/opt/GraphPrinters.cpp
@@ -14,11 +14,11 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Support/GraphWriter.h"
-#include "llvm/Pass.h"
-#include "llvm/Value.h"
#include "llvm/Analysis/CallGraph.h"
#include "llvm/Analysis/Dominators.h"
+#include "llvm/IR/Value.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/GraphWriter.h"
#include "llvm/Support/ToolOutputFile.h"
using namespace llvm;
diff --git a/tools/opt/LLVMBuild.txt b/tools/opt/LLVMBuild.txt
index 4de99f5..b174431 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
+required_libraries = AsmParser BitReader BitWriter IPO Instrumentation Scalar all-targets
diff --git a/tools/opt/Makefile b/tools/opt/Makefile
index 16d116d..ee7e1cf 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
+LINK_COMPONENTS := bitreader bitwriter asmparser instrumentation scalaropts ipo vectorize all-targets
include $(LEVEL)/Makefile.common
diff --git a/tools/opt/PrintSCC.cpp b/tools/opt/PrintSCC.cpp
index 11efdcd..a502fa7 100644
--- a/tools/opt/PrintSCC.cpp
+++ b/tools/opt/PrintSCC.cpp
@@ -25,12 +25,12 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/Pass.h"
-#include "llvm/Module.h"
+#include "llvm/ADT/SCCIterator.h"
#include "llvm/Analysis/CallGraph.h"
+#include "llvm/IR/Module.h"
+#include "llvm/Pass.h"
#include "llvm/Support/CFG.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/ADT/SCCIterator.h"
using namespace llvm;
namespace {
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp
index 7ecd25c..ac8323b 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -12,36 +12,40 @@
//
//===----------------------------------------------------------------------===//
-#include "llvm/LLVMContext.h"
-#include "llvm/DebugInfo.h"
-#include "llvm/Module.h"
-#include "llvm/PassManager.h"
-#include "llvm/CallGraphSCCPass.h"
-#include "llvm/Bitcode/ReaderWriter.h"
-#include "llvm/Assembly/PrintModulePass.h"
-#include "llvm/Analysis/Verifier.h"
-#include "llvm/Analysis/LoopPass.h"
-#include "llvm/Analysis/RegionPass.h"
-#include "llvm/Analysis/CallGraph.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetLibraryInfo.h"
-#include "llvm/Target/TargetMachine.h"
+#include "llvm/IR/LLVMContext.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/Triple.h"
-#include "llvm/Support/PassNameParser.h"
-#include "llvm/Support/Signals.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/CodeGen/CommandFlags.h"
+#include "llvm/DebugInfo.h"
+#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Module.h"
+#include "llvm/LinkAllPasses.h"
+#include "llvm/LinkAllVMCore.h"
+#include "llvm/MC/SubtargetFeature.h"
+#include "llvm/PassManager.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/IRReader.h"
#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/PassNameParser.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Signals.h"
#include "llvm/Support/SystemUtils.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/ToolOutputFile.h"
-#include "llvm/LinkAllPasses.h"
-#include "llvm/LinkAllVMCore.h"
+#include "llvm/Target/TargetLibraryInfo.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
-#include <memory>
#include <algorithm>
+#include <memory>
using namespace llvm;
// The OptimizationList is automatically populated with registered Passes by the
@@ -478,6 +482,70 @@ static void AddStandardLinkPasses(PassManagerBase &PM) {
/*RunInliner=*/ !DisableInline);
}
+//===----------------------------------------------------------------------===//
+// CodeGen-related helper functions.
+//
+static TargetOptions GetTargetOptions() {
+ TargetOptions Options;
+ Options.LessPreciseFPMADOption = EnableFPMAD;
+ Options.NoFramePointerElim = DisableFPElim;
+ Options.NoFramePointerElimNonLeaf = DisableFPElimNonLeaf;
+ Options.AllowFPOpFusion = FuseFPOps;
+ Options.UnsafeFPMath = EnableUnsafeFPMath;
+ Options.NoInfsFPMath = EnableNoInfsFPMath;
+ Options.NoNaNsFPMath = EnableNoNaNsFPMath;
+ Options.HonorSignDependentRoundingFPMathOption =
+ EnableHonorSignDependentRoundingFPMath;
+ Options.UseSoftFloat = GenerateSoftFloatCalls;
+ if (FloatABIForCalls != FloatABI::Default)
+ Options.FloatABIType = FloatABIForCalls;
+ Options.NoZerosInBSS = DontPlaceZerosInBSS;
+ Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt;
+ Options.DisableTailCalls = DisableTailCalls;
+ Options.StackAlignmentOverride = OverrideStackAlignment;
+ Options.RealignStack = EnableRealignStack;
+ Options.TrapFuncName = TrapFuncName;
+ Options.PositionIndependentExecutable = EnablePIE;
+ Options.EnableSegmentedStacks = SegmentedStacks;
+ Options.UseInitArray = UseInitArray;
+ Options.SSPBufferSize = SSPBufferSize;
+ return Options;
+}
+
+CodeGenOpt::Level GetCodeGenOptLevel() {
+ if (OptLevelO1)
+ return CodeGenOpt::Less;
+ if (OptLevelO2)
+ return CodeGenOpt::Default;
+ if (OptLevelO3)
+ return CodeGenOpt::Aggressive;
+ return CodeGenOpt::None;
+}
+
+// Returns the TargetMachine instance or zero if no triple is provided.
+static TargetMachine* GetTargetMachine(Triple TheTriple) {
+ std::string Error;
+ const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple,
+ Error);
+ // Some modules don't specify a triple, and this is okay.
+ if (!TheTarget) {
+ return 0;
+ }
+
+ // Package up features to be passed to target/subtarget
+ std::string FeaturesStr;
+ if (MAttrs.size()) {
+ SubtargetFeatures Features;
+ for (unsigned i = 0; i != MAttrs.size(); ++i)
+ Features.AddFeature(MAttrs[i]);
+ FeaturesStr = Features.getString();
+ }
+
+ return TheTarget->createTargetMachine(TheTriple.getTriple(),
+ MCPU, FeaturesStr, GetTargetOptions(),
+ RelocModel, CMModel,
+ GetCodeGenOptLevel());
+}
//===----------------------------------------------------------------------===//
// main for opt
@@ -492,6 +560,9 @@ int main(int argc, char **argv) {
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
LLVMContext &Context = getGlobalContext();
+ InitializeAllTargets();
+ InitializeAllTargetMCs();
+
// Initialize passes
PassRegistry &Registry = *PassRegistry::getPassRegistry();
initializeCore(Registry);
@@ -568,22 +639,32 @@ int main(int argc, char **argv) {
TLI->disableAllFunctions();
Passes.add(TLI);
- // Add an appropriate TargetData instance for this module.
- TargetData *TD = 0;
+ // Add an appropriate DataLayout instance for this module.
+ DataLayout *TD = 0;
const std::string &ModuleDataLayout = M.get()->getDataLayout();
if (!ModuleDataLayout.empty())
- TD = new TargetData(ModuleDataLayout);
+ TD = new DataLayout(ModuleDataLayout);
else if (!DefaultDataLayout.empty())
- TD = new TargetData(DefaultDataLayout);
+ TD = new DataLayout(DefaultDataLayout);
if (TD)
Passes.add(TD);
+ 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) {
FPasses.reset(new FunctionPassManager(M.get()));
if (TD)
- FPasses->add(new TargetData(*TD));
+ FPasses->add(new DataLayout(*TD));
}
if (PrintBreakpoints) {