summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2011-10-20 21:10:27 +0000
committerdim <dim@FreeBSD.org>2011-10-20 21:10:27 +0000
commit7b3392326c40c3c20697816acae597ba7b3144eb (patch)
tree2cbcf22585e99f8a87d12d5ff94f392c0d266819 /tools
parent1176aa52646fe641a4243a246aa7f960c708a274 (diff)
downloadFreeBSD-src-7b3392326c40c3c20697816acae597ba7b3144eb.zip
FreeBSD-src-7b3392326c40c3c20697816acae597ba7b3144eb.tar.gz
Vendor import of llvm release_30 branch r142614:
http://llvm.org/svn/llvm-project/llvm/branches/release_30@142614
Diffstat (limited to 'tools')
-rw-r--r--tools/CMakeLists.txt3
-rw-r--r--tools/Makefile5
-rw-r--r--tools/bugpoint/BugDriver.cpp3
-rw-r--r--tools/bugpoint/ExtractFunction.cpp2
-rw-r--r--tools/bugpoint/Miscompilation.cpp21
-rw-r--r--tools/bugpoint/bugpoint.cpp3
-rw-r--r--tools/edis/CMakeLists.txt29
-rw-r--r--tools/edis/EnhancedDisassembly.exports36
-rw-r--r--tools/edis/Makefile1
-rw-r--r--tools/gold/gold-plugin.cpp41
-rw-r--r--tools/llc/llc.cpp47
-rw-r--r--tools/lli/lli.cpp36
-rw-r--r--tools/llvm-config/CMakeLists.txt24
-rw-r--r--tools/llvm-cov/CMakeLists.txt5
-rw-r--r--tools/llvm-cov/Makefile (renamed from tools/llvmc/examples/mcc16/Makefile)15
-rw-r--r--tools/llvm-cov/llvm-cov.cpp78
-rw-r--r--tools/llvm-diff/DifferenceEngine.cpp4
-rw-r--r--tools/llvm-dwarfdump/CMakeLists.txt8
-rw-r--r--tools/llvm-dwarfdump/Makefile (renamed from tools/llvmc/examples/Makefile)9
-rw-r--r--tools/llvm-dwarfdump/llvm-dwarfdump.cpp116
-rw-r--r--tools/llvm-extract/llvm-extract.cpp77
-rw-r--r--tools/llvm-ld/Optimize.cpp6
-rw-r--r--tools/llvm-link/llvm-link.cpp3
-rw-r--r--tools/llvm-mc/Disassembler.cpp38
-rw-r--r--tools/llvm-mc/Disassembler.h2
-rw-r--r--tools/llvm-mc/llvm-mc.cpp178
-rw-r--r--tools/llvm-nm/llvm-nm.cpp45
-rw-r--r--tools/llvm-objdump/CMakeLists.txt3
-rw-r--r--tools/llvm-objdump/MCFunction.cpp138
-rw-r--r--tools/llvm-objdump/MCFunction.h100
-rw-r--r--tools/llvm-objdump/MachODump.cpp617
-rw-r--r--tools/llvm-objdump/Makefile3
-rw-r--r--tools/llvm-objdump/llvm-objdump.cpp328
-rw-r--r--tools/llvm-objdump/llvm-objdump.h46
-rw-r--r--tools/llvm-shlib/Makefile5
-rw-r--r--tools/llvm-size/CMakeLists.txt5
-rw-r--r--tools/llvm-size/Makefile (renamed from tools/llvmc/examples/Simple/Makefile)10
-rw-r--r--tools/llvm-size/llvm-size.cpp311
-rw-r--r--tools/llvmc/CMakeLists.txt4
-rw-r--r--tools/llvmc/Makefile18
-rw-r--r--tools/llvmc/doc/LLVMC-Reference.rst747
-rw-r--r--tools/llvmc/doc/LLVMC-Tutorial.rst127
-rw-r--r--tools/llvmc/doc/Makefile33
-rw-r--r--tools/llvmc/doc/img/lines.gifbin91 -> 0 bytes
-rw-r--r--tools/llvmc/examples/Hello/Hello.cpp29
-rw-r--r--tools/llvmc/examples/Hello/Makefile14
-rw-r--r--tools/llvmc/examples/Simple/Simple.cpp2
-rw-r--r--tools/llvmc/examples/Simple/Simple.td41
-rw-r--r--tools/llvmc/examples/Skeleton/AutoGenerated.td7
-rw-r--r--tools/llvmc/examples/Skeleton/Hooks.cpp12
-rw-r--r--tools/llvmc/examples/Skeleton/Main.cpp15
-rw-r--r--tools/llvmc/examples/Skeleton/Makefile20
-rw-r--r--tools/llvmc/examples/Skeleton/README6
-rw-r--r--tools/llvmc/examples/mcc16/Hooks.cpp109
-rw-r--r--tools/llvmc/examples/mcc16/Main.cpp57
-rw-r--r--tools/llvmc/examples/mcc16/PIC16.td234
-rw-r--r--tools/llvmc/examples/mcc16/README75
-rw-r--r--tools/llvmc/src/AutoGenerated.td17
-rw-r--r--tools/llvmc/src/Base.td.in461
-rw-r--r--tools/llvmc/src/Clang.td87
-rw-r--r--tools/llvmc/src/Hooks.cpp193
-rw-r--r--tools/llvmc/src/Main.cpp16
-rw-r--r--tools/llvmc/src/Makefile14
-rw-r--r--tools/lto/LTOCodeGenerator.cpp30
-rw-r--r--tools/lto/LTOModule.cpp37
-rw-r--r--tools/lto/LTOModule.h5
-rw-r--r--tools/macho-dump/macho-dump.cpp28
-rw-r--r--tools/opt/opt.cpp4
68 files changed, 2162 insertions, 2681 deletions
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index 8851a0b..e66648b 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -28,6 +28,7 @@ add_subdirectory(llc)
add_subdirectory(llvm-ranlib)
add_subdirectory(llvm-ar)
add_subdirectory(llvm-nm)
+add_subdirectory(llvm-size)
add_subdirectory(llvm-ld)
add_subdirectory(llvm-prof)
@@ -39,13 +40,13 @@ add_subdirectory(llvm-diff)
add_subdirectory(macho-dump)
add_subdirectory(llvm-objdump)
add_subdirectory(llvm-rtdyld)
+add_subdirectory(llvm-dwarfdump)
add_subdirectory(bugpoint)
add_subdirectory(bugpoint-passes)
add_subdirectory(llvm-bcanalyzer)
add_subdirectory(llvm-stub)
add_subdirectory(edis)
-add_subdirectory(llvmc)
if( NOT WIN32 )
add_subdirectory(lto)
diff --git a/tools/Makefile b/tools/Makefile
index 5960433..68ce314 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -25,8 +25,9 @@ PARALLEL_DIRS := opt llvm-as llvm-dis \
llvm-ld llvm-prof llvm-link \
lli llvm-extract llvm-mc \
bugpoint llvm-bcanalyzer llvm-stub \
- llvmc llvm-diff macho-dump llvm-objdump \
- llvm-rtdyld
+ llvm-diff macho-dump llvm-objdump \
+ llvm-rtdyld llvm-dwarfdump llvm-cov \
+ llvm-size
# Let users override the set of tools to build from the command line.
ifdef ONLY_TOOLS
diff --git a/tools/bugpoint/BugDriver.cpp b/tools/bugpoint/BugDriver.cpp
index aa3e290..677d178 100644
--- a/tools/bugpoint/BugDriver.cpp
+++ b/tools/bugpoint/BugDriver.cpp
@@ -127,7 +127,8 @@ bool BugDriver::addSources(const std::vector<std::string> &Filenames) {
outs() << "Linking in input file: '" << Filenames[i] << "'\n";
std::string ErrorMessage;
- if (Linker::LinkModules(Program, M.get(), &ErrorMessage)) {
+ if (Linker::LinkModules(Program, M.get(), Linker::DestroySource,
+ &ErrorMessage)) {
errs() << ToolName << ": error linking in '" << Filenames[i] << "': "
<< ErrorMessage << '\n';
return true;
diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp
index 9941add..73b65ca 100644
--- a/tools/bugpoint/ExtractFunction.cpp
+++ b/tools/bugpoint/ExtractFunction.cpp
@@ -175,7 +175,7 @@ static Constant *GetTorInit(std::vector<std::pair<Function*, int> > &TorList) {
std::vector<Constant*> ArrayElts;
Type *Int32Ty = Type::getInt32Ty(TorList[0].first->getContext());
- const StructType *STy =
+ StructType *STy =
StructType::get(Int32Ty, TorList[0].first->getType(), NULL);
for (unsigned i = 0, e = TorList.size(); i != e; ++i) {
Constant *Elts[] = {
diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp
index d645dfb..7ff16db 100644
--- a/tools/bugpoint/Miscompilation.cpp
+++ b/tools/bugpoint/Miscompilation.cpp
@@ -222,7 +222,7 @@ static Module *TestMergedProgram(const BugDriver &BD, Module *M1, Module *M2,
M1 = CloneModule(M1);
M2 = CloneModule(M2);
}
- if (Linker::LinkModules(M1, M2, &ErrorMsg)) {
+ if (Linker::LinkModules(M1, M2, Linker::DestroySource, &ErrorMsg)) {
errs() << BD.getToolName() << ": Error linking modules together:"
<< ErrorMsg << '\n';
exit(1);
@@ -384,7 +384,7 @@ static bool ExtractLoops(BugDriver &BD,
outs() << "*** Loop extraction successful!\n";
- std::vector<std::pair<std::string, const FunctionType*> > MisCompFunctions;
+ std::vector<std::pair<std::string, FunctionType*> > MisCompFunctions;
for (Module::iterator I = ToOptimizeLoopExtracted->begin(),
E = ToOptimizeLoopExtracted->end(); I != E; ++I)
if (!I->isDeclaration())
@@ -396,7 +396,8 @@ static bool ExtractLoops(BugDriver &BD,
// Replace the current program with the loop extracted version, and try to
// extract another loop.
std::string ErrorMsg;
- if (Linker::LinkModules(ToNotOptimize, ToOptimizeLoopExtracted, &ErrorMsg)){
+ if (Linker::LinkModules(ToNotOptimize, ToOptimizeLoopExtracted,
+ Linker::DestroySource, &ErrorMsg)){
errs() << BD.getToolName() << ": Error linking modules together:"
<< ErrorMsg << '\n';
exit(1);
@@ -411,8 +412,6 @@ static bool ExtractLoops(BugDriver &BD,
Function *NewF = ToNotOptimize->getFunction(MisCompFunctions[i].first);
assert(NewF && "Function not found??");
- assert(NewF->getFunctionType() == MisCompFunctions[i].second &&
- "found wrong function type?");
MiscompiledFunctions.push_back(NewF);
}
@@ -569,7 +568,7 @@ static bool ExtractBlocks(BugDriver &BD,
// together.
delete ToExtract;
- std::vector<std::pair<std::string, const FunctionType*> > MisCompFunctions;
+ std::vector<std::pair<std::string, FunctionType*> > MisCompFunctions;
for (Module::iterator I = Extracted->begin(), E = Extracted->end();
I != E; ++I)
if (!I->isDeclaration())
@@ -577,7 +576,8 @@ static bool ExtractBlocks(BugDriver &BD,
I->getFunctionType()));
std::string ErrorMsg;
- if (Linker::LinkModules(ProgClone, Extracted, &ErrorMsg)) {
+ if (Linker::LinkModules(ProgClone, Extracted, Linker::DestroySource,
+ &ErrorMsg)) {
errs() << BD.getToolName() << ": Error linking modules together:"
<< ErrorMsg << '\n';
exit(1);
@@ -593,8 +593,6 @@ static bool ExtractBlocks(BugDriver &BD,
for (unsigned i = 0, e = MisCompFunctions.size(); i != e; ++i) {
Function *NewF = ProgClone->getFunction(MisCompFunctions[i].first);
assert(NewF && "Function not found??");
- assert(NewF->getFunctionType() == MisCompFunctions[i].second &&
- "Function has wrong type??");
MiscompiledFunctions.push_back(NewF);
}
@@ -834,8 +832,7 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test,
// GetElementPtr *funcName, ulong 0, ulong 0
std::vector<Constant*> GEPargs(2,
Constant::getNullValue(Type::getInt32Ty(F->getContext())));
- Value *GEP =
- ConstantExpr::getGetElementPtr(funcName, &GEPargs[0], 2);
+ Value *GEP = ConstantExpr::getGetElementPtr(funcName, GEPargs);
std::vector<Value*> ResolverArgs;
ResolverArgs.push_back(GEP);
@@ -850,7 +847,7 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test,
NullPtr,F->getName()+".fpcache");
// Construct a new stub function that will re-route calls to F
- const FunctionType *FuncTy = F->getFunctionType();
+ FunctionType *FuncTy = F->getFunctionType();
Function *FuncWrapper = Function::Create(FuncTy,
GlobalValue::InternalLinkage,
F->getName() + "_wrapper",
diff --git a/tools/bugpoint/bugpoint.cpp b/tools/bugpoint/bugpoint.cpp
index e25414f..6a87521 100644
--- a/tools/bugpoint/bugpoint.cpp
+++ b/tools/bugpoint/bugpoint.cpp
@@ -17,16 +17,17 @@
#include "ToolRunner.h"
#include "llvm/LinkAllPasses.h"
#include "llvm/LLVMContext.h"
+#include "llvm/PassManager.h"
#include "llvm/Support/PassNameParser.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/PassManagerBuilder.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.
//#define DEBUG_BUGPOINT 1
diff --git a/tools/edis/CMakeLists.txt b/tools/edis/CMakeLists.txt
index 9406c2a..1e162f9 100644
--- a/tools/edis/CMakeLists.txt
+++ b/tools/edis/CMakeLists.txt
@@ -5,30 +5,17 @@ set(SOURCES
EDMain.cpp
)
-set(LLVM_LINK_COMPONENTS mcdisassembler)
+set(EDIS_DEPENDS LLVMMCDisassembler LLVMMCParser)
if( LLVM_TARGETS_TO_BUILD MATCHES X86 )
- list(APPEND LLVM_LINK_COMPONENTS x86asmprinter x86disassembler)
+ list(APPEND EDIS_DEPENDS LLVMX86AsmPrinter LLVMX86AsmParser LLVMX86Disassembler LLVMX86Desc)
endif()
if( LLVM_TARGETS_TO_BUILD MATCHES ARM )
- list(APPEND LLVM_LINK_COMPONENTS armasmprinter armdisassembler)
+ list(APPEND EDIS_DEPENDS LLVMARMAsmPrinter LLVMARMAsmParser LLVMARMDisassembler LLVMARMDesc)
endif()
-# TODO: Process EnhancedDisassembly.exports
+add_llvm_library(EnhancedDisassembly ${SOURCES})
+set_property(TARGET EnhancedDisassembly PROPERTY
+ OUTPUT_NAME "EnhancedDisassembly")
-if( NOT WIN32 AND LLVM_ENABLE_PIC )
- set(bsl ${BUILD_SHARED_LIBS})
- set(BUILD_SHARED_LIBS ON)
- add_llvm_library(EnhancedDisassembly ${SOURCES})
- set_property(TARGET EnhancedDisassembly PROPERTY
- OUTPUT_NAME "EnhancedDisassembly")
- set(BUILD_SHARED_LIBS ${bsl})
- set(EnhancedDisassembly_STATIC_TARGET_NAME EnhancedDisassembly_static)
-else()
- set(EnhancedDisassembly_STATIC_TARGET_NAME EnhancedDisassembly)
-endif()
-
-if( NOT BUILD_SHARED_LIBS )
- add_llvm_library(${EnhancedDisassembly_STATIC_TARGET_NAME} ${SOURCES})
- set_property(TARGET ${EnhancedDisassembly_STATIC_TARGET_NAME} PROPERTY
- OUTPUT_NAME "EnhancedDisassembly")
-endif()
+add_llvm_library_dependencies(EnhancedDisassembly
+ ${EDIS_DEPENDS})
diff --git a/tools/edis/EnhancedDisassembly.exports b/tools/edis/EnhancedDisassembly.exports
deleted file mode 100644
index 7050f7f..0000000
--- a/tools/edis/EnhancedDisassembly.exports
+++ /dev/null
@@ -1,36 +0,0 @@
-EDGetDisassembler
-EDGetRegisterName
-EDRegisterIsStackPointer
-EDRegisterIsProgramCounter
-EDCreateInsts
-EDReleaseInst
-EDInstByteSize
-EDGetInstString
-EDInstIsBranch
-EDInstIsMove
-EDBranchTargetID
-EDMoveSourceID
-EDMoveTargetID
-EDNumTokens
-EDGetToken
-EDGetTokenString
-EDOperandIndexForToken
-EDTokenIsWhitespace
-EDTokenIsPunctuation
-EDTokenIsOpcode
-EDTokenIsLiteral
-EDTokenIsRegister
-EDTokenIsNegativeLiteral
-EDLiteralTokenAbsoluteValue
-EDRegisterTokenValue
-EDNumOperands
-EDGetOperand
-EDOperandIsRegister
-EDOperandIsImmediate
-EDOperandIsMemory
-EDRegisterOperandValue
-EDImmediateOperandValue
-EDEvaluateOperand
-EDBlockCreateInsts
-EDBlockEvaluateOperand
-EDBlockVisitTokens
diff --git a/tools/edis/Makefile b/tools/edis/Makefile
index b5557fc..3fcb408 100644
--- a/tools/edis/Makefile
+++ b/tools/edis/Makefile
@@ -10,7 +10,6 @@
LEVEL = ../..
LIBRARYNAME = EnhancedDisassembly
LINK_LIBS_IN_SHARED = 1
-SHARED_LIBRARY = 1
EXPORTED_SYMBOL_FILE = $(PROJ_SRC_DIR)/EnhancedDisassembly.exports
diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp
index 9e43bef..6f547b3 100644
--- a/tools/gold/gold-plugin.cpp
+++ b/tools/gold/gold-plugin.cpp
@@ -17,6 +17,9 @@
#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/Path.h"
@@ -235,25 +238,43 @@ ld_plugin_status onload(ld_plugin_tv *tv) {
static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file,
int *claimed) {
lto_module_t M;
-
+ const void *view;
+ OwningPtr<MemoryBuffer> buffer;
if (get_view) {
- const void *view;
if (get_view(file->handle, &view) != LDPS_OK) {
(*message)(LDPL_ERROR, "Failed to get a view of %s", file->name);
return LDPS_ERR;
}
- M = lto_module_create_from_memory(view, file->filesize);
- } else if (file->offset) {
+ } else {
+ int64_t offset = 0;
// Gold has found what might be IR part-way inside of a file, such as
// an .a archive.
- M = lto_module_create_from_fd_at_offset(file->fd, file->name, -1,
- file->filesize, file->offset);
- } else {
- M = lto_module_create_from_fd(file->fd, file->name, file->filesize);
+ if (file->offset) {
+ offset = file->offset;
+ }
+ if (error_code ec =
+ MemoryBuffer::getOpenFile(file->fd, file->name, buffer, file->filesize,
+ -1, offset, false)) {
+ (*message)(LDPL_ERROR, ec.message().c_str());
+ return LDPS_ERR;
+ }
+ view = buffer->getBufferStart();
}
- if (!M)
+
+ if (!lto_module_is_object_file_in_memory(view, file->filesize))
return LDPS_OK;
+ M = lto_module_create_from_memory(view, file->filesize);
+ if (!M) {
+ if (const char* msg = lto_get_error_message()) {
+ (*message)(LDPL_ERROR,
+ "LLVM gold plugin has failed to create LTO module: %s",
+ msg);
+ return LDPS_ERR;
+ }
+ return LDPS_OK;
+ }
+
*claimed = 1;
Modules.resize(Modules.size() + 1);
claimed_file &cf = Modules.back();
@@ -360,6 +381,8 @@ static ld_plugin_status all_symbols_read_hook(void) {
bool anySymbolsPreserved = false;
for (std::list<claimed_file>::iterator I = Modules.begin(),
E = Modules.end(); I != E; ++I) {
+ if (I->syms.empty())
+ continue;
(*get_symbols)(I->handle, I->syms.size(), &I->syms[0]);
for (unsigned i = 0, e = I->syms.size(); i != e; i++) {
if (I->syms[i].resolution == LDPR_PREVAILING_DEF) {
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp
index b36e941..d29bd9b 100644
--- a/tools/llc/llc.cpp
+++ b/tools/llc/llc.cpp
@@ -32,10 +32,10 @@
#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/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Target/TargetSelect.h"
#include <memory>
using namespace llvm;
@@ -76,6 +76,37 @@ MAttrs("mattr",
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, "
@@ -201,12 +232,13 @@ int main(int argc, char **argv) {
// Initialize targets first, so that --version shows registered targets.
InitializeAllTargets();
- InitializeAllMCAsmInfos();
- InitializeAllMCInstrInfos();
- InitializeAllMCSubtargetInfos();
+ InitializeAllTargetMCs();
InitializeAllAsmPrinters();
InitializeAllAsmParsers();
+ // Register the target printer for --version.
+ cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion);
+
cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");
// Load the module to be compiled...
@@ -272,8 +304,9 @@ int main(int argc, char **argv) {
}
std::auto_ptr<TargetMachine>
- target(TheTarget->createTargetMachine(TheTriple.getTriple(), MCPU,
- FeaturesStr));
+ target(TheTarget->createTargetMachine(TheTriple.getTriple(),
+ MCPU, FeaturesStr,
+ RelocModel, CMModel));
assert(target.get() && "Could not allocate target machine!");
TargetMachine &Target = *target.get();
diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp
index 014925c..50c7a49 100644
--- a/tools/lli/lli.cpp
+++ b/tools/lli/lli.cpp
@@ -33,7 +33,7 @@
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Signals.h"
-#include "llvm/Target/TargetSelect.h"
+#include "llvm/Support/TargetSelect.h"
#include <cerrno>
#ifdef __CYGWIN__
@@ -108,6 +108,38 @@ namespace {
NoLazyCompilation("disable-lazy-compilation",
cl::desc("Disable JIT lazy compilation"),
cl::init(false));
+
+ 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));
+
+ cl::opt<llvm::CodeModel::Model>
+ CMModel("code-model",
+ cl::desc("Choose code model"),
+ cl::init(CodeModel::JITDefault),
+ cl::values(clEnumValN(CodeModel::JITDefault, "default",
+ "Target default JIT 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 ExecutionEngine *EE = 0;
@@ -164,6 +196,8 @@ int main(int argc, char **argv, char * const *envp) {
builder.setMArch(MArch);
builder.setMCPU(MCPU);
builder.setMAttrs(MAttrs);
+ builder.setRelocationModel(RelocModel);
+ builder.setCodeModel(CMModel);
builder.setErrorStr(&ErrorMsg);
builder.setEngineKind(ForceInterpreter
? EngineKind::Interpreter
diff --git a/tools/llvm-config/CMakeLists.txt b/tools/llvm-config/CMakeLists.txt
index bc23a64..6016862 100644
--- a/tools/llvm-config/CMakeLists.txt
+++ b/tools/llvm-config/CMakeLists.txt
@@ -138,27 +138,3 @@ install(FILES ${LLVM_CONFIG}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE
WORLD_READ WORLD_EXECUTE
DESTINATION bin)
-
-
-# Regeneration of library dependencies.
-
-# See the comments at the end of cmake/modules/LLVM-Config.cmake for
-# notes and guidelines.
-
-set(LLVMLibDeps ${LLVM_MAIN_SRC_DIR}/cmake/modules/LLVMLibDeps.cmake)
-set(LLVMLibDeps_TMP ${CMAKE_CURRENT_BINARY_DIR}/LLVMLibDeps.cmake.tmp)
-
-add_custom_command(OUTPUT ${LLVMLibDeps_TMP}
- COMMAND sed -e s'@\\.a@@g' -e s'@\\.so@@g' -e 's@libLLVM@LLVM@g' -e 's@: @ @' -e 's@\\\(.*\\\)@set\(MSVC_LIB_DEPS_\\1\)@' ${FINAL_LIBDEPS} > ${LLVMLibDeps_TMP}
- COMMAND ${CMAKE_COMMAND} -E copy_if_different ${LLVMLibDeps_TMP} ${LLVMLibDeps}
- DEPENDS ${FINAL_LIBDEPS}
- COMMENT "Updating cmake library dependencies file ${LLVMLibDeps}"
- )
-
-if( LLVM_TARGETS_TO_BUILD STREQUAL LLVM_ALL_TARGETS )
- add_custom_target(llvmlibdeps.target ALL DEPENDS ${LLVMLibDeps_TMP})
- add_dependencies(llvmlibdeps.target llvm-config.target)
- set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} llvmlibdeps.target)
-endif()
-
-set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} PARENT_SCOPE)
diff --git a/tools/llvm-cov/CMakeLists.txt b/tools/llvm-cov/CMakeLists.txt
new file mode 100644
index 0000000..7184b9e
--- /dev/null
+++ b/tools/llvm-cov/CMakeLists.txt
@@ -0,0 +1,5 @@
+set(LLVM_LINK_COMPONENTS instrumentation )
+
+add_llvm_tool(llvm-cov
+ llvm-cov.cpp
+ )
diff --git a/tools/llvmc/examples/mcc16/Makefile b/tools/llvm-cov/Makefile
index 4409cff..bd9fa2a 100644
--- a/tools/llvmc/examples/mcc16/Makefile
+++ b/tools/llvm-cov/Makefile
@@ -1,15 +1,18 @@
-##===- llvmc/examples/mcc16/Makefile -----------------------*- Makefile -*-===##
-#
+##===- tools/llvm-cov/Makefile -----------------------------*- Makefile -*-===##
+#
# The LLVM Compiler Infrastructure
#
# This file is distributed under the University of Illinois Open Source
# License. See LICENSE.TXT for details.
-#
+#
##===----------------------------------------------------------------------===##
-LEVEL = ../../../..
+LEVEL = ../..
+
+TOOLNAME = llvm-cov
+LINK_COMPONENTS := instrumentation
-LLVMC_BASED_DRIVER = mcc16
-BUILT_SOURCES = PIC16.inc
+# This tool has no plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-cov/llvm-cov.cpp b/tools/llvm-cov/llvm-cov.cpp
new file mode 100644
index 0000000..7b21c5b
--- /dev/null
+++ b/tools/llvm-cov/llvm-cov.cpp
@@ -0,0 +1,78 @@
+//===- tools/llvm-cov/llvm-cov.cpp - LLVM coverage tool -------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// llvm-cov is a command line tools to analyze and report coverage information.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/GCOV.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryObject.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/system_error.h"
+using namespace llvm;
+
+static cl::opt<bool>
+DumpGCOV("dump", cl::init(false), cl::desc("dump gcov file"));
+
+static cl::opt<std::string>
+InputGCNO("gcno", cl::desc("<input gcno file>"), cl::init(""));
+
+static cl::opt<std::string>
+InputGCDA("gcda", cl::desc("<input gcda file>"), cl::init(""));
+
+
+//===----------------------------------------------------------------------===//
+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 cov\n");
+
+ GCOVFile GF;
+ if (InputGCNO.empty())
+ errs() << " " << argv[0] << ": No gcov input file!\n";
+
+ OwningPtr<MemoryBuffer> GCNO_Buff;
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputGCNO, GCNO_Buff)) {
+ errs() << InputGCNO << ": " << ec.message() << "\n";
+ return 1;
+ }
+ GCOVBuffer GCNO_GB(GCNO_Buff.take());
+ if (!GF.read(GCNO_GB)) {
+ errs() << "Invalid .gcno File!\n";
+ return 1;
+ }
+
+ if (!InputGCDA.empty()) {
+ OwningPtr<MemoryBuffer> GCDA_Buff;
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputGCDA, GCDA_Buff)) {
+ errs() << InputGCDA << ": " << ec.message() << "\n";
+ return 1;
+ }
+ GCOVBuffer GCDA_GB(GCDA_Buff.take());
+ if (!GF.read(GCDA_GB)) {
+ errs() << "Invalid .gcda File!\n";
+ return 1;
+ }
+ }
+
+
+ if (DumpGCOV)
+ GF.dump();
+
+ FileInfo FI;
+ GF.collectLineCounts(FI);
+ return 0;
+}
diff --git a/tools/llvm-diff/DifferenceEngine.cpp b/tools/llvm-diff/DifferenceEngine.cpp
index ba2cec2..b240d8c 100644
--- a/tools/llvm-diff/DifferenceEngine.cpp
+++ b/tools/llvm-diff/DifferenceEngine.cpp
@@ -195,12 +195,12 @@ class FunctionDifferenceEngine {
DifferenceEngine::Context C(Engine, L, R);
BasicBlock::iterator LI = L->begin(), LE = L->end();
- BasicBlock::iterator RI = R->begin(), RE = R->end();
+ BasicBlock::iterator RI = R->begin();
llvm::SmallVector<std::pair<Instruction*,Instruction*>, 20> TentativePairs;
do {
- assert(LI != LE && RI != RE);
+ assert(LI != LE && RI != R->end());
Instruction *LeftI = &*LI, *RightI = &*RI;
// If the instructions differ, start the more sophisticated diff
diff --git a/tools/llvm-dwarfdump/CMakeLists.txt b/tools/llvm-dwarfdump/CMakeLists.txt
new file mode 100644
index 0000000..05aad3f
--- /dev/null
+++ b/tools/llvm-dwarfdump/CMakeLists.txt
@@ -0,0 +1,8 @@
+set(LLVM_LINK_COMPONENTS
+ DebugInfo
+ Object
+ )
+
+add_llvm_tool(llvm-dwarfdump
+ llvm-dwarfdump.cpp
+ )
diff --git a/tools/llvmc/examples/Makefile b/tools/llvm-dwarfdump/Makefile
index 8468e93..e61f27d 100644
--- a/tools/llvmc/examples/Makefile
+++ b/tools/llvm-dwarfdump/Makefile
@@ -1,4 +1,4 @@
-##===- tools/llvmc/examples/Makefile -----------------------*- Makefile -*-===##
+##===- tools/llvm-dwarfdump/Makefile -----------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
@@ -6,9 +6,12 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+LEVEL = ../..
-LEVEL=../../..
+TOOLNAME = llvm-dwarfdump
+LINK_COMPONENTS = DebugInfo Object
-PARALLEL_DIRS := Hello Simple mcc16 Skeleton
+# This tool has no plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
new file mode 100644
index 0000000..ca0493d
--- /dev/null
+++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -0,0 +1,116 @@
+//===-- llvm-dwarfdump.cpp - Debug info dumping utility for llvm -----------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This program is a utility that works like "dwarfdump".
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/MemoryObject.h"
+#include "llvm/Support/PrettyStackTrace.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/system_error.h"
+#include <algorithm>
+#include <cstring>
+using namespace llvm;
+using namespace object;
+
+static cl::list<std::string>
+InputFilenames(cl::Positional, cl::desc("<input object files>"),
+ cl::ZeroOrMore);
+
+static cl::opt<unsigned long long>
+Address("address", cl::init(-1ULL),
+ cl::desc("Print line information for a given address"));
+
+static void DumpInput(const StringRef &Filename) {
+ OwningPtr<MemoryBuffer> Buff;
+
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
+ errs() << Filename << ": " << ec.message() << "\n";
+ return;
+ }
+
+ OwningPtr<ObjectFile> Obj(ObjectFile::createObjectFile(Buff.take()));
+
+ StringRef DebugInfoSection;
+ StringRef DebugAbbrevSection;
+ StringRef DebugLineSection;
+ StringRef DebugArangesSection;
+ StringRef DebugStringSection;
+
+ 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;
+ }
+
+ OwningPtr<DIContext> dictx(DIContext::getDWARFContext(/*FIXME*/true,
+ DebugInfoSection,
+ DebugAbbrevSection,
+ DebugArangesSection,
+ DebugLineSection,
+ DebugStringSection));
+ if (Address == -1ULL) {
+ outs() << Filename
+ << ":\tfile format " << Obj->getFileFormatName() << "\n\n";
+ // Dump the complete DWARF structure.
+ dictx->dump(outs());
+ } else {
+ // Print line info for the specified address.
+ DILineInfo dli = dictx->getLineInfoForAddress(Address);
+ outs() << (dli.getFileName() ? dli.getFileName() : "<unknown>") << ':'
+ << dli.getLine() << ':' << dli.getColumn() << '\n';
+ }
+}
+
+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 dwarf dumper\n");
+
+ // Defaults to a.out if no filenames specified.
+ if (InputFilenames.size() == 0)
+ InputFilenames.push_back("a.out");
+
+ std::for_each(InputFilenames.begin(), InputFilenames.end(), DumpInput);
+
+ return 0;
+}
diff --git a/tools/llvm-extract/llvm-extract.cpp b/tools/llvm-extract/llvm-extract.cpp
index a6c229f..f6227ee 100644
--- a/tools/llvm-extract/llvm-extract.cpp
+++ b/tools/llvm-extract/llvm-extract.cpp
@@ -26,7 +26,9 @@
#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 <memory>
using namespace llvm;
@@ -45,16 +47,30 @@ Force("f", cl::desc("Enable binary output on terminals"));
static cl::opt<bool>
DeleteFn("delete", cl::desc("Delete specified Globals from Module"));
-// ExtractFuncs - The functions to extract from the module...
+// ExtractFuncs - The functions to extract from the module.
static cl::list<std::string>
ExtractFuncs("func", cl::desc("Specify function to extract"),
cl::ZeroOrMore, cl::value_desc("function"));
-// ExtractGlobals - The globals to extract from the module...
+// ExtractRegExpFuncs - The functions, matched via regular expression, to
+// extract from the module.
+static cl::list<std::string>
+ExtractRegExpFuncs("rfunc", cl::desc("Specify function(s) to extract using a "
+ "regular expression"),
+ cl::ZeroOrMore, cl::value_desc("rfunction"));
+
+// ExtractGlobals - The globals to extract from the module.
static cl::list<std::string>
ExtractGlobals("glob", cl::desc("Specify global to extract"),
cl::ZeroOrMore, cl::value_desc("global"));
+// ExtractRegExpGlobals - The globals, matched via regular expression, to
+// extract from the module...
+static cl::list<std::string>
+ExtractRegExpGlobals("rglob", cl::desc("Specify global(s) to extract using a "
+ "regular expression"),
+ cl::ZeroOrMore, cl::value_desc("rglobal"));
+
static cl::opt<bool>
OutputAssembly("S",
cl::desc("Write output as LLVM assembly"), cl::Hidden);
@@ -78,7 +94,8 @@ int main(int argc, char **argv) {
return 1;
}
- std::vector<GlobalValue *> GVs;
+ // Use SetVector to avoid duplicates.
+ SetVector<GlobalValue *> GVs;
// Figure out which globals we should extract.
for (size_t i = 0, e = ExtractGlobals.size(); i != e; ++i) {
@@ -88,7 +105,30 @@ int main(int argc, char **argv) {
<< ExtractGlobals[i] << "'!\n";
return 1;
}
- GVs.push_back(GV);
+ GVs.insert(GV);
+ }
+
+ // Extract globals via regular expression matching.
+ for (size_t i = 0, e = ExtractRegExpGlobals.size(); i != e; ++i) {
+ std::string Error;
+ Regex RegEx(ExtractRegExpGlobals[i]);
+ if (!RegEx.isValid(Error)) {
+ errs() << argv[0] << ": '" << ExtractRegExpGlobals[i] << "' "
+ "invalid regex: " << Error;
+ }
+ bool match = false;
+ for (Module::global_iterator GV = M.get()->global_begin(),
+ E = M.get()->global_end(); GV != E; GV++) {
+ if (RegEx.match(GV->getName())) {
+ GVs.insert(&*GV);
+ match = true;
+ }
+ }
+ if (!match) {
+ errs() << argv[0] << ": program doesn't contain global named '"
+ << ExtractRegExpGlobals[i] << "'!\n";
+ return 1;
+ }
}
// Figure out which functions we should extract.
@@ -99,7 +139,30 @@ int main(int argc, char **argv) {
<< ExtractFuncs[i] << "'!\n";
return 1;
}
- GVs.push_back(GV);
+ GVs.insert(GV);
+ }
+ // Extract functions via regular expression matching.
+ for (size_t i = 0, e = ExtractRegExpFuncs.size(); i != e; ++i) {
+ std::string Error;
+ StringRef RegExStr = ExtractRegExpFuncs[i];
+ Regex RegEx(RegExStr);
+ if (!RegEx.isValid(Error)) {
+ errs() << argv[0] << ": '" << ExtractRegExpFuncs[i] << "' "
+ "invalid regex: " << Error;
+ }
+ bool match = false;
+ for (Module::iterator F = M.get()->begin(), E = M.get()->end(); F != E;
+ F++) {
+ if (RegEx.match(F->getName())) {
+ GVs.insert(&*F);
+ match = true;
+ }
+ }
+ if (!match) {
+ errs() << argv[0] << ": program doesn't contain global named '"
+ << ExtractRegExpFuncs[i] << "'!\n";
+ return 1;
+ }
}
// Materialize requisite global values.
@@ -145,7 +208,9 @@ int main(int argc, char **argv) {
PassManager Passes;
Passes.add(new TargetData(M.get())); // Use correct TargetData
- Passes.add(createGVExtractionPass(GVs, DeleteFn));
+ std::vector<GlobalValue*> Gvs(GVs.begin(), GVs.end());
+
+ Passes.add(createGVExtractionPass(Gvs, DeleteFn));
if (!DeleteFn)
Passes.add(createGlobalDCEPass()); // Delete unreachable globals
Passes.add(createStripDeadDebugInfoPass()); // Remove dead debug info
diff --git a/tools/llvm-ld/Optimize.cpp b/tools/llvm-ld/Optimize.cpp
index ca6a477..7f3f900 100644
--- a/tools/llvm-ld/Optimize.cpp
+++ b/tools/llvm-ld/Optimize.cpp
@@ -12,14 +12,18 @@
//===----------------------------------------------------------------------===//
#include "llvm/Module.h"
+#include "llvm/PassManager.h"
+#include "llvm/Analysis/Verifier.h"
#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/PassManagerBuilder.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/PassNameParser.h"
#include "llvm/Support/PluginLoader.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#include "llvm/Transforms/Scalar.h"
using namespace llvm;
// Pass Name Options as generated by the PassNameParser
diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp
index 3fb7ba4..95ad1ca 100644
--- a/tools/llvm-link/llvm-link.cpp
+++ b/tools/llvm-link/llvm-link.cpp
@@ -103,7 +103,8 @@ int main(int argc, char **argv) {
if (Verbose) errs() << "Linking in '" << InputFilenames[i] << "'\n";
- if (Linker::LinkModules(Composite.get(), M.get(), &ErrorMessage)) {
+ if (Linker::LinkModules(Composite.get(), M.get(), Linker::DestroySource,
+ &ErrorMessage)) {
errs() << argv[0] << ": link error in '" << InputFilenames[i]
<< "': " << ErrorMessage << "\n";
return 1;
diff --git a/tools/llvm-mc/Disassembler.cpp b/tools/llvm-mc/Disassembler.cpp
index c389f6a..a9381b5 100644
--- a/tools/llvm-mc/Disassembler.cpp
+++ b/tools/llvm-mc/Disassembler.cpp
@@ -21,14 +21,15 @@
#include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
-#include "llvm/Target/TargetRegistry.h"
+#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/Triple.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/MemoryObject.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/raw_ostream.h"
using namespace llvm;
typedef std::vector<std::pair<unsigned char, const char*> > ByteArrayTy;
@@ -65,15 +66,26 @@ static bool PrintInsts(const MCDisassembler &DisAsm,
for (Index = 0; Index < Bytes.size(); Index += Size) {
MCInst Inst;
- if (DisAsm.getInstruction(Inst, Size, memoryObject, Index,
- /*REMOVE*/ nulls())) {
- Printer.printInst(&Inst, Out);
- Out << "\n";
- } else {
+ MCDisassembler::DecodeStatus S;
+ S = DisAsm.getInstruction(Inst, Size, memoryObject, Index,
+ /*REMOVE*/ nulls(), nulls());
+ switch (S) {
+ case MCDisassembler::Fail:
SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second),
"invalid instruction encoding", "warning");
if (Size == 0)
Size = 1; // skip illegible bytes
+ break;
+
+ case MCDisassembler::SoftFail:
+ SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second),
+ "potentially undefined instruction encoding", "warning");
+ // Fall through
+
+ case MCDisassembler::Success:
+ Printer.printInst(&Inst, Out, "");
+ Out << "\n";
+ break;
}
}
@@ -129,6 +141,8 @@ static bool ByteArrayFromString(ByteArrayTy &ByteArray,
int Disassembler::disassemble(const Target &T,
const std::string &Triple,
+ const std::string &Cpu,
+ const std::string &FeaturesStr,
MemoryBuffer &Buffer,
raw_ostream &Out) {
// Set up disassembler.
@@ -139,7 +153,13 @@ int Disassembler::disassemble(const Target &T,
return -1;
}
- OwningPtr<const MCDisassembler> DisAsm(T.createMCDisassembler());
+ OwningPtr<const MCSubtargetInfo> STI(T.createMCSubtargetInfo(Triple, Cpu, FeaturesStr));
+ if (!STI) {
+ errs() << "error: no subtarget info for target " << Triple << "\n";
+ return -1;
+ }
+
+ OwningPtr<const MCDisassembler> DisAsm(T.createMCDisassembler(*STI));
if (!DisAsm) {
errs() << "error: no disassembler for target " << Triple << "\n";
return -1;
@@ -147,7 +167,7 @@ int Disassembler::disassemble(const Target &T,
int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
OwningPtr<MCInstPrinter> IP(T.createMCInstPrinter(AsmPrinterVariant,
- *AsmInfo));
+ *AsmInfo, *STI));
if (!IP) {
errs() << "error: no instruction printer for target " << Triple << '\n';
return -1;
diff --git a/tools/llvm-mc/Disassembler.h b/tools/llvm-mc/Disassembler.h
index 433e71b..e8cd92d 100644
--- a/tools/llvm-mc/Disassembler.h
+++ b/tools/llvm-mc/Disassembler.h
@@ -27,6 +27,8 @@ class Disassembler {
public:
static int disassemble(const Target &target,
const std::string &tripleString,
+ const std::string &Cpu,
+ const std::string &FeaturesStr,
MemoryBuffer &buffer,
raw_ostream &Out);
diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp
index 334bf32..5fb3fdf 100644
--- a/tools/llvm-mc/llvm-mc.cpp
+++ b/tools/llvm-mc/llvm-mc.cpp
@@ -14,23 +14,18 @@
#include "llvm/MC/MCParser/AsmLexer.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
+#include "llvm/MC/MCAsmBackend.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCObjectFileInfo.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/Target/TargetAsmBackend.h"
-#include "llvm/Target/TargetAsmParser.h"
-#include "llvm/Target/TargetData.h"
-#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Target/TargetAsmInfo.h" // FIXME.
-#include "llvm/Target/TargetLowering.h" // FIXME.
-#include "llvm/Target/TargetLoweringObjectFile.h" // FIXME.
-#include "llvm/Target/TargetMachine.h" // FIXME.
-#include "llvm/Target/TargetSelect.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileUtilities.h"
@@ -42,6 +37,8 @@
#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/Support/system_error.h"
#include "Disassembler.h"
using namespace llvm;
@@ -111,6 +108,43 @@ MCPU("mcpu",
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>
NoInitialTextSection("n", cl::desc("Don't assume assembly file starts "
"in the text section"));
@@ -142,21 +176,42 @@ static const Target *GetTarget(const char *ProgName) {
// Figure out the target triple.
if (TripleName.empty())
TripleName = sys::getHostTriple();
+ Triple TheTriple(Triple::normalize(TripleName));
+
+ const Target *TheTarget = 0;
if (!ArchName.empty()) {
- llvm::Triple TT(TripleName);
- TT.setArchName(ArchName);
- TripleName = TT.str();
- }
+ for (TargetRegistry::iterator it = TargetRegistry::begin(),
+ ie = TargetRegistry::end(); it != ie; ++it) {
+ if (ArchName == it->getName()) {
+ TheTarget = &*it;
+ break;
+ }
+ }
- // Get the target specific parser.
- std::string Error;
- const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
- if (TheTarget)
- return TheTarget;
+ if (!TheTarget) {
+ errs() << ProgName << ": error: invalid target '" << ArchName << "'.\n";
+ return 0;
+ }
- errs() << ProgName << ": error: unable to get target for '" << TripleName
- << "', see --version and --triple.\n";
- return 0;
+ // Adjust the triple to match (if known), otherwise stick with the
+ // module/host triple.
+ Triple::ArchType Type = Triple::getArchTypeForLLVMName(ArchName);
+ if (Type != Triple::UnknownArch)
+ TheTriple.setArch(Type);
+ } else {
+ // Get the target specific parser.
+ std::string Error;
+ TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Error);
+ if (TheTarget == 0) {
+ errs() << ProgName << ": error: unable to get target for '"
+ << TheTriple.getTriple()
+ << "', see --version and --triple.\n";
+ return 0;
+ }
+ }
+
+ TripleName = TheTriple.getTriple();
+ return TheTarget;
}
static tool_output_file *GetOutputStream() {
@@ -309,28 +364,27 @@ static int AssembleInput(const char *ProgName) {
llvm::OwningPtr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(TripleName));
assert(MAI && "Unable to create target asm info!");
- // Package up features to be passed to target/subtarget
- std::string FeaturesStr;
+ llvm::OwningPtr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName));
+ assert(MRI && "Unable to create target register info!");
- // FIXME: We shouldn't need to do this (and link in codegen).
- // When we split this out, we should do it in a way that makes
- // it straightforward to switch subtargets on the fly (.e.g,
- // the .cpu and .code16 directives).
- OwningPtr<TargetMachine> TM(TheTarget->createTargetMachine(TripleName,
- MCPU,
- FeaturesStr));
-
- if (!TM) {
- errs() << ProgName << ": error: could not create target for triple '"
- << TripleName << "'.\n";
- return 1;
- }
+ // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and
+ // MCObjectFileInfo needs a MCContext reference in order to initialize itself.
+ OwningPtr<MCObjectFileInfo> MOFI(new MCObjectFileInfo());
+ MCContext Ctx(*MAI, *MRI, MOFI.get());
+ MOFI->InitMCObjectFileInfo(TripleName, RelocModel, CMModel, Ctx);
- const TargetAsmInfo *tai = new TargetAsmInfo(*TM);
- MCContext Ctx(*MAI, tai);
if (SaveTempLabels)
Ctx.setAllowTemporaryLabels(false);
+ // 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();
+ }
+
OwningPtr<tool_output_file> Out(GetOutputStream());
if (!Out)
return 1;
@@ -338,10 +392,6 @@ static int AssembleInput(const char *ProgName) {
formatted_raw_ostream FOS(Out->os());
OwningPtr<MCStreamer> Str;
- const TargetLoweringObjectFile &TLOF =
- TM->getTargetLowering()->getObjFileLowering();
- const_cast<TargetLoweringObjectFile&>(TLOF).Initialize(Ctx, *TM);
-
OwningPtr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
OwningPtr<MCSubtargetInfo>
STI(TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
@@ -349,35 +399,35 @@ static int AssembleInput(const char *ProgName) {
// FIXME: There is a bit of code duplication with addPassesToEmitFile.
if (FileType == OFT_AssemblyFile) {
MCInstPrinter *IP =
- TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI);
+ TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *STI);
MCCodeEmitter *CE = 0;
- TargetAsmBackend *TAB = 0;
+ MCAsmBackend *MAB = 0;
if (ShowEncoding) {
- CE = TheTarget->createCodeEmitter(*MCII, *STI, Ctx);
- TAB = TheTarget->createAsmBackend(TripleName);
+ CE = TheTarget->createMCCodeEmitter(*MCII, *STI, Ctx);
+ MAB = TheTarget->createMCAsmBackend(TripleName);
}
Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/true,
/*useLoc*/ true,
- /*useCFI*/ true, IP, CE, TAB,
+ /*useCFI*/ true, IP, CE, MAB,
ShowInst));
} else if (FileType == OFT_Null) {
Str.reset(createNullStreamer(Ctx));
} else {
assert(FileType == OFT_ObjectFile && "Invalid file type!");
- MCCodeEmitter *CE = TheTarget->createCodeEmitter(*MCII, *STI, Ctx);
- TargetAsmBackend *TAB = TheTarget->createAsmBackend(TripleName);
- Str.reset(TheTarget->createObjectStreamer(TripleName, Ctx, *TAB,
- FOS, CE, RelaxAll,
- NoExecStack));
+ MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *STI, Ctx);
+ MCAsmBackend *MAB = TheTarget->createMCAsmBackend(TripleName);
+ Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB,
+ FOS, CE, RelaxAll,
+ NoExecStack));
}
if (EnableLogging) {
Str.reset(createLoggingStreamer(Str.take(), errs()));
}
- OwningPtr<MCAsmParser> Parser(createMCAsmParser(*TheTarget, SrcMgr, Ctx,
- *Str.get(), *MAI));
- OwningPtr<TargetAsmParser> TAP(TheTarget->createAsmParser(*STI, *Parser));
+ OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx,
+ *Str.get(), *MAI));
+ OwningPtr<MCTargetAsmParser> TAP(TheTarget->createMCAsmParser(*STI, *Parser));
if (!TAP) {
errs() << ProgName
<< ": error: this target does not support assembly parsing.\n";
@@ -415,7 +465,16 @@ static int DisassembleInput(const char *ProgName, bool Enhanced) {
Res =
Disassembler::disassembleEnhanced(TripleName, *Buffer.take(), Out->os());
} else {
- Res = Disassembler::disassemble(*TheTarget, TripleName,
+ // 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();
+ }
+
+ Res = Disassembler::disassemble(*TheTarget, TripleName, MCPU, FeaturesStr,
*Buffer.take(), Out->os());
}
@@ -434,12 +493,7 @@ int main(int argc, char **argv) {
// Initialize targets and assembly printers/parsers.
llvm::InitializeAllTargetInfos();
- // FIXME: We shouldn't need to initialize the Target(Machine)s.
- llvm::InitializeAllTargets();
- llvm::InitializeAllMCAsmInfos();
- llvm::InitializeAllMCInstrInfos();
- llvm::InitializeAllMCSubtargetInfos();
- llvm::InitializeAllAsmPrinters();
+ llvm::InitializeAllTargetMCs();
llvm::InitializeAllAsmParsers();
llvm::InitializeAllDisassemblers();
diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp
index 014cb29..550ca4f 100644
--- a/tools/llvm-nm/llvm-nm.cpp
+++ b/tools/llvm-nm/llvm-nm.cpp
@@ -20,6 +20,7 @@
#include "llvm/Module.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/Bitcode/Archive.h"
+#include "llvm/Object/Archive.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FileSystem.h"
@@ -270,9 +271,9 @@ static void DumpSymbolNamesFromModule(Module *M) {
static void DumpSymbolNamesFromObject(ObjectFile *obj) {
error_code ec;
- for (ObjectFile::symbol_iterator i = obj->begin_symbols(),
- e = obj->end_symbols();
- i != e; i.increment(ec)) {
+ for (symbol_iterator i = obj->begin_symbols(),
+ e = obj->end_symbols();
+ i != e; i.increment(ec)) {
if (error(ec)) break;
bool internal;
if (error(i->isInternal(internal))) break;
@@ -285,7 +286,7 @@ static void DumpSymbolNamesFromObject(ObjectFile *obj) {
if (error(i->getSize(s.Size))) break;
}
if (PrintAddress)
- if (error(i->getAddress(s.Address))) break;
+ if (error(i->getOffset(s.Address))) break;
if (error(i->getNMTypeChar(s.TypeChar))) break;
if (error(i->getName(s.Name))) break;
SymbolList.push_back(s);
@@ -318,18 +319,34 @@ static void DumpSymbolNamesFromFile(std::string &Filename) {
errs() << ToolName << ": " << Filename << ": " << ErrorMessage << "\n";
} else if (aPath.isArchive()) {
- std::string ErrMsg;
- Archive* archive = Archive::OpenAndLoad(sys::Path(Filename), Context,
- &ErrorMessage);
- if (!archive)
- errs() << ToolName << ": " << Filename << ": " << ErrorMessage << "\n";
- std::vector<Module *> Modules;
- if (archive->getAllModules(Modules, &ErrorMessage)) {
- errs() << ToolName << ": " << Filename << ": " << ErrorMessage << "\n";
+ OwningPtr<Binary> arch;
+ if (error_code ec = object::createBinary(aPath.str(), arch)) {
+ errs() << ToolName << ": " << Filename << ": " << ec.message() << ".\n";
return;
}
- MultipleFiles = true;
- std::for_each (Modules.begin(), Modules.end(), DumpSymbolNamesFromModule);
+ if (object::Archive *a = dyn_cast<object::Archive>(arch.get())) {
+ for (object::Archive::child_iterator i = a->begin_children(),
+ e = a->end_children(); i != e; ++i) {
+ OwningPtr<Binary> child;
+ if (error_code ec = i->getAsBinary(child)) {
+ // Try opening it as a bitcode file.
+ OwningPtr<MemoryBuffer> buff(i->getBuffer());
+ Module *Result = 0;
+ if (buff)
+ Result = ParseBitcodeFile(buff.get(), Context, &ErrorMessage);
+
+ if (Result) {
+ DumpSymbolNamesFromModule(Result);
+ delete Result;
+ }
+ continue;
+ }
+ if (object::ObjectFile *o = dyn_cast<ObjectFile>(child.get())) {
+ outs() << o->getFileName() << ":\n";
+ DumpSymbolNamesFromObject(o);
+ }
+ }
+ }
} else if (aPath.isObjectFile()) {
OwningPtr<Binary> obj;
if (error_code ec = object::createBinary(aPath.str(), obj)) {
diff --git a/tools/llvm-objdump/CMakeLists.txt b/tools/llvm-objdump/CMakeLists.txt
index 4181b32..f3b2e1f 100644
--- a/tools/llvm-objdump/CMakeLists.txt
+++ b/tools/llvm-objdump/CMakeLists.txt
@@ -1,5 +1,6 @@
set(LLVM_LINK_COMPONENTS
${LLVM_TARGETS_TO_BUILD}
+ DebugInfo
MC
MCParser
MCDisassembler
@@ -8,4 +9,6 @@ set(LLVM_LINK_COMPONENTS
add_llvm_tool(llvm-objdump
llvm-objdump.cpp
+ MachODump.cpp
+ MCFunction.cpp
)
diff --git a/tools/llvm-objdump/MCFunction.cpp b/tools/llvm-objdump/MCFunction.cpp
new file mode 100644
index 0000000..5c67f1b
--- /dev/null
+++ b/tools/llvm-objdump/MCFunction.cpp
@@ -0,0 +1,138 @@
+//===-- MCFunction.cpp ----------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the algorithm to break down a region of machine code
+// into basic blocks and try to reconstruct a CFG from it.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MCFunction.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCInstrAnalysis.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/Support/MemoryObject.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/system_error.h"
+#include <set>
+using namespace llvm;
+
+MCFunction
+MCFunction::createFunctionFromMC(StringRef Name, const MCDisassembler *DisAsm,
+ const MemoryObject &Region, uint64_t Start,
+ uint64_t End, const MCInstrAnalysis *Ana,
+ raw_ostream &DebugOut,
+ SmallVectorImpl<uint64_t> &Calls) {
+ std::vector<MCDecodedInst> Instructions;
+ std::set<uint64_t> Splits;
+ Splits.insert(Start);
+ uint64_t Size;
+
+ MCFunction f(Name);
+
+ {
+ DenseSet<uint64_t> VisitedInsts;
+ SmallVector<uint64_t, 16> WorkList;
+ WorkList.push_back(Start);
+ // Disassemble code and gather basic block split points.
+ while (!WorkList.empty()) {
+ uint64_t Index = WorkList.pop_back_val();
+ if (VisitedInsts.find(Index) != VisitedInsts.end())
+ continue; // Already visited this location.
+
+ for (;Index < End; Index += Size) {
+ VisitedInsts.insert(Index);
+
+ MCInst Inst;
+ if (DisAsm->getInstruction(Inst, Size, Region, Index, DebugOut, nulls())){
+ Instructions.push_back(MCDecodedInst(Index, Size, Inst));
+ if (Ana->isBranch(Inst)) {
+ uint64_t targ = Ana->evaluateBranch(Inst, Index, Size);
+ if (targ != -1ULL && targ == Index+Size)
+ continue; // Skip nop jumps.
+
+ // If we could determine the branch target, make a note to start a
+ // new basic block there and add the target to the worklist.
+ if (targ != -1ULL) {
+ Splits.insert(targ);
+ WorkList.push_back(targ);
+ WorkList.push_back(Index+Size);
+ }
+ Splits.insert(Index+Size);
+ break;
+ } else if (Ana->isReturn(Inst)) {
+ // Return instruction. This basic block ends here.
+ Splits.insert(Index+Size);
+ break;
+ } else if (Ana->isCall(Inst)) {
+ uint64_t targ = Ana->evaluateBranch(Inst, Index, Size);
+ // Add the call to the call list if the destination is known.
+ if (targ != -1ULL && targ != Index+Size)
+ Calls.push_back(targ);
+ }
+ } else {
+ errs().write_hex(Index) << ": warning: invalid instruction encoding\n";
+ if (Size == 0)
+ Size = 1; // skip illegible bytes
+ }
+ }
+ }
+ }
+
+ // Make sure the instruction list is sorted.
+ std::sort(Instructions.begin(), Instructions.end());
+
+ // Create basic blocks.
+ unsigned ii = 0, ie = Instructions.size();
+ for (std::set<uint64_t>::iterator spi = Splits.begin(),
+ spe = llvm::prior(Splits.end()); spi != spe; ++spi) {
+ MCBasicBlock BB;
+ uint64_t BlockEnd = *llvm::next(spi);
+ // Add instructions to the BB.
+ for (; ii != ie; ++ii) {
+ if (Instructions[ii].Address < *spi ||
+ Instructions[ii].Address >= BlockEnd)
+ break;
+ BB.addInst(Instructions[ii]);
+ }
+ f.addBlock(*spi, BB);
+ }
+
+ std::sort(f.Blocks.begin(), f.Blocks.end());
+
+ // Calculate successors of each block.
+ for (MCFunction::iterator i = f.begin(), e = f.end(); i != e; ++i) {
+ MCBasicBlock &BB = const_cast<MCBasicBlock&>(i->second);
+ if (BB.getInsts().empty()) continue;
+ const MCDecodedInst &Inst = BB.getInsts().back();
+
+ if (Ana->isBranch(Inst.Inst)) {
+ uint64_t targ = Ana->evaluateBranch(Inst.Inst, Inst.Address, Inst.Size);
+ if (targ == -1ULL) {
+ // Indirect branch. Bail and add all blocks of the function as a
+ // successor.
+ for (MCFunction::iterator i = f.begin(), e = f.end(); i != e; ++i)
+ BB.addSucc(i->first);
+ } else if (targ != Inst.Address+Inst.Size)
+ BB.addSucc(targ);
+ // Conditional branches can also fall through to the next block.
+ if (Ana->isConditionalBranch(Inst.Inst) && llvm::next(i) != e)
+ BB.addSucc(llvm::next(i)->first);
+ } else {
+ // No branch. Fall through to the next block.
+ if (!Ana->isReturn(Inst.Inst) && llvm::next(i) != e)
+ BB.addSucc(llvm::next(i)->first);
+ }
+ }
+
+ return f;
+}
diff --git a/tools/llvm-objdump/MCFunction.h b/tools/llvm-objdump/MCFunction.h
new file mode 100644
index 0000000..6d3a548
--- /dev/null
+++ b/tools/llvm-objdump/MCFunction.h
@@ -0,0 +1,100 @@
+//===-- MCFunction.h ------------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the data structures to hold a CFG reconstructed from
+// machine code.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECTDUMP_MCFUNCTION_H
+#define LLVM_OBJECTDUMP_MCFUNCTION_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/DenseSet.h"
+#include "llvm/MC/MCInst.h"
+#include <map>
+
+namespace llvm {
+
+class MCDisassembler;
+class MCInstrAnalysis;
+class MemoryObject;
+class raw_ostream;
+
+/// MCDecodedInst - Small container to hold an MCInst and associated info like
+/// address and size.
+struct MCDecodedInst {
+ uint64_t Address;
+ uint64_t Size;
+ MCInst Inst;
+
+ MCDecodedInst() {}
+ MCDecodedInst(uint64_t Address, uint64_t Size, MCInst Inst)
+ : Address(Address), Size(Size), Inst(Inst) {}
+
+ bool operator<(const MCDecodedInst &RHS) const {
+ return Address < RHS.Address;
+ }
+};
+
+/// MCBasicBlock - Consists of multiple MCDecodedInsts and a list of successing
+/// MCBasicBlocks.
+class MCBasicBlock {
+ std::vector<MCDecodedInst> Insts;
+ typedef DenseSet<uint64_t> SetTy;
+ SetTy Succs;
+public:
+ ArrayRef<MCDecodedInst> getInsts() const { return Insts; }
+
+ typedef SetTy::const_iterator succ_iterator;
+ succ_iterator succ_begin() const { return Succs.begin(); }
+ succ_iterator succ_end() const { return Succs.end(); }
+
+ bool contains(uint64_t Addr) const { return Succs.count(Addr); }
+
+ void addInst(const MCDecodedInst &Inst) { Insts.push_back(Inst); }
+ void addSucc(uint64_t Addr) { Succs.insert(Addr); }
+
+ bool operator<(const MCBasicBlock &RHS) const {
+ return Insts.size() < RHS.Insts.size();
+ }
+};
+
+/// MCFunction - Represents a named function in machine code, containing
+/// multiple MCBasicBlocks.
+class MCFunction {
+ const StringRef Name;
+ // Keep BBs sorted by address.
+ typedef std::vector<std::pair<uint64_t, MCBasicBlock> > MapTy;
+ MapTy Blocks;
+public:
+ MCFunction(StringRef Name) : Name(Name) {}
+
+ // Create an MCFunction from a region of binary machine code.
+ static MCFunction
+ createFunctionFromMC(StringRef Name, const MCDisassembler *DisAsm,
+ const MemoryObject &Region, uint64_t Start, uint64_t End,
+ const MCInstrAnalysis *Ana, raw_ostream &DebugOut,
+ SmallVectorImpl<uint64_t> &Calls);
+
+ typedef MapTy::const_iterator iterator;
+ iterator begin() const { return Blocks.begin(); }
+ iterator end() const { return Blocks.end(); }
+
+ StringRef getName() const { return Name; }
+
+ MCBasicBlock &addBlock(uint64_t Address, const MCBasicBlock &BB) {
+ Blocks.push_back(std::make_pair(Address, BB));
+ return Blocks.back().second;
+ }
+};
+
+}
+
+#endif
diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp
new file mode 100644
index 0000000..3f44b29
--- /dev/null
+++ b/tools/llvm-objdump/MachODump.cpp
@@ -0,0 +1,617 @@
+//===-- MachODump.cpp - Object file dumping utility for llvm --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements the MachO-specific dumper for llvm-objdump.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm-objdump.h"
+#include "MCFunction.h"
+#include "llvm/Support/MachO.h"
+#include "llvm/Object/MachOObject.h"
+#include "llvm/ADT/OwningPtr.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/DebugInfo/DIContext.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCInstrAnalysis.h"
+#include "llvm/MC/MCInstrDesc.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/Format.h"
+#include "llvm/Support/GraphWriter.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/system_error.h"
+#include <algorithm>
+#include <cstring>
+using namespace llvm;
+using namespace object;
+
+static cl::opt<bool>
+ CFG("cfg", cl::desc("Create a CFG for every symbol in the object file and"
+ "write it to a graphviz file (MachO-only)"));
+
+static cl::opt<bool>
+ UseDbg("g", cl::desc("Print line information from debug info if available"));
+
+static cl::opt<std::string>
+ DSYMFile("dsym", cl::desc("Use .dSYM file for debug info"));
+
+static const Target *GetTarget(const MachOObject *MachOObj) {
+ // Figure out the target triple.
+ llvm::Triple TT("unknown-unknown-unknown");
+ switch (MachOObj->getHeader().CPUType) {
+ case llvm::MachO::CPUTypeI386:
+ TT.setArch(Triple::ArchType(Triple::x86));
+ break;
+ case llvm::MachO::CPUTypeX86_64:
+ TT.setArch(Triple::ArchType(Triple::x86_64));
+ break;
+ case llvm::MachO::CPUTypeARM:
+ TT.setArch(Triple::ArchType(Triple::arm));
+ break;
+ case llvm::MachO::CPUTypePowerPC:
+ TT.setArch(Triple::ArchType(Triple::ppc));
+ break;
+ case llvm::MachO::CPUTypePowerPC64:
+ TT.setArch(Triple::ArchType(Triple::ppc64));
+ break;
+ }
+
+ TripleName = TT.str();
+
+ // Get the target specific parser.
+ std::string Error;
+ const Target *TheTarget = TargetRegistry::lookupTarget(TripleName, Error);
+ if (TheTarget)
+ return TheTarget;
+
+ errs() << "llvm-objdump: error: unable to get target for '" << TripleName
+ << "', see --version and --triple.\n";
+ return 0;
+}
+
+struct Section {
+ char Name[16];
+ uint64_t Address;
+ uint64_t Size;
+ uint32_t Offset;
+ uint32_t NumRelocs;
+ uint64_t RelocTableOffset;
+};
+
+struct Symbol {
+ uint64_t Value;
+ uint32_t StringIndex;
+ uint8_t SectionIndex;
+ bool operator<(const Symbol &RHS) const { return Value < RHS.Value; }
+};
+
+template <typename T>
+static Section copySection(const T &Sect) {
+ Section S;
+ memcpy(S.Name, Sect->Name, 16);
+ S.Address = Sect->Address;
+ S.Size = Sect->Size;
+ S.Offset = Sect->Offset;
+ S.NumRelocs = Sect->NumRelocationTableEntries;
+ S.RelocTableOffset = Sect->RelocationTableOffset;
+ return S;
+}
+
+template <typename T>
+static Symbol copySymbol(const T &STE) {
+ Symbol S;
+ S.StringIndex = STE->StringIndex;
+ S.SectionIndex = STE->SectionIndex;
+ S.Value = STE->Value;
+ return S;
+}
+
+// Print additional information about an address, if available.
+static void DumpAddress(uint64_t Address, ArrayRef<Section> Sections,
+ MachOObject *MachOObj, raw_ostream &OS) {
+ for (unsigned i = 0; i != Sections.size(); ++i) {
+ uint64_t addr = Address-Sections[i].Address;
+ if (Sections[i].Address <= Address &&
+ Sections[i].Address + Sections[i].Size > Address) {
+ StringRef bytes = MachOObj->getData(Sections[i].Offset,
+ Sections[i].Size);
+ // Print constant strings.
+ if (!strcmp(Sections[i].Name, "__cstring"))
+ OS << '"' << bytes.substr(addr, bytes.find('\0', addr)) << '"';
+ // Print constant CFStrings.
+ if (!strcmp(Sections[i].Name, "__cfstring"))
+ OS << "@\"" << bytes.substr(addr, bytes.find('\0', addr)) << '"';
+ }
+ }
+}
+
+typedef std::map<uint64_t, MCFunction*> FunctionMapTy;
+typedef SmallVector<MCFunction, 16> FunctionListTy;
+static void createMCFunctionAndSaveCalls(StringRef Name,
+ const MCDisassembler *DisAsm,
+ MemoryObject &Object, uint64_t Start,
+ uint64_t End,
+ MCInstrAnalysis *InstrAnalysis,
+ uint64_t Address,
+ raw_ostream &DebugOut,
+ FunctionMapTy &FunctionMap,
+ FunctionListTy &Functions) {
+ SmallVector<uint64_t, 16> Calls;
+ MCFunction f =
+ MCFunction::createFunctionFromMC(Name, DisAsm, Object, Start, End,
+ InstrAnalysis, DebugOut, Calls);
+ Functions.push_back(f);
+ FunctionMap[Address] = &Functions.back();
+
+ // Add the gathered callees to the map.
+ for (unsigned i = 0, e = Calls.size(); i != e; ++i)
+ FunctionMap.insert(std::make_pair(Calls[i], (MCFunction*)0));
+}
+
+// Write a graphviz file for the CFG inside an MCFunction.
+static void emitDOTFile(const char *FileName, const MCFunction &f,
+ MCInstPrinter *IP) {
+ // Start a new dot file.
+ std::string Error;
+ raw_fd_ostream Out(FileName, Error);
+ if (!Error.empty()) {
+ errs() << "llvm-objdump: warning: " << Error << '\n';
+ return;
+ }
+
+ Out << "digraph " << f.getName() << " {\n";
+ Out << "graph [ rankdir = \"LR\" ];\n";
+ for (MCFunction::iterator i = f.begin(), e = f.end(); i != e; ++i) {
+ bool hasPreds = false;
+ // Only print blocks that have predecessors.
+ // FIXME: Slow.
+ for (MCFunction::iterator pi = f.begin(), pe = f.end(); pi != pe;
+ ++pi)
+ if (pi->second.contains(i->first)) {
+ hasPreds = true;
+ break;
+ }
+
+ if (!hasPreds && i != f.begin())
+ continue;
+
+ Out << '"' << i->first << "\" [ label=\"<a>";
+ // Print instructions.
+ for (unsigned ii = 0, ie = i->second.getInsts().size(); ii != ie;
+ ++ii) {
+ // Escape special chars and print the instruction in mnemonic form.
+ std::string Str;
+ raw_string_ostream OS(Str);
+ IP->printInst(&i->second.getInsts()[ii].Inst, OS, "");
+ Out << DOT::EscapeString(OS.str()) << '|';
+ }
+ Out << "<o>\" shape=\"record\" ];\n";
+
+ // Add edges.
+ for (MCBasicBlock::succ_iterator si = i->second.succ_begin(),
+ se = i->second.succ_end(); si != se; ++si)
+ Out << i->first << ":o -> " << *si <<":a\n";
+ }
+ Out << "}\n";
+}
+
+static void getSectionsAndSymbols(const macho::Header &Header,
+ MachOObject *MachOObj,
+ InMemoryStruct<macho::SymtabLoadCommand> *SymtabLC,
+ std::vector<Section> &Sections,
+ std::vector<Symbol> &Symbols,
+ SmallVectorImpl<uint64_t> &FoundFns) {
+ // Make a list of all symbols in the object file.
+ for (unsigned i = 0; i != Header.NumLoadCommands; ++i) {
+ const MachOObject::LoadCommandInfo &LCI = MachOObj->getLoadCommandInfo(i);
+ if (LCI.Command.Type == macho::LCT_Segment) {
+ InMemoryStruct<macho::SegmentLoadCommand> SegmentLC;
+ MachOObj->ReadSegmentLoadCommand(LCI, SegmentLC);
+
+ // Store the sections in this segment.
+ for (unsigned SectNum = 0; SectNum != SegmentLC->NumSections; ++SectNum) {
+ InMemoryStruct<macho::Section> Sect;
+ MachOObj->ReadSection(LCI, SectNum, Sect);
+ Sections.push_back(copySection(Sect));
+
+ }
+ } else if (LCI.Command.Type == macho::LCT_Segment64) {
+ InMemoryStruct<macho::Segment64LoadCommand> Segment64LC;
+ MachOObj->ReadSegment64LoadCommand(LCI, Segment64LC);
+
+ // Store the sections in this segment.
+ for (unsigned SectNum = 0; SectNum != Segment64LC->NumSections;
+ ++SectNum) {
+ InMemoryStruct<macho::Section64> Sect64;
+ MachOObj->ReadSection64(LCI, SectNum, Sect64);
+ Sections.push_back(copySection(Sect64));
+ }
+ } else if (LCI.Command.Type == macho::LCT_FunctionStarts) {
+ // We found a function starts segment, parse the addresses for later
+ // consumption.
+ InMemoryStruct<macho::LinkeditDataLoadCommand> LLC;
+ MachOObj->ReadLinkeditDataLoadCommand(LCI, LLC);
+
+ MachOObj->ReadULEB128s(LLC->DataOffset, FoundFns);
+ }
+ }
+ // Store the symbols.
+ if (SymtabLC) {
+ for (unsigned i = 0; i != (*SymtabLC)->NumSymbolTableEntries; ++i) {
+ if (MachOObj->is64Bit()) {
+ InMemoryStruct<macho::Symbol64TableEntry> STE;
+ MachOObj->ReadSymbol64TableEntry((*SymtabLC)->SymbolTableOffset, i,
+ STE);
+ Symbols.push_back(copySymbol(STE));
+ } else {
+ InMemoryStruct<macho::SymbolTableEntry> STE;
+ MachOObj->ReadSymbolTableEntry((*SymtabLC)->SymbolTableOffset, i,
+ STE);
+ Symbols.push_back(copySymbol(STE));
+ }
+ }
+ }
+}
+
+void llvm::DisassembleInputMachO(StringRef Filename) {
+ OwningPtr<MemoryBuffer> Buff;
+
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
+ errs() << "llvm-objdump: " << Filename << ": " << ec.message() << "\n";
+ return;
+ }
+
+ OwningPtr<MachOObject> MachOObj(MachOObject::LoadFromBuffer(Buff.take()));
+
+ const Target *TheTarget = GetTarget(MachOObj.get());
+ if (!TheTarget) {
+ // GetTarget prints out stuff.
+ return;
+ }
+ OwningPtr<const MCInstrInfo> InstrInfo(TheTarget->createMCInstrInfo());
+ OwningPtr<MCInstrAnalysis>
+ InstrAnalysis(TheTarget->createMCInstrAnalysis(InstrInfo.get()));
+
+ // Set up disassembler.
+ OwningPtr<const MCAsmInfo> AsmInfo(TheTarget->createMCAsmInfo(TripleName));
+ OwningPtr<const MCSubtargetInfo>
+ STI(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
+ OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI));
+ int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
+ OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
+ AsmPrinterVariant, *AsmInfo, *STI));
+
+ if (!InstrAnalysis || !AsmInfo || !STI || !DisAsm || !IP) {
+ errs() << "error: couldn't initialize disassembler for target "
+ << TripleName << '\n';
+ return;
+ }
+
+ outs() << '\n' << Filename << ":\n\n";
+
+ const macho::Header &Header = MachOObj->getHeader();
+
+ const MachOObject::LoadCommandInfo *SymtabLCI = 0;
+ // First, find the symbol table segment.
+ for (unsigned i = 0; i != Header.NumLoadCommands; ++i) {
+ const MachOObject::LoadCommandInfo &LCI = MachOObj->getLoadCommandInfo(i);
+ if (LCI.Command.Type == macho::LCT_Symtab) {
+ SymtabLCI = &LCI;
+ break;
+ }
+ }
+
+ // Read and register the symbol table data.
+ InMemoryStruct<macho::SymtabLoadCommand> SymtabLC;
+ MachOObj->ReadSymtabLoadCommand(*SymtabLCI, SymtabLC);
+ MachOObj->RegisterStringTable(*SymtabLC);
+
+ std::vector<Section> Sections;
+ std::vector<Symbol> Symbols;
+ SmallVector<uint64_t, 8> FoundFns;
+
+ getSectionsAndSymbols(Header, MachOObj.get(), &SymtabLC, Sections, Symbols,
+ FoundFns);
+
+ // Make a copy of the unsorted symbol list. FIXME: duplication
+ std::vector<Symbol> UnsortedSymbols(Symbols);
+ // Sort the symbols by address, just in case they didn't come in that way.
+ array_pod_sort(Symbols.begin(), Symbols.end());
+
+#ifndef NDEBUG
+ raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
+#else
+ raw_ostream &DebugOut = nulls();
+#endif
+
+ StringRef DebugAbbrevSection, DebugInfoSection, DebugArangesSection,
+ DebugLineSection, DebugStrSection;
+ OwningPtr<DIContext> diContext;
+ OwningPtr<MachOObject> DSYMObj;
+ MachOObject *DbgInfoObj = MachOObj.get();
+ // Try to find debug info and set up the DIContext for it.
+ if (UseDbg) {
+ ArrayRef<Section> DebugSections = Sections;
+ std::vector<Section> 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()) {
+ OwningPtr<MemoryBuffer> Buf;
+ if (error_code ec = MemoryBuffer::getFileOrSTDIN(DSYMFile.c_str(), Buf)) {
+ errs() << "llvm-objdump: " << Filename << ": " << ec.message() << '\n';
+ return;
+ }
+ DSYMObj.reset(MachOObject::LoadFromBuffer(Buf.take()));
+ const macho::Header &Header = DSYMObj->getHeader();
+
+ std::vector<Symbol> Symbols;
+ SmallVector<uint64_t, 8> FoundFns;
+ getSectionsAndSymbols(Header, DSYMObj.get(), 0, DSYMSections, Symbols,
+ FoundFns);
+ DebugSections = DSYMSections;
+ DbgInfoObj = DSYMObj.get();
+ }
+
+ // Find the named debug info sections.
+ for (unsigned SectIdx = 0; SectIdx != DebugSections.size(); SectIdx++) {
+ if (!strcmp(DebugSections[SectIdx].Name, "__debug_abbrev"))
+ DebugAbbrevSection = DbgInfoObj->getData(DebugSections[SectIdx].Offset,
+ DebugSections[SectIdx].Size);
+ else if (!strcmp(DebugSections[SectIdx].Name, "__debug_info"))
+ DebugInfoSection = DbgInfoObj->getData(DebugSections[SectIdx].Offset,
+ DebugSections[SectIdx].Size);
+ else if (!strcmp(DebugSections[SectIdx].Name, "__debug_aranges"))
+ DebugArangesSection = DbgInfoObj->getData(DebugSections[SectIdx].Offset,
+ DebugSections[SectIdx].Size);
+ else if (!strcmp(DebugSections[SectIdx].Name, "__debug_line"))
+ DebugLineSection = DbgInfoObj->getData(DebugSections[SectIdx].Offset,
+ DebugSections[SectIdx].Size);
+ else if (!strcmp(DebugSections[SectIdx].Name, "__debug_str"))
+ DebugStrSection = DbgInfoObj->getData(DebugSections[SectIdx].Offset,
+ DebugSections[SectIdx].Size);
+ }
+
+ // Setup the DIContext.
+ diContext.reset(DIContext::getDWARFContext(DbgInfoObj->isLittleEndian(),
+ DebugInfoSection,
+ DebugAbbrevSection,
+ DebugArangesSection,
+ DebugLineSection,
+ DebugStrSection));
+ }
+
+ FunctionMapTy FunctionMap;
+ FunctionListTy Functions;
+
+ for (unsigned SectIdx = 0; SectIdx != Sections.size(); SectIdx++) {
+ if (strcmp(Sections[SectIdx].Name, "__text"))
+ continue; // Skip non-text sections
+
+ // Insert the functions from the function starts segment into our map.
+ uint64_t VMAddr = Sections[SectIdx].Address - Sections[SectIdx].Offset;
+ for (unsigned i = 0, e = FoundFns.size(); i != e; ++i)
+ FunctionMap.insert(std::make_pair(FoundFns[i]+VMAddr, (MCFunction*)0));
+
+ StringRef Bytes = MachOObj->getData(Sections[SectIdx].Offset,
+ Sections[SectIdx].Size);
+ StringRefMemoryObject memoryObject(Bytes);
+ bool symbolTableWorked = false;
+
+ // Parse relocations.
+ std::vector<std::pair<uint64_t, uint32_t> > Relocs;
+ for (unsigned j = 0; j != Sections[SectIdx].NumRelocs; ++j) {
+ InMemoryStruct<macho::RelocationEntry> RE;
+ MachOObj->ReadRelocationEntry(Sections[SectIdx].RelocTableOffset, j, RE);
+ Relocs.push_back(std::make_pair(RE->Word0, RE->Word1 & 0xffffff));
+ }
+ array_pod_sort(Relocs.begin(), Relocs.end());
+
+ // Disassemble symbol by symbol.
+ for (unsigned SymIdx = 0; SymIdx != Symbols.size(); SymIdx++) {
+ // Make sure the symbol is defined in this section.
+ if ((unsigned)Symbols[SymIdx].SectionIndex - 1 != SectIdx)
+ continue;
+
+ // Start at the address of the symbol relative to the section's address.
+ uint64_t Start = Symbols[SymIdx].Value - Sections[SectIdx].Address;
+ // Stop disassembling either at the beginning of the next symbol or at
+ // the end of the section.
+ uint64_t End = (SymIdx+1 == Symbols.size() ||
+ Symbols[SymIdx].SectionIndex != Symbols[SymIdx+1].SectionIndex) ?
+ Sections[SectIdx].Size :
+ Symbols[SymIdx+1].Value - Sections[SectIdx].Address;
+ uint64_t Size;
+
+ if (Start >= End)
+ continue;
+
+ symbolTableWorked = true;
+
+ if (!CFG) {
+ // Normal disassembly, print addresses, bytes and mnemonic form.
+ outs() << MachOObj->getStringAtIndex(Symbols[SymIdx].StringIndex)
+ << ":\n";
+ DILineInfo lastLine;
+ for (uint64_t Index = Start; Index < End; Index += Size) {
+ MCInst Inst;
+
+ if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
+ DebugOut, nulls())) {
+ outs() << format("%8llx:\t", Sections[SectIdx].Address + Index);
+ DumpBytes(StringRef(Bytes.data() + Index, Size));
+ IP->printInst(&Inst, outs(), "");
+
+ // Print debug info.
+ if (diContext) {
+ DILineInfo dli =
+ diContext->getLineInfoForAddress(Sections[SectIdx].Address +
+ Index);
+ // Print valid line info if it changed.
+ if (dli != lastLine && dli.getLine() != 0)
+ outs() << "\t## " << dli.getFileName() << ':'
+ << dli.getLine() << ':' << dli.getColumn();
+ lastLine = dli;
+ }
+ outs() << "\n";
+ } else {
+ errs() << "llvm-objdump: warning: invalid instruction encoding\n";
+ if (Size == 0)
+ Size = 1; // skip illegible bytes
+ }
+ }
+ } else {
+ // Create CFG and use it for disassembly.
+ createMCFunctionAndSaveCalls(
+ MachOObj->getStringAtIndex(Symbols[SymIdx].StringIndex),
+ DisAsm.get(), memoryObject, Start, End, InstrAnalysis.get(),
+ Start, DebugOut, FunctionMap, Functions);
+ }
+ }
+
+ if (CFG) {
+ if (!symbolTableWorked) {
+ // Reading the symbol table didn't work, create a big __TEXT symbol.
+ createMCFunctionAndSaveCalls("__TEXT", DisAsm.get(), memoryObject,
+ 0, Sections[SectIdx].Size,
+ InstrAnalysis.get(),
+ Sections[SectIdx].Offset, DebugOut,
+ FunctionMap, Functions);
+ }
+ for (std::map<uint64_t, MCFunction*>::iterator mi = FunctionMap.begin(),
+ me = FunctionMap.end(); mi != me; ++mi)
+ if (mi->second == 0) {
+ // Create functions for the remaining callees we have gathered,
+ // but we didn't find a name for them.
+ SmallVector<uint64_t, 16> Calls;
+ MCFunction f =
+ MCFunction::createFunctionFromMC("unknown", DisAsm.get(),
+ memoryObject, mi->first,
+ Sections[SectIdx].Size,
+ InstrAnalysis.get(), DebugOut,
+ Calls);
+ Functions.push_back(f);
+ mi->second = &Functions.back();
+ for (unsigned i = 0, e = Calls.size(); i != e; ++i) {
+ std::pair<uint64_t, MCFunction*> p(Calls[i], (MCFunction*)0);
+ if (FunctionMap.insert(p).second)
+ mi = FunctionMap.begin();
+ }
+ }
+
+ DenseSet<uint64_t> PrintedBlocks;
+ for (unsigned ffi = 0, ffe = Functions.size(); ffi != ffe; ++ffi) {
+ MCFunction &f = Functions[ffi];
+ for (MCFunction::iterator fi = f.begin(), fe = f.end(); fi != fe; ++fi){
+ if (!PrintedBlocks.insert(fi->first).second)
+ continue; // We already printed this block.
+
+ // We assume a block has predecessors when it's the first block after
+ // a symbol.
+ bool hasPreds = FunctionMap.find(fi->first) != FunctionMap.end();
+
+ // See if this block has predecessors.
+ // FIXME: Slow.
+ for (MCFunction::iterator pi = f.begin(), pe = f.end(); pi != pe;
+ ++pi)
+ if (pi->second.contains(fi->first)) {
+ hasPreds = true;
+ break;
+ }
+
+ // No predecessors, this is a data block. Print as .byte directives.
+ if (!hasPreds) {
+ uint64_t End = llvm::next(fi) == fe ? Sections[SectIdx].Size :
+ llvm::next(fi)->first;
+ outs() << "# " << End-fi->first << " bytes of data:\n";
+ for (unsigned pos = fi->first; pos != End; ++pos) {
+ outs() << format("%8x:\t", Sections[SectIdx].Address + pos);
+ DumpBytes(StringRef(Bytes.data() + pos, 1));
+ outs() << format("\t.byte 0x%02x\n", (uint8_t)Bytes[pos]);
+ }
+ continue;
+ }
+
+ if (fi->second.contains(fi->first)) // Print a header for simple loops
+ outs() << "# Loop begin:\n";
+
+ DILineInfo lastLine;
+ // Walk over the instructions and print them.
+ for (unsigned ii = 0, ie = fi->second.getInsts().size(); ii != ie;
+ ++ii) {
+ const MCDecodedInst &Inst = fi->second.getInsts()[ii];
+
+ // If there's a symbol at this address, print its name.
+ if (FunctionMap.find(Sections[SectIdx].Address + Inst.Address) !=
+ FunctionMap.end())
+ outs() << FunctionMap[Sections[SectIdx].Address + Inst.Address]->
+ getName() << ":\n";
+
+ outs() << format("%8llx:\t", Sections[SectIdx].Address +
+ Inst.Address);
+ DumpBytes(StringRef(Bytes.data() + Inst.Address, Inst.Size));
+
+ if (fi->second.contains(fi->first)) // Indent simple loops.
+ outs() << '\t';
+
+ IP->printInst(&Inst.Inst, outs(), "");
+
+ // Look for relocations inside this instructions, if there is one
+ // print its target and additional information if available.
+ for (unsigned j = 0; j != Relocs.size(); ++j)
+ if (Relocs[j].first >= Sections[SectIdx].Address + Inst.Address &&
+ Relocs[j].first < Sections[SectIdx].Address + Inst.Address +
+ Inst.Size) {
+ outs() << "\t# "
+ << MachOObj->getStringAtIndex(
+ UnsortedSymbols[Relocs[j].second].StringIndex)
+ << ' ';
+ DumpAddress(UnsortedSymbols[Relocs[j].second].Value, Sections,
+ MachOObj.get(), outs());
+ }
+
+ // If this instructions contains an address, see if we can evaluate
+ // it and print additional information.
+ uint64_t targ = InstrAnalysis->evaluateBranch(Inst.Inst,
+ Inst.Address,
+ Inst.Size);
+ if (targ != -1ULL)
+ DumpAddress(targ, Sections, MachOObj.get(), outs());
+
+ // Print debug info.
+ if (diContext) {
+ DILineInfo dli =
+ diContext->getLineInfoForAddress(Sections[SectIdx].Address +
+ Inst.Address);
+ // Print valid line info if it changed.
+ if (dli != lastLine && dli.getLine() != 0)
+ outs() << "\t## " << dli.getFileName() << ':'
+ << dli.getLine() << ':' << dli.getColumn();
+ lastLine = dli;
+ }
+
+ outs() << '\n';
+ }
+ }
+
+ emitDOTFile((f.getName().str() + ".dot").c_str(), f, IP.get());
+ }
+ }
+ }
+}
diff --git a/tools/llvm-objdump/Makefile b/tools/llvm-objdump/Makefile
index 4d7cd34..703bf6c 100644
--- a/tools/llvm-objdump/Makefile
+++ b/tools/llvm-objdump/Makefile
@@ -9,7 +9,8 @@
LEVEL = ../..
TOOLNAME = llvm-objdump
-LINK_COMPONENTS = $(TARGETS_TO_BUILD) MC MCParser MCDisassembler Object
+LINK_COMPONENTS = $(TARGETS_TO_BUILD) DebugInfo MC MCParser MCDisassembler \
+ Object
# This tool has no plugins, optimize startup time.
TOOL_NO_EXPORTS = 1
diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp
index 4079e4a..4ae13be 100644
--- a/tools/llvm-objdump/llvm-objdump.cpp
+++ b/tools/llvm-objdump/llvm-objdump.cpp
@@ -13,6 +13,9 @@
//
//===----------------------------------------------------------------------===//
+#include "llvm-objdump.h"
+#include "MCFunction.h"
+#include "llvm/Object/Archive.h"
#include "llvm/Object/ObjectFile.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/Triple.h"
@@ -21,9 +24,13 @@
#include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/GraphWriter.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -31,44 +38,59 @@
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
-#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Target/TargetSelect.h"
#include <algorithm>
#include <cstring>
using namespace llvm;
using namespace object;
-namespace {
- cl::list<std::string>
- InputFilenames(cl::Positional, cl::desc("<input object files>"),
- cl::ZeroOrMore);
+static cl::list<std::string>
+InputFilenames(cl::Positional, cl::desc("<input object files>"),cl::ZeroOrMore);
- cl::opt<bool>
- Disassemble("disassemble",
- cl::desc("Display assembler mnemonics for the machine instructions"));
- cl::alias
- Disassembled("d", cl::desc("Alias for --disassemble"),
- cl::aliasopt(Disassemble));
+static cl::opt<bool>
+Disassemble("disassemble",
+ cl::desc("Display assembler mnemonics for the machine instructions"));
+static cl::alias
+Disassembled("d", cl::desc("Alias for --disassemble"),
+ cl::aliasopt(Disassemble));
- cl::opt<std::string>
- TripleName("triple", cl::desc("Target triple to disassemble for, "
+static cl::opt<bool>
+Relocations("r", cl::desc("Display the relocation entries in the file"));
+
+static cl::opt<bool>
+MachO("macho", cl::desc("Use MachO specific object file parser"));
+static cl::alias
+MachOm("m", cl::desc("Alias for --macho"), cl::aliasopt(MachO));
+
+cl::opt<std::string>
+llvm::TripleName("triple", cl::desc("Target triple to disassemble for, "
+ "see -version for available targets"));
+
+cl::opt<std::string>
+llvm::ArchName("arch", cl::desc("Target arch to disassemble for, "
"see -version for available targets"));
- cl::opt<std::string>
- ArchName("arch", cl::desc("Target arch to disassemble for, "
- "see -version for available targets"));
+static cl::opt<bool>
+SectionHeaders("section-headers", cl::desc("Display summaries of the headers "
+ "for each section."));
+static cl::alias
+SectionHeadersShort("headers", cl::desc("Alias for --section-headers"),
+ cl::aliasopt(SectionHeaders));
+static cl::alias
+SectionHeadersShorter("h", cl::desc("Alias for --section-headers"),
+ cl::aliasopt(SectionHeaders));
- StringRef ToolName;
+static StringRef ToolName;
- bool error(error_code ec) {
- if (!ec) return false;
+static bool error(error_code ec) {
+ if (!ec) return false;
- outs() << ToolName << ": error reading file: " << ec.message() << ".\n";
- outs().flush();
- return true;
- }
+ outs() << ToolName << ": error reading file: " << ec.message() << ".\n";
+ outs().flush();
+ return true;
}
static const Target *GetTarget(const ObjectFile *Obj = NULL) {
@@ -96,27 +118,8 @@ static const Target *GetTarget(const ObjectFile *Obj = NULL) {
return 0;
}
-namespace {
-class StringRefMemoryObject : public MemoryObject {
-private:
- StringRef Bytes;
-public:
- StringRefMemoryObject(StringRef bytes) : Bytes(bytes) {}
-
- uint64_t getBase() const { return 0; }
- uint64_t getExtent() const { return Bytes.size(); }
-
- int readByte(uint64_t Addr, uint8_t *Byte) const {
- if (Addr > getExtent())
- return -1;
- *Byte = Bytes[Addr];
- return 0;
- }
-};
-}
-
-static void DumpBytes(StringRef bytes) {
- static char hex_rep[] = "0123456789abcdef";
+void llvm::DumpBytes(StringRef bytes) {
+ static const char hex_rep[] = "0123456789abcdef";
// FIXME: The real way to do this is to figure out the longest instruction
// and align to that size before printing. I'll fix this when I get
// around to outputting relocations.
@@ -141,44 +144,45 @@ static void DumpBytes(StringRef bytes) {
outs() << output;
}
-static void DisassembleInput(const StringRef &Filename) {
- OwningPtr<MemoryBuffer> Buff;
-
- if (error_code ec = MemoryBuffer::getFileOrSTDIN(Filename, Buff)) {
- errs() << ToolName << ": " << Filename << ": " << ec.message() << "\n";
- return;
- }
-
- OwningPtr<ObjectFile> Obj(ObjectFile::createObjectFile(Buff.take()));
+static bool RelocAddressLess(RelocationRef a, RelocationRef b) {
+ uint64_t a_addr, b_addr;
+ if (error(a.getAddress(a_addr))) return false;
+ if (error(b.getAddress(b_addr))) return false;
+ return a_addr < b_addr;
+}
- const Target *TheTarget = GetTarget(Obj.get());
+static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
+ const Target *TheTarget = GetTarget(Obj);
if (!TheTarget) {
// GetTarget prints out stuff.
return;
}
outs() << '\n';
- outs() << Filename
+ outs() << Obj->getFileName()
<< ":\tfile format " << Obj->getFileFormatName() << "\n\n";
error_code ec;
- for (ObjectFile::section_iterator i = Obj->begin_sections(),
- e = Obj->end_sections();
- i != e; i.increment(ec)) {
+ for (section_iterator i = Obj->begin_sections(),
+ e = Obj->end_sections();
+ i != e; i.increment(ec)) {
if (error(ec)) break;
bool text;
if (error(i->isText(text))) break;
if (!text) continue;
+ uint64_t SectionAddr;
+ if (error(i->getAddress(SectionAddr))) break;
+
// Make a list of all the symbols in this section.
std::vector<std::pair<uint64_t, StringRef> > Symbols;
- for (ObjectFile::symbol_iterator si = Obj->begin_symbols(),
- se = Obj->end_symbols();
- si != se; si.increment(ec)) {
+ for (symbol_iterator si = Obj->begin_symbols(),
+ se = Obj->end_symbols();
+ si != se; si.increment(ec)) {
bool contains;
if (!error(i->containsSymbol(*si, contains)) && contains) {
uint64_t Address;
- if (error(si->getAddress(Address))) break;
+ if (error(si->getOffset(Address))) break;
StringRef Name;
if (error(si->getName(Name))) break;
Symbols.push_back(std::make_pair(Address, Name));
@@ -188,6 +192,20 @@ static void DisassembleInput(const StringRef &Filename) {
// Sort the symbols by address, just in case they didn't come in that way.
array_pod_sort(Symbols.begin(), Symbols.end());
+ // Make a list of all the relocations for this section.
+ std::vector<RelocationRef> Rels;
+ if (InlineRelocs) {
+ for (relocation_iterator ri = i->begin_relocations(),
+ re = i->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);
+
StringRef name;
if (error(i->getName(name))) break;
outs() << "Disassembly of section " << name << ':';
@@ -205,7 +223,16 @@ static void DisassembleInput(const StringRef &Filename) {
return;
}
- OwningPtr<const MCDisassembler> DisAsm(TheTarget->createMCDisassembler());
+ OwningPtr<const MCSubtargetInfo> STI(
+ TheTarget->createMCSubtargetInfo(TripleName, "", ""));
+
+ if (!STI) {
+ errs() << "error: no subtarget info for target " << TripleName << "\n";
+ return;
+ }
+
+ OwningPtr<const MCDisassembler> DisAsm(
+ TheTarget->createMCDisassembler(*STI));
if (!DisAsm) {
errs() << "error: no disassembler for target " << TripleName << "\n";
return;
@@ -213,9 +240,10 @@ static void DisassembleInput(const StringRef &Filename) {
int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
OwningPtr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
- AsmPrinterVariant, *AsmInfo));
+ AsmPrinterVariant, *AsmInfo, *STI));
if (!IP) {
- errs() << "error: no instruction printer for target " << TripleName << '\n';
+ errs() << "error: no instruction printer for target " << TripleName
+ << '\n';
return;
}
@@ -227,14 +255,24 @@ static void DisassembleInput(const StringRef &Filename) {
uint64_t SectSize;
if (error(i->getSize(SectSize))) break;
+ std::vector<RelocationRef>::const_iterator rel_cur = Rels.begin();
+ std::vector<RelocationRef>::const_iterator rel_end = Rels.end();
// Disassemble symbol by symbol.
for (unsigned si = 0, se = Symbols.size(); si != se; ++si) {
uint64_t Start = Symbols[si].first;
- uint64_t End = si == se-1 ? SectSize : Symbols[si + 1].first - 1;
- outs() << '\n' << Symbols[si].second << ":\n";
+ uint64_t End;
+ // The end is either the size of the section or the beginning of the next
+ // symbol.
+ if (si == se - 1)
+ End = SectSize;
+ // Make sure this symbol takes up space.
+ else if (Symbols[si + 1].first != Start)
+ End = Symbols[si + 1].first - 1;
+ else
+ // This symbol has the same address as the next symbol. Skip it.
+ continue;
- for (Index = Start; Index < End; Index += Size) {
- MCInst Inst;
+ outs() << '\n' << Symbols[si].second << ":\n";
#ifndef NDEBUG
raw_ostream &DebugOut = DebugFlag ? dbgs() : nulls();
@@ -242,23 +280,152 @@ static void DisassembleInput(const StringRef &Filename) {
raw_ostream &DebugOut = nulls();
#endif
- if (DisAsm->getInstruction(Inst, Size, memoryObject, Index, DebugOut)) {
- uint64_t addr;
- if (error(i->getAddress(addr))) break;
- outs() << format("%8x:\t", addr + Index);
+ for (Index = Start; Index < End; Index += Size) {
+ MCInst Inst;
+
+ if (DisAsm->getInstruction(Inst, Size, memoryObject, Index,
+ DebugOut, nulls())) {
+ outs() << format("%8x:\t", SectionAddr + Index);
DumpBytes(StringRef(Bytes.data() + Index, Size));
- IP->printInst(&Inst, outs());
+ IP->printInst(&Inst, outs(), "");
outs() << "\n";
} else {
errs() << ToolName << ": warning: invalid instruction encoding\n";
if (Size == 0)
Size = 1; // skip illegible bytes
}
+
+ // Print relocation for instruction.
+ while (rel_cur != rel_end) {
+ uint64_t addr;
+ SmallString<16> name;
+ SmallString<32> val;
+ if (error(rel_cur->getAddress(addr))) goto skip_print_rel;
+ // Stop when rel_cur's address is past the current instruction.
+ if (addr > Index + Size) break;
+ if (error(rel_cur->getTypeName(name))) goto skip_print_rel;
+ if (error(rel_cur->getValueString(val))) goto skip_print_rel;
+
+ outs() << format("\t\t\t%8x: ", SectionAddr + addr) << name << "\t"
+ << val << "\n";
+
+ skip_print_rel:
+ ++rel_cur;
+ }
}
}
}
}
+static void PrintRelocations(const ObjectFile *o) {
+ error_code ec;
+ for (section_iterator si = o->begin_sections(), se = o->end_sections();
+ si != se; si.increment(ec)){
+ if (error(ec)) return;
+ if (si->begin_relocations() == si->end_relocations())
+ continue;
+ StringRef secname;
+ if (error(si->getName(secname))) continue;
+ outs() << "RELOCATION RECORDS FOR [" << secname << "]:\n";
+ for (relocation_iterator ri = si->begin_relocations(),
+ re = si->end_relocations();
+ ri != re; ri.increment(ec)) {
+ if (error(ec)) return;
+
+ uint64_t address;
+ SmallString<32> relocname;
+ SmallString<32> valuestr;
+ if (error(ri->getTypeName(relocname))) continue;
+ if (error(ri->getAddress(address))) continue;
+ if (error(ri->getValueString(valuestr))) continue;
+ outs() << address << " " << relocname << " " << valuestr << "\n";
+ }
+ outs() << "\n";
+ }
+}
+
+static void PrintSectionHeaders(const ObjectFile *o) {
+ outs() << "Sections:\n"
+ "Idx Name Size Address Type\n";
+ error_code ec;
+ unsigned i = 0;
+ for (section_iterator si = o->begin_sections(), se = o->end_sections();
+ si != se; si.increment(ec)) {
+ if (error(ec)) return;
+ StringRef Name;
+ if (error(si->getName(Name))) return;
+ uint64_t Address;
+ if (error(si->getAddress(Address))) return;
+ uint64_t Size;
+ if (error(si->getSize(Size))) return;
+ bool Text, Data, BSS;
+ if (error(si->isText(Text))) return;
+ if (error(si->isData(Data))) return;
+ if (error(si->isBSS(BSS))) return;
+ std::string Type = (std::string(Text ? "TEXT " : "") +
+ (Data ? "DATA " : "") + (BSS ? "BSS" : ""));
+ outs() << format("%3d %-13s %09"PRIx64" %017"PRIx64" %s\n", i, Name.str().c_str(), Size,
+ Address, Type.c_str());
+ ++i;
+ }
+}
+
+static void DumpObject(const ObjectFile *o) {
+ if (Disassemble)
+ DisassembleObject(o, Relocations);
+ if (Relocations && !Disassemble)
+ PrintRelocations(o);
+ if (SectionHeaders)
+ PrintSectionHeaders(o);
+}
+
+/// @brief Dump each object file in \a a;
+static void DumpArchive(const Archive *a) {
+ for (Archive::child_iterator i = a->begin_children(),
+ e = a->end_children(); i != e; ++i) {
+ OwningPtr<Binary> child;
+ if (error_code ec = i->getAsBinary(child)) {
+ errs() << ToolName << ": '" << a->getFileName() << "': " << ec.message()
+ << ".\n";
+ continue;
+ }
+ if (ObjectFile *o = dyn_cast<ObjectFile>(child.get()))
+ DumpObject(o);
+ else
+ errs() << ToolName << ": '" << a->getFileName() << "': "
+ << "Unrecognized file type.\n";
+ }
+}
+
+/// @brief Open file and figure out how to dump it.
+static void DumpInput(StringRef file) {
+ // If file isn't stdin, check that it exists.
+ if (file != "-" && !sys::fs::exists(file)) {
+ errs() << ToolName << ": '" << file << "': " << "No such file\n";
+ return;
+ }
+
+ if (MachO && Disassemble) {
+ DisassembleInputMachO(file);
+ return;
+ }
+
+ // Attempt to open the binary.
+ OwningPtr<Binary> binary;
+ if (error_code ec = createBinary(file, binary)) {
+ errs() << ToolName << ": '" << file << "': " << ec.message() << ".\n";
+ return;
+ }
+
+ if (Archive *a = dyn_cast<Archive>(binary.get())) {
+ DumpArchive(a);
+ } else if (ObjectFile *o = dyn_cast<ObjectFile>(binary.get())) {
+ DumpObject(o);
+ } else {
+ errs() << ToolName << ": '" << file << "': " << "Unrecognized file type.\n";
+ }
+}
+
int main(int argc, char **argv) {
// Print a stack trace if we signal out.
sys::PrintStackTraceOnErrorSignal();
@@ -267,10 +434,7 @@ int main(int argc, char **argv) {
// Initialize targets and assembly printers/parsers.
llvm::InitializeAllTargetInfos();
- // FIXME: We shouldn't need to initialize the Target(Machine)s.
- llvm::InitializeAllTargets();
- llvm::InitializeAllMCAsmInfos();
- llvm::InitializeAllAsmPrinters();
+ llvm::InitializeAllTargetMCs();
llvm::InitializeAllAsmParsers();
llvm::InitializeAllDisassemblers();
@@ -283,15 +447,13 @@ int main(int argc, char **argv) {
if (InputFilenames.size() == 0)
InputFilenames.push_back("a.out");
- // -d is the only flag that is currently implemented, so just print help if
- // it is not set.
- if (!Disassemble) {
+ if (!Disassemble && !Relocations && !SectionHeaders) {
cl::PrintHelpMessage();
return 2;
}
std::for_each(InputFilenames.begin(), InputFilenames.end(),
- DisassembleInput);
+ DumpInput);
return 0;
}
diff --git a/tools/llvm-objdump/llvm-objdump.h b/tools/llvm-objdump/llvm-objdump.h
new file mode 100644
index 0000000..75f852a
--- /dev/null
+++ b/tools/llvm-objdump/llvm-objdump.h
@@ -0,0 +1,46 @@
+//===-- llvm-objdump.h ----------------------------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJDUMP_H
+#define LLVM_OBJDUMP_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/DataTypes.h"
+#include "llvm/Support/MemoryObject.h"
+
+namespace llvm {
+
+extern cl::opt<std::string> TripleName;
+extern cl::opt<std::string> ArchName;
+
+// Various helper functions.
+void DumpBytes(StringRef bytes);
+void DisassembleInputMachO(StringRef Filename);
+
+class StringRefMemoryObject : public MemoryObject {
+private:
+ StringRef Bytes;
+public:
+ StringRefMemoryObject(StringRef bytes) : Bytes(bytes) {}
+
+ uint64_t getBase() const { return 0; }
+ uint64_t getExtent() const { return Bytes.size(); }
+
+ int readByte(uint64_t Addr, uint8_t *Byte) const {
+ if (Addr >= getExtent())
+ return -1;
+ *Byte = Bytes[Addr];
+ return 0;
+ }
+};
+
+}
+
+#endif
diff --git a/tools/llvm-shlib/Makefile b/tools/llvm-shlib/Makefile
index 9e6faca..0695c00 100644
--- a/tools/llvm-shlib/Makefile
+++ b/tools/llvm-shlib/Makefile
@@ -30,10 +30,11 @@ endif
include $(LEVEL)/Makefile.common
# Include all archives in libLLVM.(so|dylib) except the ones that have
-# their own dynamic libraries.
+# their own dynamic libraries and TableGen.
Archives := $(wildcard $(LibDir)/libLLVM*.a)
SharedLibraries := $(wildcard $(LibDir)/libLLVM*$(SHLIBEXT))
-IncludeInLibLlvm := $(filter-out $(basename $(SharedLibraries)).a, $(Archives))
+ExcludeFromLibLlvm := $(basename $(SharedLibraries)).a %/libLLVMTableGen.a
+IncludeInLibLlvm := $(filter-out $(ExcludeFromLibLlvm), $(Archives))
LLVMLibsOptions := $(IncludeInLibLlvm:$(LibDir)/lib%.a=-l%)
LLVMLibsPaths := $(IncludeInLibLlvm)
diff --git a/tools/llvm-size/CMakeLists.txt b/tools/llvm-size/CMakeLists.txt
new file mode 100644
index 0000000..933cc75
--- /dev/null
+++ b/tools/llvm-size/CMakeLists.txt
@@ -0,0 +1,5 @@
+set(LLVM_LINK_COMPONENTS object)
+
+add_llvm_tool(llvm-size
+ llvm-size.cpp
+ )
diff --git a/tools/llvmc/examples/Simple/Makefile b/tools/llvm-size/Makefile
index c10387c..5d0e27e 100644
--- a/tools/llvmc/examples/Simple/Makefile
+++ b/tools/llvm-size/Makefile
@@ -1,4 +1,4 @@
-##===- llvmc/examples/Simple/Makefile ----------------------*- Makefile -*-===##
+##===- tools/llvm-size/Makefile ----------------------------*- Makefile -*-===##
#
# The LLVM Compiler Infrastructure
#
@@ -6,10 +6,12 @@
# License. See LICENSE.TXT for details.
#
##===----------------------------------------------------------------------===##
+LEVEL = ../..
-LEVEL = ../../../..
+TOOLNAME = llvm-size
+LINK_COMPONENTS = object
-LLVMC_BASED_DRIVER = Simple
-BUILT_SOURCES = Simple.inc
+# This tool has no plugins, optimize startup time.
+TOOL_NO_EXPORTS = 1
include $(LEVEL)/Makefile.common
diff --git a/tools/llvm-size/llvm-size.cpp b/tools/llvm-size/llvm-size.cpp
new file mode 100644
index 0000000..70e5cb9
--- /dev/null
+++ b/tools/llvm-size/llvm-size.cpp
@@ -0,0 +1,311 @@
+//===-- llvm-size.cpp - Print the size of each object section -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This program is a utility that works like traditional Unix "size",
+// that is, it prints out the size of each section, and the total size of all
+// sections.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/APInt.h"
+#include "llvm/Object/Archive.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Casting.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/raw_ostream.h"
+#include "llvm/Support/Signals.h"
+#include "llvm/Support/system_error.h"
+#include <algorithm>
+#include <string>
+using namespace llvm;
+using namespace object;
+
+enum OutputFormatTy {berkeley, sysv};
+static cl::opt<OutputFormatTy>
+ OutputFormat("format",
+ cl::desc("Specify output format"),
+ cl::values(clEnumVal(sysv, "System V format"),
+ clEnumVal(berkeley, "Berkeley format"),
+ clEnumValEnd),
+ cl::init(berkeley));
+
+static cl::opt<OutputFormatTy>
+ OutputFormatShort(cl::desc("Specify output format"),
+ cl::values(clEnumValN(sysv, "A", "System V format"),
+ clEnumValN(berkeley, "B", "Berkeley format"),
+ clEnumValEnd),
+ cl::init(berkeley));
+
+enum RadixTy {octal = 8, decimal = 10, hexadecimal = 16};
+static cl::opt<unsigned int>
+ Radix("-radix",
+ cl::desc("Print size in radix. Only 8, 10, and 16 are valid"),
+ cl::init(decimal));
+
+static cl::opt<RadixTy>
+ RadixShort(cl::desc("Print size in radix:"),
+ cl::values(clEnumValN(octal, "o", "Print size in octal"),
+ clEnumValN(decimal, "d", "Print size in decimal"),
+ clEnumValN(hexadecimal, "x", "Print size in hexadecimal"),
+ clEnumValEnd),
+ cl::init(decimal));
+
+static cl::list<std::string>
+ InputFilenames(cl::Positional, cl::desc("<input files>"),
+ cl::ZeroOrMore);
+
+static std::string ToolName;
+
+/// @brief If ec is not success, print the error and return true.
+static bool error(error_code ec) {
+ if (!ec) return false;
+
+ outs() << ToolName << ": error reading file: " << ec.message() << ".\n";
+ outs().flush();
+ return true;
+}
+
+/// @brief Get the length of the string that represents @p num in Radix
+/// including the leading 0x or 0 for hexadecimal and octal respectively.
+static size_t getNumLengthAsString(uint64_t num) {
+ APInt conv(64, num);
+ SmallString<32> result;
+ conv.toString(result, Radix, false, true);
+ return result.size();
+}
+
+/// @brief Print the size of each section in @p o.
+///
+/// The format used is determined by @c OutputFormat and @c Radix.
+static void PrintObjectSectionSizes(ObjectFile *o) {
+ uint64_t total = 0;
+ std::string fmtbuf;
+ raw_string_ostream fmt(fmtbuf);
+
+ const char *radix_fmt = 0;
+ switch (Radix) {
+ case octal:
+ radix_fmt = "llo";
+ break;
+ case decimal:
+ radix_fmt = "llu";
+ break;
+ case hexadecimal:
+ radix_fmt = "llx";
+ break;
+ }
+ if (OutputFormat == sysv) {
+ // Run two passes over all sections. The first gets the lengths needed for
+ // formatting the output. The second actually does the output.
+ std::size_t max_name_len = strlen("section");
+ std::size_t max_size_len = strlen("size");
+ std::size_t max_addr_len = strlen("addr");
+ error_code ec;
+ for (section_iterator i = o->begin_sections(),
+ e = o->end_sections(); i != e;
+ i.increment(ec)) {
+ if (error(ec))
+ return;
+ uint64_t size = 0;
+ if (error(i->getSize(size)))
+ return;
+ total += size;
+
+ StringRef name;
+ uint64_t addr = 0;
+ if (error(i->getName(name))) return;
+ if (error(i->getAddress(addr))) return;
+ max_name_len = std::max(max_name_len, name.size());
+ max_size_len = std::max(max_size_len, getNumLengthAsString(size));
+ max_addr_len = std::max(max_addr_len, getNumLengthAsString(addr));
+ }
+
+ // Add extra padding.
+ max_name_len += 2;
+ max_size_len += 2;
+ max_addr_len += 2;
+
+ // Setup header format.
+ fmt << "%-" << max_name_len << "s "
+ << "%" << max_size_len << "s "
+ << "%" << max_addr_len << "s\n";
+
+ // Print header
+ outs() << format(fmt.str().c_str(),
+ static_cast<const char*>("section"),
+ static_cast<const char*>("size"),
+ static_cast<const char*>("addr"));
+ fmtbuf.clear();
+
+ // Setup per section format.
+ fmt << "%-" << max_name_len << "s "
+ << "%#" << max_size_len << radix_fmt << " "
+ << "%#" << max_addr_len << radix_fmt << "\n";
+
+ // Print each section.
+ for (section_iterator i = o->begin_sections(),
+ e = o->end_sections(); i != e;
+ i.increment(ec)) {
+ if (error(ec))
+ return;
+
+ StringRef name;
+ uint64_t size = 0;
+ uint64_t addr = 0;
+ if (error(i->getName(name))) return;
+ if (error(i->getSize(size))) return;
+ if (error(i->getAddress(addr))) return;
+ std::string namestr = name;
+
+ outs() << format(fmt.str().c_str(),
+ namestr.c_str(),
+ size,
+ addr);
+ }
+
+ // Print total.
+ fmtbuf.clear();
+ fmt << "%-" << max_name_len << "s "
+ << "%#" << max_size_len << radix_fmt << "\n";
+ outs() << format(fmt.str().c_str(),
+ static_cast<const char*>("Total"),
+ total);
+ } else {
+ // The Berkeley format does not display individual section sizes. It
+ // displays the cumulative size for each section type.
+ uint64_t total_text = 0;
+ uint64_t total_data = 0;
+ uint64_t total_bss = 0;
+
+ // Make one pass over the section table to calculate sizes.
+ error_code ec;
+ for (section_iterator i = o->begin_sections(),
+ e = o->end_sections(); i != e;
+ i.increment(ec)) {
+ if (error(ec))
+ return;
+
+ uint64_t size = 0;
+ bool isText = false;
+ bool isData = false;
+ bool isBSS = false;
+ if (error(i->getSize(size))) return;
+ if (error(i->isText(isText))) return;
+ if (error(i->isData(isData))) return;
+ if (error(i->isBSS(isBSS))) return;
+ if (isText)
+ total_text += size;
+ else if (isData)
+ total_data += size;
+ else if (isBSS)
+ total_bss += size;
+ }
+
+ total = total_text + total_data + total_bss;
+
+ // Print result.
+ fmt << "%#7" << radix_fmt << " "
+ << "%#7" << radix_fmt << " "
+ << "%#7" << radix_fmt << " ";
+ outs() << format(fmt.str().c_str(),
+ total_text,
+ total_data,
+ total_bss);
+ fmtbuf.clear();
+ fmt << "%7" << (Radix == octal ? "llo" : "llu") << " "
+ << "%7llx ";
+ outs() << format(fmt.str().c_str(),
+ total,
+ total);
+ }
+}
+
+/// @brief Print the section sizes for @p file. If @p file is an archive, print
+/// the section sizes for each archive member.
+static void PrintFileSectionSizes(StringRef file) {
+ // If file is not stdin, check that it exists.
+ if (file != "-") {
+ bool exists;
+ if (sys::fs::exists(file, exists) || !exists) {
+ errs() << ToolName << ": '" << file << "': " << "No such file\n";
+ return;
+ }
+ }
+
+ // Attempt to open the binary.
+ OwningPtr<Binary> binary;
+ if (error_code ec = createBinary(file, binary)) {
+ errs() << ToolName << ": " << file << ": " << ec.message() << ".\n";
+ return;
+ }
+
+ if (Archive *a = dyn_cast<Archive>(binary.get())) {
+ // This is an archive. Iterate over each member and display its sizes.
+ for (object::Archive::child_iterator i = a->begin_children(),
+ e = a->end_children(); i != e; ++i) {
+ OwningPtr<Binary> child;
+ if (error_code ec = i->getAsBinary(child)) {
+ errs() << ToolName << ": " << file << ": " << ec.message() << ".\n";
+ continue;
+ }
+ if (ObjectFile *o = dyn_cast<ObjectFile>(child.get())) {
+ if (OutputFormat == sysv)
+ outs() << o->getFileName() << " (ex " << a->getFileName()
+ << "):\n";
+ PrintObjectSectionSizes(o);
+ if (OutputFormat == berkeley)
+ outs() << o->getFileName() << " (ex " << a->getFileName() << ")\n";
+ }
+ }
+ } else if (ObjectFile *o = dyn_cast<ObjectFile>(binary.get())) {
+ if (OutputFormat == sysv)
+ outs() << o->getFileName() << " :\n";
+ PrintObjectSectionSizes(o);
+ if (OutputFormat == berkeley)
+ outs() << o->getFileName() << "\n";
+ } else {
+ errs() << ToolName << ": " << file << ": " << "Unrecognized file type.\n";
+ }
+ // System V adds an extra newline at the end of each file.
+ if (OutputFormat == sysv)
+ outs() << "\n";
+}
+
+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 object size dumper\n");
+
+ ToolName = argv[0];
+ if (OutputFormatShort.getNumOccurrences())
+ OutputFormat = OutputFormatShort;
+ if (RadixShort.getNumOccurrences())
+ Radix = RadixShort;
+
+ if (InputFilenames.size() == 0)
+ InputFilenames.push_back("a.out");
+
+ if (OutputFormat == berkeley)
+ outs() << " text data bss "
+ << (Radix == octal ? "oct" : "dec")
+ << " hex filename\n";
+
+ std::for_each(InputFilenames.begin(), InputFilenames.end(),
+ PrintFileSectionSizes);
+
+ return 0;
+}
diff --git a/tools/llvmc/CMakeLists.txt b/tools/llvmc/CMakeLists.txt
deleted file mode 100644
index 10ad5d8..0000000
--- a/tools/llvmc/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-# add_subdirectory(src)
-
-# TODO: support plugins and user-configured builds.
-# See ./doc/LLVMC-Reference.rst "Customizing LLVMC: the compilation graph"
diff --git a/tools/llvmc/Makefile b/tools/llvmc/Makefile
deleted file mode 100644
index 7c03e2a..0000000
--- a/tools/llvmc/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-##===- tools/llvmc/Makefile --------------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open
-# Source License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../..
-
-DIRS = src
-
-ifeq ($(BUILD_EXAMPLES),1)
- OPTIONAL_DIRS += examples
-endif
-
-include $(LEVEL)/Makefile.common
diff --git a/tools/llvmc/doc/LLVMC-Reference.rst b/tools/llvmc/doc/LLVMC-Reference.rst
deleted file mode 100644
index 041aedf..0000000
--- a/tools/llvmc/doc/LLVMC-Reference.rst
+++ /dev/null
@@ -1,747 +0,0 @@
-===================================
-Customizing LLVMC: Reference Manual
-===================================
-..
- This file was automatically generated by rst2html.
- Please do not edit directly!
- The ReST source lives in the directory 'tools/llvmc/doc'.
-
-.. contents::
-
-.. raw:: html
-
- <div class="doc_author">
- <p>Written by <a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a></p>
- </div>
-
-Introduction
-============
-
-LLVMC is a generic compiler driver, designed to be customizable and
-extensible. It plays the same role for LLVM as the ``gcc`` program does for
-GCC - LLVMC's job is essentially to transform a set of input files into a set of
-targets depending on configuration rules and user options. What makes LLVMC
-different is that these transformation rules are completely customizable - in
-fact, LLVMC knows nothing about the specifics of transformation (even the
-command-line options are mostly not hard-coded) and regards the transformation
-structure as an abstract graph. The structure of this graph is described in
-high-level TableGen code, from which an efficient C++ representation is
-automatically derived. This makes it possible to adapt LLVMC for other
-purposes - for example, as a build tool for game resources.
-
-Because LLVMC employs TableGen_ as its configuration language, you
-need to be familiar with it to customize LLVMC.
-
-.. _TableGen: http://llvm.org/docs/TableGenFundamentals.html
-
-
-Compiling with ``llvmc``
-========================
-
-LLVMC tries hard to be as compatible with ``gcc`` as possible,
-although there are some small differences. Most of the time, however,
-you shouldn't be able to notice them::
-
- $ # This works as expected:
- $ llvmc -O3 -Wall hello.cpp
- $ ./a.out
- hello
-
-One nice feature of LLVMC is that one doesn't have to distinguish between
-different compilers for different languages (think ``g++`` vs. ``gcc``) - the
-right toolchain is chosen automatically based on input language names (which
-are, in turn, determined from file extensions). If you want to force files
-ending with ".c" to compile as C++, use the ``-x`` option, just like you would
-do it with ``gcc``::
-
- $ # hello.c is really a C++ file
- $ llvmc -x c++ hello.c
- $ ./a.out
- hello
-
-On the other hand, when using LLVMC as a linker to combine several C++
-object files you should provide the ``--linker`` option since it's
-impossible for LLVMC to choose the right linker in that case::
-
- $ llvmc -c hello.cpp
- $ llvmc hello.o
- [A lot of link-time errors skipped]
- $ llvmc --linker=c++ hello.o
- $ ./a.out
- hello
-
-By default, LLVMC uses ``llvm-gcc`` to compile the source code. It is also
-possible to choose the ``clang`` compiler with the ``-clang`` option.
-
-
-Predefined options
-==================
-
-LLVMC has some built-in options that can't be overridden in the TableGen code:
-
-* ``-o FILE`` - Output file name.
-
-* ``-x LANGUAGE`` - Specify the language of the following input files
- until the next -x option.
-
-* ``-v`` - Enable verbose mode, i.e. print out all executed commands.
-
-* ``--save-temps`` - Write temporary files to the current directory and do not
- delete them on exit. This option can also take an argument: the
- ``--save-temps=obj`` switch will write files into the directory specified with
- the ``-o`` option. The ``--save-temps=cwd`` and ``--save-temps`` switches are
- both synonyms for the default behaviour.
-
-* ``--temp-dir DIRECTORY`` - Store temporary files in the given directory. This
- directory is deleted on exit unless ``--save-temps`` is specified. If
- ``--save-temps=obj`` is also specified, ``--temp-dir`` is given the
- precedence.
-
-* ``--check-graph`` - Check the compilation for common errors like mismatched
- output/input language names, multiple default edges and cycles. Exit with code
- zero if no errors were found, and return the number of found errors
- otherwise. Hidden option, useful for debugging.
-
-* ``--view-graph`` - Show a graphical representation of the compilation graph
- and exit. Requires that you have ``dot`` and ``gv`` programs installed. Hidden
- option, useful for debugging.
-
-* ``--write-graph`` - Write a ``compilation-graph.dot`` file in the current
- directory with the compilation graph description in Graphviz format (identical
- to the file used by the ``--view-graph`` option). The ``-o`` option can be
- used to set the output file name. Hidden option, useful for debugging.
-
-* ``--help``, ``--help-hidden``, ``--version`` - These options have
- their standard meaning.
-
-Compiling LLVMC-based drivers
-=============================
-
-It's easiest to start working on your own LLVMC driver by copying the skeleton
-project which lives under ``$LLVMC_DIR/examples/Skeleton``::
-
- $ cd $LLVMC_DIR/examples
- $ cp -r Skeleton MyDriver
- $ cd MyDriver
- $ ls
- AutoGenerated.td Hooks.cpp Main.cpp Makefile
-
-As you can see, our basic driver consists of only three files (not counting the
-build script). ``AutoGenerated.td`` contains TableGen description of the
-compilation graph; its format is documented in the following
-sections. ``Hooks.cpp`` is an empty file that should be used for hook
-definitions (see `below`__). ``Main.cpp`` is just a helper used to compile the
-auto-generated C++ code produced from TableGen source.
-
-__ hooks_
-
-The first thing that you should do is to change the ``LLVMC_BASED_DRIVER``
-variable in the ``Makefile``::
-
- LLVMC_BASED_DRIVER=MyDriver
-
-It can also be a good idea to put your TableGen code into a file with a less
-generic name::
-
- $ touch MyDriver.td
- $ vim AutoGenerated.td
- [...]
- include "MyDriver.td"
-
-If you have more than one TableGen source file, they all should be included from
-``AutoGenerated.td``, since this file is used by the build system to generate
-C++ code.
-
-To build your driver, just ``cd`` to its source directory and run ``make``. The
-resulting executable will be put into ``$LLVM_OBJ_DIR/$(BuildMode)/bin``.
-
-If you're compiling LLVM with different source and object directories, then you
-must perform the following additional steps before running ``make``::
-
- # LLVMC_SRC_DIR = $LLVM_SRC_DIR/tools/llvmc/
- # LLVMC_OBJ_DIR = $LLVM_OBJ_DIR/tools/llvmc/
- $ mkdir $LLVMC_OBJ_DIR/examples/MyDriver/
- $ cp $LLVMC_SRC_DIR/examples/MyDriver/Makefile \
- $LLVMC_OBJ_DIR/examples/MyDriver/
- $ cd $LLVMC_OBJ_DIR/examples/MyDriver
- $ make
-
-
-Customizing LLVMC: the compilation graph
-========================================
-
-Each TableGen configuration file should include the common definitions::
-
- include "llvm/CompilerDriver/Common.td"
-
-Internally, LLVMC stores information about possible source transformations in
-form of a graph. Nodes in this graph represent tools, and edges between two
-nodes represent a transformation path. A special "root" node is used to mark
-entry points for the transformations. LLVMC also assigns a weight to each edge
-(more on this later) to choose between several alternative edges.
-
-The definition of the compilation graph (see file ``llvmc/src/Base.td`` for an
-example) is just a list of edges::
-
- def CompilationGraph : CompilationGraph<[
- Edge<"root", "llvm_gcc_c">,
- Edge<"root", "llvm_gcc_assembler">,
- ...
-
- Edge<"llvm_gcc_c", "llc">,
- Edge<"llvm_gcc_cpp", "llc">,
- ...
-
- OptionalEdge<"llvm_gcc_c", "opt", (case (switch_on "opt"),
- (inc_weight))>,
- OptionalEdge<"llvm_gcc_cpp", "opt", (case (switch_on "opt"),
- (inc_weight))>,
- ...
-
- OptionalEdge<"llvm_gcc_assembler", "llvm_gcc_cpp_linker",
- (case (input_languages_contain "c++"), (inc_weight),
- (or (parameter_equals "linker", "g++"),
- (parameter_equals "linker", "c++")), (inc_weight))>,
- ...
-
- ]>;
-
-As you can see, the edges can be either default or optional, where optional
-edges are differentiated by an additional ``case`` expression used to calculate
-the weight of this edge. Notice also that we refer to tools via their names (as
-strings). This makes it possible to add edges to an existing compilation graph
-without having to know about all tool definitions used in the graph.
-
-The default edges are assigned a weight of 1, and optional edges get a weight of
-0 + 2*N where N is the number of tests that evaluated to true in the ``case``
-expression. It is also possible to provide an integer parameter to
-``inc_weight`` and ``dec_weight`` - in this case, the weight is increased (or
-decreased) by the provided value instead of the default 2. Default weight of an
-optional edge can be changed by using the ``default`` clause of the ``case``
-construct.
-
-When passing an input file through the graph, LLVMC picks the edge with the
-maximum weight. To avoid ambiguity, there should be only one default edge
-between two nodes (with the exception of the root node, which gets a special
-treatment - there you are allowed to specify one default edge *per language*).
-
-When multiple compilation graphs are defined, they are merged together. Multiple
-edges with the same end nodes are not allowed (i.e. the graph is not a
-multigraph), and will lead to a compile-time error.
-
-To get a visual representation of the compilation graph (useful for debugging),
-run ``llvmc --view-graph``. You will need ``dot`` and ``gsview`` installed for
-this to work properly.
-
-Describing options
-==================
-
-Command-line options supported by the driver are defined by using an
-``OptionList``::
-
- def Options : OptionList<[
- (switch_option "E", (help "Help string")),
- (alias_option "quiet", "q")
- ...
- ]>;
-
-As you can see, the option list is just a list of DAGs, where each DAG is an
-option description consisting of the option name and some properties. More than
-one option list can be defined (they are all merged together in the end), which
-can be handy if one wants to separate option groups syntactically.
-
-* Possible option types:
-
- - ``switch_option`` - a simple boolean switch without arguments, for example
- ``-O2`` or ``-time``. At most one occurrence is allowed by default.
-
- - ``parameter_option`` - option that takes one argument, for example
- ``-std=c99``. It is also allowed to use spaces instead of the equality
- sign: ``-std c99``. At most one occurrence is allowed.
-
- - ``parameter_list_option`` - same as the above, but more than one option
- occurrence is allowed.
-
- - ``prefix_option`` - same as the parameter_option, but the option name and
- argument do not have to be separated. Example: ``-ofile``. This can be also
- specified as ``-o file``; however, ``-o=file`` will be parsed incorrectly
- (``=file`` will be interpreted as option value). At most one occurrence is
- allowed.
-
- - ``prefix_list_option`` - same as the above, but more than one occurrence of
- the option is allowed; example: ``-lm -lpthread``.
-
- - ``alias_option`` - a special option type for creating aliases. Unlike other
- option types, aliases are not allowed to have any properties besides the
- aliased option name.
- Usage example: ``(alias_option "preprocess", "E")``
-
- - ``switch_list_option`` - like ``switch_option`` with the ``zero_or_more``
- property, but remembers how many times the switch was turned on. Useful
- mostly for forwarding. Example: when ``-foo`` is a switch option (with the
- ``zero_or_more`` property), the command ``driver -foo -foo`` is forwarded
- as ``some-tool -foo``, but when ``-foo`` is a switch list, the same command
- is forwarded as ``some-tool -foo -foo``.
-
-
-* Possible option properties:
-
- - ``help`` - help string associated with this option. Used for ``--help``
- output.
-
- - ``required`` - this option must be specified exactly once (or, in case of
- the list options without the ``multi_val`` property, at least
- once). Incompatible with ``optional`` and ``one_or_more``.
-
- - ``optional`` - the option can be specified either zero times or exactly
- once. The default for switch options. Useful only for list options in
- conjunction with ``multi_val``. Incompatible with ``required``,
- ``zero_or_more`` and ``one_or_more``.
-
- - ``one_or_more`` - the option must be specified at least once. Can be useful
- to allow switch options be both obligatory and be specified multiple
- times. For list options is useful only in conjunction with ``multi_val``;
- for ordinary it is synonymous with ``required``. Incompatible with
- ``required``, ``optional`` and ``zero_or_more``.
-
- - ``zero_or_more`` - the option can be specified zero or more times. Useful
- to allow a single switch option to be specified more than
- once. Incompatible with ``required``, ``optional`` and ``one_or_more``.
-
- - ``hidden`` - the description of this option will not appear in
- the ``--help`` output (but will appear in the ``--help-hidden``
- output).
-
- - ``really_hidden`` - the option will not be mentioned in any help
- output.
-
- - ``comma_separated`` - Indicates that any commas specified for an option's
- value should be used to split the value up into multiple values for the
- option. This property is valid only for list options. In conjunction with
- ``forward_value`` can be used to implement option forwarding in style of
- gcc's ``-Wa,``.
-
- - ``multi_val n`` - this option takes *n* arguments (can be useful in some
- special cases). Usage example: ``(parameter_list_option "foo", (multi_val
- 3))``; the command-line syntax is '-foo a b c'. Only list options can have
- this attribute; you can, however, use the ``one_or_more``, ``optional``
- and ``required`` properties.
-
- - ``init`` - this option has a default value, either a string (if it is a
- parameter), or a boolean (if it is a switch; as in C++, boolean constants
- are called ``true`` and ``false``). List options can't have ``init``
- attribute.
- Usage examples: ``(switch_option "foo", (init true))``; ``(prefix_option
- "bar", (init "baz"))``.
-
-.. _case:
-
-Conditional evaluation
-======================
-
-The 'case' construct is the main means by which programmability is achieved in
-LLVMC. It can be used to calculate edge weights, program actions and modify the
-shell commands to be executed. The 'case' expression is designed after the
-similarly-named construct in functional languages and takes the form ``(case
-(test_1), statement_1, (test_2), statement_2, ... (test_N), statement_N)``. The
-statements are evaluated only if the corresponding tests evaluate to true.
-
-Examples::
-
- // Edge weight calculation
-
- // Increases edge weight by 5 if "-A" is provided on the
- // command-line, and by 5 more if "-B" is also provided.
- (case
- (switch_on "A"), (inc_weight 5),
- (switch_on "B"), (inc_weight 5))
-
-
- // Tool command line specification
-
- // Evaluates to "cmdline1" if the option "-A" is provided on the
- // command line; to "cmdline2" if "-B" is provided;
- // otherwise to "cmdline3".
-
- (case
- (switch_on "A"), "cmdline1",
- (switch_on "B"), "cmdline2",
- (default), "cmdline3")
-
-Note the slight difference in 'case' expression handling in contexts of edge
-weights and command line specification - in the second example the value of the
-``"B"`` switch is never checked when switch ``"A"`` is enabled, and the whole
-expression always evaluates to ``"cmdline1"`` in that case.
-
-Case expressions can also be nested, i.e. the following is legal::
-
- (case (switch_on "E"), (case (switch_on "o"), ..., (default), ...)
- (default), ...)
-
-You should, however, try to avoid doing that because it hurts readability. It is
-usually better to split tool descriptions and/or use TableGen inheritance
-instead.
-
-* Possible tests are:
-
- - ``switch_on`` - Returns true if a given command-line switch is provided by
- the user. Can be given multiple arguments, in that case ``(switch_on "foo",
- "bar", "baz")`` is equivalent to ``(and (switch_on "foo"), (switch_on
- "bar"), (switch_on "baz"))``.
- Example: ``(switch_on "opt")``.
-
- - ``any_switch_on`` - Given a number of switch options, returns true if any of
- the switches is turned on.
- Example: ``(any_switch_on "foo", "bar", "baz")`` is equivalent to ``(or
- (switch_on "foo"), (switch_on "bar"), (switch_on "baz"))``.
-
- - ``parameter_equals`` - Returns true if a command-line parameter (first
- argument) equals a given value (second argument).
- Example: ``(parameter_equals "W", "all")``.
-
- - ``element_in_list`` - Returns true if a command-line parameter list (first
- argument) contains a given value (second argument).
- Example: ``(element_in_list "l", "pthread")``.
-
- - ``input_languages_contain`` - Returns true if a given language
- belongs to the current input language set.
- Example: ``(input_languages_contain "c++")``.
-
- - ``in_language`` - Evaluates to true if the input file language is equal to
- the argument. At the moment works only with ``command`` and ``actions`` (on
- non-join nodes).
- Example: ``(in_language "c++")``.
-
- - ``not_empty`` - Returns true if a given option (which should be either a
- parameter or a parameter list) is set by the user. Like ``switch_on``, can
- be also given multiple arguments.
- Examples: ``(not_empty "o")``, ``(not_empty "o", "l")``.
-
- - ``any_not_empty`` - Returns true if ``not_empty`` returns true for any of
- the provided options.
- Example: ``(any_not_empty "foo", "bar", "baz")`` is equivalent to ``(or
- (not_empty "foo"), (not_empty "bar"), (not_empty "baz"))``.
-
- - ``empty`` - The opposite of ``not_empty``. Equivalent to ``(not (not_empty
- X))``. Can be given multiple arguments.
-
- - ``any_not_empty`` - Returns true if ``not_empty`` returns true for any of
- the provided options.
- Example: ``(any_empty "foo", "bar", "baz")`` is equivalent to ``(or
- (not_empty "foo"), (not_empty "bar"), (not_empty "baz"))``.
-
- - ``single_input_file`` - Returns true if there was only one input file
- provided on the command-line. Used without arguments:
- ``(single_input_file)``.
-
- - ``multiple_input_files`` - Equivalent to ``(not (single_input_file))`` (the
- case of zero input files is considered an error).
-
- - ``default`` - Always evaluates to true. Should always be the last
- test in the ``case`` expression.
-
- - ``and`` - A standard logical combinator that returns true iff all of
- its arguments return true. Used like this: ``(and (test1), (test2),
- ... (testN))``. Nesting of ``and`` and ``or`` is allowed, but not
- encouraged.
-
- - ``or`` - A logical combinator that returns true iff any of its arguments
- return true.
- Example: ``(or (test1), (test2), ... (testN))``.
-
- - ``not`` - Standard unary logical combinator that negates its
- argument.
- Example: ``(not (or (test1), (test2), ... (testN)))``.
-
-
-Writing a tool description
-==========================
-
-As was said earlier, nodes in the compilation graph represent tools, which are
-described separately. A tool definition looks like this (taken from the
-``llvmc/src/Base.td`` file)::
-
- def llvm_gcc_cpp : Tool<[
- (in_language "c++"),
- (out_language "llvm-assembler"),
- (output_suffix "bc"),
- (command "llvm-g++ -c -emit-llvm"),
- (sink)
- ]>;
-
-This defines a new tool called ``llvm_gcc_cpp``, which is an alias for
-``llvm-g++``. As you can see, a tool definition is just a list of properties;
-most of them should be self-explanatory. The ``sink`` property means that this
-tool should be passed all command-line options that aren't mentioned in the
-option list.
-
-The complete list of all currently implemented tool properties follows.
-
-* Possible tool properties:
-
- - ``in_language`` - input language name. Can be given multiple arguments, in
- case the tool supports multiple input languages. Used for typechecking and
- mapping file extensions to tools.
-
- - ``out_language`` - output language name. Multiple output languages are
- allowed. Used for typechecking the compilation graph.
-
- - ``output_suffix`` - output file suffix. Can also be changed dynamically, see
- documentation on `actions`__.
-
-__ actions_
-
- - ``command`` - the actual command used to run the tool. You can use output
- redirection with ``>``, hook invocations (``$CALL``), environment variables
- (via ``$ENV``) and the ``case`` construct.
-
- - ``join`` - this tool is a "join node" in the graph, i.e. it gets a list of
- input files and joins them together. Used for linkers.
-
- - ``sink`` - all command-line options that are not handled by other tools are
- passed to this tool.
-
- - ``actions`` - A single big ``case`` expression that specifies how this tool
- reacts on command-line options (described in more detail `below`__).
-
-__ actions_
-
- - ``out_file_option``, ``in_file_option`` - Options appended to the
- ``command`` string to designate output and input files. Default values are
- ``"-o"`` and ``""``, respectively.
-
-.. _actions:
-
-Actions
--------
-
-A tool often needs to react to command-line options, and this is precisely what
-the ``actions`` property is for. The next example illustrates this feature::
-
- def llvm_gcc_linker : Tool<[
- (in_language "object-code"),
- (out_language "executable"),
- (output_suffix "out"),
- (command "llvm-gcc"),
- (join),
- (actions (case (not_empty "L"), (forward "L"),
- (not_empty "l"), (forward "l"),
- (not_empty "dummy"),
- [(append_cmd "-dummy1"), (append_cmd "-dummy2")])
- ]>;
-
-The ``actions`` tool property is implemented on top of the omnipresent ``case``
-expression. It associates one or more different *actions* with given
-conditions - in the example, the actions are ``forward``, which forwards a given
-option unchanged, and ``append_cmd``, which appends a given string to the tool
-execution command. Multiple actions can be associated with a single condition by
-using a list of actions (used in the example to append some dummy options). The
-same ``case`` construct can also be used in the ``cmd_line`` property to modify
-the tool command line.
-
-The "join" property used in the example means that this tool behaves like a
-linker.
-
-The list of all possible actions follows.
-
-* Possible actions:
-
- - ``append_cmd`` - Append a string to the tool invocation command.
- Example: ``(case (switch_on "pthread"), (append_cmd "-lpthread"))``.
-
- - ``error`` - Exit with error.
- Example: ``(error "Mixing -c and -S is not allowed!")``.
-
- - ``warning`` - Print a warning.
- Example: ``(warning "Specifying both -O1 and -O2 is meaningless!")``.
-
- - ``forward`` - Forward the option unchanged.
- Example: ``(forward "Wall")``.
-
- - ``forward_as`` - Change the option's name, but forward the argument
- unchanged.
- Example: ``(forward_as "O0", "--disable-optimization")``.
-
- - ``forward_value`` - Forward only option's value. Cannot be used with switch
- options (since they don't have values), but works fine with lists.
- Example: ``(forward_value "Wa,")``.
-
- - ``forward_transformed_value`` - As above, but applies a hook to the
- option's value before forwarding (see `below`__). When
- ``forward_transformed_value`` is applied to a list
- option, the hook must have signature
- ``std::string hooks::HookName (const std::vector<std::string>&)``.
- Example: ``(forward_transformed_value "m", "ConvertToMAttr")``.
-
- __ hooks_
-
- - ``output_suffix`` - Modify the output suffix of this tool.
- Example: ``(output_suffix "i")``.
-
- - ``stop_compilation`` - Stop compilation after this tool processes its
- input. Used without arguments.
- Example: ``(stop_compilation)``.
-
-
-Language map
-============
-
-If you are adding support for a new language to LLVMC, you'll need to modify the
-language map, which defines mappings from file extensions to language names. It
-is used to choose the proper toolchain(s) for a given input file set. Language
-map definition looks like this::
-
- def LanguageMap : LanguageMap<
- [LangToSuffixes<"c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]>,
- LangToSuffixes<"c", ["c"]>,
- ...
- ]>;
-
-For example, without those definitions the following command wouldn't work::
-
- $ llvmc hello.cpp
- llvmc: Unknown suffix: cpp
-
-The language map entries are needed only for the tools that are linked from the
-root node. A tool can have multiple output languages.
-
-Option preprocessor
-===================
-
-It is sometimes useful to run error-checking code before processing the
-compilation graph. For example, if optimization options "-O1" and "-O2" are
-implemented as switches, we might want to output a warning if the user invokes
-the driver with both of these options enabled.
-
-The ``OptionPreprocessor`` feature is reserved specially for these
-occasions. Example (adapted from ``llvm/src/Base.td.in``)::
-
-
- def Preprocess : OptionPreprocessor<
- (case (not (any_switch_on "O0", "O1", "O2", "O3")),
- (set_option "O2"),
- (and (switch_on "O3"), (any_switch_on "O0", "O1", "O2")),
- (unset_option "O0", "O1", "O2"),
- (and (switch_on "O2"), (any_switch_on "O0", "O1")),
- (unset_option "O0", "O1"),
- (and (switch_on "O1"), (switch_on "O0")),
- (unset_option "O0"))
- >;
-
-Here, ``OptionPreprocessor`` is used to unset all spurious ``-O`` options so
-that they are not forwarded to the compiler. If no optimization options are
-specified, ``-O2`` is enabled.
-
-``OptionPreprocessor`` is basically a single big ``case`` expression, which is
-evaluated only once right after the driver is started. The only allowed actions
-in ``OptionPreprocessor`` are ``error``, ``warning``, and two special actions:
-``unset_option`` and ``set_option``. As their names suggest, they can be used to
-set or unset a given option. To set an option with ``set_option``, use the
-two-argument form: ``(set_option "parameter", VALUE)``. Here, ``VALUE`` can be
-either a string, a string list, or a boolean constant.
-
-For convenience, ``set_option`` and ``unset_option`` also work with multiple
-arguments. That is, instead of ``[(unset_option "A"), (unset_option "B")]`` you
-can use ``(unset_option "A", "B")``. Obviously, ``(set_option "A", "B")`` is
-only valid if both ``A`` and ``B`` are switches.
-
-
-More advanced topics
-====================
-
-.. _hooks:
-
-Hooks and environment variables
--------------------------------
-
-Normally, LLVMC searches for programs in the system ``PATH``. Sometimes, this is
-not sufficient: for example, we may want to specify tool paths or names in the
-configuration file. This can be achieved via the hooks mechanism. To write your
-own hooks, add their definitions to the ``Hooks.cpp`` or drop a ``.cpp`` file
-into your driver directory. Hooks should live in the ``hooks`` namespace and
-have the signature ``std::string hooks::MyHookName ([const char* Arg0 [ const
-char* Arg2 [, ...]]])``. They can be used from the ``command`` tool property::
-
- (command "$CALL(MyHook)/path/to/file -o $CALL(AnotherHook)")
-
-To pass arguments to hooks, use the following syntax::
-
- (command "$CALL(MyHook, 'Arg1', 'Arg2', 'Arg # 3')/path/to/file -o1 -o2")
-
-It is also possible to use environment variables in the same manner::
-
- (command "$ENV(VAR1)/path/to/file -o $ENV(VAR2)")
-
-To change the command line string based on user-provided options use
-the ``case`` expression (documented `above`__)::
-
- (command
- (case
- (switch_on "E"),
- "llvm-g++ -E -x c $INFILE -o $OUTFILE",
- (default),
- "llvm-g++ -c -x c $INFILE -o $OUTFILE -emit-llvm"))
-
-__ case_
-
-Debugging
----------
-
-When writing LLVMC-based drivers, it can be useful to get a visual view of the
-resulting compilation graph. This can be achieved via the command line option
-``--view-graph`` (which assumes that Graphviz_ and Ghostview_ are
-installed). There is also a ``--write-graph`` option that creates a Graphviz
-source file (``compilation-graph.dot``) in the current directory.
-
-Another useful ``llvmc`` option is ``--check-graph``. It checks the compilation
-graph for common errors like mismatched output/input language names, multiple
-default edges and cycles. When invoked with ``--check-graph``, ``llvmc`` doesn't
-perform any compilation tasks and returns the number of encountered errors as
-its status code. In the future, these checks will be performed at compile-time
-and this option will disappear.
-
-.. _Graphviz: http://www.graphviz.org/
-.. _Ghostview: http://pages.cs.wisc.edu/~ghost/
-
-Conditioning on the executable name
------------------------------------
-
-For now, the executable name (the value passed to the driver in ``argv[0]``) is
-accessible only in the C++ code (i.e. hooks). Use the following code::
-
- namespace llvmc {
- extern const char* ProgramName;
- }
-
- namespace hooks {
-
- std::string MyHook() {
- //...
- if (strcmp(ProgramName, "mydriver") == 0) {
- //...
-
- }
-
- } // end namespace hooks
-
-In general, you're encouraged not to make the behaviour dependent on the
-executable file name, and use command-line switches instead. See for example how
-the ``llvmc`` program behaves when it needs to choose the correct linker options
-(think ``g++`` vs. ``gcc``).
-
-.. raw:: html
-
- <hr />
- <address>
- <a href="http://jigsaw.w3.org/css-validator/check/referer">
- <img src="http://jigsaw.w3.org/css-validator/images/vcss-blue"
- alt="Valid CSS" /></a>
- <a href="http://validator.w3.org/check?uri=referer">
- <img src="http://www.w3.org/Icons/valid-xhtml10-blue"
- alt="Valid XHTML 1.0 Transitional"/></a>
-
- <a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a><br />
- <a href="http://llvm.org">LLVM Compiler Infrastructure</a><br />
-
- Last modified: $Date: 2008-12-11 11:34:48 -0600 (Thu, 11 Dec 2008) $
- </address>
diff --git a/tools/llvmc/doc/LLVMC-Tutorial.rst b/tools/llvmc/doc/LLVMC-Tutorial.rst
deleted file mode 100644
index fc4c124..0000000
--- a/tools/llvmc/doc/LLVMC-Tutorial.rst
+++ /dev/null
@@ -1,127 +0,0 @@
-======================
-Tutorial - Using LLVMC
-======================
-..
- This file was automatically generated by rst2html.
- Please do not edit directly!
- The ReST source lives in the directory 'tools/llvmc/doc'.
-
-.. contents::
-
-.. raw:: html
-
- <div class="doc_author">
- <p>Written by <a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a></p>
- </div>
-
-Introduction
-============
-
-LLVMC is a generic compiler driver, which plays the same role for LLVM as the
-``gcc`` program does for GCC - the difference being that LLVMC is designed to be
-more adaptable and easier to customize. Most of LLVMC functionality is
-implemented via high-level TableGen code, from which a corresponding C++ source
-file is automatically generated. This tutorial describes the basic usage and
-configuration of LLVMC.
-
-
-Using the ``llvmc`` program
-===========================
-
-In general, ``llvmc`` tries to be command-line compatible with ``gcc`` as much
-as possible, so most of the familiar options work::
-
- $ llvmc -O3 -Wall hello.cpp
- $ ./a.out
- hello
-
-This will invoke ``llvm-g++`` under the hood (you can see which commands are
-executed by using the ``-v`` option). For further help on command-line LLVMC
-usage, refer to the ``llvmc --help`` output.
-
-
-Using LLVMC to generate toolchain drivers
-=========================================
-
-LLVMC-based drivers are written mostly using TableGen_, so you need to be
-familiar with it to get anything done.
-
-.. _TableGen: http://llvm.org/docs/TableGenFundamentals.html
-
-Start by compiling ``example/Simple``, which is a primitive wrapper for
-``gcc``::
-
- $ cd $LLVM_OBJ_DIR/tools/examples/Simple
- $ make
- $ cat > hello.c
- #include <stdio.h>
- int main() { printf("Hello\n"); }
- $ $LLVM_BIN_DIR/Simple -v hello.c
- gcc hello.c -o hello.out
- $ ./hello.out
- Hello
-
-We have thus produced a simple driver called, appropriately, ``Simple``, from
-the input TableGen file ``Simple.td``. The ``llvmc`` program itself is generated
-using a similar process (see ``llvmc/src``). Contents of the file ``Simple.td``
-look like this::
-
- // Include common definitions
- include "llvm/CompilerDriver/Common.td"
-
- // Tool descriptions
- def gcc : Tool<
- [(in_language "c"),
- (out_language "executable"),
- (output_suffix "out"),
- (command "gcc"),
- (sink),
-
- // -o is what is used by default, out_file_option here is included for
- // instructive purposes.
- (out_file_option "-o")
- ]>;
-
- // Language map
- def LanguageMap : LanguageMap<[(lang_to_suffixes "c", "c")]>;
-
- // Compilation graph
- def CompilationGraph : CompilationGraph<[(edge "root", "gcc")]>;
-
-As you can see, this file consists of three parts: tool descriptions, language
-map, and the compilation graph definition.
-
-At the heart of LLVMC is the idea of a compilation graph: vertices in this graph
-are tools, and edges represent a transformation path between two tools (for
-example, assembly source produced by the compiler can be transformed into
-executable code by an assembler). The compilation graph is basically a list of
-edges; a special node named ``root`` is used to mark graph entry points.
-
-Tool descriptions are represented as property lists: most properties in the
-example above should be self-explanatory; the ``sink`` property means that all
-options lacking an explicit description should be forwarded to this tool.
-
-The ``LanguageMap`` associates a language name with a list of suffixes and is
-used for deciding which toolchain corresponds to a given input file.
-
-To learn more about writing your own drivers with LLVMC, refer to the reference
-manual and examples in the ``examples`` directory. Of a particular interest is
-the ``Skeleton`` example, which can serve as a template for your LLVMC-based
-drivers.
-
-.. raw:: html
-
- <hr />
- <address>
- <a href="http://jigsaw.w3.org/css-validator/check/referer">
- <img src="http://jigsaw.w3.org/css-validator/images/vcss-blue"
- alt="Valid CSS" /></a>
- <a href="http://validator.w3.org/check?uri=referer">
- <img src="http://www.w3.org/Icons/valid-xhtml10-blue"
- alt="Valid XHTML 1.0 Transitional"/></a>
-
- <a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a><br />
- <a href="http://llvm.org">LLVM Compiler Infrastructure</a><br />
-
- Last modified: $Date: 2008-12-11 11:34:48 -0600 (Thu, 11 Dec 2008) $
- </address>
diff --git a/tools/llvmc/doc/Makefile b/tools/llvmc/doc/Makefile
deleted file mode 100644
index ef98767..0000000
--- a/tools/llvmc/doc/Makefile
+++ /dev/null
@@ -1,33 +0,0 @@
-##===- tools/llvmc/doc/Makefile ----------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL=../../..
-
-ifneq (,$(strip $(wildcard $(LEVEL)/Makefile.config)))
-include $(LEVEL)/Makefile.config
-else
-CP=cp
-RM=rm
-endif
-
-DOC_DIR=../../../docs
-RST2HTML=rst2html --stylesheet=llvm.css --link-stylesheet
-
-all : LLVMC-Reference.html LLVMC-Tutorial.html
- $(CP) LLVMC-Reference.html $(DOC_DIR)/CompilerDriver.html
- $(CP) LLVMC-Tutorial.html $(DOC_DIR)/CompilerDriverTutorial.html
-
-LLVMC-Tutorial.html : LLVMC-Tutorial.rst
- $(RST2HTML) $< $@
-
-LLVMC-Reference.html : LLVMC-Reference.rst
- $(RST2HTML) $< $@
-
-clean :
- $(RM) LLVMC-Tutorial.html LLVMC-Reference.html
diff --git a/tools/llvmc/doc/img/lines.gif b/tools/llvmc/doc/img/lines.gif
deleted file mode 100644
index 88f491e..0000000
--- a/tools/llvmc/doc/img/lines.gif
+++ /dev/null
Binary files differ
diff --git a/tools/llvmc/examples/Hello/Hello.cpp b/tools/llvmc/examples/Hello/Hello.cpp
deleted file mode 100644
index 71f04fd..0000000
--- a/tools/llvmc/examples/Hello/Hello.cpp
+++ /dev/null
@@ -1,29 +0,0 @@
-//===- Hello.cpp - Example code from "Writing an LLVMC Plugin" ------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Shows how to write llvmc-based drivers without using TableGen.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CompilerDriver/AutoGenerated.h"
-#include "llvm/CompilerDriver/Main.inc"
-
-#include "llvm/Support/raw_ostream.h"
-
-namespace llvmc {
-namespace autogenerated {
-
-int PreprocessOptions () { return 0; }
-
-int PopulateLanguageMap (LanguageMap&) { llvm::outs() << "Hello!\n"; return 0; }
-
-int PopulateCompilationGraph (CompilationGraph&) { return 0; }
-
-}
-}
diff --git a/tools/llvmc/examples/Hello/Makefile b/tools/llvmc/examples/Hello/Makefile
deleted file mode 100644
index c281be6..0000000
--- a/tools/llvmc/examples/Hello/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- tools/llvmc/examples/Hello/Makefile -----------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../../..
-
-LLVMC_BASED_DRIVER = Hello
-
-include $(LEVEL)/Makefile.common
diff --git a/tools/llvmc/examples/Simple/Simple.cpp b/tools/llvmc/examples/Simple/Simple.cpp
deleted file mode 100644
index 8ac7313..0000000
--- a/tools/llvmc/examples/Simple/Simple.cpp
+++ /dev/null
@@ -1,2 +0,0 @@
-#include "llvm/CompilerDriver/Main.inc"
-#include "Simple.inc"
diff --git a/tools/llvmc/examples/Simple/Simple.td b/tools/llvmc/examples/Simple/Simple.td
deleted file mode 100644
index b47483b..0000000
--- a/tools/llvmc/examples/Simple/Simple.td
+++ /dev/null
@@ -1,41 +0,0 @@
-//===- Simple.td - A simple LLVMC-based driver ----------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// A simple LLVMC-based gcc wrapper.
-//
-// To compile, use this command:
-//
-// $ cd $LLVM_OBJ_DIR/tools/llvmc
-// $ make BUILD_EXAMPLES=1
-//
-// Run as:
-//
-// $ $LLVM_OBJ_DIR/$(BuildMode)/bin/Simple
-//
-// For instructions on how to build your own LLVMC-based driver, see
-// the 'examples/Skeleton' directory.
-//===----------------------------------------------------------------------===//
-
-include "llvm/CompilerDriver/Common.td"
-
-def gcc : Tool<
-[(in_language "c"),
- (out_language "executable"),
- (output_suffix "out"),
- (command "gcc"),
- (sink),
-
- // -o is what is used by default, out_file_option here is included for
- // instructive purposes.
- (out_file_option "-o")
-]>;
-
-def LanguageMap : LanguageMap<[(lang_to_suffixes "c", "c")]>;
-
-def CompilationGraph : CompilationGraph<[(edge "root", "gcc")]>;
diff --git a/tools/llvmc/examples/Skeleton/AutoGenerated.td b/tools/llvmc/examples/Skeleton/AutoGenerated.td
deleted file mode 100644
index 97483ce..0000000
--- a/tools/llvmc/examples/Skeleton/AutoGenerated.td
+++ /dev/null
@@ -1,7 +0,0 @@
-//===- AutoGenerated.td ------------------------------------*- tablegen -*-===//
-//
-// Write the TableGen description of your llvmc-based driver here.
-//
-//===----------------------------------------------------------------------===//
-
-include "llvm/CompilerDriver/Common.td"
diff --git a/tools/llvmc/examples/Skeleton/Hooks.cpp b/tools/llvmc/examples/Skeleton/Hooks.cpp
deleted file mode 100644
index ddd38f6..0000000
--- a/tools/llvmc/examples/Skeleton/Hooks.cpp
+++ /dev/null
@@ -1,12 +0,0 @@
-//===--- Hooks.cpp - The LLVM Compiler Driver -------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open
-// Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Hook definitions should go here.
-//
-//===----------------------------------------------------------------------===//
diff --git a/tools/llvmc/examples/Skeleton/Main.cpp b/tools/llvmc/examples/Skeleton/Main.cpp
deleted file mode 100644
index 24c7768..0000000
--- a/tools/llvmc/examples/Skeleton/Main.cpp
+++ /dev/null
@@ -1,15 +0,0 @@
-//===--- Main.cpp - The LLVM Compiler Driver -------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open
-// Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Just include CompilerDriver/Main.inc and AutoGenerated.inc.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CompilerDriver/Main.inc"
-#include "AutoGenerated.inc"
diff --git a/tools/llvmc/examples/Skeleton/Makefile b/tools/llvmc/examples/Skeleton/Makefile
deleted file mode 100644
index 41ca823..0000000
--- a/tools/llvmc/examples/Skeleton/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-##===- llvmc/examples/Skeleton/Makefile --------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open
-# Source License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-# Change this so that $(LEVEL)/Makefile.common refers to
-# $LLVM_OBJ_DIR/Makefile.common or $YOUR_LLVM_BASED_PROJECT/Makefile.common.
-export LEVEL = ../../../..
-
-# Change this to the name of your LLVMC-based driver.
-LLVMC_BASED_DRIVER = llvmc-skeleton
-
-# Change this to the name of .inc file built from your .td file.
-BUILT_SOURCES = AutoGenerated.inc
-
-include $(LEVEL)/Makefile.common
diff --git a/tools/llvmc/examples/Skeleton/README b/tools/llvmc/examples/Skeleton/README
deleted file mode 100644
index 282ee15..0000000
--- a/tools/llvmc/examples/Skeleton/README
+++ /dev/null
@@ -1,6 +0,0 @@
-
-This is a template that can be used to create your own LLVMC-based drivers. Just
-copy the `Skeleton` directory to the location of your preference and edit
-`Skeleton/Makefile` and `Skeleton/AutoGenerated.td`.
-
-The build system assumes that your project is based on LLVM.
diff --git a/tools/llvmc/examples/mcc16/Hooks.cpp b/tools/llvmc/examples/mcc16/Hooks.cpp
deleted file mode 100644
index 95158ef..0000000
--- a/tools/llvmc/examples/mcc16/Hooks.cpp
+++ /dev/null
@@ -1,109 +0,0 @@
-#include "llvm/Support/Path.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/raw_ostream.h"
-
-#include <string>
-
-namespace llvmc {
- extern char *ProgramName;
-
- namespace autogenerated {
- extern llvm::cl::opt<std::string> Parameter_p;
- }
-}
-
-using namespace llvm;
-using namespace llvmc;
-
-// Returns the platform specific directory separator via #ifdefs.
-// FIXME: This currently work on linux and windows only. It does not
-// work on other unices.
-static std::string GetDirSeparator() {
-#if __linux__ || __APPLE__
- return "/";
-#else
- return "\\";
-#endif
-}
-
-namespace hooks {
-// Get preprocessor define for the part.
-// It is __partname format in lower case.
-std::string
-GetLowerCasePartDefine(void) {
- std::string Partname;
- if (autogenerated::Parameter_p.empty()) {
- Partname = "16f1xxx";
- } else {
- Partname = autogenerated::Parameter_p;
- }
-
- std::string LowerCase;
- for (unsigned i = 0; i < Partname.size(); i++) {
- LowerCase.push_back(std::tolower(Partname[i]));
- }
-
- return "__" + LowerCase;
-}
-
-std::string
-GetUpperCasePartDefine(void) {
- std::string Partname;
- if (autogenerated::Parameter_p.empty()) {
- Partname = "16f1xxx";
- } else {
- Partname = autogenerated::Parameter_p;
- }
-
- std::string UpperCase;
- for (unsigned i = 0; i < Partname.size(); i++) {
- UpperCase.push_back(std::toupper(Partname[i]));
- }
-
- return "__" + UpperCase;
-}
-
-// Get the dir where c16 executables reside.
-std::string GetBinDir() {
- // Construct a Path object from the program name.
- void *P = (void*) (intptr_t) GetBinDir;
- sys::Path ProgramFullPath
- = sys::Path::GetMainExecutable(llvmc::ProgramName, P);
-
- // Get the dir name for the program. It's last component should be 'bin'.
- std::string BinDir = ProgramFullPath.getDirname();
-
- // llvm::errs() << "BinDir: " << BinDir << '\n';
- return BinDir + GetDirSeparator();
-}
-
-// Get the Top-level Installation dir for c16.
-std::string GetInstallDir() {
- sys::Path BinDirPath = sys::Path(GetBinDir());
-
- // Go one more level up to get the install dir.
- std::string InstallDir = BinDirPath.getDirname();
-
- return InstallDir + GetDirSeparator();
-}
-
-// Get the dir where the c16 header files reside.
-std::string GetStdHeadersDir() {
- return GetInstallDir() + "include";
-}
-
-// Get the dir where the assembler header files reside.
-std::string GetStdAsmHeadersDir() {
- return GetInstallDir() + "inc";
-}
-
-// Get the dir where the linker scripts reside.
-std::string GetStdLinkerScriptsDir() {
- return GetInstallDir() + "lkr";
-}
-
-// Get the dir where startup code, intrinsics and lib reside.
-std::string GetStdLibsDir() {
- return GetInstallDir() + "lib";
-}
-}
diff --git a/tools/llvmc/examples/mcc16/Main.cpp b/tools/llvmc/examples/mcc16/Main.cpp
deleted file mode 100644
index 5d4992d..0000000
--- a/tools/llvmc/examples/mcc16/Main.cpp
+++ /dev/null
@@ -1,57 +0,0 @@
-//===--- Main.cpp - The LLVM Compiler Driver -------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open
-// Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Usually this file just includes CompilerDriver/Main.inc, but here we apply
-// some trickery to make the built-in '-save-temps' option hidden and enable
-// '--temp-dir' by default.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CompilerDriver/BuiltinOptions.h"
-#include "llvm/CompilerDriver/Main.h"
-
-#include "llvm/Support/Path.h"
-#include "llvm/Config/config.h"
-
-#include <iostream>
-
-#include "PIC16.inc"
-
-namespace {
-
-// Modify the PACKAGE_VERSION to use build number in top level configure file.
-void PIC16VersionPrinter(void) {
- std::cout << "MPLAB C16 1.0 " << PACKAGE_VERSION << "\n";
-}
-
-}
-
-int main(int argc, char** argv) {
-
- // HACK
- SaveTemps.setHiddenFlag(llvm::cl::Hidden);
- TempDirname.setHiddenFlag(llvm::cl::Hidden);
- Languages.setHiddenFlag(llvm::cl::Hidden);
- DryRun.setHiddenFlag(llvm::cl::Hidden);
-
- llvm::cl::SetVersionPrinter(PIC16VersionPrinter);
-
- // Ask for a standard temp dir, but just cache its basename., and delete it.
- llvm::sys::Path tempDir;
- tempDir = llvm::sys::Path::GetTemporaryDirectory();
- TempDirname = tempDir.getBasename();
- tempDir.eraseFromDisk(true);
-
- // We are creating a temp dir in current dir, with the cached name.
- // But before that remove if one already exists with that name..
- tempDir = TempDirname;
- tempDir.eraseFromDisk(true);
-
- return llvmc::Main(argc, argv);
-}
diff --git a/tools/llvmc/examples/mcc16/PIC16.td b/tools/llvmc/examples/mcc16/PIC16.td
deleted file mode 100644
index 6f04196..0000000
--- a/tools/llvmc/examples/mcc16/PIC16.td
+++ /dev/null
@@ -1,234 +0,0 @@
-//===- PIC16.td - PIC16 toolchain driver -------------------*- tablegen -*-===//
-//
-// A basic driver for the PIC16 toolchain.
-//
-//===----------------------------------------------------------------------===//
-
-include "llvm/CompilerDriver/Common.td"
-
-// Options
-
-def OptionList : OptionList<[
- (switch_option "g",
- (help "Enable Debugging")),
- (switch_option "E",
- (help "Stop after preprocessing, do not compile")),
- (switch_option "S",
- (help "Stop after compilation, do not assemble")),
- (switch_option "bc",
- (help "Stop after b-code generation, do not compile")),
- (switch_option "c",
- (help "Stop after assemble, do not link")),
- (prefix_option "p",
- (help "Specify part name")),
- (prefix_list_option "I",
- (help "Add a directory to include path")),
- (prefix_list_option "L",
- (help "Add a directory to library path")),
- (prefix_list_option "K",
- (help "Add a directory to linker script search path")),
- (parameter_option "l",
- (help "Specify a library to link")),
- (parameter_option "k",
- (help "Specify a linker script")),
- (parameter_option "m",
- (help "Generate linker map file with the given name")),
- (prefix_list_option "D",
- (help "Define a macro")),
- (switch_option "X",
- (help "Do not invoke mp2hex to create an output hex file.")),
- (switch_option "O0",
- (help "Do not optimize")),
- (switch_option "O1",
- (help "Optimization Level 1.")),
- (switch_option "O2",
- (help "Optimization Level 2.")),
- (switch_option "O3",
- (help "Optimization Level 3.")),
- (switch_option "Od",
- (help "Perform Debug-safe Optimizations only.")),
- (switch_option "w",
- (help "Disable all warnings.")),
-// (switch_option "O1",
-// (help "Optimization level 1")),
-// (switch_option "O2",
-// (help "Optimization level 2. (Default)")),
-// (parameter_option "pre-RA-sched",
-// (help "Example of an option that is passed to llc")),
- (parameter_option "regalloc",
- (help "Register allocator to use (possible values: simple, linearscan, pbqp, local; default=linearscan)")),
- (prefix_list_option "Wa,", (comma_separated),
- (help "Pass options to assembler (Run 'gpasm -help' for assembler options)")),
- (prefix_list_option "Wl,", (comma_separated),
- (help "Pass options to linker (Run 'mplink -help' for linker options)"))
-// (prefix_list_option "Wllc,",
-// (help "Pass options to llc")),
-// (prefix_list_option "Wo,",
-// (help "Pass options to llvm-ld"))
-]>;
-
-// Tools
-class clang_based<string language, string cmd, string ext_E> : Tool<
-[(in_language language),
- (out_language "llvm-bitcode"),
- (output_suffix "bc"),
- (command cmd),
- (actions (case
- (and (multiple_input_files),
- (or (switch_on "S"), (switch_on "c"))),
- (error "cannot specify -o with -c or -S with multiple files"),
- (switch_on "E"), [(forward "E"),
- (stop_compilation), (output_suffix ext_E)],
- (and (switch_on "E"), (empty "o")), (no_out_file),
- (switch_on "bc"),[(stop_compilation), (output_suffix "bc")],
- (switch_on "g"), (append_cmd "-g"),
- (switch_on "w"), (append_cmd "-w"),
- (switch_on "O1"), (append_cmd ""),
- (switch_on "O2"), (append_cmd ""),
- (switch_on "O3"), (append_cmd ""),
- (switch_on "Od"), (append_cmd ""),
- (not_empty "D"), (forward "D"),
- (not_empty "I"), (forward "I"),
- (switch_on "O0"), (append_cmd "-O0"),
- (default), (append_cmd "-O1")))
-// (sink)
-]>;
-
-def clang_cc : clang_based<"c", "$CALL(GetBinDir)clang -cc1 -I $CALL(GetStdHeadersDir) -D $CALL(GetLowerCasePartDefine) -D $CALL(GetUpperCasePartDefine) -triple=pic16- -emit-llvm-bc ", "i">;
-
-//def clang_cc : Tool<[
-// (in_language "c"),
-// (out_language "llvm-bitcode"),
-// (output_suffix "bc"),
-// (cmd_line "$CALL(GetBinDir)clang-cc -I $CALL(GetStdHeadersDir) -triple=pic16- -emit-llvm-bc "),
-// (cmd_line kkkkk
-// (actions (case
-// (switch_on "g"), (append_cmd "g"),
-// (not_empty "I"), (forward "I"))),
-// (sink)
-//]>;
-
-
-// pre-link-and-lto step.
-def llvm_ld : Tool<[
- (in_language "llvm-bitcode"),
- (out_language "llvm-bitcode"),
- (output_suffix "bc"),
- (command "$CALL(GetBinDir)llvm-ld -L $CALL(GetStdLibsDir) -disable-licm-promotion -l std"),
- (out_file_option "-b"),
- (actions (case
- (switch_on "O0"), (append_cmd "-disable-opt"),
- (switch_on "O1"), (append_cmd "-disable-opt"),
-// Whenever O3 is not specified on the command line, default i.e. disable-inlining will always be added.
- (switch_on "O2"), (append_cmd ""),
- (switch_on "O3"), (append_cmd ""),
- (default), (append_cmd "-disable-inlining"))),
- (join)
-]>;
-
-// optimize single file
-def llvm_ld_optimizer : Tool<[
- (in_language "llvm-bitcode"),
- (out_language "llvm-bitcode"),
- (output_suffix "bc"),
-// FIXME: we are still not disabling licm-promotion.
-// -disable-licm-promotion and building stdn library causes c16-71 to fail.
- (command "$CALL(GetBinDir)llvm-ld "),
- (out_file_option "-b"),
- (actions (case
- (switch_on "O0"), (append_cmd "-disable-opt"),
- (switch_on "O1"), (append_cmd "-disable-opt"),
-// Whenever O3 is not specified on the command line, default i.e. disable-inlining will always be added.
- (switch_on "O2"), (append_cmd ""),
- (switch_on "O3"), (append_cmd ""),
- (default), (append_cmd "-disable-inlining")))
-]>;
-
-// optimizer step.
-def pic16passes : Tool<[
- (in_language "llvm-bitcode"),
- (out_language "llvm-bitcode"),
- (output_suffix "obc"),
- (command "$CALL(GetBinDir)opt -pic16cloner -pic16overlay -f"),
- (actions (case
- (switch_on "O0"), (append_cmd "-disable-opt")))
-]>;
-
-def llc : Tool<[
- (in_language "llvm-bitcode"),
- (out_language "assembler"),
- (output_suffix "s"),
- (command "$CALL(GetBinDir)llc -march=pic16 -disable-jump-tables -pre-RA-sched=list-burr -f"),
- (actions (case
- (switch_on "S"), (stop_compilation),
-// (not_empty "Wllc,"), (unpack_values "Wllc,"),
-// (not_empty "pre-RA-sched"), (forward "pre-RA-sched")))
- (not_empty "regalloc"), (forward "regalloc"),
- (empty "regalloc"), (append_cmd "-regalloc=linearscan")))
-]>;
-
-def gpasm : Tool<[
- (in_language "assembler"),
- (out_language "object-code"),
- (output_suffix "o"),
- (command "$CALL(GetBinDir)gpasm -z -r decimal -I $CALL(GetStdAsmHeadersDir) -C -c -w 2"),
- (actions (case
- (switch_on "c"), (stop_compilation),
- (switch_on "g"), (append_cmd "-g"),
- (not_empty "p"), (forward "p"),
- (empty "p"), (append_cmd "-p 16f1xxx"),
- (not_empty "Wa,"), (forward_value "Wa,")))
-]>;
-
-def mplink : Tool<[
- (in_language "object-code"),
- (out_language "executable"),
- (output_suffix "cof"),
- (command "$CALL(GetBinDir)mplink -e -k $CALL(GetStdLinkerScriptsDir) -l $CALL(GetStdLibsDir) intrinsics.lib stdn.lib"),
- (actions (case
- (not_empty "Wl,"), (forward_value "Wl,"),
- (switch_on "X"), (append_cmd "-x"),
- (not_empty "L"), (forward_as "L", "-l"),
- (not_empty "K"), (forward_as "K", "-k"),
- (not_empty "m"), (forward "m"),
- (not_empty "p"), [(forward "p"), (append_cmd "-c")],
- (empty "p"), (append_cmd "-p 16f1xxx -c"),
-// (not_empty "l"), [(unpack_values "l"),(append_cmd ".lib")])),
- (not_empty "k"), (forward "k"),
- (not_empty "l"), (forward "l"))),
- (join)
-]>;
-
-// Language map
-
-def LanguageMap : LanguageMap<[
- (lang_to_suffixes "c", "c"),
- (lang_to_suffixes "c-cpp-output", "i"),
- (lang_to_suffixes "assembler", "s"),
- (lang_to_suffixes "assembler-with-cpp", "S"),
- (lang_to_suffixes "llvm-assembler", "ll"),
- (lang_to_suffixes "llvm-bitcode", "bc"),
- (lang_to_suffixes "object-code", "o"),
- (lang_to_suffixes "executable", "cof")
-]>;
-
-// Compilation graph
-
-def CompilationGraph : CompilationGraph<[
- (edge "root", "clang_cc"),
- (edge "root", "llvm_ld"),
- (optional_edge "root", "llvm_ld_optimizer",
- (case (switch_on "S"), (inc_weight),
- (switch_on "c"), (inc_weight))),
- (edge "root", "gpasm"),
- (edge "root", "mplink"),
- (edge "clang_cc", "llvm_ld"),
- (optional_edge "clang_cc", "llvm_ld_optimizer",
- (case (switch_on "S"), (inc_weight),
- (switch_on "c"), (inc_weight))),
- (edge "llvm_ld", "pic16passes"),
- (edge "llvm_ld_optimizer", "pic16passes"),
- (edge "pic16passes", "llc"),
- (edge "llc", "gpasm"),
- (edge "gpasm", "mplink")
-]>;
diff --git a/tools/llvmc/examples/mcc16/README b/tools/llvmc/examples/mcc16/README
deleted file mode 100644
index 6d2b73d..0000000
--- a/tools/llvmc/examples/mcc16/README
+++ /dev/null
@@ -1,75 +0,0 @@
-This is a basic compiler driver for the PIC16 toolchain that shows how to create
-your own llvmc-based drivers. It is based on the examples/Skeleton template.
-
-The PIC16 toolchain looks like this:
-
-clang-cc (FE) -> llvm-ld (optimizer) -> llc (codegen) -> native-as -> native-ld
-
-Following features were requested by Sanjiv:
-
-From: Sanjiv Gupta <sanjiv.gupta <at> microchip.com>
-Subject: Re: llvmc for PIC16
-Newsgroups: gmane.comp.compilers.llvm.devel
-Date: 2009-06-05 06:51:14 GMT
-
-The salient features that we want to have in the driver are:
-1. llvm-ld will be used as "The Optimizer".
-2. If the user has specified to generate the final executable, then
-llvm-ld should run on all the .bc files generated by clang and create a
-single optimized .bc file for further tools.
-3. -Wo <options> - pass optimizations to the llvm-ld
-4. mcc16 -Wl <options> - pass options to native linker.
-5. mcc16 -Wa <options> - pass options to native assembler.
-
-Here are some example command lines and sample command invocations as to
-what should be done.
-
-$ mcc16 -S foo.c
-// [clang-cc foo.c] -> foo.bc
-// [llvm-ld foo.bc] -> foo.opt.bc
-// [llc foo.opt.bc] -> foo.s
-
-$ mcc16 -S foo.c bar.c
-// [clang-cc foo.c] -> foo.bc
-// [llvm-ld foo.bc] -> foo.opt.bc
-// [llc foo.opt.bc] -> foo.s
-// [clang-cc bar.c] -> bar.bc
-// [llvm-ld bar.bc] -> bar.opt.bc
-// [llc bar.opt.bc] -> bar.s
-
-** Use of -g causes llvm-ld to run with -disable-opt
-$ mcc16 -S -g foo.c
-// [clang-cc foo.c] -> foo.bc
-// [llvm-ld -disable-opt foo.bc] -> foo.opt.bc
-// [llc foo.opt.bc] -> foo.s
-
-** -I is passed to clang-cc, -pre-RA-sched=list-burr to llc.
-$ mcc16 -S -g -I ../include -pre-RA-sched=list-burr foo.c
-// [clang-cc -I ../include foo.c] -> foo.bc
-// [llvm-ld -disable-opt foo.bc] -> foo.opt.bc
-// [llc -pre-RA-sched=list-burr foo.opt.bc] -> foo.s
-
-** -Wo passes options to llvm-ld
-$ mcc16 -Wo=opt1,opt2 -S -I ../include -pre-RA-sched=list-burr foo.c
-// [clang-cc -I ../include foo.c] -> foo.bc
-// [llvm-ld -opt1 -opt2 foo.bc] -> foo.opt.bc
-// [llc -pre-RA-sched=list-burr foo.opt.bc] -> foo.s
-
-** -Wa passes options to native as.
-$ mcc16 -c foo.c -Wa=opt1
-// [clang-cc foo.c] -> foo.bc
-// [llvm-ld foo.bc] -> foo.opt.bc
-// [llc foo.opt.bc] -> foo.s
-// [native-as -opt1 foo.s] -> foo.o
-
-$ mcc16 -Wo=opt1 -Wl=opt2 -Wa=opt3 foo.c bar.c
-// [clang-cc foo.c] -> foo.bc
-// [clang-cc bar.c] -> bar.bc
-// [llvm-ld -opt1 foo.bc bar.bc] -> a.out.bc
-// [llc a.out.bc] -> a.out.s
-// [native-as -opt3 a.out.s] -> a.out.o
-// [native-ld -opt2 a.out.o] -> a.out
-
-Is this achievable by a tablegen based driver ?
-
-- Sanjiv
diff --git a/tools/llvmc/src/AutoGenerated.td b/tools/llvmc/src/AutoGenerated.td
deleted file mode 100644
index 8507b1f..0000000
--- a/tools/llvmc/src/AutoGenerated.td
+++ /dev/null
@@ -1,17 +0,0 @@
-//===- AutoGenerated.td - LLVMC toolchain descriptions -----*- tablegen -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains compilation graph description used by llvmc.
-//
-//===----------------------------------------------------------------------===//
-
-include "llvm/CompilerDriver/Common.td"
-
-include "Base.td"
-include "Clang.td"
diff --git a/tools/llvmc/src/Base.td.in b/tools/llvmc/src/Base.td.in
deleted file mode 100644
index 84e39e7..0000000
--- a/tools/llvmc/src/Base.td.in
+++ /dev/null
@@ -1,461 +0,0 @@
-//===- Base.td - LLVMC toolchain descriptions --------------*- tablegen -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains compilation graph description used by llvmc.
-//
-//===----------------------------------------------------------------------===//
-
-// Options
-
-def OptList : OptionList<[
- (switch_option "emit-llvm",
- (help "Emit LLVM .ll files instead of native object files")),
- (switch_option "E",
- (help "Stop after the preprocessing stage, do not run the compiler")),
- (switch_option "fsyntax-only",
- (help "Stop after checking the input for syntax errors")),
- (switch_option "opt",
- (help "Enable opt")),
- (switch_option "O0",
- (help "Turn off optimization"), (zero_or_more)),
- (switch_option "O1",
- (help "Optimization level 1"), (zero_or_more)),
- (switch_option "O2",
- (help "Optimization level 2"), (zero_or_more)),
- (switch_option "O3",
- (help "Optimization level 3"), (zero_or_more)),
- (switch_option "S",
- (help "Stop after compilation, do not assemble")),
- (switch_option "c",
- (help "Compile and assemble, but do not link")),
- (switch_option "m32",
- (help "Generate code for a 32-bit environment"), (hidden)),
- (switch_option "m64",
- (help "Generate code for a 64-bit environment"), (hidden)),
- (switch_option "fPIC",
- (help "Relocation model: PIC"), (hidden)),
- (switch_option "mdynamic-no-pic",
- (help "Relocation model: dynamic-no-pic"), (hidden)),
- (parameter_option "linker",
- (help "Choose linker (possible values: gcc, g++)")),
- (parameter_option "mtune",
- (help "Target a specific CPU type"), (forward_not_split)),
- (parameter_list_option "march",
- (help "Generate code for the specified machine type")),
- (parameter_option "mcpu",
- (help "A deprecated synonym for -mtune"), (hidden), (forward_not_split)),
- (parameter_option "mfpu",
- (help "Specify type of floating point unit"),
- (hidden), (forward_not_split)),
- (parameter_option "mabi",
- (help "Generate code for the specified ABI"), (hidden)),
- (parameter_option "mfloat-abi",
- (help "Specifies which floating-point ABI to use"), (hidden)),
- (switch_option "mfix-and-continue",
- (help "Needed by gdb to load .o files dynamically"), (hidden)),
- (parameter_option "MF",
- (help "Specify a file to write dependencies to"), (hidden)),
- (parameter_list_option "MT",
- (help "Change the name of the rule emitted by dependency generation"),
- (hidden)),
- (parameter_list_option "include",
- (help "Include the named file prior to preprocessing")),
- (parameter_list_option "iquote",
- (help "Search dir only for files requested with #inlcude \"file\""),
- (hidden)),
- (prefix_list_option "I",
- (help "Add a directory to include path")),
- (prefix_list_option "D",
- (help "Define a macro")),
- (parameter_list_option "Xpreprocessor", (hidden),
- (help "Pass options to preprocessor")),
- (prefix_list_option "Wa,", (comma_separated),
- (help "Pass options to assembler")),
- (parameter_list_option "Xassembler", (hidden),
- (help "Pass options to assembler")),
- (prefix_list_option "Wllc,", (comma_separated),
- (help "Pass options to llc")),
- (prefix_list_option "Wl,",
- (help "Pass options to linker")),
- (parameter_list_option "Xlinker", (hidden),
- (help "Pass options to linker")),
- (prefix_list_option "Wo,", (comma_separated),
- (help "Pass options to opt")),
- (prefix_list_option "m",
- (help "Enable or disable various extensions (-mmmx, -msse, etc.)"),
- (hidden))
-]>;
-
-def LinkerOptList : OptionList<[
- (prefix_list_option "L",
- (help "Add a directory to link path")),
- (prefix_list_option "l",
- (help "Search a library when linking")),
- (parameter_option "filelist", (hidden),
- (help "Link the files listed in file")),
- (switch_option "nostartfiles",
- (help "Do not use the standard system startup files when linking"),
- (hidden)),
- (switch_option "nodefaultlibs",
- (help "Do not use the standard system libraries when linking"), (hidden)),
- (switch_option "nostdlib",
- (help
- "Do not use the standard system startup files or libraries when linking"),
- (hidden)),
- (switch_option "pie",
- (help "Produce a position independent executable"), (hidden)),
- (switch_option "rdynamic",
- (help "Add all symbols to the dynamic export table"), (hidden)),
- (switch_option "s",
- (help "Strip all symbols"), (hidden)),
- (switch_option "static",
- (help "Do not link against shared libraries"), (hidden)),
- (switch_option "static-libgcc",
- (help "Use static libgcc"), (hidden)),
- (switch_option "shared",
- (help "Create a DLL instead of the regular executable")),
- (switch_option "shared-libgcc",
- (help "Use shared libgcc"), (hidden)),
- (parameter_option "T",
- (help "Read linker script"), (hidden)),
- (parameter_option "u",
- (help "Start with undefined reference to SYMBOL"), (hidden)),
- (switch_option "pthread",
- (help "Enable threads")),
-
- // TODO: Add a conditional compilation mechanism to make Darwin-only options
- // like '-arch' really Darwin-only.
- (parameter_option "arch",
- (help "Compile for the specified target architecture"), (hidden)),
- (prefix_list_option "F",
- (help "Add a directory to framework search path")),
- (parameter_list_option "framework",
- (help "Specifies a framework to link against")),
- (parameter_list_option "weak_framework",
- (help "Specifies a framework to weakly link against"), (hidden)),
- (switch_option "dynamiclib", (hidden),
- (help "Produce a dynamic library")),
- (switch_option "prebind", (hidden),
- (help "Prebind all undefined symbols")),
- (switch_option "dead_strip", (hidden),
- (help "Remove unreachable blocks of code")),
- (switch_option "single_module", (hidden),
- (help "Build the library so it contains only one module")),
- (parameter_option "install_name", (hidden),
- (help "File name the library will be installed in")),
- (parameter_option "compatibility_version", (hidden),
- (help "Compatibility version number")),
- (parameter_option "current_version", (hidden),
- (help "Current version number"))
-]>;
-
-// Option preprocessor.
-
-def Preprocess : OptionPreprocessor<
-(case (not (any_switch_on "O0", "O1", "O2", "O3")),
- (set_option "O2"),
- (and (switch_on "O3"), (any_switch_on "O0", "O1", "O2")),
- (unset_option "O0", "O1", "O2"),
- (and (switch_on "O2"), (any_switch_on "O0", "O1")),
- (unset_option "O0", "O1"),
- (switch_on "O1", "O0"),
- (unset_option "O0"))
->;
-
-// Tools
-
-class llvm_gcc_based <string cmd, string in_lang, string E_ext, dag out_lang,
- string out_ext> : Tool<
-[(in_language in_lang),
- out_lang,
- (output_suffix out_ext),
- (command cmd),
- (actions
- (case
- (and (not_empty "o"),
- (multiple_input_files), (or (switch_on "S"), (switch_on "c"))),
- (error "cannot specify -o with -c or -S with multiple files"),
- (switch_on "E"),
- [(forward "E"), (stop_compilation), (output_suffix E_ext)],
- (and (switch_on "E"), (empty "o")), (no_out_file),
-
- // ('-emit-llvm') && !('opt') -> stop compilation
- (and (switch_on "emit-llvm"), (not (switch_on "opt"))),
- (stop_compilation),
- // ('-S' && '-emit-llvm') && !('opt') -> output .ll
- (and (switch_on "emit-llvm", "S"), (not (switch_on "opt"))),
- [(forward "S"), (output_suffix "ll")],
- // Usually just output .bc
- (not (switch_on "fsyntax-only")),
- [(append_cmd "-c"), (append_cmd "-emit-llvm")],
-
- // -fsyntax-only
- (switch_on "fsyntax-only"), [(forward "fsyntax-only"),
- (no_out_file), (stop_compilation)],
-
- // Forwards
- (not_empty "Xpreprocessor"), (forward "Xpreprocessor"),
- (not_empty "include"), (forward "include"),
- (not_empty "iquote"), (forward "iquote"),
- (not_empty "save-temps"), (append_cmd "-save-temps"),
- (not_empty "I"), (forward "I"),
- (not_empty "F"), (forward "F"),
- (not_empty "D"), (forward "D"),
- (not_empty "arch"), (forward "arch"),
- (not_empty "march"), (forward "march"),
- (not_empty "mcpu"), (forward "mcpu"),
- (not_empty "mtune"), (forward "mtune"),
- (not_empty "mfpu"), (forward "mfpu"),
- (not_empty "mabi"), (forward "mabi"),
- (not_empty "mfloat-abi"), (forward "mfloat-abi"),
- (not_empty "m"), (forward "m"),
- (switch_on "mfix-and-continue"), (forward "mfix-and-continue"),
- (switch_on "m32"), (forward "m32"),
- (switch_on "m64"), (forward "m64"),
- (switch_on "O0"), (forward "O0"),
- (switch_on "O1"), (forward "O1"),
- (switch_on "O2"), (forward "O2"),
- (switch_on "O3"), (forward "O3"),
- (switch_on "fPIC"), (forward "fPIC"),
- (switch_on "mdynamic-no-pic"), (forward "mdynamic-no-pic"),
- (not_empty "MF"), (forward "MF"),
- (not_empty "MT"), (forward "MT"))),
- (sink)
-]>;
-
-class llvm_gcc_comp_based <string cmd, string in_lang, string E_ext>
-: llvm_gcc_based<cmd, in_lang, E_ext,
- (out_language "llvm-bitcode", "object-code"), "bc">;
-
-class llvm_gcc_pch_based <string cmd, string in_lang, string E_ext>
-: llvm_gcc_based<cmd, in_lang, E_ext,
- (out_language "precompiled-header"), "gch">;
-
-def llvm_gcc_c : llvm_gcc_comp_based
- <"@LLVMGCCCOMMAND@ -x c", "c", "i">;
-def llvm_gcc_cpp : llvm_gcc_comp_based
- <"@LLVMGXXCOMMAND@ -x c++", "c++", "i">;
-def llvm_gcc_m : llvm_gcc_comp_based
- <"@LLVMGCCCOMMAND@ -x objective-c", "objective-c", "mi">;
-def llvm_gcc_mxx : llvm_gcc_comp_based
- <"@LLVMGCCCOMMAND@ -x objective-c++", "objective-c++", "mi">;
-
-def llvm_gcc_c_pch : llvm_gcc_pch_based
- <"@LLVMGCCCOMMAND@ -x c-header", "c-header", "i">;
-def llvm_gcc_cpp_pch : llvm_gcc_pch_based
- <"@LLVMGXXCOMMAND@ -x c++-header", "c++-header", "i">;
-def llvm_gcc_m_pch : llvm_gcc_pch_based
- <"@LLVMGCCCOMMAND@ -x objective-c-header", "objective-c-header", "mi">;
-def llvm_gcc_mxx_pch : llvm_gcc_pch_based
- <"@LLVMGCCCOMMAND@ -x objective-c++-header", "objective-c++-header", "mi">;
-
-def opt : Tool<
-[(in_language "llvm-bitcode"),
- (out_language "llvm-bitcode"),
- (output_suffix "opt.bc"),
- (actions (case (switch_on "emit-llvm"), (stop_compilation),
- (switch_on "emit-llvm", "S"),
- [(append_cmd "-S"), (output_suffix "ll")],
- (not_empty "Wo,"), (forward_value "Wo,"),
- (switch_on "O1"), (forward "O1"),
- (switch_on "O2"), (forward "O2"),
- (switch_on "O3"), (forward "O3"))),
- (command "opt -f")
-]>;
-
-def llvm_as : Tool<
-[(in_language "llvm-assembler"),
- (out_language "llvm-bitcode"),
- (output_suffix "bc"),
- (command "llvm-as"),
- (actions (case (and (switch_on "emit-llvm"), (not (switch_on "opt"))),
- (stop_compilation)))
-]>;
-
-def llvm_gcc_assembler : Tool<
-[(in_language "assembler"),
- (out_language "object-code"),
- (output_suffix "o"),
- (command "@LLVMGCCCOMMAND@ -c -x assembler"),
- (actions (case
- (switch_on "c"), (stop_compilation),
- (not_empty "arch"), (forward "arch"),
- (not_empty "Xassembler"), (forward "Xassembler"),
- (not_empty "march"), (forward "march"),
- (not_empty "mcpu"), (forward "mcpu"),
- (not_empty "mtune"), (forward "mtune"),
- (not_empty "mabi"), (forward "mabi"),
- (not_empty "mfloat-abi"), (forward "mfloat-abi"),
- (switch_on "m32"), (forward "m32"),
- (switch_on "m64"), (forward "m64"),
- (not_empty "Wa,"), (forward "Wa,")))
-]>;
-
-def llc : Tool<
-[(in_language "llvm-bitcode", "llvm-assembler"),
- (out_language "assembler"),
- (output_suffix "s"),
- (command "llc -disable-cfi"),
- (actions (case
- (switch_on "S"), (stop_compilation),
- (switch_on "O0"), (forward "O0"),
- (switch_on "O1"), (forward "O1"),
- (switch_on "O2"), (forward "O2"),
- (switch_on "O3"), (forward "O3"),
- (switch_on "fPIC"), (append_cmd "-relocation-model=pic"),
- (switch_on "mdynamic-no-pic"),
- (append_cmd "-relocation-model=dynamic-no-pic"),
- (not_empty "march"), (forward_transformed_value
- "march", "ConvertMArchToMAttr"),
- (not_empty "mcpu"), (forward_transformed_value "mcpu", "ConvertMCpu"),
- (and (not_empty "mtune"), (empty "mcpu")),
- (forward_as "mtune", "-mcpu"),
- (not_empty "mfpu"), (forward_transformed_value "mfpu", "ConvertMFpu"),
- (not_empty "m"), (forward_transformed_value "m", "ConvertToMAttr"),
- (not_empty "Wllc,"), (forward_value "Wllc,")))
-]>;
-
-// Base class for linkers
-class llvm_gcc_based_linker <string cmd, dag on_empty> : Tool<
-[(in_language "object-code", "static-library", "dynamic-library"),
- (out_language "executable"),
- (output_suffix "out"),
- (command cmd),
- (works_on_empty (case (and (not_empty "filelist"), on_empty), true,
- (default), false)),
- (join),
- (actions (case
- (switch_on "pthread"), (append_cmd "-lpthread"),
- (not_empty "L"), (forward "L"),
- (not_empty "F"), (forward "F"),
- (not_empty "arch"), (forward "arch"),
- (not_empty "framework"), (forward "framework"),
- (not_empty "weak_framework"), (forward "weak_framework"),
- (not_empty "filelist"), (forward "filelist"),
- (not_empty "march"), (forward "march"),
- (not_empty "mcpu"), (forward "mcpu"),
- (not_empty "mtune"), (forward "mtune"),
- (not_empty "mabi"), (forward "mabi"),
- (not_empty "mfloat-abi"), (forward "mfloat-abi"),
- (switch_on "m32"), (forward "m32"),
- (switch_on "m64"), (forward "m64"),
- (not_empty "l"), (forward "l"),
- (not_empty "Xlinker"), (forward "Xlinker"),
- (not_empty "Wl,"), (forward "Wl,"),
- (switch_on "nostartfiles"), (forward "nostartfiles"),
- (switch_on "nodefaultlibs"), (forward "nodefaultlibs"),
- (switch_on "nostdlib"), (forward "nostdlib"),
- (switch_on "pie"), (forward "pie"),
- (switch_on "rdynamic"), (forward "rdynamic"),
- (switch_on "s"), (forward "s"),
- (switch_on "static"), (forward "static"),
- (switch_on "static-libgcc"), (forward "static-libgcc"),
- (switch_on "shared"), (forward "shared"),
- (switch_on "shared-libgcc"), (forward "shared-libgcc"),
- (not_empty "T"), (forward "T"),
- (not_empty "u"), (forward "u"),
- (switch_on "dynamiclib"), (forward "dynamiclib"),
- (switch_on "prebind"), (forward "prebind"),
- (switch_on "dead_strip"), (forward "dead_strip"),
- (switch_on "single_module"), (forward "single_module"),
- (not_empty "compatibility_version"),
- (forward "compatibility_version"),
- (not_empty "current_version"), (forward "current_version"),
- (not_empty "install_name"), (forward "install_name")))
-]>;
-
-// Default linker
-def llvm_gcc_linker : llvm_gcc_based_linker<"@LLVMGCCCOMMAND@",
- (not (or (parameter_equals "linker", "g++"),
- (parameter_equals "linker", "c++")))>;
-// Alternative linker for C++
-def llvm_gcc_cpp_linker : llvm_gcc_based_linker<"@LLVMGXXCOMMAND@",
- (or (parameter_equals "linker", "g++"),
- (parameter_equals "linker", "c++"))>;
-
-// Language map
-
-def LanguageMap : LanguageMap<[
- (lang_to_suffixes "precompiled-header", ["gch", "pch"]),
- (lang_to_suffixes "c++", ["cc", "cp", "cxx", "cpp", "CPP", "c++", "C"]),
- (lang_to_suffixes "c++-header", "hpp"),
- (lang_to_suffixes "c", "c"),
- (lang_to_suffixes "c-header", "h"),
- (lang_to_suffixes "c-cpp-output", "i"),
- (lang_to_suffixes "objective-c-cpp-output", "mi"),
- (lang_to_suffixes "objective-c++", "mm"),
- (lang_to_suffixes "objective-c++-header", "hmm"),
- (lang_to_suffixes "objective-c", "m"),
- (lang_to_suffixes "objective-c-header", "hm"),
- (lang_to_suffixes "assembler", "s"),
- (lang_to_suffixes "assembler-with-cpp", "S"),
- (lang_to_suffixes "llvm-assembler", "ll"),
- (lang_to_suffixes "llvm-bitcode", "bc"),
- (lang_to_suffixes "object-code", ["o", "*empty*"]),
- (lang_to_suffixes "static-library", ["a", "lib"]),
- (lang_to_suffixes "dynamic-library", ["so", "dylib", "dll"]),
- (lang_to_suffixes "executable", "out")
-]>;
-
-// Compilation graph
-
-def CompilationGraph : CompilationGraph<[
- (edge "root", "llvm_gcc_c"),
- (edge "root", "llvm_gcc_assembler"),
- (edge "root", "llvm_gcc_cpp"),
- (edge "root", "llvm_gcc_m"),
- (edge "root", "llvm_gcc_mxx"),
- (edge "root", "llc"),
-
- (edge "root", "llvm_gcc_c_pch"),
- (edge "root", "llvm_gcc_cpp_pch"),
- (edge "root", "llvm_gcc_m_pch"),
- (edge "root", "llvm_gcc_mxx_pch"),
-
- (edge "llvm_gcc_c", "llc"),
- (edge "llvm_gcc_cpp", "llc"),
- (edge "llvm_gcc_m", "llc"),
- (edge "llvm_gcc_mxx", "llc"),
- (edge "llvm_as", "llc"),
-
- (optional_edge "root", "llvm_as",
- (case (or (switch_on "emit-llvm"),
- (switch_on "opt")), (inc_weight))),
- (optional_edge "llvm_gcc_c", "opt",
- (case (switch_on "opt"), (inc_weight))),
- (optional_edge "llvm_gcc_cpp", "opt",
- (case (switch_on "opt"), (inc_weight))),
- (optional_edge "llvm_gcc_m", "opt",
- (case (switch_on "opt"), (inc_weight))),
- (optional_edge "llvm_gcc_mxx", "opt",
- (case (switch_on "opt"), (inc_weight))),
- (optional_edge "llvm_as", "opt",
- (case (switch_on "opt"), (inc_weight))),
- (edge "opt", "llc"),
-
- (edge "llc", "llvm_gcc_assembler"),
- (edge "llvm_gcc_assembler", "llvm_gcc_linker"),
- (optional_edge "llvm_gcc_assembler", "llvm_gcc_cpp_linker",
- (case
- (or (input_languages_contain "c++"),
- (input_languages_contain "objective-c++")),
- (inc_weight),
- (or (parameter_equals "linker", "g++"),
- (parameter_equals "linker", "c++")), (inc_weight))),
-
-
- (edge "root", "llvm_gcc_linker"),
- (optional_edge "root", "llvm_gcc_cpp_linker",
- (case
- (or (input_languages_contain "c++"),
- (input_languages_contain "objective-c++")),
- (inc_weight),
- (or (parameter_equals "linker", "g++"),
- (parameter_equals "linker", "c++")), (inc_weight)))
-]>;
diff --git a/tools/llvmc/src/Clang.td b/tools/llvmc/src/Clang.td
deleted file mode 100644
index e2d32e8..0000000
--- a/tools/llvmc/src/Clang.td
+++ /dev/null
@@ -1,87 +0,0 @@
-//===- Clang.td - LLVMC toolchain descriptions -------------*- tablegen -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file contains compilation graph description used by llvmc.
-//
-//===----------------------------------------------------------------------===//
-
-
-def Options : OptionList<[
-(switch_option "clang", (help "Use Clang instead of llvm-gcc"))
-]>;
-
-class clang_based<string language, string cmd, string ext_E> : Tool<
-[(in_language language),
- (out_language "llvm-bitcode"),
- (output_suffix "bc"),
- (command cmd),
- (actions (case (switch_on "E"),
- [(forward "E"), (stop_compilation), (output_suffix ext_E)],
- (and (switch_on "E"), (empty "o")), (no_out_file),
- (switch_on "fsyntax-only"), (stop_compilation),
- (switch_on "S", "emit-llvm"),
- [(append_cmd "-emit-llvm"),
- (stop_compilation), (output_suffix "ll")],
- (not (switch_on "S", "emit-llvm")),
- (append_cmd "-emit-llvm-bc"),
- (switch_on "c", "emit-llvm"),
- (stop_compilation),
- (not_empty "include"), (forward "include"),
- (not_empty "I"), (forward "I"))),
- (sink)
-]>;
-
-def clang_c : clang_based<"c", "clang -x c", "i">;
-def clang_cpp : clang_based<"c++", "clang -x c++", "i">;
-def clang_objective_c : clang_based<"objective-c",
- "clang -x objective-c", "mi">;
-def clang_objective_cpp : clang_based<"objective-c++",
- "clang -x objective-c++", "mi">;
-
-def as : Tool<
-[(in_language "assembler"),
- (out_language "object-code"),
- (output_suffix "o"),
- (command "as"),
- (actions (case (not_empty "Wa,"), (forward_value "Wa,"),
- (switch_on "c"), (stop_compilation)))
-]>;
-
-// Default linker
-def llvm_ld : Tool<
-[(in_language "object-code"),
- (out_language "executable"),
- (output_suffix "out"),
- (command "llvm-ld -native -disable-internalize"),
- (actions (case
- (switch_on "pthread"), (append_cmd "-lpthread"),
- (not_empty "L"), (forward "L"),
- (not_empty "l"), (forward "l"),
- (not_empty "Wl,"), (forward_value "Wl,"))),
- (join)
-]>;
-
-// Compilation graph
-
-def ClangCompilationGraph : CompilationGraph<[
- (optional_edge "root", "clang_c",
- (case (switch_on "clang"), (inc_weight))),
- (optional_edge "root", "clang_cpp",
- (case (switch_on "clang"), (inc_weight))),
- (optional_edge "root", "clang_objective_c",
- (case (switch_on "clang"), (inc_weight))),
- (optional_edge "root", "clang_objective_cpp",
- (case (switch_on "clang"), (inc_weight))),
- (edge "clang_c", "llc"),
- (edge "clang_cpp", "llc"),
- (edge "clang_objective_c", "llc"),
- (edge "clang_objective_cpp", "llc"),
- (optional_edge "llc", "as", (case (switch_on "clang"), (inc_weight))),
- (edge "as", "llvm_ld")
-]>;
diff --git a/tools/llvmc/src/Hooks.cpp b/tools/llvmc/src/Hooks.cpp
deleted file mode 100644
index ddad08a..0000000
--- a/tools/llvmc/src/Hooks.cpp
+++ /dev/null
@@ -1,193 +0,0 @@
-#include "llvm/ADT/StringMap.h"
-
-#include <string>
-#include <vector>
-
-namespace hooks {
-
-/// NUM_KEYS - Calculate the size of a const char* array.
-#define NUM_KEYS(Keys) sizeof(Keys) / sizeof(const char*)
-
-// See http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
-inline unsigned NextHighestPowerOf2 (unsigned i) {
- --i;
- i |= i >> 1;
- i |= i >> 2;
- i |= i >> 4;
- i |= i >> 8;
- i |= i >> 16;
- ++i;
- return i;
-}
-
-typedef std::vector<std::string> StrVec;
-typedef llvm::StringMap<const char*> ArgMap;
-
-/// AddPlusOrMinus - Convert 'no-foo' to '-foo' and 'foo' to '+foo'.
-void AddPlusOrMinus (const std::string& Arg, std::string& out) {
- if (Arg.find("no-") == 0 && Arg[3] != 0) {
- out += '-';
- out += Arg.c_str() + 3;
- }
- else {
- out += '+';
- out += Arg;
- }
-}
-
-// -march values that need to be special-cased.
-const char* MArchKeysARM[] = { "armv4t", "armv5t", "armv5te", "armv6",
- "armv6-m", "armv6t2", "armv7-a", "armv7-m" };
-const char* MArchValuesARM[] = { "v4t", "v5t", "v5te", "v6", "v6m", "v6t2",
- "v7a", "v7m" };
-const unsigned MArchNumKeysARM = NUM_KEYS(MArchKeysARM);
-const unsigned MArchMapSize = NextHighestPowerOf2(MArchNumKeysARM);
-
-// -march values that should be forwarded as -mcpu
-const char* MArchMCpuKeysARM[] = { "iwmmxt", "ep9312" };
-const char* MArchMCpuValuesARM[] = { "iwmmxt", "ep9312"};
-const unsigned MArchMCpuNumKeysARM = NUM_KEYS(MArchMCpuKeysARM);
-
-
-void FillInArgMap(ArgMap& Args, const char* Keys[],
- const char* Values[], unsigned NumKeys)
-{
- for (unsigned i = 0; i < NumKeys; ++i) {
- // Explicit cast to StringRef here is necessary to pick up the right
- // overload.
- Args.GetOrCreateValue(llvm::StringRef(Keys[i]), Values[i]);
- }
-}
-
-/// ConvertMArchToMAttr - Convert -march from the gcc dialect to
-/// something llc can understand.
-std::string ConvertMArchToMAttr(const StrVec& Opts) {
- static ArgMap MArchMap(MArchMapSize);
- static ArgMap MArchMCpuMap(MArchMapSize);
- static bool StaticDataInitialized = false;
-
- if (!StaticDataInitialized) {
- FillInArgMap(MArchMap, MArchKeysARM, MArchValuesARM, MArchNumKeysARM);
- FillInArgMap(MArchMCpuMap, MArchMCpuKeysARM,
- MArchMCpuValuesARM, MArchMCpuNumKeysARM);
- StaticDataInitialized = true;
- }
-
- std::string mattr("-mattr=");
- std::string mcpu("-mcpu=");
- bool mattrTouched = false;
- bool mcpuTouched = false;
-
- for (StrVec::const_iterator B = Opts.begin(), E = Opts.end(); B!=E; ++B) {
- const std::string& Arg = *B;
-
- // Check if the argument should be forwarded to -mcpu instead of -mattr.
- {
- ArgMap::const_iterator I = MArchMCpuMap.find(Arg);
-
- if (I != MArchMCpuMap.end()) {
- mcpuTouched = true;
- mcpu += I->getValue();
- continue;
- }
- }
-
- if (mattrTouched)
- mattr += ",";
-
- // Check if the argument is a special case.
- {
- ArgMap::const_iterator I = MArchMap.find(Arg);
-
- if (I != MArchMap.end()) {
- mattrTouched = true;
- mattr += '+';
- mattr += I->getValue();
- continue;
- }
- }
-
- AddPlusOrMinus(Arg, mattr);
- }
-
- std::string out;
- if (mattrTouched)
- out += mattr;
- if (mcpuTouched)
- out += (mattrTouched ? " " : "") + mcpu;
-
- return out;
-}
-
-// -mcpu values that need to be special-cased.
-const char* MCpuKeysPPC[] = { "G3", "G4", "G5", "powerpc", "powerpc64"};
-const char* MCpuValuesPPC[] = { "g3", "g4", "g5", "ppc", "ppc64"};
-const unsigned MCpuNumKeysPPC = NUM_KEYS(MCpuKeysPPC);
-const unsigned MCpuMapSize = NextHighestPowerOf2(MCpuNumKeysPPC);
-
-/// ConvertMCpu - Convert -mcpu value from the gcc to the llc dialect.
-std::string ConvertMCpu(const char* Val) {
- static ArgMap MCpuMap(MCpuMapSize);
- static bool StaticDataInitialized = false;
-
- if (!StaticDataInitialized) {
- FillInArgMap(MCpuMap, MCpuKeysPPC, MCpuValuesPPC, MCpuNumKeysPPC);
- StaticDataInitialized = true;
- }
-
- std::string ret = "-mcpu=";
- ArgMap::const_iterator I = MCpuMap.find(Val);
- if (I != MCpuMap.end()) {
- return ret + I->getValue();
- }
- return ret + Val;
-}
-
-// -mfpu values that need to be special-cased.
-const char* MFpuKeysARM[] = { "vfp", "vfpv3",
- "vfpv3-fp16", "vfpv3-d16", "vfpv3-d16-fp16",
- "neon", "neon-fp16" };
-const char* MFpuValuesARM[] = { "vfp2", "vfp3",
- "+vfp3,+fp16", "+vfp3,+d16", "+vfp3,+d16,+fp16",
- "+neon", "+neon,+neonfp" };
-const unsigned MFpuNumKeysARM = NUM_KEYS(MFpuKeysARM);
-const unsigned MFpuMapSize = NextHighestPowerOf2(MFpuNumKeysARM);
-
-/// ConvertMFpu - Convert -mfpu value from the gcc to the llc dialect.
-std::string ConvertMFpu(const char* Val) {
- static ArgMap MFpuMap(MFpuMapSize);
- static bool StaticDataInitialized = false;
-
- if (!StaticDataInitialized) {
- FillInArgMap(MFpuMap, MFpuKeysARM, MFpuValuesARM, MFpuNumKeysARM);
- StaticDataInitialized = true;
- }
-
- std::string ret = "-mattr=";
- ArgMap::const_iterator I = MFpuMap.find(Val);
- if (I != MFpuMap.end()) {
- return ret + I->getValue();
- }
- return ret + '+' + Val;
-}
-
-/// ConvertToMAttr - Convert '-mfoo' and '-mno-bar' to '-mattr=+foo,-bar'.
-std::string ConvertToMAttr(const StrVec& Opts) {
- std::string out("-mattr=");
- bool firstIter = true;
-
- for (StrVec::const_iterator B = Opts.begin(), E = Opts.end(); B!=E; ++B) {
- const std::string& Arg = *B;
-
- if (firstIter)
- firstIter = false;
- else
- out += ",";
-
- AddPlusOrMinus(Arg, out);
- }
-
- return out;
-}
-
-}
diff --git a/tools/llvmc/src/Main.cpp b/tools/llvmc/src/Main.cpp
deleted file mode 100644
index 9f9c71a..0000000
--- a/tools/llvmc/src/Main.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-//===--- Main.cpp - The LLVM Compiler Driver -------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open
-// Source License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Just include AutoGenerated.inc and CompilerDriver/Main.inc.
-//
-//===----------------------------------------------------------------------===//
-
-#include "AutoGenerated.inc"
-
-#include "llvm/CompilerDriver/Main.inc"
diff --git a/tools/llvmc/src/Makefile b/tools/llvmc/src/Makefile
deleted file mode 100644
index f3f3091..0000000
--- a/tools/llvmc/src/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
-##===- tools/llvmc/src/Makefile ----------------------------*- Makefile -*-===##
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open
-# Source License. See LICENSE.TXT for details.
-#
-##===----------------------------------------------------------------------===##
-
-LEVEL = ../../..
-LLVMC_BASED_DRIVER = llvmc
-BUILT_SOURCES = AutoGenerated.inc
-
-include $(LEVEL)/Makefile.common
diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp
index 14594cf..6c8dbad 100644
--- a/tools/lto/LTOCodeGenerator.cpp
+++ b/tools/lto/LTOCodeGenerator.cpp
@@ -23,6 +23,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/Passes.h"
+#include "llvm/Analysis/Verifier.h"
#include "llvm/Bitcode/ReaderWriter.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
@@ -31,19 +32,21 @@
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Target/TargetSelect.h"
+#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/MemoryBuffer.h"
-#include "llvm/Support/PassManagerBuilder.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/Signals.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/system_error.h"
#include "llvm/Config/config.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include <cstdlib>
#include <unistd.h>
#include <fcntl.h>
@@ -73,8 +76,7 @@ LTOCodeGenerator::LTOCodeGenerator()
_nativeObjectFile(NULL)
{
InitializeAllTargets();
- InitializeAllMCAsmInfos();
- InitializeAllMCSubtargetInfos();
+ InitializeAllTargetMCs();
InitializeAllAsmPrinters();
}
@@ -191,7 +193,7 @@ bool LTOCodeGenerator::compile_to_file(const char** name, std::string& errMsg)
bool genResult = false;
tool_output_file objFile(uniqueObjPath.c_str(), errMsg);
if (!errMsg.empty())
- return NULL;
+ return true;
genResult = this->generateObjectFile(objFile.os(), errMsg);
objFile.os().close();
if (objFile.os().has_error()) {
@@ -250,23 +252,25 @@ bool LTOCodeGenerator::determineTarget(std::string& errMsg)
// The relocation model is actually a static member of TargetMachine
// and needs to be set before the TargetMachine is instantiated.
+ Reloc::Model RelocModel = Reloc::Default;
switch( _codeModel ) {
case LTO_CODEGEN_PIC_MODEL_STATIC:
- TargetMachine::setRelocationModel(Reloc::Static);
+ RelocModel = Reloc::Static;
break;
case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
- TargetMachine::setRelocationModel(Reloc::PIC_);
+ RelocModel = Reloc::PIC_;
break;
case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
- TargetMachine::setRelocationModel(Reloc::DynamicNoPIC);
+ RelocModel = Reloc::DynamicNoPIC;
break;
}
- // construct LTModule, hand over ownership of module and target
+ // construct LTOModule, hand over ownership of module and target
SubtargetFeatures Features;
Features.getDefaultSubtargetFeatures(llvm::Triple(Triple));
std::string FeatureStr = Features.getString();
- _target = march->createTargetMachine(Triple, _mCpu, FeatureStr);
+ _target = march->createTargetMachine(Triple, _mCpu, FeatureStr,
+ RelocModel);
}
return false;
}
@@ -308,7 +312,7 @@ void LTOCodeGenerator::applyScopeRestrictions() {
passes.add(createVerifierPass());
// mark which symbols can not be internalized
- MCContext Context(*_target->getMCAsmInfo(), NULL);
+ MCContext Context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(), NULL);
Mangler mangler(Context, *_target->getTargetData());
std::vector<const char*> mustPreserveList;
SmallPtrSet<GlobalValue*, 8> asmUsed;
@@ -329,7 +333,7 @@ void LTOCodeGenerator::applyScopeRestrictions() {
if (LLVMCompilerUsed)
LLVMCompilerUsed->eraseFromParent();
- const llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(_context);
+ llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(_context);
std::vector<Constant*> asmUsed2;
for (SmallPtrSet<GlobalValue*, 16>::const_iterator i = asmUsed.begin(),
e = asmUsed.end(); i !=e; ++i) {
diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp
index dc99b94..4ba8985 100644
--- a/tools/lto/LTOModule.cpp
+++ b/tools/lto/LTOModule.cpp
@@ -27,6 +27,8 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetRegistry.h"
+#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/system_error.h"
#include "llvm/Target/Mangler.h"
#include "llvm/MC/MCAsmInfo.h"
@@ -38,10 +40,9 @@
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/SubtargetFeature.h"
-#include "llvm/Target/TargetAsmParser.h"
+#include "llvm/MC/MCTargetAsmParser.h"
#include "llvm/Target/TargetMachine.h"
-#include "llvm/Target/TargetRegistry.h"
-#include "llvm/Target/TargetSelect.h"
+#include "llvm/Target/TargetRegisterInfo.h"
using namespace llvm;
@@ -135,8 +136,7 @@ LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer,
static bool Initialized = false;
if (!Initialized) {
InitializeAllTargets();
- InitializeAllMCAsmInfos();
- InitializeAllMCSubtargetInfos();
+ InitializeAllTargetMCs();
InitializeAllAsmParsers();
Initialized = true;
}
@@ -165,7 +165,7 @@ LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer,
std::string CPU;
TargetMachine *target = march->createTargetMachine(Triple, CPU, FeatureStr);
LTOModule *Ret = new LTOModule(m.take(), target);
- bool Err = Ret->ParseSymbols();
+ bool Err = Ret->ParseSymbols(errMsg);
if (Err) {
delete Ret;
return NULL;
@@ -581,7 +581,8 @@ namespace {
markDefined(*Symbol);
}
virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {}
- virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size) {}
+ virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
+ unsigned ByteAlignment) {}
virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol,
uint64_t Size, unsigned ByteAlignment) {}
virtual void EmitBytes(StringRef Data, unsigned AddrSpace) {}
@@ -612,22 +613,30 @@ namespace {
};
}
-bool LTOModule::addAsmGlobalSymbols(MCContext &Context) {
+bool LTOModule::addAsmGlobalSymbols(MCContext &Context, std::string &errMsg) {
const std::string &inlineAsm = _module->getModuleInlineAsm();
+ if (inlineAsm.empty())
+ return false;
OwningPtr<RecordStreamer> Streamer(new RecordStreamer(Context));
MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(inlineAsm);
SourceMgr SrcMgr;
SrcMgr.AddNewSourceBuffer(Buffer, SMLoc());
- OwningPtr<MCAsmParser> Parser(createMCAsmParser(_target->getTarget(), SrcMgr,
+ OwningPtr<MCAsmParser> Parser(createMCAsmParser(SrcMgr,
Context, *Streamer,
*_target->getMCAsmInfo()));
OwningPtr<MCSubtargetInfo> STI(_target->getTarget().
createMCSubtargetInfo(_target->getTargetTriple(),
_target->getTargetCPU(),
_target->getTargetFeatureString()));
- OwningPtr<TargetAsmParser>
- TAP(_target->getTarget().createAsmParser(*STI, *Parser.get()));
+ OwningPtr<MCTargetAsmParser>
+ TAP(_target->getTarget().createMCAsmParser(*STI, *Parser.get()));
+ if (!TAP) {
+ errMsg = "target " + std::string(_target->getTarget().getName()) +
+ " does not define AsmParser.";
+ return true;
+ }
+
Parser->setTargetParser(*TAP);
int Res = Parser->Run(false);
if (Res)
@@ -660,9 +669,9 @@ static bool isAliasToDeclaration(const GlobalAlias &V) {
return isDeclaration(*V.getAliasedGlobal());
}
-bool LTOModule::ParseSymbols() {
+bool LTOModule::ParseSymbols(std::string &errMsg) {
// Use mangler to add GlobalPrefix to names to match linker names.
- MCContext Context(*_target->getMCAsmInfo(), NULL);
+ MCContext Context(*_target->getMCAsmInfo(), *_target->getRegisterInfo(),NULL);
Mangler mangler(Context, *_target->getTargetData());
// add functions
@@ -683,7 +692,7 @@ bool LTOModule::ParseSymbols() {
}
// add asm globals
- if (addAsmGlobalSymbols(Context))
+ if (addAsmGlobalSymbols(Context, errMsg))
return true;
// add aliases
diff --git a/tools/lto/LTOModule.h b/tools/lto/LTOModule.h
index 0b64a90..ca08aea 100644
--- a/tools/lto/LTOModule.h
+++ b/tools/lto/LTOModule.h
@@ -76,7 +76,7 @@ struct LTOModule {
private:
LTOModule(llvm::Module* m, llvm::TargetMachine* t);
- bool ParseSymbols();
+ bool ParseSymbols(std::string &errMsg);
void addDefinedSymbol(llvm::GlobalValue* def,
llvm::Mangler& mangler,
bool isFunction);
@@ -86,7 +86,8 @@ private:
llvm::Mangler &mangler);
void addDefinedDataSymbol(llvm::GlobalValue* v,
llvm::Mangler &mangler);
- bool addAsmGlobalSymbols(llvm::MCContext &Context);
+ bool addAsmGlobalSymbols(llvm::MCContext &Context,
+ std::string &errMsg);
void addAsmGlobalSymbol(const char *,
lto_symbol_attributes scope);
void addAsmGlobalSymbolUndef(const char *);
diff --git a/tools/macho-dump/macho-dump.cpp b/tools/macho-dump/macho-dump.cpp
index f324259..2b22c3b 100644
--- a/tools/macho-dump/macho-dump.cpp
+++ b/tools/macho-dump/macho-dump.cpp
@@ -310,6 +310,29 @@ static int DumpDysymtabCommand(MachOObject &Obj,
return Res;
}
+static int DumpLinkeditDataCommand(MachOObject &Obj,
+ const MachOObject::LoadCommandInfo &LCI) {
+ InMemoryStruct<macho::LinkeditDataLoadCommand> LLC;
+ Obj.ReadLinkeditDataLoadCommand(LCI, LLC);
+ if (!LLC)
+ return Error("unable to read segment load command");
+
+ outs() << " ('dataoff', " << LLC->DataOffset << ")\n"
+ << " ('datasize', " << LLC->DataSize << ")\n"
+ << " ('_addresses', [\n";
+
+ SmallVector<uint64_t, 8> Addresses;
+ Obj.ReadULEB128s(LLC->DataOffset, Addresses);
+ for (unsigned i = 0, e = Addresses.size(); i != e; ++i)
+ outs() << " # Address " << i << '\n'
+ << " ('address', " << format("0x%x", Addresses[i]) << "),\n";
+
+ outs() << " ])\n";
+
+ return 0;
+}
+
+
static int DumpLoadCommand(MachOObject &Obj, unsigned Index) {
const MachOObject::LoadCommandInfo &LCI = Obj.getLoadCommandInfo(Index);
int Res = 0;
@@ -330,6 +353,11 @@ static int DumpLoadCommand(MachOObject &Obj, unsigned Index) {
case macho::LCT_Dysymtab:
Res = DumpDysymtabCommand(Obj, LCI);
break;
+ case macho::LCT_CodeSignature:
+ case macho::LCT_SegmentSplitInfo:
+ case macho::LCT_FunctionStarts:
+ Res = DumpLinkeditDataCommand(Obj, LCI);
+ break;
default:
Warning("unknown load command: " + Twine(LCI.Command.Type));
break;
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp
index aa375c5..ffd2c21 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -35,11 +35,11 @@
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
-#include "llvm/Support/PassManagerBuilder.h"
#include "llvm/Support/SystemUtils.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/LinkAllPasses.h"
#include "llvm/LinkAllVMCore.h"
+#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include <memory>
#include <algorithm>
using namespace llvm;
@@ -431,8 +431,6 @@ static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM,
static void AddStandardCompilePasses(PassManagerBase &PM) {
PM.add(createVerifierPass()); // Verify that input is correct
- addPass(PM, createLowerSetJmpPass()); // Lower llvm.setjmp/.longjmp
-
// If the -strip-debug command line option was specified, do it.
if (StripDebug)
addPass(PM, createStripSymbolsPass(true));
OpenPOWER on IntegriCloud