aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-05-29 02:49:00 -0700
committerStephen Hines <srhines@google.com>2014-05-29 02:49:00 -0700
commitdce4a407a24b04eebc6a376f8e62b41aaa7b071f (patch)
treedcebc53f2b182f145a2e659393bf9a0472cedf23 /tools
parent220b921aed042f9e520c26cffd8282a94c66c3d5 (diff)
downloadexternal_llvm-dce4a407a24b04eebc6a376f8e62b41aaa7b071f.zip
external_llvm-dce4a407a24b04eebc6a376f8e62b41aaa7b071f.tar.gz
external_llvm-dce4a407a24b04eebc6a376f8e62b41aaa7b071f.tar.bz2
Update LLVM for 3.5 rebase (r209712).
Change-Id: I149556c940fb7dc92d075273c87ff584f400941f
Diffstat (limited to 'tools')
-rw-r--r--tools/bugpoint/BugDriver.cpp14
-rw-r--r--tools/bugpoint/BugDriver.h6
-rw-r--r--tools/bugpoint/CrashDebugger.cpp9
-rw-r--r--tools/bugpoint/ExecutionDriver.cpp8
-rw-r--r--tools/bugpoint/ExtractFunction.cpp24
-rw-r--r--tools/bugpoint/FindBugs.cpp2
-rw-r--r--tools/bugpoint/Miscompilation.cpp6
-rw-r--r--tools/bugpoint/OptimizerDriver.cpp16
-rw-r--r--tools/bugpoint/ToolRunner.cpp37
-rw-r--r--tools/bugpoint/ToolRunner.h16
-rw-r--r--tools/bugpoint/bugpoint.cpp2
-rw-r--r--tools/llc/Android.mk3
-rw-r--r--tools/llc/llc.cpp68
-rw-r--r--tools/lli/RemoteMemoryManager.cpp13
-rw-r--r--tools/lli/RemoteMemoryManager.h2
-rw-r--r--tools/lli/RemoteTarget.cpp4
-rw-r--r--tools/lli/RemoteTargetExternal.cpp2
-rw-r--r--tools/lli/Unix/RPCChannel.inc4
-rw-r--r--tools/lli/lli.cpp17
-rw-r--r--tools/llvm-ar/llvm-ar.cpp6
-rw-r--r--tools/llvm-as/llvm-as.cpp3
-rw-r--r--tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp34
-rw-r--r--tools/llvm-c-test/object.c5
-rw-r--r--tools/llvm-config/CMakeLists.txt3
-rw-r--r--tools/llvm-cov/llvm-cov.cpp24
-rw-r--r--tools/llvm-diff/DiffLog.cpp4
-rw-r--r--tools/llvm-diff/DifferenceEngine.h2
-rw-r--r--tools/llvm-dis/llvm-dis.cpp5
-rw-r--r--tools/llvm-dwarfdump/llvm-dwarfdump.cpp54
-rw-r--r--tools/llvm-extract/llvm-extract.cpp25
-rw-r--r--tools/llvm-link/llvm-link.cpp9
-rw-r--r--tools/llvm-lto/llvm-lto.cpp30
-rw-r--r--tools/llvm-mc/Disassembler.cpp22
-rw-r--r--tools/llvm-mc/llvm-mc.cpp46
-rw-r--r--tools/llvm-nm/llvm-nm.cpp60
-rw-r--r--tools/llvm-objdump/MachODump.cpp12
-rw-r--r--tools/llvm-objdump/llvm-objdump.cpp87
-rw-r--r--tools/llvm-profdata/llvm-profdata.cpp13
-rw-r--r--tools/llvm-readobj/ARMAttributeParser.cpp102
-rw-r--r--tools/llvm-readobj/ARMEHABIPrinter.h13
-rw-r--r--tools/llvm-readobj/CMakeLists.txt9
-rw-r--r--tools/llvm-readobj/COFFDumper.cpp464
-rw-r--r--tools/llvm-readobj/ELFDumper.cpp94
-rw-r--r--tools/llvm-readobj/StreamWriter.h29
-rw-r--r--tools/llvm-readobj/Win64EHDumper.cpp328
-rw-r--r--tools/llvm-readobj/Win64EHDumper.h62
-rw-r--r--tools/llvm-rtdyld/llvm-rtdyld.cpp38
-rw-r--r--tools/llvm-shlib/Makefile4
-rw-r--r--tools/llvm-size/llvm-size.cpp2
-rw-r--r--tools/llvm-stress/llvm-stress.cpp6
-rw-r--r--tools/llvm-symbolizer/LLVMSymbolize.cpp79
-rw-r--r--tools/llvm-symbolizer/LLVMSymbolize.h12
-rw-r--r--tools/llvm-symbolizer/llvm-symbolizer.cpp15
-rw-r--r--tools/lto/lto.cpp169
-rw-r--r--tools/obj2yaml/CMakeLists.txt2
-rw-r--r--tools/obj2yaml/Error.cpp54
-rw-r--r--tools/obj2yaml/Error.h42
-rw-r--r--tools/obj2yaml/coff2yaml.cpp5
-rw-r--r--tools/obj2yaml/elf2yaml.cpp290
-rw-r--r--tools/obj2yaml/obj2yaml.cpp45
-rw-r--r--tools/obj2yaml/obj2yaml.h7
-rw-r--r--tools/opt/NewPMDriver.cpp20
-rw-r--r--tools/opt/PassRegistry.def51
-rw-r--r--tools/opt/Passes.cpp145
-rw-r--r--tools/opt/PrintSCC.cpp6
-rw-r--r--tools/opt/opt.cpp30
-rw-r--r--tools/yaml2obj/yaml2elf.cpp237
-rw-r--r--tools/yaml2obj/yaml2obj.cpp34
68 files changed, 2008 insertions, 1083 deletions
diff --git a/tools/bugpoint/BugDriver.cpp b/tools/bugpoint/BugDriver.cpp
index 2d1b903..cecccbe 100644
--- a/tools/bugpoint/BugDriver.cpp
+++ b/tools/bugpoint/BugDriver.cpp
@@ -70,12 +70,16 @@ BugDriver::BugDriver(const char *toolname, bool find_bugs,
unsigned timeout, unsigned memlimit, bool use_valgrind,
LLVMContext& ctxt)
: Context(ctxt), ToolName(toolname), ReferenceOutputFile(OutputFile),
- Program(0), Interpreter(0), SafeInterpreter(0), gcc(0),
- run_find_bugs(find_bugs), Timeout(timeout),
+ Program(nullptr), Interpreter(nullptr), SafeInterpreter(nullptr),
+ gcc(nullptr), run_find_bugs(find_bugs), Timeout(timeout),
MemoryLimit(memlimit), UseValgrind(use_valgrind) {}
BugDriver::~BugDriver() {
delete Program;
+ if (Interpreter != SafeInterpreter)
+ delete Interpreter;
+ delete SafeInterpreter;
+ delete gcc;
}
@@ -112,18 +116,18 @@ Module *llvm::ParseInputFile(const std::string &Filename,
// parsed), and false on success.
//
bool BugDriver::addSources(const std::vector<std::string> &Filenames) {
- assert(Program == 0 && "Cannot call addSources multiple times!");
+ assert(!Program && "Cannot call addSources multiple times!");
assert(!Filenames.empty() && "Must specify at least on input filename!");
// Load the first input file.
Program = ParseInputFile(Filenames[0], Context);
- if (Program == 0) return true;
+ if (!Program) return true;
outs() << "Read input file : '" << Filenames[0] << "'\n";
for (unsigned i = 1, e = Filenames.size(); i != e; ++i) {
std::unique_ptr<Module> M(ParseInputFile(Filenames[i], Context));
- if (M.get() == 0) return true;
+ if (!M.get()) return true;
outs() << "Linking in input file: '" << Filenames[i] << "'\n";
std::string ErrorMessage;
diff --git a/tools/bugpoint/BugDriver.h b/tools/bugpoint/BugDriver.h
index c01bbe5..3169d29 100644
--- a/tools/bugpoint/BugDriver.h
+++ b/tools/bugpoint/BugDriver.h
@@ -202,7 +202,7 @@ public:
const std::string &BitcodeFile = "",
const std::string &SharedObj = "",
bool RemoveBitcode = false,
- std::string *Error = 0) const;
+ std::string *Error = nullptr) const;
/// EmitProgressBitcode - This function is used to output M to a file named
/// "bugpoint-ID.bc".
@@ -244,7 +244,7 @@ public:
/// this method will never return null.
Module *runPassesOn(Module *M, const std::vector<std::string> &Passes,
bool AutoDebugCrashes = false, unsigned NumExtraArgs = 0,
- const char * const *ExtraArgs = NULL);
+ const char * const *ExtraArgs = nullptr);
/// runPasses - Run the specified passes on Program, outputting a bitcode
/// file and writting the filename into OutputFile if successful. If the
@@ -259,7 +259,7 @@ public:
const std::vector<std::string> &PassesToRun,
std::string &OutputFilename, bool DeleteOutput = false,
bool Quiet = false, unsigned NumExtraArgs = 0,
- const char * const *ExtraArgs = NULL) const;
+ const char * const *ExtraArgs = nullptr) const;
/// runManyPasses - Take the specified pass list and create different
/// combinations of passes to compile the program with. Compile the program with
diff --git a/tools/bugpoint/CrashDebugger.cpp b/tools/bugpoint/CrashDebugger.cpp
index bdaa6c9..8bd61b3 100644
--- a/tools/bugpoint/CrashDebugger.cpp
+++ b/tools/bugpoint/CrashDebugger.cpp
@@ -63,7 +63,7 @@ ReducePassList::doTest(std::vector<std::string> &Prefix,
std::vector<std::string> &Suffix,
std::string &Error) {
std::string PrefixOutput;
- Module *OrigProgram = 0;
+ Module *OrigProgram = nullptr;
if (!Prefix.empty()) {
outs() << "Checking to see if these passes crash: "
<< getPassesString(Prefix) << ": ";
@@ -73,7 +73,7 @@ ReducePassList::doTest(std::vector<std::string> &Prefix,
OrigProgram = BD.Program;
BD.Program = ParseInputFile(PrefixOutput, BD.getContext());
- if (BD.Program == 0) {
+ if (BD.Program == nullptr) {
errs() << BD.getToolName() << ": Error reading bitcode file '"
<< PrefixOutput << "'!\n";
exit(1);
@@ -149,7 +149,7 @@ ReduceCrashingGlobalVariables::TestGlobalVariables(
for (Module::global_iterator I = M->global_begin(), E = M->global_end();
I != E; ++I)
if (I->hasInitializer() && !GVSet.count(I)) {
- I->setInitializer(0);
+ I->setInitializer(nullptr);
I->setLinkage(GlobalValue::ExternalLinkage);
}
@@ -410,6 +410,7 @@ bool ReduceCrashingInstructions::TestInsts(std::vector<const Instruction*>
// Verify that this is still valid.
PassManager Passes;
Passes.add(createVerifierPass());
+ Passes.add(createDebugInfoVerifierPass());
Passes.run(*M);
// Try running on the hacked up program...
@@ -446,7 +447,7 @@ static bool DebugACrash(BugDriver &BD,
for (Module::global_iterator I = M->global_begin(), E = M->global_end();
I != E; ++I)
if (I->hasInitializer()) {
- I->setInitializer(0);
+ I->setInitializer(nullptr);
I->setLinkage(GlobalValue::ExternalLinkage);
DeletedInit = true;
}
diff --git a/tools/bugpoint/ExecutionDriver.cpp b/tools/bugpoint/ExecutionDriver.cpp
index 609de03..5ed7d2c 100644
--- a/tools/bugpoint/ExecutionDriver.cpp
+++ b/tools/bugpoint/ExecutionDriver.cpp
@@ -145,7 +145,7 @@ bool BugDriver::initializeExecutionEnvironment() {
// Create an instance of the AbstractInterpreter interface as specified on
// the command line
- SafeInterpreter = 0;
+ SafeInterpreter = nullptr;
std::string Message;
switch (InterpreterSel) {
@@ -256,7 +256,7 @@ bool BugDriver::initializeExecutionEnvironment() {
if (!gcc) { outs() << Message << "\nExiting.\n"; exit(1); }
// If there was an error creating the selected interpreter, quit with error.
- return Interpreter == 0;
+ return Interpreter == nullptr;
}
/// compileProgram - Try to compile the specified module, returning false and
@@ -298,7 +298,7 @@ std::string BugDriver::executeProgram(const Module *Program,
const std::string &SharedObj,
AbstractInterpreter *AI,
std::string *Error) const {
- if (AI == 0) AI = Interpreter;
+ if (!AI) AI = Interpreter;
assert(AI && "Interpreter should have been created already!");
bool CreatedBitcode = false;
if (BitcodeFile.empty()) {
@@ -445,7 +445,7 @@ bool BugDriver::diffProgram(const Module *Program,
std::string *ErrMsg) const {
// Execute the program, generating an output file...
std::string Output(
- executeProgram(Program, "", BitcodeFile, SharedObject, 0, ErrMsg));
+ executeProgram(Program, "", BitcodeFile, SharedObject, nullptr, ErrMsg));
if (!ErrMsg->empty())
return false;
diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp
index 8bcae8a..38cdf24 100644
--- a/tools/bugpoint/ExtractFunction.cpp
+++ b/tools/bugpoint/ExtractFunction.cpp
@@ -34,6 +34,8 @@
#include <set>
using namespace llvm;
+#define DEBUG_TYPE "bugpoint"
+
namespace llvm {
bool DisableSimplifyCFG = false;
extern cl::opt<std::string> OutputPrefix;
@@ -49,7 +51,7 @@ namespace {
Function* globalInitUsesExternalBA(GlobalVariable* GV) {
if (!GV->hasInitializer())
- return 0;
+ return nullptr;
Constant *I = GV->getInitializer();
@@ -76,7 +78,7 @@ namespace {
Todo.push_back(C);
}
}
- return 0;
+ return nullptr;
}
} // end anonymous namespace
@@ -148,7 +150,7 @@ Module *BugDriver::performFinalCleanups(Module *M, bool MayModifySemantics) {
CleanupPasses.push_back("deadargelim");
Module *New = runPassesOn(M, CleanupPasses);
- if (New == 0) {
+ if (!New) {
errs() << "Final cleanups failed. Sorry. :( Please report a bug!\n";
return M;
}
@@ -165,11 +167,11 @@ Module *BugDriver::ExtractLoop(Module *M) {
LoopExtractPasses.push_back("loop-extract-single");
Module *NewM = runPassesOn(M, LoopExtractPasses);
- if (NewM == 0) {
+ if (!NewM) {
outs() << "*** Loop extraction failed: ";
EmitProgressBitcode(M, "loopextraction", true);
outs() << "*** Sorry. :( Please report a bug!\n";
- return 0;
+ return nullptr;
}
// Check to see if we created any new functions. If not, no loops were
@@ -178,7 +180,7 @@ Module *BugDriver::ExtractLoop(Module *M) {
static unsigned NumExtracted = 32;
if (M->size() == NewM->size() || --NumExtracted == 0) {
delete NewM;
- return 0;
+ return nullptr;
} else {
assert(M->size() < NewM->size() && "Loop extract removed functions?");
Module::iterator MI = NewM->begin();
@@ -335,10 +337,10 @@ llvm::SplitFunctionsOutOfModule(Module *M,
<< "' and from test function '" << TestFn->getName() << "'.\n";
exit(1);
}
- I->setInitializer(0); // Delete the initializer to make it external
+ I->setInitializer(nullptr); // Delete the initializer to make it external
} else {
// If we keep it in the safe module, then delete it in the test module
- GV->setInitializer(0);
+ GV->setInitializer(nullptr);
}
}
@@ -370,7 +372,7 @@ Module *BugDriver::ExtractMappedBlocksFromModule(const
outs() << "*** Basic Block extraction failed!\n";
errs() << "Error creating temporary file: " << EC.message() << "\n";
EmitProgressBitcode(M, "basicblockextractfail", true);
- return 0;
+ return nullptr;
}
sys::RemoveFileOnSignal(Filename);
@@ -389,7 +391,7 @@ Module *BugDriver::ExtractMappedBlocksFromModule(const
errs() << "Error writing list of blocks to not extract\n";
EmitProgressBitcode(M, "basicblockextractfail", true);
BlocksToNotExtractFile.os().clear_error();
- return 0;
+ return nullptr;
}
BlocksToNotExtractFile.keep();
@@ -403,7 +405,7 @@ Module *BugDriver::ExtractMappedBlocksFromModule(const
sys::fs::remove(Filename.c_str());
- if (Ret == 0) {
+ if (!Ret) {
outs() << "*** Basic Block extraction failed, please report a bug!\n";
EmitProgressBitcode(M, "basicblockextractfail", true);
}
diff --git a/tools/bugpoint/FindBugs.cpp b/tools/bugpoint/FindBugs.cpp
index e2941f6..a0c859b 100644
--- a/tools/bugpoint/FindBugs.cpp
+++ b/tools/bugpoint/FindBugs.cpp
@@ -45,7 +45,7 @@ bool BugDriver::runManyPasses(const std::vector<std::string> &AllPasses,
return false;
}
- srand(time(NULL));
+ srand(time(nullptr));
unsigned num = 1;
while(1) {
diff --git a/tools/bugpoint/Miscompilation.cpp b/tools/bugpoint/Miscompilation.cpp
index fecae60..f5936ac 100644
--- a/tools/bugpoint/Miscompilation.cpp
+++ b/tools/bugpoint/Miscompilation.cpp
@@ -235,7 +235,7 @@ static Module *TestMergedProgram(const BugDriver &BD, Module *M1, Module *M2,
if (!Error.empty()) {
// Delete the linked module
delete M1;
- return NULL;
+ return nullptr;
}
return M1;
}
@@ -592,7 +592,7 @@ static bool ExtractBlocks(BugDriver &BD,
MiscompiledFunctions,
VMap);
Module *Extracted = BD.ExtractMappedBlocksFromModule(Blocks, ToExtract);
- if (Extracted == 0) {
+ if (!Extracted) {
// Weird, extraction should have worked.
errs() << "Nondeterministic problem extracting blocks??\n";
delete ProgClone;
@@ -845,7 +845,7 @@ static void CleanupAndPrepareModules(BugDriver &BD, Module *&Test,
Safe->getOrInsertFunction("getPointerToNamedFunction",
Type::getInt8PtrTy(Safe->getContext()),
Type::getInt8PtrTy(Safe->getContext()),
- (Type *)0);
+ (Type *)nullptr);
// Use the function we just added to get addresses of functions we need.
for (Module::iterator F = Safe->begin(), E = Safe->end(); F != E; ++F) {
diff --git a/tools/bugpoint/OptimizerDriver.cpp b/tools/bugpoint/OptimizerDriver.cpp
index f91f493..b2722e6 100644
--- a/tools/bugpoint/OptimizerDriver.cpp
+++ b/tools/bugpoint/OptimizerDriver.cpp
@@ -36,6 +36,8 @@
using namespace llvm;
+#define DEBUG_TYPE "bugpoint"
+
namespace llvm {
extern cl::opt<std::string> OutputPrefix;
}
@@ -194,7 +196,7 @@ bool BugDriver::runPasses(Module *Program,
Args.push_back(InputFilename.c_str());
for (unsigned i = 0; i < NumExtraArgs; ++i)
Args.push_back(*ExtraArgs);
- Args.push_back(0);
+ Args.push_back(nullptr);
DEBUG(errs() << "\nAbout to run:\t";
for (unsigned i = 0, e = Args.size()-1; i != e; ++i)
@@ -210,12 +212,12 @@ bool BugDriver::runPasses(Module *Program,
// Redirect stdout and stderr to nowhere if SilencePasses is given
StringRef Nowhere;
- const StringRef *Redirects[3] = {0, &Nowhere, &Nowhere};
+ const StringRef *Redirects[3] = {nullptr, &Nowhere, &Nowhere};
std::string ErrMsg;
- int result = sys::ExecuteAndWait(Prog, Args.data(), 0,
- (SilencePasses ? Redirects : 0), Timeout,
- MemoryLimit, &ErrMsg);
+ int result = sys::ExecuteAndWait(Prog, Args.data(), nullptr,
+ (SilencePasses ? Redirects : nullptr),
+ Timeout, MemoryLimit, &ErrMsg);
// If we are supposed to delete the bitcode file or if the passes crashed,
// remove it now. This may fail if the file was never created, but that's ok.
@@ -262,11 +264,11 @@ Module *BugDriver::runPassesOn(Module *M,
EmitProgressBitcode(M, "pass-error", false);
exit(debugOptimizerCrash());
}
- return 0;
+ return nullptr;
}
Module *Ret = ParseInputFile(BitcodeResult, Context);
- if (Ret == 0) {
+ if (!Ret) {
errs() << getToolName() << ": Error reading bitcode file '"
<< BitcodeResult << "'!\n";
exit(1);
diff --git a/tools/bugpoint/ToolRunner.cpp b/tools/bugpoint/ToolRunner.cpp
index f0fb4bf..c481b03 100644
--- a/tools/bugpoint/ToolRunner.cpp
+++ b/tools/bugpoint/ToolRunner.cpp
@@ -11,7 +11,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "toolrunner"
#include "ToolRunner.h"
#include "llvm/Config/config.h" // for HAVE_LINK_R
#include "llvm/Support/CommandLine.h"
@@ -24,6 +23,8 @@
#include <sstream>
using namespace llvm;
+#define DEBUG_TYPE "toolrunner"
+
namespace llvm {
cl::opt<bool>
SaveTemps("save-temps", cl::init(false), cl::desc("Save temporary files"));
@@ -61,7 +62,7 @@ static int RunProgramWithTimeout(StringRef ProgramPath,
StringRef StdErrFile,
unsigned NumSeconds = 0,
unsigned MemoryLimit = 0,
- std::string *ErrMsg = 0) {
+ std::string *ErrMsg = nullptr) {
const StringRef *Redirects[3] = { &StdInFile, &StdOutFile, &StdErrFile };
#if 0 // For debug purposes
@@ -73,7 +74,7 @@ static int RunProgramWithTimeout(StringRef ProgramPath,
}
#endif
- return sys::ExecuteAndWait(ProgramPath, Args, 0, Redirects,
+ return sys::ExecuteAndWait(ProgramPath, Args, nullptr, Redirects,
NumSeconds, MemoryLimit, ErrMsg);
}
@@ -102,7 +103,7 @@ static int RunProgramRemotelyWithTimeout(StringRef RemoteClientPath,
#endif
// Run the program remotely with the remote client
- int ReturnCode = sys::ExecuteAndWait(RemoteClientPath, Args, 0,
+ int ReturnCode = sys::ExecuteAndWait(RemoteClientPath, Args, nullptr,
Redirects, NumSeconds, MemoryLimit);
// Has the remote client fail?
@@ -218,7 +219,7 @@ int LLI::ExecuteProgram(const std::string &Bitcode,
// Add optional parameters to the running program from Argv
for (unsigned i=0, e = Args.size(); i != e; ++i)
LLIArgs.push_back(Args[i].c_str());
- LLIArgs.push_back(0);
+ LLIArgs.push_back(nullptr);
outs() << "<lli>"; outs().flush();
DEBUG(errs() << "\nAbout to run:\t";
@@ -276,7 +277,7 @@ AbstractInterpreter *AbstractInterpreter::createLLI(const char *Argv0,
}
Message = "Cannot find `lli' in executable directory!\n";
- return 0;
+ return nullptr;
}
//===---------------------------------------------------------------------===//
@@ -327,7 +328,7 @@ void CustomCompiler::compileProgram(const std::string &Bitcode,
for (std::size_t i = 0; i < CompilerArgs.size(); ++i)
ProgramArgs.push_back(CompilerArgs.at(i).c_str());
ProgramArgs.push_back(Bitcode.c_str());
- ProgramArgs.push_back(0);
+ ProgramArgs.push_back(nullptr);
// Add optional parameters to the running program from Argv
for (unsigned i = 0, e = CompilerArgs.size(); i != e; ++i)
@@ -384,7 +385,7 @@ int CustomExecutor::ExecuteProgram(const std::string &Bitcode,
for (std::size_t i = 0; i < ExecutorArgs.size(); ++i)
ProgramArgs.push_back(ExecutorArgs.at(i).c_str());
ProgramArgs.push_back(Bitcode.c_str());
- ProgramArgs.push_back(0);
+ ProgramArgs.push_back(nullptr);
// Add optional parameters to the running program from Argv
for (unsigned i = 0, e = Args.size(); i != e; ++i)
@@ -447,7 +448,7 @@ AbstractInterpreter *AbstractInterpreter::createCustomCompiler(
std::vector<std::string> Args;
lexCommand(Message, CompileCommandLine, CmdPath, Args);
if (CmdPath.empty())
- return 0;
+ return nullptr;
return new CustomCompiler(CmdPath, Args);
}
@@ -463,7 +464,7 @@ AbstractInterpreter *AbstractInterpreter::createCustomExecutor(
std::vector<std::string> Args;
lexCommand(Message, ExecCommandLine, CmdPath, Args);
if (CmdPath.empty())
- return 0;
+ return nullptr;
return new CustomExecutor(CmdPath, Args);
}
@@ -498,7 +499,7 @@ GCC::FileType LLC::OutputCode(const std::string &Bitcode,
if (UseIntegratedAssembler)
LLCArgs.push_back("-filetype=obj");
- LLCArgs.push_back (0);
+ LLCArgs.push_back (nullptr);
outs() << (UseIntegratedAssembler ? "<llc-ia>" : "<llc>");
outs().flush();
@@ -558,7 +559,7 @@ LLC *AbstractInterpreter::createLLC(const char *Argv0,
PrependMainExecutablePath("llc", Argv0, (void *)(intptr_t) & createLLC);
if (LLCPath.empty()) {
Message = "Cannot find `llc' in executable directory!\n";
- return 0;
+ return nullptr;
}
GCC *gcc = GCC::create(Message, GCCBinary, GCCArgs);
@@ -624,7 +625,7 @@ int JIT::ExecuteProgram(const std::string &Bitcode,
// Add optional parameters to the running program from Argv
for (unsigned i=0, e = Args.size(); i != e; ++i)
JITArgs.push_back(Args[i].c_str());
- JITArgs.push_back(0);
+ JITArgs.push_back(nullptr);
outs() << "<jit>"; outs().flush();
DEBUG(errs() << "\nAbout to run:\t";
@@ -650,7 +651,7 @@ AbstractInterpreter *AbstractInterpreter::createJIT(const char *Argv0,
}
Message = "Cannot find `lli' in executable directory!\n";
- return 0;
+ return nullptr;
}
//===---------------------------------------------------------------------===//
@@ -736,7 +737,7 @@ int GCC::ExecuteProgram(const std::string &ProgramFile,
#endif
if (TargetTriple.getArch() == Triple::sparc)
GCCArgs.push_back("-mcpu=v9");
- GCCArgs.push_back(0); // NULL terminator
+ GCCArgs.push_back(nullptr); // NULL terminator
outs() << "<gcc>"; outs().flush();
DEBUG(errs() << "\nAbout to run:\t";
@@ -785,7 +786,7 @@ int GCC::ExecuteProgram(const std::string &ProgramFile,
// Add optional parameters to the running program from Argv
for (unsigned i = 0, e = Args.size(); i != e; ++i)
ProgramArgs.push_back(Args[i].c_str());
- ProgramArgs.push_back(0); // NULL terminator
+ ProgramArgs.push_back(nullptr); // NULL terminator
// Now that we have a binary, run it!
outs() << "<program>"; outs().flush();
@@ -884,7 +885,7 @@ int GCC::MakeSharedObject(const std::string &InputFile, FileType fileType,
// command line, so this should be safe.
for (unsigned i = 0, e = ArgsForGCC.size(); i != e; ++i)
GCCArgs.push_back(ArgsForGCC[i].c_str());
- GCCArgs.push_back(0); // NULL terminator
+ GCCArgs.push_back(nullptr); // NULL terminator
@@ -909,7 +910,7 @@ GCC *GCC::create(std::string &Message,
std::string GCCPath = sys::FindProgramByName(GCCBinary);
if (GCCPath.empty()) {
Message = "Cannot find `"+ GCCBinary +"' in PATH!\n";
- return 0;
+ return nullptr;
}
std::string RemoteClientPath;
diff --git a/tools/bugpoint/ToolRunner.h b/tools/bugpoint/ToolRunner.h
index 38a5835..6e7b95c 100644
--- a/tools/bugpoint/ToolRunner.h
+++ b/tools/bugpoint/ToolRunner.h
@@ -63,7 +63,7 @@ public:
FileType fileType,
const std::string &InputFile,
const std::string &OutputFile,
- std::string *Error = 0,
+ std::string *Error = nullptr,
const std::vector<std::string> &GCCArgs =
std::vector<std::string>(),
unsigned Timeout = 0,
@@ -89,15 +89,17 @@ class AbstractInterpreter {
public:
static LLC *createLLC(const char *Argv0, std::string &Message,
const std::string &GCCBinary,
- const std::vector<std::string> *Args = 0,
- const std::vector<std::string> *GCCArgs = 0,
+ const std::vector<std::string> *Args = nullptr,
+ const std::vector<std::string> *GCCArgs = nullptr,
bool UseIntegratedAssembler = false);
- static AbstractInterpreter* createLLI(const char *Argv0, std::string &Message,
- const std::vector<std::string> *Args=0);
+ static AbstractInterpreter*
+ createLLI(const char *Argv0, std::string &Message,
+ const std::vector<std::string> *Args = nullptr);
- static AbstractInterpreter* createJIT(const char *Argv0, std::string &Message,
- const std::vector<std::string> *Args=0);
+ static AbstractInterpreter*
+ createJIT(const char *Argv0, std::string &Message,
+ const std::vector<std::string> *Args = nullptr);
static AbstractInterpreter*
createCustomCompiler(std::string &Message,
diff --git a/tools/bugpoint/bugpoint.cpp b/tools/bugpoint/bugpoint.cpp
index 5c03b41..c7dae0f 100644
--- a/tools/bugpoint/bugpoint.cpp
+++ b/tools/bugpoint/bugpoint.cpp
@@ -99,7 +99,7 @@ namespace {
class AddToDriver : public FunctionPassManager {
BugDriver &D;
public:
- AddToDriver(BugDriver &_D) : FunctionPassManager(0), D(_D) {}
+ AddToDriver(BugDriver &_D) : FunctionPassManager(nullptr), D(_D) {}
void add(Pass *P) override {
const void *ID = P->getPassID();
diff --git a/tools/llc/Android.mk b/tools/llc/Android.mk
index 391ba39..f9c87fe 100644
--- a/tools/llc/Android.mk
+++ b/tools/llc/Android.mk
@@ -56,7 +56,8 @@ llvm_llc_STATIC_LIBRARIES := \
libLLVMAnalysis \
libLLVMTarget \
libLLVMCore \
- libLLVMSupport
+ libLLVMSupport \
+ libLLVMObject
llvm_llc_arm64_STATIC_LIBRARIES := \
libLLVMARM64Info \
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp
index 8fbdc49..09ff461 100644
--- a/tools/llc/llc.cpp
+++ b/tools/llc/llc.cpp
@@ -28,6 +28,7 @@
#include "llvm/PassManager.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/ManagedStatic.h"
@@ -74,15 +75,24 @@ OptLevel("O",
static cl::opt<std::string>
TargetTriple("mtriple", cl::desc("Override target triple for module"));
-cl::opt<bool> NoVerify("disable-verify", cl::Hidden,
- cl::desc("Do not verify input module"));
+static cl::opt<bool> NoVerify("disable-verify", cl::Hidden,
+ cl::desc("Do not verify input module"));
-cl::opt<bool>
-DisableSimplifyLibCalls("disable-simplify-libcalls",
- cl::desc("Disable simplify-libcalls"),
- cl::init(false));
+static cl::opt<bool> DisableSimplifyLibCalls("disable-simplify-libcalls",
+ cl::desc("Disable simplify-libcalls"));
-static int compileModule(char**, LLVMContext&);
+static cl::opt<bool> ShowMCEncoding("show-mc-encoding", cl::Hidden,
+ cl::desc("Show encoding in .s output"));
+
+static cl::opt<bool> EnableDwarfDirectory(
+ "enable-dwarf-directory", cl::Hidden,
+ cl::desc("Use .file directives with an explicit directory."));
+
+static cl::opt<bool> AsmVerbose("asm-verbose",
+ cl::desc("Add comments to directives."),
+ cl::init(true));
+
+static int compileModule(char **, LLVMContext &);
// GetFileNameRoot - Helper function to get the basename of a filename.
static inline std::string
@@ -157,7 +167,7 @@ static tool_output_file *GetOutputStream(const char *TargetName,
if (!error.empty()) {
errs() << error << '\n';
delete FDOut;
- return 0;
+ return nullptr;
}
return FDOut;
@@ -207,17 +217,23 @@ static int compileModule(char **argv, LLVMContext &Context) {
// Load the module to be compiled...
SMDiagnostic Err;
std::unique_ptr<Module> M;
- Module *mod = 0;
+ Module *mod = nullptr;
Triple TheTriple;
bool SkipModule = MCPU == "help" ||
(!MAttrs.empty() && MAttrs.front() == "help");
+ // If user asked for the 'native' CPU, autodetect here. If autodection fails,
+ // this will set the CPU to an empty string which tells the target to
+ // pick a basic default.
+ if (MCPU == "native")
+ MCPU = sys::getHostCPUName();
+
// If user just wants to list available options, skip module loading
if (!SkipModule) {
M.reset(ParseIRFile(InputFilename, Err, Context));
mod = M.get();
- if (mod == 0) {
+ if (mod == nullptr) {
Err.print(argv[0], errs());
return 1;
}
@@ -265,19 +281,23 @@ static int compileModule(char **argv, LLVMContext &Context) {
TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
Options.DisableIntegratedAS = NoIntegratedAssembler;
+ Options.MCOptions.ShowMCEncoding = ShowMCEncoding;
+ Options.MCOptions.MCUseDwarfDirectory = EnableDwarfDirectory;
+ Options.MCOptions.AsmVerbose = AsmVerbose;
std::unique_ptr<TargetMachine> target(
TheTarget->createTargetMachine(TheTriple.getTriple(), MCPU, FeaturesStr,
Options, RelocModel, CMModel, OLvl));
assert(target.get() && "Could not allocate target machine!");
- assert(mod && "Should have exited after outputting help!");
- TargetMachine &Target = *target.get();
- if (DisableCFI)
- Target.setMCUseCFI(false);
+ // If we don't have a module then just exit now. We do this down
+ // here since the CPU/Feature help is underneath the target machine
+ // creation.
+ if (SkipModule)
+ return 0;
- if (EnableDwarfDirectory)
- Target.setMCUseDwarfDirectory(true);
+ assert(mod && "Should have exited if we didn't have a module!");
+ TargetMachine &Target = *target.get();
if (GenerateSoftFloatCalls)
FloatABIForCalls = FloatABI::Soft;
@@ -301,22 +321,16 @@ static int compileModule(char **argv, LLVMContext &Context) {
mod->setDataLayout(DL);
PM.add(new DataLayoutPass(mod));
- // Override default to generate verbose assembly.
- Target.setAsmVerbosityDefault(true);
-
- if (RelaxAll) {
- if (FileType != TargetMachine::CGFT_ObjectFile)
- errs() << argv[0]
+ if (RelaxAll.getNumOccurrences() > 0 &&
+ FileType != TargetMachine::CGFT_ObjectFile)
+ errs() << argv[0]
<< ": warning: ignoring -mc-relax-all because filetype != obj";
- else
- Target.setMCRelaxAll(true);
- }
{
formatted_raw_ostream FOS(Out->os());
- AnalysisID StartAfterID = 0;
- AnalysisID StopAfterID = 0;
+ AnalysisID StartAfterID = nullptr;
+ AnalysisID StopAfterID = nullptr;
const PassRegistry *PR = PassRegistry::getPassRegistry();
if (!StartAfter.empty()) {
const PassInfo *PI = PR->getPassInfo(StartAfter);
diff --git a/tools/lli/RemoteMemoryManager.cpp b/tools/lli/RemoteMemoryManager.cpp
index e9f4d53..200ab75 100644
--- a/tools/lli/RemoteMemoryManager.cpp
+++ b/tools/lli/RemoteMemoryManager.cpp
@@ -12,7 +12,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "lli"
#include "RemoteMemoryManager.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/ObjectImage.h"
@@ -21,6 +20,8 @@
using namespace llvm;
+#define DEBUG_TYPE "lli"
+
RemoteMemoryManager::~RemoteMemoryManager() {
for (SmallVector<Allocation, 2>::iterator
I = AllocatedSections.begin(), E = AllocatedSections.end();
@@ -178,16 +179,16 @@ void RemoteMemoryManager::setPoisonMemory(bool poison) { llvm_unreachable("Unexp
void RemoteMemoryManager::AllocateGOT() { llvm_unreachable("Unexpected!"); }
uint8_t *RemoteMemoryManager::getGOTBase() const {
llvm_unreachable("Unexpected!");
- return 0;
+ return nullptr;
}
uint8_t *RemoteMemoryManager::startFunctionBody(const Function *F, uintptr_t &ActualSize){
llvm_unreachable("Unexpected!");
- return 0;
+ return nullptr;
}
uint8_t *RemoteMemoryManager::allocateStub(const GlobalValue* F, unsigned StubSize,
unsigned Alignment) {
llvm_unreachable("Unexpected!");
- return 0;
+ return nullptr;
}
void RemoteMemoryManager::endFunctionBody(const Function *F, uint8_t *FunctionStart,
uint8_t *FunctionEnd) {
@@ -195,11 +196,11 @@ void RemoteMemoryManager::endFunctionBody(const Function *F, uint8_t *FunctionSt
}
uint8_t *RemoteMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment) {
llvm_unreachable("Unexpected!");
- return 0;
+ return nullptr;
}
uint8_t *RemoteMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment) {
llvm_unreachable("Unexpected!");
- return 0;
+ return nullptr;
}
void RemoteMemoryManager::deallocateFunctionBody(void *Body) {
llvm_unreachable("Unexpected!");
diff --git a/tools/lli/RemoteMemoryManager.h b/tools/lli/RemoteMemoryManager.h
index 11f600f..cf5d7c6 100644
--- a/tools/lli/RemoteMemoryManager.h
+++ b/tools/lli/RemoteMemoryManager.h
@@ -63,7 +63,7 @@ private:
RemoteTarget *Target;
public:
- RemoteMemoryManager() : Target(NULL) {}
+ RemoteMemoryManager() : Target(nullptr) {}
virtual ~RemoteMemoryManager();
uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
diff --git a/tools/lli/RemoteTarget.cpp b/tools/lli/RemoteTarget.cpp
index 55fc064..850fdc5 100644
--- a/tools/lli/RemoteTarget.cpp
+++ b/tools/lli/RemoteTarget.cpp
@@ -30,9 +30,9 @@ using namespace llvm;
bool RemoteTarget::allocateSpace(size_t Size, unsigned Alignment,
uint64_t &Address) {
- sys::MemoryBlock *Prev = Allocations.size() ? &Allocations.back() : NULL;
+ sys::MemoryBlock *Prev = Allocations.size() ? &Allocations.back() : nullptr;
sys::MemoryBlock Mem = sys::Memory::AllocateRWX(Size, Prev, &ErrorMsg);
- if (Mem.base() == NULL)
+ if (Mem.base() == nullptr)
return false;
if ((uintptr_t)Mem.base() % Alignment) {
ErrorMsg = "unable to allocate sufficiently aligned memory";
diff --git a/tools/lli/RemoteTargetExternal.cpp b/tools/lli/RemoteTargetExternal.cpp
index c1bc8df..fe46248 100644
--- a/tools/lli/RemoteTargetExternal.cpp
+++ b/tools/lli/RemoteTargetExternal.cpp
@@ -26,6 +26,8 @@
using namespace llvm;
+#define DEBUG_TYPE "lli"
+
bool RemoteTargetExternal::allocateSpace(size_t Size, unsigned Alignment,
uint64_t &Address) {
DEBUG(dbgs() << "Message [allocate space] size: " << Size <<
diff --git a/tools/lli/Unix/RPCChannel.inc b/tools/lli/Unix/RPCChannel.inc
index 4d245d6..6a9ae14 100644
--- a/tools/lli/Unix/RPCChannel.inc
+++ b/tools/lli/Unix/RPCChannel.inc
@@ -60,7 +60,7 @@ bool RPCChannel::createServer() {
}
// Execute the child process.
- char *args[1] = { NULL };
+ char *args[1] = { nullptr };
int rc = execv(ChildName.c_str(), args);
if (rc != 0)
perror("Error executing child process: ");
@@ -84,7 +84,7 @@ bool RPCChannel::createClient() {
return true;
}
-void RPCChannel::Wait() { wait(NULL); }
+void RPCChannel::Wait() { wait(nullptr); }
static bool CheckError(int rc, size_t Size, const char *Desc) {
if (rc < 0) {
diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp
index c0c0f9d..4cde105 100644
--- a/tools/lli/lli.cpp
+++ b/tools/lli/lli.cpp
@@ -13,7 +13,6 @@
//
//===----------------------------------------------------------------------===//
-#define DEBUG_TYPE "lli"
#include "llvm/IR/LLVMContext.h"
#include "RemoteMemoryManager.h"
#include "RemoteTarget.h"
@@ -64,6 +63,8 @@
using namespace llvm;
+#define DEBUG_TYPE "lli"
+
namespace {
cl::opt<std::string>
InputFile(cl::desc("<input bitcode>"), cl::Positional, cl::init("-"));
@@ -282,13 +283,13 @@ public:
const std::string ModuleID = M->getModuleIdentifier();
std::string CacheName;
if (!getCacheFilename(ModuleID, CacheName))
- return NULL;
+ return nullptr;
// Load the object from the cache filename
std::unique_ptr<MemoryBuffer> IRObjectBuffer;
MemoryBuffer::getFile(CacheName.c_str(), IRObjectBuffer, -1, false);
// If the file isn't there, that's OK.
if (!IRObjectBuffer)
- return NULL;
+ return nullptr;
// MCJIT will want to write into this buffer, and we don't want that
// because the file has probably just been mmapped. Instead we make
// a copy. The filed-based buffer will be released when it goes
@@ -319,8 +320,8 @@ private:
}
};
-static ExecutionEngine *EE = 0;
-static LLIObjectCache *CacheManager = 0;
+static ExecutionEngine *EE = nullptr;
+static LLIObjectCache *CacheManager = nullptr;
static void do_shutdown() {
// Cygwin-1.5 invokes DLL's dtors before atexit handler.
@@ -449,7 +450,7 @@ int main(int argc, char **argv, char * const *envp) {
Mod->setTargetTriple(Triple::normalize(TargetTriple));
// Enable MCJIT if desired.
- RTDyldMemoryManager *RTDyldMM = 0;
+ RTDyldMemoryManager *RTDyldMM = nullptr;
if (UseMCJIT && !ForceInterpreter) {
builder.setUseMCJIT(true);
if (RemoteMCJIT)
@@ -462,7 +463,7 @@ int main(int argc, char **argv, char * const *envp) {
errs() << "error: Remote process execution requires -use-mcjit\n";
exit(1);
}
- builder.setJITMemoryManager(ForceInterpreter ? 0 :
+ builder.setJITMemoryManager(ForceInterpreter ? nullptr :
JITMemoryManager::CreateDefaultMemManager());
}
@@ -533,7 +534,7 @@ int main(int argc, char **argv, char * const *envp) {
Err.print(argv[0], errs());
return 1;
}
- EE->addObjectFile(Obj.get());
+ EE->addObjectFile(std::unique_ptr<object::ObjectFile>(Obj.get()));
}
for (unsigned i = 0, e = ExtraArchives.size(); i != e; ++i) {
diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp
index 047f54e..ed7291e 100644
--- a/tools/llvm-ar/llvm-ar.cpp
+++ b/tools/llvm-ar/llvm-ar.cpp
@@ -516,7 +516,7 @@ computeInsertAction(ArchiveOperation Operation,
// We could try to optimize this to a fstat, but it is not a common
// operation.
sys::fs::file_status Status;
- failIfError(sys::fs::status(*MI, Status));
+ failIfError(sys::fs::status(*MI, Status), *MI);
if (Status.getLastModificationTime() < I->getLastModified()) {
if (PosName.empty())
return IA_AddOldMember;
@@ -856,7 +856,7 @@ static void performWriteOperation(ArchiveOperation Operation,
Output.keep();
Out.close();
sys::fs::rename(TemporaryOutput, ArchiveName);
- TemporaryOutput = NULL;
+ TemporaryOutput = nullptr;
}
static void createSymbolTable(object::Archive *OldArchive) {
@@ -969,6 +969,6 @@ static int performOperation(ArchiveOperation Operation) {
}
}
- performOperation(Operation, NULL);
+ performOperation(Operation, nullptr);
return 0;
}
diff --git a/tools/llvm-as/llvm-as.cpp b/tools/llvm-as/llvm-as.cpp
index 7583b12..007241c 100644
--- a/tools/llvm-as/llvm-as.cpp
+++ b/tools/llvm-as/llvm-as.cpp
@@ -21,6 +21,7 @@
#include "llvm/IR/Module.h"
#include "llvm/IR/Verifier.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
@@ -94,7 +95,7 @@ int main(int argc, char **argv) {
// Parse the file now...
SMDiagnostic Err;
std::unique_ptr<Module> M(ParseAssemblyFile(InputFilename, Err, Context));
- if (M.get() == 0) {
+ if (!M.get()) {
Err.print(argv[0], errs());
return 1;
}
diff --git a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
index 9e17783..dfdaa03 100644
--- a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
+++ b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp
@@ -84,7 +84,7 @@ static const char *GetBlockName(unsigned BlockID,
if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) {
if (BlockID == bitc::BLOCKINFO_BLOCK_ID)
return "BLOCKINFO_BLOCK";
- return 0;
+ return nullptr;
}
// Check to see if we have a blockinfo record for this block, with a name.
@@ -95,10 +95,10 @@ static const char *GetBlockName(unsigned BlockID,
}
- if (CurStreamType != LLVMIRBitstream) return 0;
+ if (CurStreamType != LLVMIRBitstream) return nullptr;
switch (BlockID) {
- default: return 0;
+ default: return nullptr;
case bitc::MODULE_BLOCK_ID: return "MODULE_BLOCK";
case bitc::PARAMATTR_BLOCK_ID: return "PARAMATTR_BLOCK";
case bitc::PARAMATTR_GROUP_BLOCK_ID: return "PARAMATTR_GROUP_BLOCK_ID";
@@ -120,13 +120,13 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
if (BlockID < bitc::FIRST_APPLICATION_BLOCKID) {
if (BlockID == bitc::BLOCKINFO_BLOCK_ID) {
switch (CodeID) {
- default: return 0;
+ default: return nullptr;
case bitc::BLOCKINFO_CODE_SETBID: return "SETBID";
case bitc::BLOCKINFO_CODE_BLOCKNAME: return "BLOCKNAME";
case bitc::BLOCKINFO_CODE_SETRECORDNAME: return "SETRECORDNAME";
}
}
- return 0;
+ return nullptr;
}
// Check to see if we have a blockinfo record for this record, with a name.
@@ -138,13 +138,13 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
}
- if (CurStreamType != LLVMIRBitstream) return 0;
+ if (CurStreamType != LLVMIRBitstream) return nullptr;
switch (BlockID) {
- default: return 0;
+ default: return nullptr;
case bitc::MODULE_BLOCK_ID:
switch (CodeID) {
- default: return 0;
+ default: return nullptr;
case bitc::MODULE_CODE_VERSION: return "VERSION";
case bitc::MODULE_CODE_TRIPLE: return "TRIPLE";
case bitc::MODULE_CODE_DATALAYOUT: return "DATALAYOUT";
@@ -159,14 +159,14 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
}
case bitc::PARAMATTR_BLOCK_ID:
switch (CodeID) {
- default: return 0;
+ default: return nullptr;
case bitc::PARAMATTR_CODE_ENTRY_OLD: return "ENTRY";
case bitc::PARAMATTR_CODE_ENTRY: return "ENTRY";
case bitc::PARAMATTR_GRP_CODE_ENTRY: return "ENTRY";
}
case bitc::TYPE_BLOCK_ID_NEW:
switch (CodeID) {
- default: return 0;
+ default: return nullptr;
case bitc::TYPE_CODE_NUMENTRY: return "NUMENTRY";
case bitc::TYPE_CODE_VOID: return "VOID";
case bitc::TYPE_CODE_FLOAT: return "FLOAT";
@@ -189,7 +189,7 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
case bitc::CONSTANTS_BLOCK_ID:
switch (CodeID) {
- default: return 0;
+ default: return nullptr;
case bitc::CST_CODE_SETTYPE: return "SETTYPE";
case bitc::CST_CODE_NULL: return "NULL";
case bitc::CST_CODE_UNDEF: return "UNDEF";
@@ -215,7 +215,7 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
}
case bitc::FUNCTION_BLOCK_ID:
switch (CodeID) {
- default: return 0;
+ default: return nullptr;
case bitc::FUNC_CODE_DECLAREBLOCKS: return "DECLAREBLOCKS";
case bitc::FUNC_CODE_INST_BINOP: return "INST_BINOP";
@@ -249,18 +249,18 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
}
case bitc::VALUE_SYMTAB_BLOCK_ID:
switch (CodeID) {
- default: return 0;
+ default: return nullptr;
case bitc::VST_CODE_ENTRY: return "ENTRY";
case bitc::VST_CODE_BBENTRY: return "BBENTRY";
}
case bitc::METADATA_ATTACHMENT_ID:
switch(CodeID) {
- default:return 0;
+ default:return nullptr;
case bitc::METADATA_ATTACHMENT: return "METADATA_ATTACHMENT";
}
case bitc::METADATA_BLOCK_ID:
switch(CodeID) {
- default:return 0;
+ default:return nullptr;
case bitc::METADATA_STRING: return "METADATA_STRING";
case bitc::METADATA_NAME: return "METADATA_NAME";
case bitc::METADATA_KIND: return "METADATA_KIND";
@@ -270,7 +270,7 @@ static const char *GetCodeName(unsigned CodeID, unsigned BlockID,
}
case bitc::USELIST_BLOCK_ID:
switch(CodeID) {
- default:return 0;
+ default:return nullptr;
case bitc::USELIST_CODE_ENTRY: return "USELIST_CODE_ENTRY";
}
}
@@ -345,7 +345,7 @@ static bool ParseBlock(BitstreamCursor &Stream, unsigned BlockID,
if (Stream.EnterSubBlock(BlockID, &NumWords))
return Error("Malformed block record");
- const char *BlockName = 0;
+ const char *BlockName = nullptr;
if (Dump) {
outs() << Indent << "<";
if ((BlockName = GetBlockName(BlockID, *Stream.getBitStreamReader())))
diff --git a/tools/llvm-c-test/object.c b/tools/llvm-c-test/object.c
index 2792928..a5421d9 100644
--- a/tools/llvm-c-test/object.c
+++ b/tools/llvm-c-test/object.c
@@ -72,9 +72,8 @@ int object_list_symbols(void) {
while (!LLVMIsSymbolIteratorAtEnd(O, sym)) {
LLVMMoveToContainingSection(sect, sym);
- printf("%s @0x%08" PRIx64 "/0x%08" PRIx64 " +%" PRIu64 " (%s)\n",
- LLVMGetSymbolName(sym), LLVMGetSymbolAddress(sym),
- LLVMGetSymbolFileOffset(sym), LLVMGetSymbolSize(sym),
+ printf("%s @0x%08" PRIx64 " +%" PRIu64 " (%s)\n", LLVMGetSymbolName(sym),
+ LLVMGetSymbolAddress(sym), LLVMGetSymbolSize(sym),
LLVMGetSectionName(sect));
LLVMMoveToNextSymbol(sym);
diff --git a/tools/llvm-config/CMakeLists.txt b/tools/llvm-config/CMakeLists.txt
index 6f29a82..8d83762 100644
--- a/tools/llvm-config/CMakeLists.txt
+++ b/tools/llvm-config/CMakeLists.txt
@@ -16,7 +16,8 @@ set(LLVM_OBJ_ROOT ${LLVM_BINARY_DIR})
set(LLVM_CPPFLAGS "${CMAKE_CPP_FLAGS} ${CMAKE_CPP_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}")
set(LLVM_CFLAGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}")
set(LLVM_CXXFLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}")
-set(LLVM_LDFLAGS ${CMAKE_SHARED_LINKER_FLAGS})
+# Use the C++ link flags, since they should be a superset of C link flags.
+set(LLVM_LDFLAGS "${CMAKE_CXX_LINK_FLAGS}")
set(LLVM_BUILDMODE ${CMAKE_BUILD_TYPE})
set(LLVM_SYSTEM_LIBS ${SYSTEM_LIBS})
string(REPLACE ";" " " LLVM_TARGETS_BUILT "${LLVM_TARGETS_TO_BUILD}")
diff --git a/tools/llvm-cov/llvm-cov.cpp b/tools/llvm-cov/llvm-cov.cpp
index 587ee11..9463609 100644
--- a/tools/llvm-cov/llvm-cov.cpp
+++ b/tools/llvm-cov/llvm-cov.cpp
@@ -26,34 +26,42 @@ using namespace llvm;
static cl::opt<std::string> SourceFile(cl::Positional, cl::Required,
cl::desc("SOURCEFILE"));
-static cl::opt<bool> AllBlocks("a", cl::init(false),
+static cl::opt<bool> AllBlocks("a", cl::Grouping, cl::init(false),
cl::desc("Display all basic blocks"));
static cl::alias AllBlocksA("all-blocks", cl::aliasopt(AllBlocks));
-static cl::opt<bool> BranchProb("b", cl::init(false),
+static cl::opt<bool> BranchProb("b", cl::Grouping, cl::init(false),
cl::desc("Display branch probabilities"));
static cl::alias BranchProbA("branch-probabilities", cl::aliasopt(BranchProb));
-static cl::opt<bool> BranchCount("c", cl::init(false),
+static cl::opt<bool> BranchCount("c", cl::Grouping, cl::init(false),
cl::desc("Display branch counts instead "
"of percentages (requires -b)"));
static cl::alias BranchCountA("branch-counts", cl::aliasopt(BranchCount));
-static cl::opt<bool> FuncSummary("f", cl::init(false),
+static cl::opt<bool> LongNames("l", cl::Grouping, cl::init(false),
+ cl::desc("Prefix filenames with the main file"));
+static cl::alias LongNamesA("long-file-names", cl::aliasopt(LongNames));
+
+static cl::opt<bool> FuncSummary("f", cl::Grouping, cl::init(false),
cl::desc("Show coverage for each function"));
static cl::alias FuncSummaryA("function-summaries", cl::aliasopt(FuncSummary));
+static cl::opt<bool> NoOutput("n", cl::Grouping, cl::init(false),
+ cl::desc("Do not output any .gcov files"));
+static cl::alias NoOutputA("no-output", cl::aliasopt(NoOutput));
+
static cl::opt<std::string>
ObjectDir("o", cl::value_desc("DIR|FILE"), cl::init(""),
cl::desc("Find objects in DIR or based on FILE's path"));
static cl::alias ObjectDirA("object-directory", cl::aliasopt(ObjectDir));
static cl::alias ObjectDirB("object-file", cl::aliasopt(ObjectDir));
-static cl::opt<bool> PreservePaths("p", cl::init(false),
+static cl::opt<bool> PreservePaths("p", cl::Grouping, cl::init(false),
cl::desc("Preserve path components"));
static cl::alias PreservePathsA("preserve-paths", cl::aliasopt(PreservePaths));
-static cl::opt<bool> UncondBranch("u", cl::init(false),
+static cl::opt<bool> UncondBranch("u", cl::Grouping, cl::init(false),
cl::desc("Display unconditional branch info "
"(requires -b)"));
static cl::alias UncondBranchA("unconditional-branches",
@@ -126,9 +134,9 @@ int main(int argc, char **argv) {
GF.dump();
GCOVOptions Options(AllBlocks, BranchProb, BranchCount, FuncSummary,
- PreservePaths, UncondBranch);
+ PreservePaths, UncondBranch, LongNames, NoOutput);
FileInfo FI(Options);
GF.collectLineCounts(FI);
- FI.print(InputGCNO, InputGCDA);
+ FI.print(SourceFile, InputGCNO, InputGCDA);
return 0;
}
diff --git a/tools/llvm-diff/DiffLog.cpp b/tools/llvm-diff/DiffLog.cpp
index caf779b..24a1b08 100644
--- a/tools/llvm-diff/DiffLog.cpp
+++ b/tools/llvm-diff/DiffLog.cpp
@@ -35,11 +35,11 @@ void DiffLogBuilder::addMatch(Instruction *L, Instruction *R) {
}
void DiffLogBuilder::addLeft(Instruction *L) {
// HACK: VS 2010 has a bug in the stdlib that requires this.
- Diff.push_back(DiffRecord(L, DiffRecord::second_type(0)));
+ Diff.push_back(DiffRecord(L, DiffRecord::second_type(nullptr)));
}
void DiffLogBuilder::addRight(Instruction *R) {
// HACK: VS 2010 has a bug in the stdlib that requires this.
- Diff.push_back(DiffRecord(DiffRecord::first_type(0), R));
+ Diff.push_back(DiffRecord(DiffRecord::first_type(nullptr), R));
}
unsigned DiffLogBuilder::getNumLines() const { return Diff.size(); }
diff --git a/tools/llvm-diff/DifferenceEngine.h b/tools/llvm-diff/DifferenceEngine.h
index 73bf6eb..4470968 100644
--- a/tools/llvm-diff/DifferenceEngine.h
+++ b/tools/llvm-diff/DifferenceEngine.h
@@ -59,7 +59,7 @@ namespace llvm {
};
DifferenceEngine(Consumer &consumer)
- : consumer(consumer), globalValueOracle(0) {}
+ : consumer(consumer), globalValueOracle(nullptr) {}
void diff(Module *L, Module *R);
void diff(Function *L, Function *R);
diff --git a/tools/llvm-dis/llvm-dis.cpp b/tools/llvm-dis/llvm-dis.cpp
index c6f0dcf..0df7328 100644
--- a/tools/llvm-dis/llvm-dis.cpp
+++ b/tools/llvm-dis/llvm-dis.cpp
@@ -25,6 +25,7 @@
#include "llvm/IR/Type.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/DataStream.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/FormattedStream.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -135,7 +136,7 @@ int main(int argc, char **argv) {
DisplayFilename = InputFilename;
M.reset(getStreamedBitcodeModule(DisplayFilename, streamer, Context,
&ErrorMessage));
- if(M.get() != 0) {
+ if(M.get()) {
if (error_code EC = M->materializeAllPermanently()) {
ErrorMessage = EC.message();
M.reset();
@@ -143,7 +144,7 @@ int main(int argc, char **argv) {
}
}
- if (M.get() == 0) {
+ if (!M.get()) {
errs() << argv[0] << ": ";
if (ErrorMessage.size())
errs() << ErrorMessage << "\n";
diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
index f4a9ae8..46ac36e 100644
--- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
+++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp
@@ -38,19 +38,6 @@ 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 cl::opt<bool>
-PrintFunctions("functions", cl::init(false),
- cl::desc("Print function names as well as line information "
- "for a given address"));
-
-static cl::opt<bool>
-PrintInlining("inlining", cl::init(false),
- cl::desc("Print all inlined frames for a given address"));
-
static cl::opt<DIDumpType>
DumpType("debug-dump", cl::init(DIDT_All),
cl::desc("Dump of debug sections:"),
@@ -78,14 +65,6 @@ DumpType("debug-dump", cl::init(DIDT_All),
clEnumValN(DIDT_StrOffsetsDwo, "str_offsets.dwo", ".debug_str_offsets.dwo"),
clEnumValEnd));
-static void PrintDILineInfo(DILineInfo dli) {
- if (PrintFunctions)
- outs() << (dli.getFunctionName() ? dli.getFunctionName() : "<unknown>")
- << "\n";
- outs() << (dli.getFileName() ? dli.getFileName() : "<unknown>") << ':'
- << dli.getLine() << ':' << dli.getColumn() << '\n';
-}
-
static void DumpInput(const StringRef &Filename) {
std::unique_ptr<MemoryBuffer> Buff;
@@ -103,35 +82,10 @@ static void DumpInput(const StringRef &Filename) {
std::unique_ptr<DIContext> DICtx(DIContext::getDWARFContext(Obj.get()));
- if (Address == -1ULL) {
- outs() << Filename
- << ":\tfile format " << Obj->getFileFormatName() << "\n\n";
- // Dump the complete DWARF structure.
- DICtx->dump(outs(), DumpType);
- } else {
- // Print line info for the specified address.
- int SpecFlags = DILineInfoSpecifier::FileLineInfo |
- DILineInfoSpecifier::AbsoluteFilePath;
- if (PrintFunctions)
- SpecFlags |= DILineInfoSpecifier::FunctionName;
- if (PrintInlining) {
- DIInliningInfo InliningInfo =
- DICtx->getInliningInfoForAddress(Address, SpecFlags);
- uint32_t n = InliningInfo.getNumberOfFrames();
- if (n == 0) {
- // Print one empty debug line info in any case.
- PrintDILineInfo(DILineInfo());
- } else {
- for (uint32_t i = 0; i < n; i++) {
- DILineInfo dli = InliningInfo.getFrame(i);
- PrintDILineInfo(dli);
- }
- }
- } else {
- DILineInfo dli = DICtx->getLineInfoForAddress(Address, SpecFlags);
- PrintDILineInfo(dli);
- }
- }
+ outs() << Filename
+ << ":\tfile format " << Obj->getFileFormatName() << "\n\n";
+ // Dump the complete DWARF structure.
+ DICtx->dump(outs(), DumpType);
}
int main(int argc, char **argv) {
diff --git a/tools/llvm-extract/llvm-extract.cpp b/tools/llvm-extract/llvm-extract.cpp
index 2e5a2af..0f70868 100644
--- a/tools/llvm-extract/llvm-extract.cpp
+++ b/tools/llvm-extract/llvm-extract.cpp
@@ -22,6 +22,7 @@
#include "llvm/IRReader/IRReader.h"
#include "llvm/PassManager.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Regex.h"
@@ -103,7 +104,7 @@ int main(int argc, char **argv) {
std::unique_ptr<Module> M;
M.reset(getLazyIRFileModule(InputFilename, Err, Context));
- if (M.get() == 0) {
+ if (!M.get()) {
Err.print(argv[0], errs());
return 1;
}
@@ -165,10 +166,9 @@ int main(int argc, char **argv) {
"invalid regex: " << Error;
}
bool match = false;
- for (Module::global_iterator GV = M->global_begin(),
- E = M->global_end(); GV != E; GV++) {
- if (RegEx.match(GV->getName())) {
- GVs.insert(&*GV);
+ for (auto &GV : M->globals()) {
+ if (RegEx.match(GV.getName())) {
+ GVs.insert(&GV);
match = true;
}
}
@@ -228,22 +228,19 @@ int main(int argc, char **argv) {
else {
// Deleting. Materialize every GV that's *not* in GVs.
SmallPtrSet<GlobalValue *, 8> GVSet(GVs.begin(), GVs.end());
- for (Module::global_iterator I = M->global_begin(), E = M->global_end();
- I != E; ++I) {
- GlobalVariable *G = I;
- if (!GVSet.count(G) && G->isMaterializable()) {
+ for (auto &G : M->globals()) {
+ if (!GVSet.count(&G) && G.isMaterializable()) {
std::string ErrInfo;
- if (G->Materialize(&ErrInfo)) {
+ if (G.Materialize(&ErrInfo)) {
errs() << argv[0] << ": error reading input: " << ErrInfo << "\n";
return 1;
}
}
}
- for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) {
- Function *F = I;
- if (!GVSet.count(F) && F->isMaterializable()) {
+ for (auto &F : *M) {
+ if (!GVSet.count(&F) && F.isMaterializable()) {
std::string ErrInfo;
- if (F->Materialize(&ErrInfo)) {
+ if (F.Materialize(&ErrInfo)) {
errs() << argv[0] << ": error reading input: " << ErrInfo << "\n";
return 1;
}
diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp
index 1f0e224..ed8c06e 100644
--- a/tools/llvm-link/llvm-link.cpp
+++ b/tools/llvm-link/llvm-link.cpp
@@ -19,6 +19,7 @@
#include "llvm/IR/Verifier.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/PrettyStackTrace.h"
@@ -61,13 +62,13 @@ static inline Module *LoadFile(const char *argv0, const std::string &FN,
LLVMContext& Context) {
SMDiagnostic Err;
if (Verbose) errs() << "Loading '" << FN << "'\n";
- Module* Result = 0;
+ Module* Result = nullptr;
Result = ParseIRFile(FN, Err, Context);
if (Result) return Result; // Load successful!
Err.print(argv0, errs());
- return NULL;
+ return nullptr;
}
int main(int argc, char **argv) {
@@ -84,7 +85,7 @@ int main(int argc, char **argv) {
std::unique_ptr<Module> Composite(
LoadFile(argv[0], InputFilenames[BaseArg], Context));
- if (Composite.get() == 0) {
+ if (!Composite.get()) {
errs() << argv[0] << ": error loading file '"
<< InputFilenames[BaseArg] << "'\n";
return 1;
@@ -93,7 +94,7 @@ int main(int argc, char **argv) {
Linker L(Composite.get(), SuppressWarnings);
for (unsigned i = BaseArg+1; i < InputFilenames.size(); ++i) {
std::unique_ptr<Module> M(LoadFile(argv[0], InputFilenames[i], Context));
- if (M.get() == 0) {
+ if (!M.get()) {
errs() << argv[0] << ": error loading file '" <<InputFilenames[i]<< "'\n";
return 1;
}
diff --git a/tools/llvm-lto/llvm-lto.cpp b/tools/llvm-lto/llvm-lto.cpp
index ec3f0fa..8c2d1cd 100644
--- a/tools/llvm-lto/llvm-lto.cpp
+++ b/tools/llvm-lto/llvm-lto.cpp
@@ -17,6 +17,7 @@
#include "llvm/LTO/LTOCodeGenerator.h"
#include "llvm/LTO/LTOModule.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
@@ -83,7 +84,20 @@ int main(int argc, char **argv) {
LTOCodeGenerator CodeGen;
- CodeGen.setCodePICModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC);
+ switch (RelocModel) {
+ case Reloc::Static:
+ CodeGen.setCodePICModel(LTO_CODEGEN_PIC_MODEL_STATIC);
+ break;
+ case Reloc::PIC_:
+ CodeGen.setCodePICModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC);
+ break;
+ case Reloc::DynamicNoPIC:
+ CodeGen.setCodePICModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC);
+ break;
+ default:
+ CodeGen.setCodePICModel(LTO_CODEGEN_PIC_MODEL_DEFAULT);
+ }
+
CodeGen.setDebugInfo(LTO_DEBUG_MODEL_DWARF);
CodeGen.setTargetOptions(Options);
@@ -130,12 +144,22 @@ int main(int argc, char **argv) {
for (unsigned i = 0; i < KeptDSOSyms.size(); ++i)
CodeGen.addMustPreserveSymbol(KeptDSOSyms[i].c_str());
+ std::string attrs;
+ for (unsigned i = 0; i < MAttrs.size(); ++i) {
+ if (i > 0)
+ attrs.append(",");
+ attrs.append(MAttrs[i]);
+ }
+
+ if (!attrs.empty())
+ CodeGen.setAttr(attrs.c_str());
+
if (!OutputFilename.empty()) {
size_t len = 0;
std::string ErrorInfo;
const void *Code = CodeGen.compile(&len, DisableOpt, DisableInline,
DisableGVNLoadPRE, ErrorInfo);
- if (Code == NULL) {
+ if (!Code) {
errs() << argv[0]
<< ": error compiling the code: " << ErrorInfo << "\n";
return 1;
@@ -152,7 +176,7 @@ int main(int argc, char **argv) {
FileStream.write(reinterpret_cast<const char *>(Code), len);
} else {
std::string ErrorInfo;
- const char *OutputName = NULL;
+ const char *OutputName = nullptr;
if (!CodeGen.compile_to_file(&OutputName, DisableOpt, DisableInline,
DisableGVNLoadPRE, ErrorInfo)) {
errs() << argv[0]
diff --git a/tools/llvm-mc/Disassembler.cpp b/tools/llvm-mc/Disassembler.cpp
index 9c402f2..9367590 100644
--- a/tools/llvm-mc/Disassembler.cpp
+++ b/tools/llvm-mc/Disassembler.cpp
@@ -14,8 +14,11 @@
#include "Disassembler.h"
#include "llvm/ADT/Triple.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -158,7 +161,24 @@ int Disassembler::disassemble(const Target &T,
MemoryBuffer &Buffer,
SourceMgr &SM,
raw_ostream &Out) {
- std::unique_ptr<const MCDisassembler> DisAsm(T.createMCDisassembler(STI));
+
+ std::unique_ptr<const MCRegisterInfo> MRI(T.createMCRegInfo(Triple));
+ if (!MRI) {
+ errs() << "error: no register info for target " << Triple << "\n";
+ return -1;
+ }
+
+ std::unique_ptr<const MCAsmInfo> MAI(T.createMCAsmInfo(*MRI, Triple));
+ if (!MAI) {
+ errs() << "error: no assembly info for target " << Triple << "\n";
+ return -1;
+ }
+
+ // Set up the MCContext for creating symbols and MCExpr's.
+ MCContext Ctx(MAI.get(), MRI.get(), nullptr);
+
+ std::unique_ptr<const MCDisassembler> DisAsm(
+ T.createMCDisassembler(STI, Ctx));
if (!DisAsm) {
errs() << "error: no disassembler for target " << Triple << "\n";
return -1;
diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp
index 61fd2c4..84d578b 100644
--- a/tools/llvm-mc/llvm-mc.cpp
+++ b/tools/llvm-mc/llvm-mc.cpp
@@ -25,6 +25,7 @@
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCTargetAsmParser.h"
+#include "llvm/MC/MCTargetOptionsCommandFlags.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/FileUtilities.h"
@@ -64,12 +65,6 @@ static cl::opt<unsigned>
OutputAsmVariant("output-asm-variant",
cl::desc("Syntax variant to use for output printing"));
-static cl::opt<bool>
-RelaxAll("mc-relax-all", cl::desc("Relax all fixups"));
-
-static cl::opt<bool>
-NoExecStack("mc-no-exec-stack", cl::desc("File doesn't need an exec stack"));
-
enum OutputFileType {
OFT_Null,
OFT_AssemblyFile,
@@ -147,12 +142,12 @@ NoInitialTextSection("n", cl::desc("Don't assume assembly file starts "
"in the text section"));
static cl::opt<bool>
-SaveTempLabels("L", cl::desc("Don't discard temporary labels"));
-
-static cl::opt<bool>
GenDwarfForAssembly("g", cl::desc("Generate dwarf debugging info for assembly "
"source files"));
+static cl::opt<int>
+DwarfVersion("dwarf-version", cl::desc("Dwarf version"), cl::init(4));
+
static cl::opt<std::string>
DebugCompilationDir("fdebug-compilation-dir",
cl::desc("Specifies the debug info's compilation dir"));
@@ -161,6 +156,12 @@ static cl::opt<std::string>
MainFileName("main-file-name",
cl::desc("Specifies the name we should consider the input file"));
+static cl::opt<bool> SaveTempLabels("save-temp-labels",
+ cl::desc("Don't discard temporary labels"));
+
+static cl::opt<bool> NoExecStack("no-exec-stack",
+ cl::desc("File doesn't need an exec stack"));
+
enum ActionType {
AC_AsLex,
AC_Assemble,
@@ -197,7 +198,7 @@ static const Target *GetTarget(const char *ProgName) {
Error);
if (!TheTarget) {
errs() << ProgName << ": " << Error;
- return 0;
+ return nullptr;
}
// Update the triple name and return the found target.
@@ -215,7 +216,7 @@ static tool_output_file *GetOutputStream() {
if (!Err.empty()) {
errs() << Err << '\n';
delete Out;
- return 0;
+ return nullptr;
}
return Out;
@@ -320,9 +321,11 @@ static int AsLexInput(SourceMgr &SrcMgr, MCAsmInfo &MAI, tool_output_file *Out)
static int AssembleInput(const char *ProgName, const Target *TheTarget,
SourceMgr &SrcMgr, MCContext &Ctx, MCStreamer &Str,
MCAsmInfo &MAI, MCSubtargetInfo &STI, MCInstrInfo &MCII) {
- std::unique_ptr<MCAsmParser> Parser(createMCAsmParser(SrcMgr, Ctx, Str, MAI));
+ std::unique_ptr<MCAsmParser> Parser(
+ createMCAsmParser(SrcMgr, Ctx, Str, MAI));
std::unique_ptr<MCTargetAsmParser> TAP(
- TheTarget->createMCAsmParser(STI, *Parser, MCII));
+ TheTarget->createMCAsmParser(STI, *Parser, MCII,
+ InitMCTargetOptionsFromFlags()));
if (!TAP) {
errs() << ProgName
<< ": error: this target does not support assembly parsing.\n";
@@ -403,6 +406,12 @@ int main(int argc, char **argv) {
Ctx.setAllowTemporaryLabels(false);
Ctx.setGenDwarfForAssembly(GenDwarfForAssembly);
+ if (DwarfVersion < 2 || DwarfVersion > 4) {
+ errs() << ProgName << ": Dwarf version " << DwarfVersion
+ << " is not supported." << '\n';
+ return 1;
+ }
+ Ctx.setDwarfVersion(DwarfVersion);
if (!DwarfDebugFlags.empty())
Ctx.setDwarfDebugFlags(StringRef(DwarfDebugFlags));
if (!DwarfDebugProducer.empty())
@@ -432,20 +441,19 @@ int main(int argc, char **argv) {
std::unique_ptr<MCSubtargetInfo> STI(
TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr));
- MCInstPrinter *IP = NULL;
+ MCInstPrinter *IP = nullptr;
if (FileType == OFT_AssemblyFile) {
IP =
TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI, *MCII, *MRI, *STI);
- MCCodeEmitter *CE = 0;
- MCAsmBackend *MAB = 0;
+ MCCodeEmitter *CE = nullptr;
+ MCAsmBackend *MAB = nullptr;
if (ShowEncoding) {
CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx);
MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU);
}
Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/ true,
- /*UseCFI*/ true,
- /*useDwarfDirectory*/
- true, IP, CE, MAB, ShowInst));
+ /*useDwarfDirectory*/ true, IP, CE,
+ MAB, ShowInst));
} else if (FileType == OFT_Null) {
Str.reset(createNullStreamer(Ctx));
diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp
index 22e019a..3be9247 100644
--- a/tools/llvm-nm/llvm-nm.cpp
+++ b/tools/llvm-nm/llvm-nm.cpp
@@ -181,11 +181,30 @@ static bool compareSymbolName(const NMSymbol &A, const NMSymbol &B) {
return false;
}
+static char isSymbolList64Bit(SymbolicFile *Obj) {
+ if (isa<IRObjectFile>(Obj))
+ return false;
+ else if (isa<COFFObjectFile>(Obj))
+ return false;
+ else if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(Obj))
+ return MachO->is64Bit();
+ else if (isa<ELF32LEObjectFile>(Obj))
+ return false;
+ else if (isa<ELF64LEObjectFile>(Obj))
+ return true;
+ else if (isa<ELF32BEObjectFile>(Obj))
+ return false;
+ else if(isa<ELF64BEObjectFile>(Obj))
+ return true;
+ else
+ return false;
+}
+
static StringRef CurrentFilename;
typedef std::vector<NMSymbol> SymbolListT;
static SymbolListT SymbolList;
-static void sortAndPrintSymbolList() {
+static void sortAndPrintSymbolList(SymbolicFile *Obj) {
if (!NoSort) {
if (NumericSort)
std::sort(SymbolList.begin(), SymbolList.end(), compareSymbolAddress);
@@ -205,6 +224,15 @@ static void sortAndPrintSymbolList() {
<< " Size Line Section\n";
}
+ const char *printBlanks, *printFormat;
+ if (isSymbolList64Bit(Obj)) {
+ printBlanks = " ";
+ printFormat = "%016" PRIx64;
+ } else {
+ printBlanks = " ";
+ printFormat = "%08" PRIx64;
+ }
+
for (SymbolListT::iterator I = SymbolList.begin(), E = SymbolList.end();
I != E; ++I) {
if ((I->TypeChar != 'U') && UndefinedOnly)
@@ -214,19 +242,19 @@ static void sortAndPrintSymbolList() {
if (SizeSort && !PrintAddress && I->Size == UnknownAddressOrSize)
continue;
- char SymbolAddrStr[10] = "";
- char SymbolSizeStr[10] = "";
+ char SymbolAddrStr[18] = "";
+ char SymbolSizeStr[18] = "";
if (OutputFormat == sysv || I->Address == UnknownAddressOrSize)
- strcpy(SymbolAddrStr, " ");
+ strcpy(SymbolAddrStr, printBlanks);
if (OutputFormat == sysv)
- strcpy(SymbolSizeStr, " ");
+ strcpy(SymbolSizeStr, printBlanks);
if (I->Address != UnknownAddressOrSize)
- format("%08" PRIx64, I->Address)
+ format(printFormat, I->Address)
.print(SymbolAddrStr, sizeof(SymbolAddrStr));
if (I->Size != UnknownAddressOrSize)
- format("%08" PRIx64, I->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr));
+ format(printFormat, I->Size).print(SymbolSizeStr, sizeof(SymbolSizeStr));
if (OutputFormat == posix) {
outs() << I->Name << " " << I->TypeChar << " " << SymbolAddrStr
@@ -392,7 +420,7 @@ static char getSymbolNMTypeChar(const GlobalValue &GV) {
if (isa<GlobalVariable>(GV))
return 'd';
const GlobalAlias *GA = cast<GlobalAlias>(&GV);
- const GlobalValue *AliasedGV = GA->getAliasedGlobal();
+ const GlobalValue *AliasedGV = GA->getAliasee();
return getSymbolNMTypeChar(*AliasedGV);
}
@@ -514,7 +542,7 @@ static void dumpSymbolNamesFromObject(SymbolicFile *Obj) {
}
CurrentFilename = Obj->getFileName();
- sortAndPrintSymbolList();
+ sortAndPrintSymbolList(Obj);
}
static void dumpSymbolNamesFromFile(std::string &Filename) {
@@ -567,10 +595,24 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
E = UB->end_objects();
I != E; ++I) {
std::unique_ptr<ObjectFile> Obj;
+ std::unique_ptr<Archive> A;
if (!I->getAsObjectFile(Obj)) {
outs() << Obj->getFileName() << ":\n";
dumpSymbolNamesFromObject(Obj.get());
}
+ else if (!I->getAsArchive(A)) {
+ for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end();
+ AI != AE; ++AI) {
+ std::unique_ptr<Binary> Child;
+ if (AI->getAsBinary(Child, &Context))
+ continue;
+ if (SymbolicFile *O = dyn_cast<SymbolicFile>(Child.get())) {
+ outs() << A->getFileName() << ":";
+ outs() << O->getFileName() << ":\n";
+ dumpSymbolNamesFromObject(O);
+ }
+ }
+ }
}
return;
}
diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp
index 89b038f..3ca582f 100644
--- a/tools/llvm-objdump/MachODump.cpp
+++ b/tools/llvm-objdump/MachODump.cpp
@@ -17,6 +17,7 @@
#include "llvm/ADT/Triple.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstPrinter.h"
@@ -64,7 +65,7 @@ static const Target *GetTarget(const MachOObjectFile *MachOObj) {
errs() << "llvm-objdump: error: unable to get target for '" << TripleName
<< "', see --version and --triple.\n";
- return 0;
+ return nullptr;
}
struct SymbolSorter {
@@ -225,8 +226,9 @@ static void DisassembleInputMachO2(StringRef Filename,
TheTarget->createMCAsmInfo(*MRI, TripleName));
std::unique_ptr<const MCSubtargetInfo> STI(
TheTarget->createMCSubtargetInfo(TripleName, "", ""));
+ MCContext Ctx(AsmInfo.get(), MRI.get(), nullptr);
std::unique_ptr<const MCDisassembler> DisAsm(
- TheTarget->createMCDisassembler(*STI));
+ TheTarget->createMCDisassembler(*STI, Ctx));
int AsmPrinterVariant = AsmInfo->getAssemblerDialect();
std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
AsmPrinterVariant, *AsmInfo, *InstrInfo, *MRI, *STI));
@@ -419,9 +421,9 @@ static void DisassembleInputMachO2(StringRef Filename,
DILineInfo dli =
diContext->getLineInfoForAddress(SectAddress + Index);
// Print valid line info if it changed.
- if (dli != lastLine && dli.getLine() != 0)
- outs() << "\t## " << dli.getFileName() << ':'
- << dli.getLine() << ':' << dli.getColumn();
+ if (dli != lastLine && dli.Line != 0)
+ outs() << "\t## " << dli.FileName << ':' << dli.Line << ':'
+ << dli.Column;
lastLine = dli;
}
outs() << "\n";
diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp
index 729fcba..a4fc6d0 100644
--- a/tools/llvm-objdump/llvm-objdump.cpp
+++ b/tools/llvm-objdump/llvm-objdump.cpp
@@ -157,7 +157,7 @@ bool llvm::error(error_code EC) {
return true;
}
-static const Target *getTarget(const ObjectFile *Obj = NULL) {
+static const Target *getTarget(const ObjectFile *Obj = nullptr) {
// Figure out the target triple.
llvm::Triple TheTriple("unknown-unknown-unknown");
if (TripleName.empty()) {
@@ -167,6 +167,12 @@ static const Target *getTarget(const ObjectFile *Obj = NULL) {
// the best we can do here is indicate that it is mach-o.
if (Obj->isMachO())
TheTriple.setObjectFormat(Triple::MachO);
+
+ if (Obj->isCOFF()) {
+ const auto COFFObj = dyn_cast<COFFObjectFile>(Obj);
+ if (COFFObj->getArch() == Triple::thumb)
+ TheTriple.setTriple("thumbv7-windows");
+ }
}
} else
TheTriple.setTriple(Triple::normalize(TripleName));
@@ -177,7 +183,7 @@ static const Target *getTarget(const ObjectFile *Obj = NULL) {
Error);
if (!TheTarget) {
errs() << ToolName << ": " << Error;
- return 0;
+ return nullptr;
}
// Update the triple name and return the found target.
@@ -309,24 +315,25 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) {
return;
}
- std::unique_ptr<MCDisassembler> DisAsm(TheTarget->createMCDisassembler(*STI));
+ std::unique_ptr<const MCObjectFileInfo> MOFI(new MCObjectFileInfo);
+ MCContext Ctx(AsmInfo.get(), MRI.get(), MOFI.get());
+
+ std::unique_ptr<MCDisassembler> DisAsm(
+ TheTarget->createMCDisassembler(*STI, Ctx));
+
if (!DisAsm) {
errs() << "error: no disassembler for target " << TripleName << "\n";
return;
}
- std::unique_ptr<const MCObjectFileInfo> MOFI;
- std::unique_ptr<MCContext> Ctx;
if (Symbolize) {
- MOFI.reset(new MCObjectFileInfo);
- Ctx.reset(new MCContext(AsmInfo.get(), MRI.get(), MOFI.get()));
std::unique_ptr<MCRelocationInfo> RelInfo(
- TheTarget->createMCRelocationInfo(TripleName, *Ctx.get()));
+ TheTarget->createMCRelocationInfo(TripleName, Ctx));
if (RelInfo) {
std::unique_ptr<MCSymbolizer> Symzer(
- MCObjectSymbolizer::createObjectSymbolizer(*Ctx.get(),
- std::move(RelInfo), Obj));
+ MCObjectSymbolizer::createObjectSymbolizer(Ctx, std::move(RelInfo),
+ Obj));
if (Symzer)
DisAsm->setSymbolizer(std::move(Symzer));
}
@@ -664,16 +671,33 @@ static void PrintSectionContents(const ObjectFile *Obj) {
static void PrintCOFFSymbolTable(const COFFObjectFile *coff) {
const coff_file_header *header;
- if (error(coff->getHeader(header))) return;
- int aux_count = 0;
- const coff_symbol *symbol = 0;
- for (int i = 0, e = header->NumberOfSymbols; i != e; ++i) {
- if (aux_count--) {
- // Figure out which type of aux this is.
- if (symbol->isSectionDefinition()) { // Section definition.
+ if (error(coff->getHeader(header)))
+ return;
+
+ for (unsigned SI = 0, SE = header->NumberOfSymbols; SI != SE; ++SI) {
+ const coff_symbol *Symbol;
+ StringRef Name;
+ if (error(coff->getSymbol(SI, Symbol)))
+ return;
+
+ if (error(coff->getSymbolName(Symbol, Name)))
+ return;
+
+ outs() << "[" << format("%2d", SI) << "]"
+ << "(sec " << format("%2d", int(Symbol->SectionNumber)) << ")"
+ << "(fl 0x00)" // Flag bits, which COFF doesn't have.
+ << "(ty " << format("%3x", unsigned(Symbol->Type)) << ")"
+ << "(scl " << format("%3x", unsigned(Symbol->StorageClass)) << ") "
+ << "(nx " << unsigned(Symbol->NumberOfAuxSymbols) << ") "
+ << "0x" << format("%08x", unsigned(Symbol->Value)) << " "
+ << Name << "\n";
+
+ for (unsigned AI = 0, AE = Symbol->NumberOfAuxSymbols; AI < AE; ++AI, ++SI) {
+ if (Symbol->isSectionDefinition()) {
const coff_aux_section_definition *asd;
- if (error(coff->getAuxSymbol<coff_aux_section_definition>(i, asd)))
+ if (error(coff->getAuxSymbol<coff_aux_section_definition>(SI + 1, asd)))
return;
+
outs() << "AUX "
<< format("scnlen 0x%x nreloc %d nlnno %d checksum 0x%x "
, unsigned(asd->Length)
@@ -683,21 +707,20 @@ static void PrintCOFFSymbolTable(const COFFObjectFile *coff) {
<< format("assoc %d comdat %d\n"
, unsigned(asd->Number)
, unsigned(asd->Selection));
- } else
+ } else if (Symbol->isFileRecord()) {
+ const coff_aux_file *AF;
+ if (error(coff->getAuxSymbol<coff_aux_file>(SI + 1, AF)))
+ return;
+
+ StringRef Name(AF->FileName,
+ Symbol->NumberOfAuxSymbols * COFF::SymbolSize);
+ outs() << "AUX " << Name.rtrim(StringRef("\0", 1)) << '\n';
+
+ SI = SI + Symbol->NumberOfAuxSymbols;
+ break;
+ } else {
outs() << "AUX Unknown\n";
- } else {
- StringRef name;
- if (error(coff->getSymbol(i, symbol))) return;
- if (error(coff->getSymbolName(symbol, name))) return;
- outs() << "[" << format("%2d", i) << "]"
- << "(sec " << format("%2d", int(symbol->SectionNumber)) << ")"
- << "(fl 0x00)" // Flag bits, which COFF doesn't have.
- << "(ty " << format("%3x", unsigned(symbol->Type)) << ")"
- << "(scl " << format("%3x", unsigned(symbol->StorageClass)) << ") "
- << "(nx " << unsigned(symbol->NumberOfAuxSymbols) << ") "
- << "0x" << format("%08x", unsigned(symbol->Value)) << " "
- << name << "\n";
- aux_count = symbol->NumberOfAuxSymbols;
+ }
}
}
}
diff --git a/tools/llvm-profdata/llvm-profdata.cpp b/tools/llvm-profdata/llvm-profdata.cpp
index 397b523..fdde32a 100644
--- a/tools/llvm-profdata/llvm-profdata.cpp
+++ b/tools/llvm-profdata/llvm-profdata.cpp
@@ -15,6 +15,7 @@
#include "llvm/ProfileData/InstrProfReader.h"
#include "llvm/ProfileData/InstrProfWriter.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"
@@ -39,16 +40,15 @@ int merge_main(int argc, const char *argv[]) {
cl::opt<std::string> OutputFilename("output", cl::value_desc("output"),
cl::init("-"),
cl::desc("Output file"));
- cl::alias OutputFilenameA("o", cl::desc("Alias for --output"),
- cl::aliasopt(OutputFilename));
+ cl::alias OutputFilenameA("o", cl::desc("Alias for --output"), cl::Required,
+ cl::aliasopt(OutputFilename));
cl::ParseCommandLineOptions(argc, argv, "LLVM profile data merger\n");
- if (OutputFilename.empty())
- OutputFilename = "-";
+ if (OutputFilename.compare("-") == 0)
+ exitWithError("Cannot write indexed profdata format to stdout.");
std::string ErrorInfo;
- // FIXME: F_Text would be available if line_iterator could accept CRLF.
raw_fd_ostream Output(OutputFilename.data(), ErrorInfo, sys::fs::F_None);
if (!ErrorInfo.empty())
exitWithError(ErrorInfo, OutputFilename);
@@ -112,6 +112,7 @@ int show_main(int argc, const char *argv[]) {
Func.Name.find(ShowFunction) != Func.Name.npos);
++TotalFunctions;
+ assert(Func.Counts.size() > 0 && "function missing entry counter");
if (Func.Counts[0] > MaxFunctionCount)
MaxFunctionCount = Func.Counts[0];
@@ -156,7 +157,7 @@ int main(int argc, const char *argv[]) {
StringRef ProgName(sys::path::filename(argv[0]));
if (argc > 1) {
- int (*func)(int, const char *[]) = 0;
+ int (*func)(int, const char *[]) = nullptr;
if (strcmp(argv[1], "merge") == 0)
func = merge_main;
diff --git a/tools/llvm-readobj/ARMAttributeParser.cpp b/tools/llvm-readobj/ARMAttributeParser.cpp
index 5857547..d35cd14 100644
--- a/tools/llvm-readobj/ARMAttributeParser.cpp
+++ b/tools/llvm-readobj/ARMAttributeParser.cpp
@@ -9,6 +9,7 @@
#include "ARMAttributeParser.h"
#include "StreamWriter.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/LEB128.h"
@@ -22,11 +23,6 @@ static const EnumEntry<unsigned> TagNames[] = {
{ "Tag_Symbol", ARMBuildAttrs::Symbol },
};
-template <typename type_, size_t size_>
-size_t countof(const type_ (&)[size_]) {
- return size_;
-}
-
namespace llvm {
#define ATTRIBUTE_HANDLER(Attr_) \
{ ARMBuildAttrs::Attr_, &ARMAttributeParser::Attr_ }
@@ -129,7 +125,8 @@ void ARMAttributeParser::CPU_arch(AttrType Tag, const uint8_t *Data,
};
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -155,7 +152,8 @@ void ARMAttributeParser::ARM_ISA_use(AttrType Tag, const uint8_t *Data,
static const char *Strings[] = { "Not Permitted", "Permitted" };
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -164,7 +162,8 @@ void ARMAttributeParser::THUMB_ISA_use(AttrType Tag, const uint8_t *Data,
static const char *Strings[] = { "Not Permitted", "Thumb-1", "Thumb-2" };
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -176,7 +175,8 @@ void ARMAttributeParser::FP_arch(AttrType Tag, const uint8_t *Data,
};
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -185,7 +185,8 @@ void ARMAttributeParser::WMMX_arch(AttrType Tag, const uint8_t *Data,
static const char *Strings[] = { "Not Permitted", "WMMXv1", "WMMXv2" };
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -196,7 +197,8 @@ void ARMAttributeParser::Advanced_SIMD_arch(AttrType Tag, const uint8_t *Data,
};
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -208,7 +210,8 @@ void ARMAttributeParser::PCS_config(AttrType Tag, const uint8_t *Data,
};
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -217,7 +220,8 @@ void ARMAttributeParser::ABI_PCS_R9_use(AttrType Tag, const uint8_t *Data,
static const char *Strings[] = { "v6", "Static Base", "TLS", "Unused" };
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -228,7 +232,8 @@ void ARMAttributeParser::ABI_PCS_RW_data(AttrType Tag, const uint8_t *Data,
};
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -237,7 +242,8 @@ void ARMAttributeParser::ABI_PCS_RO_data(AttrType Tag, const uint8_t *Data,
static const char *Strings[] = { "Absolute", "PC-relative", "Not Permitted" };
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -246,7 +252,8 @@ void ARMAttributeParser::ABI_PCS_GOT_use(AttrType Tag, const uint8_t *Data,
static const char *Strings[] = { "Not Permitted", "Direct", "GOT-Indirect" };
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -257,7 +264,8 @@ void ARMAttributeParser::ABI_PCS_wchar_t(AttrType Tag, const uint8_t *Data,
};
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -266,7 +274,8 @@ void ARMAttributeParser::ABI_FP_rounding(AttrType Tag, const uint8_t *Data,
static const char *Strings[] = { "IEEE-754", "Runtime" };
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -275,7 +284,8 @@ void ARMAttributeParser::ABI_FP_denormal(AttrType Tag, const uint8_t *Data,
static const char *Strings[] = { "Unsupported", "IEEE-754", "Sign Only" };
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -284,7 +294,8 @@ void ARMAttributeParser::ABI_FP_exceptions(AttrType Tag, const uint8_t *Data,
static const char *Strings[] = { "Not Permitted", "IEEE-754" };
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -294,7 +305,8 @@ void ARMAttributeParser::ABI_FP_user_exceptions(AttrType Tag,
static const char *Strings[] = { "Not Permitted", "IEEE-754" };
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -305,7 +317,8 @@ void ARMAttributeParser::ABI_FP_number_model(AttrType Tag, const uint8_t *Data,
};
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -318,7 +331,7 @@ void ARMAttributeParser::ABI_align_needed(AttrType Tag, const uint8_t *Data,
uint64_t Value = ParseInteger(Data, Offset);
std::string Description;
- if (Value < countof(Strings))
+ if (Value < array_lengthof(Strings))
Description = std::string(Strings[Value]);
else if (Value <= 12)
Description = std::string("8-byte alignment, ") + utostr(1 << Value)
@@ -339,7 +352,7 @@ void ARMAttributeParser::ABI_align_preserved(AttrType Tag, const uint8_t *Data,
uint64_t Value = ParseInteger(Data, Offset);
std::string Description;
- if (Value < countof(Strings))
+ if (Value < array_lengthof(Strings))
Description = std::string(Strings[Value]);
else if (Value <= 12)
Description = std::string("8-byte stack alignment, ") + utostr(1 << Value)
@@ -357,7 +370,8 @@ void ARMAttributeParser::ABI_enum_size(AttrType Tag, const uint8_t *Data,
};
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -368,7 +382,8 @@ void ARMAttributeParser::ABI_HardFP_use(AttrType Tag, const uint8_t *Data,
};
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -379,7 +394,8 @@ void ARMAttributeParser::ABI_VFP_args(AttrType Tag, const uint8_t *Data,
};
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -388,7 +404,8 @@ void ARMAttributeParser::ABI_WMMX_args(AttrType Tag, const uint8_t *Data,
static const char *Strings[] = { "AAPCS", "iWMMX", "Custom" };
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -401,7 +418,8 @@ void ARMAttributeParser::ABI_optimization_goals(AttrType Tag,
};
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -414,7 +432,8 @@ void ARMAttributeParser::ABI_FP_optimization_goals(AttrType Tag,
};
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -445,7 +464,8 @@ void ARMAttributeParser::CPU_unaligned_access(AttrType Tag, const uint8_t *Data,
static const char *Strings[] = { "Not Permitted", "v6-style" };
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -454,7 +474,8 @@ void ARMAttributeParser::FP_HP_extension(AttrType Tag, const uint8_t *Data,
static const char *Strings[] = { "If Available", "Permitted" };
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -463,7 +484,8 @@ void ARMAttributeParser::ABI_FP_16bit_format(AttrType Tag, const uint8_t *Data,
static const char *Strings[] = { "Not Permitted", "IEEE-754", "VFPv3" };
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -472,7 +494,8 @@ void ARMAttributeParser::MPextension_use(AttrType Tag, const uint8_t *Data,
static const char *Strings[] = { "Not Permitted", "Permitted" };
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -483,7 +506,8 @@ void ARMAttributeParser::DIV_use(AttrType Tag, const uint8_t *Data,
};
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -492,7 +516,8 @@ void ARMAttributeParser::T2EE_use(AttrType Tag, const uint8_t *Data,
static const char *Strings[] = { "Not Permitted", "Permitted" };
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -504,7 +529,8 @@ void ARMAttributeParser::Virtualization_use(AttrType Tag, const uint8_t *Data,
};
uint64_t Value = ParseInteger(Data, Offset);
- StringRef ValueDesc = (Value < countof(Strings)) ? Strings[Value] : NULL;
+ StringRef ValueDesc =
+ (Value < array_lengthof(Strings)) ? Strings[Value] : nullptr;
PrintAttribute(Tag, Value, ValueDesc);
}
@@ -534,7 +560,7 @@ void ARMAttributeParser::ParseAttributeList(const uint8_t *Data,
Offset += Length;
bool Handled = false;
- for (unsigned AHI = 0, AHE = countof(DisplayRoutines);
+ for (unsigned AHI = 0, AHE = array_lengthof(DisplayRoutines);
AHI != AHE && !Handled; ++AHI) {
if (DisplayRoutines[AHI].Attribute == Tag) {
(this->*DisplayRoutines[AHI].Routine)(ARMBuildAttrs::AttrType(Tag),
diff --git a/tools/llvm-readobj/ARMEHABIPrinter.h b/tools/llvm-readobj/ARMEHABIPrinter.h
index 75e2bee..7608cfb 100644
--- a/tools/llvm-readobj/ARMEHABIPrinter.h
+++ b/tools/llvm-readobj/ARMEHABIPrinter.h
@@ -12,6 +12,7 @@
#include "Error.h"
#include "StreamWriter.h"
+#include "llvm/ADT/STLExtras.h"
#include "llvm/Object/ELF.h"
#include "llvm/Object/ELFTypes.h"
#include "llvm/Support/ARMEHABI.h"
@@ -20,13 +21,6 @@
#include "llvm/Support/Format.h"
#include "llvm/Support/type_traits.h"
-namespace {
-template <typename type_, size_t N>
-size_t countof(const type_ (&)[N]) {
- return N;
-}
-}
-
namespace llvm {
namespace ARM {
namespace EHABI {
@@ -296,7 +290,8 @@ void OpcodeDecoder::PrintRegisters(uint32_t VFPMask, StringRef Prefix) {
void OpcodeDecoder::Decode(const uint8_t *Opcodes, off_t Offset, size_t Length) {
for (unsigned OCI = Offset; OCI < Length + Offset; ) {
bool Decoded = false;
- for (unsigned REI = 0, REE = countof(Ring); REI != REE && !Decoded; ++REI) {
+ for (unsigned REI = 0, REE = array_lengthof(Ring);
+ REI != REE && !Decoded; ++REI) {
if ((Opcodes[OCI ^ 3] & Ring[REI].Mask) == Ring[REI].Value) {
(this->*Ring[REI].Routine)(Opcodes, OCI);
Decoded = true;
@@ -390,7 +385,7 @@ PrinterContext<ET>::FindExceptionTable(unsigned IndexSectionIndex,
}
}
}
- return NULL;
+ return nullptr;
}
template <typename ET>
diff --git a/tools/llvm-readobj/CMakeLists.txt b/tools/llvm-readobj/CMakeLists.txt
index 036185d..b057dcd 100644
--- a/tools/llvm-readobj/CMakeLists.txt
+++ b/tools/llvm-readobj/CMakeLists.txt
@@ -5,12 +5,13 @@ set(LLVM_LINK_COMPONENTS
)
add_llvm_tool(llvm-readobj
- llvm-readobj.cpp
- ObjDumper.cpp
+ ARMAttributeParser.cpp
COFFDumper.cpp
ELFDumper.cpp
- MachODumper.cpp
Error.cpp
+ llvm-readobj.cpp
+ MachODumper.cpp
+ ObjDumper.cpp
StreamWriter.cpp
- ARMAttributeParser.cpp
+ Win64EHDumper.cpp
)
diff --git a/tools/llvm-readobj/COFFDumper.cpp b/tools/llvm-readobj/COFFDumper.cpp
index cd40da7..91f2a57 100644
--- a/tools/llvm-readobj/COFFDumper.cpp
+++ b/tools/llvm-readobj/COFFDumper.cpp
@@ -16,6 +16,7 @@
#include "Error.h"
#include "ObjDumper.h"
#include "StreamWriter.h"
+#include "Win64EHDumper.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Object/COFF.h"
@@ -58,45 +59,24 @@ private:
void printSymbol(const SymbolRef &Sym);
void printRelocation(const SectionRef &Section, const RelocationRef &Reloc);
void printDataDirectory(uint32_t Index, const std::string &FieldName);
- void printX64UnwindInfo();
template <class PEHeader> void printPEHeader(const PEHeader *Hdr);
void printBaseOfDataField(const pe32_header *Hdr);
void printBaseOfDataField(const pe32plus_header *Hdr);
- void printRuntimeFunction(
- const RuntimeFunction& RTF,
- uint64_t OffsetInSection,
- const std::vector<RelocationRef> &Rels);
-
- void printUnwindInfo(
- const Win64EH::UnwindInfo& UI,
- uint64_t OffsetInSection,
- const std::vector<RelocationRef> &Rels);
-
- void printUnwindCode(const Win64EH::UnwindInfo &UI, ArrayRef<UnwindCode> UCs);
-
void printCodeViewLineTables(const SectionRef &Section);
void cacheRelocations();
- error_code getSectionContents(
- const std::vector<RelocationRef> &Rels,
- uint64_t Offset,
- ArrayRef<uint8_t> &Contents,
- uint64_t &Addr);
-
- error_code getSection(
- const std::vector<RelocationRef> &Rels,
- uint64_t Offset,
- const coff_section **Section,
- uint64_t *AddrPtr);
+ error_code resolveSymbol(const coff_section *Section, uint64_t Offset,
+ SymbolRef &Sym);
+ error_code resolveSymbolName(const coff_section *Section, uint64_t Offset,
+ StringRef &Name);
typedef DenseMap<const coff_section*, std::vector<RelocationRef> > RelocMapTy;
const llvm::object::COFFObjectFile *Obj;
RelocMapTy RelocMap;
- std::vector<RelocationRef> EmptyRelocs;
};
} // namespace
@@ -116,110 +96,33 @@ error_code createCOFFDumper(const object::ObjectFile *Obj, StreamWriter &Writer,
} // namespace llvm
-
-// Returns the name of the unwind code.
-static StringRef getUnwindCodeTypeName(uint8_t Code) {
- switch(Code) {
- default: llvm_unreachable("Invalid unwind code");
- case UOP_PushNonVol: return "PUSH_NONVOL";
- case UOP_AllocLarge: return "ALLOC_LARGE";
- case UOP_AllocSmall: return "ALLOC_SMALL";
- case UOP_SetFPReg: return "SET_FPREG";
- case UOP_SaveNonVol: return "SAVE_NONVOL";
- case UOP_SaveNonVolBig: return "SAVE_NONVOL_FAR";
- case UOP_SaveXMM128: return "SAVE_XMM128";
- case UOP_SaveXMM128Big: return "SAVE_XMM128_FAR";
- case UOP_PushMachFrame: return "PUSH_MACHFRAME";
- }
-}
-
-// Returns the name of a referenced register.
-static StringRef getUnwindRegisterName(uint8_t Reg) {
- switch(Reg) {
- default: llvm_unreachable("Invalid register");
- case 0: return "RAX";
- case 1: return "RCX";
- case 2: return "RDX";
- case 3: return "RBX";
- case 4: return "RSP";
- case 5: return "RBP";
- case 6: return "RSI";
- case 7: return "RDI";
- case 8: return "R8";
- case 9: return "R9";
- case 10: return "R10";
- case 11: return "R11";
- case 12: return "R12";
- case 13: return "R13";
- case 14: return "R14";
- case 15: return "R15";
- }
-}
-
-// Calculates the number of array slots required for the unwind code.
-static unsigned getNumUsedSlots(const UnwindCode &UnwindCode) {
- switch (UnwindCode.getUnwindOp()) {
- default: llvm_unreachable("Invalid unwind code");
- case UOP_PushNonVol:
- case UOP_AllocSmall:
- case UOP_SetFPReg:
- case UOP_PushMachFrame:
- return 1;
- case UOP_SaveNonVol:
- case UOP_SaveXMM128:
- return 2;
- case UOP_SaveNonVolBig:
- case UOP_SaveXMM128Big:
- return 3;
- case UOP_AllocLarge:
- return (UnwindCode.getOpInfo() == 0) ? 2 : 3;
- }
-}
-
-// Given a symbol sym this functions returns the address and section of it.
-static error_code resolveSectionAndAddress(const COFFObjectFile *Obj,
- const SymbolRef &Sym,
- const coff_section *&ResolvedSection,
- uint64_t &ResolvedAddr) {
- if (error_code EC = Sym.getAddress(ResolvedAddr))
- return EC;
-
- section_iterator iter(Obj->section_begin());
- if (error_code EC = Sym.getSection(iter))
- return EC;
-
- ResolvedSection = Obj->getCOFFSection(*iter);
- return object_error::success;
-}
-
-// Given a vector of relocations for a section and an offset into this section
-// the function returns the symbol used for the relocation at the offset.
-static error_code resolveSymbol(const std::vector<RelocationRef> &Rels,
- uint64_t Offset, SymbolRef &Sym) {
- for (std::vector<RelocationRef>::const_iterator RelI = Rels.begin(),
- RelE = Rels.end();
- RelI != RelE; ++RelI) {
- uint64_t Ofs;
- if (error_code EC = RelI->getOffset(Ofs))
+// Given a a section and an offset into this section the function returns the
+// symbol used for the relocation at the offset.
+error_code COFFDumper::resolveSymbol(const coff_section *Section,
+ uint64_t Offset, SymbolRef &Sym) {
+ const auto &Relocations = RelocMap[Section];
+ for (const auto &Relocation : Relocations) {
+ uint64_t RelocationOffset;
+ if (error_code EC = Relocation.getOffset(RelocationOffset))
return EC;
- if (Ofs == Offset) {
- Sym = *RelI->getSymbol();
+ if (RelocationOffset == Offset) {
+ Sym = *Relocation.getSymbol();
return readobj_error::success;
}
}
-
return readobj_error::unknown_symbol;
}
-// Given a vector of relocations for a section and an offset into this section
-// the function returns the name of the symbol used for the relocation at the
-// offset.
-static error_code resolveSymbolName(const std::vector<RelocationRef> &Rels,
- uint64_t Offset, StringRef &Name) {
- SymbolRef Sym;
- if (error_code EC = resolveSymbol(Rels, Offset, Sym)) return EC;
- if (error_code EC = Sym.getName(Name)) return EC;
+// Given a section and an offset into this section the function returns the name
+// of the symbol used for the relocation at the offset.
+error_code COFFDumper::resolveSymbolName(const coff_section *Section,
+ uint64_t Offset, StringRef &Name) {
+ SymbolRef Symbol;
+ if (error_code EC = resolveSymbol(Section, Offset, Symbol))
+ return EC;
+ if (error_code EC = Symbol.getName(Name))
+ return EC;
return object_error::success;
}
@@ -403,50 +306,6 @@ WeakExternalCharacteristics[] = {
{ "Alias" , COFF::IMAGE_WEAK_EXTERN_SEARCH_ALIAS }
};
-static const EnumEntry<unsigned> UnwindFlags[] = {
- { "ExceptionHandler", Win64EH::UNW_ExceptionHandler },
- { "TerminateHandler", Win64EH::UNW_TerminateHandler },
- { "ChainInfo" , Win64EH::UNW_ChainInfo }
-};
-
-static const EnumEntry<unsigned> UnwindOpInfo[] = {
- { "RAX", 0 },
- { "RCX", 1 },
- { "RDX", 2 },
- { "RBX", 3 },
- { "RSP", 4 },
- { "RBP", 5 },
- { "RSI", 6 },
- { "RDI", 7 },
- { "R8", 8 },
- { "R9", 9 },
- { "R10", 10 },
- { "R11", 11 },
- { "R12", 12 },
- { "R13", 13 },
- { "R14", 14 },
- { "R15", 15 }
-};
-
-// Some additional COFF structures not defined by llvm::object.
-namespace {
- struct coff_aux_file_record {
- char FileName[18];
- };
-} // namespace
-
-static uint64_t getOffsetOfLSDA(const Win64EH::UnwindInfo& UI) {
- return static_cast<const char*>(UI.getLanguageSpecificData())
- - reinterpret_cast<const char*>(&UI);
-}
-
-static uint32_t getLargeSlotValue(ArrayRef<UnwindCode> UCs) {
- if (UCs.size() < 3)
- return 0;
-
- return UCs[1].FrameOffset + (static_cast<uint32_t>(UCs[2].FrameOffset) << 16);
-}
-
template<typename T>
static error_code getSymbolAuxData(const COFFObjectFile *Obj,
const coff_symbol *Symbol, const T* &Aux) {
@@ -455,69 +314,6 @@ static error_code getSymbolAuxData(const COFFObjectFile *Obj,
return readobj_error::success;
}
-static std::string formatSymbol(const std::vector<RelocationRef> &Rels,
- uint64_t Offset, uint32_t Disp) {
- std::string Buffer;
- raw_string_ostream Str(Buffer);
-
- StringRef Sym;
- if (resolveSymbolName(Rels, Offset, Sym)) {
- Str << format(" (0x%" PRIX64 ")", Offset);
- return Str.str();
- }
-
- Str << Sym;
- if (Disp > 0) {
- Str << format(" +0x%X (0x%" PRIX64 ")", Disp, Offset);
- } else {
- Str << format(" (0x%" PRIX64 ")", Offset);
- }
-
- return Str.str();
-}
-
-// Given a vector of relocations for a section and an offset into this section
-// the function resolves the symbol used for the relocation at the offset and
-// returns the section content and the address inside the content pointed to
-// by the symbol.
-error_code COFFDumper::getSectionContents(
- const std::vector<RelocationRef> &Rels, uint64_t Offset,
- ArrayRef<uint8_t> &Contents, uint64_t &Addr) {
-
- SymbolRef Sym;
- const coff_section *Section;
-
- if (error_code EC = resolveSymbol(Rels, Offset, Sym))
- return EC;
- if (error_code EC = resolveSectionAndAddress(Obj, Sym, Section, Addr))
- return EC;
- if (error_code EC = Obj->getSectionContents(Section, Contents))
- return EC;
-
- return object_error::success;
-}
-
-error_code COFFDumper::getSection(
- const std::vector<RelocationRef> &Rels, uint64_t Offset,
- const coff_section **SectionPtr, uint64_t *AddrPtr) {
-
- SymbolRef Sym;
- if (error_code EC = resolveSymbol(Rels, Offset, Sym))
- return EC;
-
- const coff_section *Section;
- uint64_t Addr;
- if (error_code EC = resolveSectionAndAddress(Obj, Sym, Section, Addr))
- return EC;
-
- if (SectionPtr)
- *SectionPtr = Section;
- if (AddrPtr)
- *AddrPtr = Addr;
-
- return object_error::success;
-}
-
void COFFDumper::cacheRelocations() {
for (const SectionRef &S : Obj->sections()) {
const coff_section *Section = Obj->getCOFFSection(S);
@@ -541,7 +337,7 @@ void COFFDumper::printDataDirectory(uint32_t Index, const std::string &FieldName
void COFFDumper::printFileHeaders() {
// Print COFF header
- const coff_file_header *COFFHeader = 0;
+ const coff_file_header *COFFHeader = nullptr;
if (error(Obj->getCOFFHeader(COFFHeader)))
return;
@@ -564,13 +360,13 @@ void COFFDumper::printFileHeaders() {
// Print PE header. This header does not exist if this is an object file and
// not an executable.
- const pe32_header *PEHeader = 0;
+ const pe32_header *PEHeader = nullptr;
if (error(Obj->getPE32Header(PEHeader)))
return;
if (PEHeader)
printPEHeader<pe32_header>(PEHeader);
- const pe32plus_header *PEPlusHeader = 0;
+ const pe32plus_header *PEPlusHeader = nullptr;
if (error(Obj->getPE32PlusHeader(PEPlusHeader)))
return;
if (PEPlusHeader)
@@ -685,8 +481,8 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) {
}
StringRef FunctionName;
- if (error(resolveSymbolName(RelocMap[Obj->getCOFFSection(Section)],
- Offset, FunctionName)))
+ if (error(resolveSymbolName(Obj->getCOFFSection(Section), Offset,
+ FunctionName)))
return;
W.printString("FunctionName", FunctionName);
if (FunctionLineTables.count(FunctionName) != 0) {
@@ -700,7 +496,7 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) {
break;
}
case COFF::DEBUG_STRING_TABLE_SUBSECTION:
- if (PayloadSize == 0 || StringTable.data() != 0 ||
+ if (PayloadSize == 0 || StringTable.data() != nullptr ||
Contents.back() != '\0') {
// Empty or duplicate or non-null-terminated subsection.
error(object_error::parse_failed);
@@ -712,7 +508,8 @@ void COFFDumper::printCodeViewLineTables(const SectionRef &Section) {
// Holds the translation table from file indices
// to offsets in the string table.
- if (PayloadSize == 0 || FileIndexToStringOffsetTable.data() != 0) {
+ if (PayloadSize == 0 ||
+ FileIndexToStringOffsetTable.data() != nullptr) {
// Empty or duplicate subsection.
error(object_error::parse_failed);
return;
@@ -979,13 +776,16 @@ void COFFDumper::printSymbol(const SymbolRef &Sym) {
W.printBinary("Unused", makeArrayRef(Aux->Unused));
} else if (Symbol->isFileRecord()) {
- const coff_aux_file_record *Aux;
+ const coff_aux_file *Aux;
if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
break;
DictScope AS(W, "AuxFileRecord");
- W.printString("FileName", StringRef(Aux->FileName));
+ StringRef Name(Aux->FileName,
+ Symbol->NumberOfAuxSymbols * COFF::SymbolSize);
+ W.printString("FileName", Name.rtrim(StringRef("\0", 1)));
+ break;
} else if (Symbol->isSectionDefinition()) {
const coff_aux_section_definition *Aux;
if (error(getSymbolAuxData(Obj, Symbol + I, Aux)))
@@ -1045,181 +845,23 @@ void COFFDumper::printUnwindInfo() {
return;
ListScope D(W, "UnwindInformation");
- if (Header->Machine != COFF::IMAGE_FILE_MACHINE_AMD64) {
- W.startLine() << "Unsupported image machine type "
- "(currently only AMD64 is supported).\n";
- return;
- }
-
- printX64UnwindInfo();
-}
-
-void COFFDumper::printX64UnwindInfo() {
- for (const SectionRef &Section : Obj->sections()) {
- StringRef Name;
- if (error(Section.getName(Name)))
- continue;
- if (Name != ".pdata" && !Name.startswith(".pdata$"))
- continue;
-
- const coff_section *PData = Obj->getCOFFSection(Section);
-
- ArrayRef<uint8_t> Contents;
- if (error(Obj->getSectionContents(PData, Contents)) || Contents.empty())
- continue;
-
- ArrayRef<RuntimeFunction> RFs(
- reinterpret_cast<const RuntimeFunction *>(Contents.data()),
- Contents.size() / sizeof(RuntimeFunction));
-
- for (const RuntimeFunction *I = RFs.begin(), *E = RFs.end(); I < E; ++I) {
- const uint64_t OffsetInSection = std::distance(RFs.begin(), I)
- * sizeof(RuntimeFunction);
-
- printRuntimeFunction(*I, OffsetInSection, RelocMap[PData]);
- }
- }
-}
-
-void COFFDumper::printRuntimeFunction(
- const RuntimeFunction& RTF,
- uint64_t OffsetInSection,
- const std::vector<RelocationRef> &Rels) {
-
- DictScope D(W, "RuntimeFunction");
- W.printString("StartAddress",
- formatSymbol(Rels, OffsetInSection + 0, RTF.StartAddress));
- W.printString("EndAddress",
- formatSymbol(Rels, OffsetInSection + 4, RTF.EndAddress));
- W.printString("UnwindInfoAddress",
- formatSymbol(Rels, OffsetInSection + 8, RTF.UnwindInfoOffset));
-
- const coff_section* XData = 0;
- uint64_t UnwindInfoOffset = 0;
- if (error(getSection(Rels, OffsetInSection + 8, &XData, &UnwindInfoOffset)))
- return;
-
- ArrayRef<uint8_t> XContents;
- if (error(Obj->getSectionContents(XData, XContents)) || XContents.empty())
- return;
-
- UnwindInfoOffset += RTF.UnwindInfoOffset;
- if (UnwindInfoOffset > XContents.size())
- return;
-
- const Win64EH::UnwindInfo *UI =
- reinterpret_cast<const Win64EH::UnwindInfo *>(
- XContents.data() + UnwindInfoOffset);
-
- printUnwindInfo(*UI, UnwindInfoOffset, RelocMap[XData]);
-}
-
-void COFFDumper::printUnwindInfo(
- const Win64EH::UnwindInfo& UI,
- uint64_t OffsetInSection,
- const std::vector<RelocationRef> &Rels) {
- DictScope D(W, "UnwindInfo");
- W.printNumber("Version", UI.getVersion());
- W.printFlags("Flags", UI.getFlags(), makeArrayRef(UnwindFlags));
- W.printNumber("PrologSize", UI.PrologSize);
- if (UI.getFrameRegister() != 0) {
- W.printEnum("FrameRegister", UI.getFrameRegister(),
- makeArrayRef(UnwindOpInfo));
- W.printHex("FrameOffset", UI.getFrameOffset());
- } else {
- W.printString("FrameRegister", StringRef("-"));
- W.printString("FrameOffset", StringRef("-"));
- }
-
- W.printNumber("UnwindCodeCount", UI.NumCodes);
- {
- ListScope CodesD(W, "UnwindCodes");
- ArrayRef<UnwindCode> UCs(&UI.UnwindCodes[0], UI.NumCodes);
- for (const UnwindCode *I = UCs.begin(), *E = UCs.end(); I < E; ++I) {
- unsigned UsedSlots = getNumUsedSlots(*I);
- if (UsedSlots > UCs.size()) {
- errs() << "Corrupt unwind data";
- return;
- }
- printUnwindCode(UI, ArrayRef<UnwindCode>(I, E));
- I += UsedSlots - 1;
- }
- }
-
- uint64_t LSDAOffset = OffsetInSection + getOffsetOfLSDA(UI);
- if (UI.getFlags() & (UNW_ExceptionHandler | UNW_TerminateHandler)) {
- W.printString("Handler", formatSymbol(Rels, LSDAOffset,
- UI.getLanguageSpecificHandlerOffset()));
- } else if (UI.getFlags() & UNW_ChainInfo) {
- const RuntimeFunction *Chained = UI.getChainedFunctionEntry();
- if (Chained) {
- DictScope D(W, "Chained");
- W.printString("StartAddress", formatSymbol(Rels, LSDAOffset + 0,
- Chained->StartAddress));
- W.printString("EndAddress", formatSymbol(Rels, LSDAOffset + 4,
- Chained->EndAddress));
- W.printString("UnwindInfoAddress", formatSymbol(Rels, LSDAOffset + 8,
- Chained->UnwindInfoOffset));
- }
- }
-}
-
-// Prints one unwind code. Because an unwind code can occupy up to 3 slots in
-// the unwind codes array, this function requires that the correct number of
-// slots is provided.
-void COFFDumper::printUnwindCode(const Win64EH::UnwindInfo& UI,
- ArrayRef<UnwindCode> UCs) {
- assert(UCs.size() >= getNumUsedSlots(UCs[0]));
-
- W.startLine() << format("0x%02X: ", unsigned(UCs[0].u.CodeOffset))
- << getUnwindCodeTypeName(UCs[0].getUnwindOp());
-
- uint32_t AllocSize = 0;
-
- switch (UCs[0].getUnwindOp()) {
- case UOP_PushNonVol:
- outs() << " reg=" << getUnwindRegisterName(UCs[0].getOpInfo());
+ switch (Header->Machine) {
+ case COFF::IMAGE_FILE_MACHINE_AMD64: {
+ Win64EH::Dumper Dumper(W);
+ Win64EH::Dumper::SymbolResolver Resolver =
+ [](const object::coff_section *Section, uint64_t Offset,
+ SymbolRef &Symbol, void *user_data) -> error_code {
+ COFFDumper *Dumper = reinterpret_cast<COFFDumper*>(user_data);
+ return Dumper->resolveSymbol(Section, Offset, Symbol);
+ };
+ Win64EH::Dumper::Context Ctx(*Obj, Resolver, this);
+ Dumper.printData(Ctx);
break;
-
- case UOP_AllocLarge:
- if (UCs[0].getOpInfo() == 0) {
- AllocSize = UCs[1].FrameOffset * 8;
- } else {
- AllocSize = getLargeSlotValue(UCs);
- }
- outs() << " size=" << AllocSize;
- break;
- case UOP_AllocSmall:
- outs() << " size=" << ((UCs[0].getOpInfo() + 1) * 8);
- break;
- case UOP_SetFPReg:
- if (UI.getFrameRegister() == 0) {
- outs() << " reg=<invalid>";
- } else {
- outs() << " reg=" << getUnwindRegisterName(UI.getFrameRegister())
- << format(", offset=0x%X", UI.getFrameOffset() * 16);
- }
- break;
- case UOP_SaveNonVol:
- outs() << " reg=" << getUnwindRegisterName(UCs[0].getOpInfo())
- << format(", offset=0x%X", UCs[1].FrameOffset * 8);
- break;
- case UOP_SaveNonVolBig:
- outs() << " reg=" << getUnwindRegisterName(UCs[0].getOpInfo())
- << format(", offset=0x%X", getLargeSlotValue(UCs));
- break;
- case UOP_SaveXMM128:
- outs() << " reg=XMM" << static_cast<uint32_t>(UCs[0].getOpInfo())
- << format(", offset=0x%X", UCs[1].FrameOffset * 16);
- break;
- case UOP_SaveXMM128Big:
- outs() << " reg=XMM" << static_cast<uint32_t>(UCs[0].getOpInfo())
- << format(", offset=0x%X", getLargeSlotValue(UCs));
- break;
- case UOP_PushMachFrame:
- outs() << " errcode=" << (UCs[0].getOpInfo() == 0 ? "no" : "yes");
+ }
+ default:
+ W.printEnum("unsupported Image Machine", Header->Machine,
+ makeArrayRef(ImageFileMachineType));
break;
}
-
- outs() << "\n";
}
+
diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp
index 4cd3393..de4c207 100644
--- a/tools/llvm-readobj/ELFDumper.cpp
+++ b/tools/llvm-readobj/ELFDumper.cpp
@@ -437,6 +437,29 @@ static const EnumEntry<unsigned> ElfSegmentFlags[] = {
LLVM_READOBJ_ENUM_ENT(ELF, PF_R)
};
+static const EnumEntry<unsigned> ElfHeaderMipsFlags[] = {
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_NOREORDER),
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_PIC),
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_CPIC),
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI2),
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_32BITMODE),
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_NAN2008),
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ABI_O32),
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_MICROMIPS),
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_ASE_M16),
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_1),
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_2),
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_3),
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_4),
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_5),
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32),
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64),
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32R2),
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R2),
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_32R6),
+ LLVM_READOBJ_ENUM_ENT(ELF, EF_MIPS_ARCH_64R6)
+};
+
template<class ELFT>
void ELFDumper<ELFT>::printFileHeaders() {
const typename ELFO::Elf_Ehdr *Header = Obj->getHeader();
@@ -464,7 +487,11 @@ void ELFDumper<ELFT>::printFileHeaders() {
W.printHex ("Entry", Header->e_entry);
W.printHex ("ProgramHeaderOffset", Header->e_phoff);
W.printHex ("SectionHeaderOffset", Header->e_shoff);
- W.printFlags ("Flags", Header->e_flags);
+ if (Header->e_machine == EM_MIPS)
+ W.printFlags("Flags", Header->e_flags, makeArrayRef(ElfHeaderMipsFlags),
+ unsigned(ELF::EF_MIPS_ARCH));
+ else
+ W.printFlags("Flags", Header->e_flags);
W.printNumber("HeaderSize", Header->e_ehsize);
W.printNumber("ProgramHeaderEntrySize", Header->e_phentsize);
W.printNumber("ProgramHeaderCount", Header->e_phnum);
@@ -652,7 +679,8 @@ void ELFDumper<ELFT>::printSymbol(typename ELFO::Elf_Sym_Iter Symbol) {
std::string FullSymbolName(SymbolName);
if (Symbol.isDynamic()) {
bool IsDefault;
- ErrorOr<StringRef> Version = Obj->getSymbolVersion(0, &*Symbol, IsDefault);
+ ErrorOr<StringRef> Version = Obj->getSymbolVersion(nullptr, &*Symbol,
+ IsDefault);
if (Version) {
FullSymbolName += (IsDefault ? "@@" : "@");
FullSymbolName += *Version;
@@ -712,6 +740,8 @@ static const char *getTypeString(uint64_t Type) {
LLVM_READOBJ_TYPE_CASE(VERNEED);
LLVM_READOBJ_TYPE_CASE(VERNEEDNUM);
LLVM_READOBJ_TYPE_CASE(VERSYM);
+ LLVM_READOBJ_TYPE_CASE(RELCOUNT);
+ LLVM_READOBJ_TYPE_CASE(GNU_HASH);
LLVM_READOBJ_TYPE_CASE(MIPS_RLD_VERSION);
LLVM_READOBJ_TYPE_CASE(MIPS_FLAGS);
LLVM_READOBJ_TYPE_CASE(MIPS_BASE_ADDRESS);
@@ -727,6 +757,57 @@ static const char *getTypeString(uint64_t Type) {
#undef LLVM_READOBJ_TYPE_CASE
+#define LLVM_READOBJ_DT_FLAG_ENT(prefix, enum) \
+ { #enum, prefix##_##enum }
+
+static const EnumEntry<unsigned> ElfDynamicDTFlags[] = {
+ LLVM_READOBJ_DT_FLAG_ENT(DF, ORIGIN),
+ LLVM_READOBJ_DT_FLAG_ENT(DF, SYMBOLIC),
+ LLVM_READOBJ_DT_FLAG_ENT(DF, TEXTREL),
+ LLVM_READOBJ_DT_FLAG_ENT(DF, BIND_NOW),
+ LLVM_READOBJ_DT_FLAG_ENT(DF, STATIC_TLS)
+};
+
+static const EnumEntry<unsigned> ElfDynamicDTMipsFlags[] = {
+ LLVM_READOBJ_DT_FLAG_ENT(RHF, NONE),
+ LLVM_READOBJ_DT_FLAG_ENT(RHF, QUICKSTART),
+ LLVM_READOBJ_DT_FLAG_ENT(RHF, NOTPOT),
+ LLVM_READOBJ_DT_FLAG_ENT(RHS, NO_LIBRARY_REPLACEMENT),
+ LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_MOVE),
+ LLVM_READOBJ_DT_FLAG_ENT(RHF, SGI_ONLY),
+ LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_INIT),
+ LLVM_READOBJ_DT_FLAG_ENT(RHF, DELTA_C_PLUS_PLUS),
+ LLVM_READOBJ_DT_FLAG_ENT(RHF, GUARANTEE_START_INIT),
+ LLVM_READOBJ_DT_FLAG_ENT(RHF, PIXIE),
+ LLVM_READOBJ_DT_FLAG_ENT(RHF, DEFAULT_DELAY_LOAD),
+ LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTART),
+ LLVM_READOBJ_DT_FLAG_ENT(RHF, REQUICKSTARTED),
+ LLVM_READOBJ_DT_FLAG_ENT(RHF, CORD),
+ LLVM_READOBJ_DT_FLAG_ENT(RHF, NO_UNRES_UNDEF),
+ LLVM_READOBJ_DT_FLAG_ENT(RHF, RLD_ORDER_SAFE)
+};
+
+#undef LLVM_READOBJ_DT_FLAG_ENT
+
+template <typename T, typename TFlag>
+void printFlags(T Value, ArrayRef<EnumEntry<TFlag>> Flags, raw_ostream &OS) {
+ typedef EnumEntry<TFlag> FlagEntry;
+ typedef SmallVector<FlagEntry, 10> FlagVector;
+ FlagVector SetFlags;
+
+ for (const auto &Flag : Flags) {
+ if (Flag.Value == 0)
+ continue;
+
+ if ((Value & Flag.Value) == Flag.Value)
+ SetFlags.push_back(Flag);
+ }
+
+ for (const auto &Flag : SetFlags) {
+ OS << Flag.Name << " ";
+ }
+}
+
template <class ELFT>
static void printValue(const ELFFile<ELFT> *O, uint64_t Type, uint64_t Value,
bool Is64, raw_ostream &OS) {
@@ -755,14 +836,15 @@ static void printValue(const ELFFile<ELFT> *O, uint64_t Type, uint64_t Value,
case DT_DEBUG:
case DT_VERNEED:
case DT_VERSYM:
+ case DT_GNU_HASH:
case DT_NULL:
- case DT_MIPS_FLAGS:
case DT_MIPS_BASE_ADDRESS:
case DT_MIPS_GOTSYM:
case DT_MIPS_RLD_MAP:
case DT_MIPS_PLTGOT:
OS << format("0x%" PRIX64, Value);
break;
+ case DT_RELCOUNT:
case DT_VERNEEDNUM:
case DT_MIPS_RLD_VERSION:
case DT_MIPS_LOCAL_GOTNO:
@@ -792,6 +874,12 @@ static void printValue(const ELFFile<ELFT> *O, uint64_t Type, uint64_t Value,
case DT_RUNPATH:
OS << O->getDynamicString(Value);
break;
+ case DT_MIPS_FLAGS:
+ printFlags(Value, makeArrayRef(ElfDynamicDTMipsFlags), OS);
+ break;
+ case DT_FLAGS:
+ printFlags(Value, makeArrayRef(ElfDynamicDTFlags), OS);
+ break;
}
}
diff --git a/tools/llvm-readobj/StreamWriter.h b/tools/llvm-readobj/StreamWriter.h
index c40077a..9282dcc 100644
--- a/tools/llvm-readobj/StreamWriter.h
+++ b/tools/llvm-readobj/StreamWriter.h
@@ -81,9 +81,9 @@ public:
ArrayRef<EnumEntry<TEnum> > EnumValues) {
StringRef Name;
bool Found = false;
- for (size_t i = 0; i < EnumValues.size(); ++i) {
- if (EnumValues[i].Value == Value) {
- Name = EnumValues[i].Name;
+ for (const auto &EnumItem : EnumValues) {
+ if (EnumItem.Value == Value) {
+ Name = EnumItem.Name;
Found = true;
break;
}
@@ -103,25 +103,22 @@ public:
typedef SmallVector<FlagEntry, 10> FlagVector;
FlagVector SetFlags;
- for (typename ArrayRef<FlagEntry>::const_iterator I = Flags.begin(),
- E = Flags.end(); I != E; ++I) {
- if (I->Value == 0)
+ for (const auto &Flag : Flags) {
+ if (Flag.Value == 0)
continue;
- bool IsEnum = (I->Value & EnumMask) != 0;
- if ((!IsEnum && (Value & I->Value) == I->Value) ||
- (IsEnum && (Value & EnumMask) == I->Value)) {
- SetFlags.push_back(*I);
+ bool IsEnum = (Flag.Value & EnumMask) != 0;
+ if ((!IsEnum && (Value & Flag.Value) == Flag.Value) ||
+ (IsEnum && (Value & EnumMask) == Flag.Value)) {
+ SetFlags.push_back(Flag);
}
}
std::sort(SetFlags.begin(), SetFlags.end(), &flagName<TFlag>);
startLine() << Label << " [ (" << hex(Value) << ")\n";
- for (typename FlagVector::const_iterator I = SetFlags.begin(),
- E = SetFlags.end();
- I != E; ++I) {
- startLine() << " " << I->Name << " (" << hex(I->Value) << ")\n";
+ for (const auto &Flag : SetFlags) {
+ startLine() << " " << Flag.Name << " (" << hex(Flag.Value) << ")\n";
}
startLine() << "]\n";
}
@@ -176,10 +173,10 @@ public:
void printList(StringRef Label, const SmallVectorImpl<T_> &List) {
startLine() << Label << ": [";
bool Comma = false;
- for (unsigned LI = 0, LE = List.size(); LI != LE; ++LI) {
+ for (const auto &Item : List) {
if (Comma)
OS << ", ";
- OS << List[LI];
+ OS << Item;
Comma = true;
}
OS << "]\n";
diff --git a/tools/llvm-readobj/Win64EHDumper.cpp b/tools/llvm-readobj/Win64EHDumper.cpp
new file mode 100644
index 0000000..c64d362
--- /dev/null
+++ b/tools/llvm-readobj/Win64EHDumper.cpp
@@ -0,0 +1,328 @@
+//===- Win64EHDumper.cpp - Win64 EH Printer ---------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Win64EHDumper.h"
+#include "llvm-readobj.h"
+#include "llvm/Object/COFF.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Format.h"
+
+using namespace llvm;
+using namespace llvm::object;
+using namespace llvm::Win64EH;
+
+static const EnumEntry<unsigned> UnwindFlags[] = {
+ { "ExceptionHandler", UNW_ExceptionHandler },
+ { "TerminateHandler", UNW_TerminateHandler },
+ { "ChainInfo" , UNW_ChainInfo }
+};
+
+static const EnumEntry<unsigned> UnwindOpInfo[] = {
+ { "RAX", 0 },
+ { "RCX", 1 },
+ { "RDX", 2 },
+ { "RBX", 3 },
+ { "RSP", 4 },
+ { "RBP", 5 },
+ { "RSI", 6 },
+ { "RDI", 7 },
+ { "R8", 8 },
+ { "R9", 9 },
+ { "R10", 10 },
+ { "R11", 11 },
+ { "R12", 12 },
+ { "R13", 13 },
+ { "R14", 14 },
+ { "R15", 15 }
+};
+
+static uint64_t getOffsetOfLSDA(const UnwindInfo& UI) {
+ return static_cast<const char*>(UI.getLanguageSpecificData())
+ - reinterpret_cast<const char*>(&UI);
+}
+
+static uint32_t getLargeSlotValue(ArrayRef<UnwindCode> UC) {
+ if (UC.size() < 3)
+ return 0;
+ return UC[1].FrameOffset + (static_cast<uint32_t>(UC[2].FrameOffset) << 16);
+}
+
+// Returns the name of the unwind code.
+static StringRef getUnwindCodeTypeName(uint8_t Code) {
+ switch (Code) {
+ default: llvm_unreachable("Invalid unwind code");
+ case UOP_PushNonVol: return "PUSH_NONVOL";
+ case UOP_AllocLarge: return "ALLOC_LARGE";
+ case UOP_AllocSmall: return "ALLOC_SMALL";
+ case UOP_SetFPReg: return "SET_FPREG";
+ case UOP_SaveNonVol: return "SAVE_NONVOL";
+ case UOP_SaveNonVolBig: return "SAVE_NONVOL_FAR";
+ case UOP_SaveXMM128: return "SAVE_XMM128";
+ case UOP_SaveXMM128Big: return "SAVE_XMM128_FAR";
+ case UOP_PushMachFrame: return "PUSH_MACHFRAME";
+ }
+}
+
+// Returns the name of a referenced register.
+static StringRef getUnwindRegisterName(uint8_t Reg) {
+ switch (Reg) {
+ default: llvm_unreachable("Invalid register");
+ case 0: return "RAX";
+ case 1: return "RCX";
+ case 2: return "RDX";
+ case 3: return "RBX";
+ case 4: return "RSP";
+ case 5: return "RBP";
+ case 6: return "RSI";
+ case 7: return "RDI";
+ case 8: return "R8";
+ case 9: return "R9";
+ case 10: return "R10";
+ case 11: return "R11";
+ case 12: return "R12";
+ case 13: return "R13";
+ case 14: return "R14";
+ case 15: return "R15";
+ }
+}
+
+// Calculates the number of array slots required for the unwind code.
+static unsigned getNumUsedSlots(const UnwindCode &UnwindCode) {
+ switch (UnwindCode.getUnwindOp()) {
+ default: llvm_unreachable("Invalid unwind code");
+ case UOP_PushNonVol:
+ case UOP_AllocSmall:
+ case UOP_SetFPReg:
+ case UOP_PushMachFrame:
+ return 1;
+ case UOP_SaveNonVol:
+ case UOP_SaveXMM128:
+ return 2;
+ case UOP_SaveNonVolBig:
+ case UOP_SaveXMM128Big:
+ return 3;
+ case UOP_AllocLarge:
+ return (UnwindCode.getOpInfo() == 0) ? 2 : 3;
+ }
+}
+
+static std::string formatSymbol(const Dumper::Context &Ctx,
+ const coff_section *Section, uint64_t Offset,
+ uint32_t Displacement) {
+ std::string Buffer;
+ raw_string_ostream OS(Buffer);
+
+ StringRef Name;
+ SymbolRef Symbol;
+ if (Ctx.ResolveSymbol(Section, Offset, Symbol, Ctx.UserData) ||
+ Symbol.getName(Name)) {
+ OS << format(" (0x%" PRIX64 ")", Offset);
+ return OS.str();
+ }
+
+ OS << Name;
+ if (Displacement > 0)
+ OS << format(" +0x%X (0x%" PRIX64 ")", Displacement, Offset);
+ else
+ OS << format(" (0x%" PRIX64 ")", Offset);
+ return OS.str();
+}
+
+static error_code resolveRelocation(const Dumper::Context &Ctx,
+ const coff_section *Section,
+ uint64_t Offset,
+ const coff_section *&ResolvedSection,
+ uint64_t &ResolvedAddress) {
+ SymbolRef Symbol;
+ if (error_code EC = Ctx.ResolveSymbol(Section, Offset, Symbol, Ctx.UserData))
+ return EC;
+
+ if (error_code EC = Symbol.getAddress(ResolvedAddress))
+ return EC;
+
+ section_iterator SI = Ctx.COFF.section_begin();
+ if (error_code EC = Symbol.getSection(SI))
+ return EC;
+
+ ResolvedSection = Ctx.COFF.getCOFFSection(*SI);
+ return object_error::success;
+}
+
+namespace llvm {
+namespace Win64EH {
+void Dumper::printRuntimeFunctionEntry(const Context &Ctx,
+ const coff_section *Section,
+ uint64_t Offset,
+ const RuntimeFunction &RF) {
+ SW.printString("StartAddress",
+ formatSymbol(Ctx, Section, Offset + 0, RF.StartAddress));
+ SW.printString("EndAddress",
+ formatSymbol(Ctx, Section, Offset + 4, RF.EndAddress));
+ SW.printString("UnwindInfoAddress",
+ formatSymbol(Ctx, Section, Offset + 8, RF.UnwindInfoOffset));
+}
+
+// Prints one unwind code. Because an unwind code can occupy up to 3 slots in
+// the unwind codes array, this function requires that the correct number of
+// slots is provided.
+void Dumper::printUnwindCode(const UnwindInfo& UI, ArrayRef<UnwindCode> UC) {
+ assert(UC.size() >= getNumUsedSlots(UC[0]));
+
+ SW.startLine() << format("0x%02X: ", unsigned(UC[0].u.CodeOffset))
+ << getUnwindCodeTypeName(UC[0].getUnwindOp());
+
+ switch (UC[0].getUnwindOp()) {
+ case UOP_PushNonVol:
+ OS << " reg=" << getUnwindRegisterName(UC[0].getOpInfo());
+ break;
+
+ case UOP_AllocLarge:
+ OS << " size="
+ << ((UC[0].getOpInfo() == 0) ? UC[1].FrameOffset * 8
+ : getLargeSlotValue(UC));
+ break;
+
+ case UOP_AllocSmall:
+ OS << " size=" << (UC[0].getOpInfo() + 1) * 8;
+ break;
+
+ case UOP_SetFPReg:
+ if (UI.getFrameRegister() == 0)
+ OS << " reg=<invalid>";
+ else
+ OS << " reg=" << getUnwindRegisterName(UI.getFrameRegister())
+ << format(", offset=0x%X", UI.getFrameOffset() * 16);
+ break;
+
+ case UOP_SaveNonVol:
+ OS << " reg=" << getUnwindRegisterName(UC[0].getOpInfo())
+ << format(", offset=0x%X", UC[1].FrameOffset * 8);
+ break;
+
+ case UOP_SaveNonVolBig:
+ OS << " reg=" << getUnwindRegisterName(UC[0].getOpInfo())
+ << format(", offset=0x%X", getLargeSlotValue(UC));
+ break;
+
+ case UOP_SaveXMM128:
+ OS << " reg=XMM" << static_cast<uint32_t>(UC[0].getOpInfo())
+ << format(", offset=0x%X", UC[1].FrameOffset * 16);
+ break;
+
+ case UOP_SaveXMM128Big:
+ OS << " reg=XMM" << static_cast<uint32_t>(UC[0].getOpInfo())
+ << format(", offset=0x%X", getLargeSlotValue(UC));
+ break;
+
+ case UOP_PushMachFrame:
+ OS << " errcode=" << (UC[0].getOpInfo() == 0 ? "no" : "yes");
+ break;
+ }
+
+ OS << "\n";
+}
+
+void Dumper::printUnwindInfo(const Context &Ctx, const coff_section *Section,
+ off_t Offset, const UnwindInfo &UI) {
+ DictScope UIS(SW, "UnwindInfo");
+ SW.printNumber("Version", UI.getVersion());
+ SW.printFlags("Flags", UI.getFlags(), makeArrayRef(UnwindFlags));
+ SW.printNumber("PrologSize", UI.PrologSize);
+ if (UI.getFrameRegister()) {
+ SW.printEnum("FrameRegister", UI.getFrameRegister(),
+ makeArrayRef(UnwindOpInfo));
+ SW.printHex("FrameOffset", UI.getFrameOffset());
+ } else {
+ SW.printString("FrameRegister", StringRef("-"));
+ SW.printString("FrameOffset", StringRef("-"));
+ }
+
+ SW.printNumber("UnwindCodeCount", UI.NumCodes);
+ {
+ ListScope UCS(SW, "UnwindCodes");
+ ArrayRef<UnwindCode> UC(&UI.UnwindCodes[0], UI.NumCodes);
+ for (const UnwindCode *UCI = UC.begin(), *UCE = UC.end(); UCI < UCE; ++UCI) {
+ unsigned UsedSlots = getNumUsedSlots(*UCI);
+ if (UsedSlots > UC.size()) {
+ errs() << "corrupt unwind data";
+ return;
+ }
+
+ printUnwindCode(UI, ArrayRef<UnwindCode>(UCI, UCE));
+ UCI = UCI + UsedSlots - 1;
+ }
+ }
+
+ uint64_t LSDAOffset = Offset + getOffsetOfLSDA(UI);
+ if (UI.getFlags() & (UNW_ExceptionHandler | UNW_TerminateHandler)) {
+ SW.printString("Handler",
+ formatSymbol(Ctx, Section, LSDAOffset,
+ UI.getLanguageSpecificHandlerOffset()));
+ } else if (UI.getFlags() & UNW_ChainInfo) {
+ if (const RuntimeFunction *Chained = UI.getChainedFunctionEntry()) {
+ DictScope CS(SW, "Chained");
+ printRuntimeFunctionEntry(Ctx, Section, LSDAOffset, *Chained);
+ }
+ }
+}
+
+void Dumper::printRuntimeFunction(const Context &Ctx,
+ const coff_section *Section,
+ uint64_t SectionOffset,
+ const RuntimeFunction &RF) {
+ DictScope RFS(SW, "RuntimeFunction");
+ printRuntimeFunctionEntry(Ctx, Section, SectionOffset, RF);
+
+ const coff_section *XData;
+ uint64_t Offset;
+ if (error(resolveRelocation(Ctx, Section, SectionOffset + 8, XData, Offset)))
+ return;
+
+ ArrayRef<uint8_t> Contents;
+ if (error(Ctx.COFF.getSectionContents(XData, Contents)) || Contents.empty())
+ return;
+
+ Offset = Offset + RF.UnwindInfoOffset;
+ if (Offset > Contents.size())
+ return;
+
+ const auto UI = reinterpret_cast<const UnwindInfo*>(Contents.data() + Offset);
+ printUnwindInfo(Ctx, XData, Offset, *UI);
+}
+
+void Dumper::printData(const Context &Ctx) {
+ for (const auto &Section : Ctx.COFF.sections()) {
+ StringRef Name;
+ if (error(Section.getName(Name)))
+ continue;
+
+ if (Name != ".pdata" && !Name.startswith(".pdata$"))
+ continue;
+
+ const coff_section *PData = Ctx.COFF.getCOFFSection(Section);
+ ArrayRef<uint8_t> Contents;
+ if (error(Ctx.COFF.getSectionContents(PData, Contents)) || Contents.empty())
+ continue;
+
+ const RuntimeFunction *Entries =
+ reinterpret_cast<const RuntimeFunction *>(Contents.data());
+ const size_t Count = Contents.size() / sizeof(RuntimeFunction);
+ ArrayRef<RuntimeFunction> RuntimeFunctions(Entries, Count);
+
+ size_t Index = 0;
+ for (const auto &RF : RuntimeFunctions) {
+ printRuntimeFunction(Ctx, Ctx.COFF.getCOFFSection(Section),
+ Index * sizeof(RuntimeFunction), RF);
+ ++Index;
+ }
+ }
+}
+}
+}
+
diff --git a/tools/llvm-readobj/Win64EHDumper.h b/tools/llvm-readobj/Win64EHDumper.h
new file mode 100644
index 0000000..2eac810
--- /dev/null
+++ b/tools/llvm-readobj/Win64EHDumper.h
@@ -0,0 +1,62 @@
+//===- Win64EHDumper.h - Win64 EH Printing ----------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_READOBJ_WIN64EHPRINTER_H
+#define LLVM_TOOLS_READOBJ_WIN64EHPRINTER_H
+
+#include "StreamWriter.h"
+#include "llvm/Support/Win64EH.h"
+
+namespace llvm {
+namespace object {
+class COFFObjectFile;
+class SymbolRef;
+struct coff_section;
+}
+
+namespace Win64EH {
+class Dumper {
+ StreamWriter &SW;
+ raw_ostream &OS;
+
+public:
+ typedef error_code (*SymbolResolver)(const object::coff_section *, uint64_t,
+ object::SymbolRef &, void *);
+
+ struct Context {
+ const object::COFFObjectFile &COFF;
+ SymbolResolver ResolveSymbol;
+ void *UserData;
+
+ Context(const object::COFFObjectFile &COFF, SymbolResolver Resolver,
+ void *UserData)
+ : COFF(COFF), ResolveSymbol(Resolver), UserData(UserData) {}
+ };
+
+private:
+ void printRuntimeFunctionEntry(const Context &Ctx,
+ const object::coff_section *Section,
+ uint64_t SectionOffset,
+ const RuntimeFunction &RF);
+ void printUnwindCode(const UnwindInfo& UI, ArrayRef<UnwindCode> UC);
+ void printUnwindInfo(const Context &Ctx, const object::coff_section *Section,
+ off_t Offset, const UnwindInfo &UI);
+ void printRuntimeFunction(const Context &Ctx,
+ const object::coff_section *Section,
+ uint64_t SectionOffset, const RuntimeFunction &RF);
+
+public:
+ Dumper(StreamWriter &SW) : SW(SW), OS(SW.getOStream()) {}
+
+ void printData(const Context &Ctx);
+};
+}
+}
+
+#endif
diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp
index ac43653..be5c345 100644
--- a/tools/llvm-rtdyld/llvm-rtdyld.cpp
+++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp
@@ -18,6 +18,7 @@
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/Object/MachO.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Memory.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -51,6 +52,11 @@ EntryPoint("entry",
cl::desc("Function to call as entry point."),
cl::init("_main"));
+static cl::list<std::string>
+Dylibs("dylib",
+ cl::desc("Add library."),
+ cl::ZeroOrMore);
+
/* *** */
// A trivial memory manager that doesn't do anything fancy, just uses the
@@ -69,7 +75,7 @@ public:
void *getPointerToNamedFunction(const std::string &Name,
bool AbortOnFailure = true) override {
- return 0;
+ return nullptr;
}
bool finalizeMemory(std::string *ErrMsg) override { return false; }
@@ -85,7 +91,7 @@ uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size,
unsigned Alignment,
unsigned SectionID,
StringRef SectionName) {
- sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, 0, 0);
+ sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, nullptr, nullptr);
FunctionMemory.push_back(MB);
return (uint8_t*)MB.base();
}
@@ -95,7 +101,7 @@ uint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size,
unsigned SectionID,
StringRef SectionName,
bool IsReadOnly) {
- sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, 0, 0);
+ sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, nullptr, nullptr);
DataMemory.push_back(MB);
return (uint8_t*)MB.base();
}
@@ -121,9 +127,25 @@ static int Error(const Twine &Msg) {
return 1;
}
+static void loadDylibs() {
+ for (const std::string &Dylib : Dylibs) {
+ if (sys::fs::is_regular_file(Dylib)) {
+ std::string ErrMsg;
+ if (sys::DynamicLibrary::LoadLibraryPermanently(Dylib.c_str(), &ErrMsg))
+ llvm::errs() << "Error loading '" << Dylib << "': "
+ << ErrMsg << "\n";
+ } else
+ llvm::errs() << "Dylib not found: '" << Dylib << "'.\n";
+ }
+}
+
+
/* *** */
static int printLineInfoForInput() {
+ // Load any dylibs requested on the command line.
+ loadDylibs();
+
// If we don't have any input files, read from stdin.
if (!InputFileList.size())
InputFileList.push_back("-");
@@ -172,8 +194,7 @@ static int printLineInfoForInput() {
DILineInfoTable::iterator End = Lines.end();
for (DILineInfoTable::iterator It = Begin; It != End; ++It) {
outs() << " Line info @ " << It->first - Addr << ": "
- << It->second.getFileName()
- << ", line:" << It->second.getLine() << "\n";
+ << It->second.FileName << ", line:" << It->second.Line << "\n";
}
}
}
@@ -183,6 +204,9 @@ static int printLineInfoForInput() {
}
static int executeInput() {
+ // Load any dylibs requested on the command line.
+ loadDylibs();
+
// Instantiate a dynamic linker.
TrivialMemoryManager MemMgr;
RuntimeDyld Dyld(&MemMgr);
@@ -214,7 +238,7 @@ static int executeInput() {
// Get the address of the entry point (_main by default).
void *MainAddress = Dyld.getSymbolAddress(EntryPoint);
- if (MainAddress == 0)
+ if (!MainAddress)
return Error("no definition for '" + EntryPoint + "'");
// Invalidate the instruction cache for each loaded function.
@@ -235,7 +259,7 @@ static int executeInput() {
const char **Argv = new const char*[2];
// Use the name of the first input object module as argv[0] for the target.
Argv[0] = InputFileList[0].c_str();
- Argv[1] = 0;
+ Argv[1] = nullptr;
return Main(1, Argv);
}
diff --git a/tools/llvm-shlib/Makefile b/tools/llvm-shlib/Makefile
index 7bbc24c..19077a3 100644
--- a/tools/llvm-shlib/Makefile
+++ b/tools/llvm-shlib/Makefile
@@ -9,8 +9,8 @@
LEVEL := ../..
-LIBRARYNAME = LLVM-$(LLVMVersion)
-LIBRARYALIASNAME = LLVM-$(LLVM_VERSION_MAJOR).$(LLVM_VERSION_MINOR)$(LLVM_VERSION_SUFFIX)
+LIBRARYNAME = LLVM-$(LLVM_VERSION_MAJOR).$(LLVM_VERSION_MINOR)$(LLVM_VERSION_SUFFIX)
+LIBRARYALIASNAME = LLVM-$(LLVMVersion)
NO_BUILD_ARCHIVE := 1
LINK_LIBS_IN_SHARED := 1
diff --git a/tools/llvm-size/llvm-size.cpp b/tools/llvm-size/llvm-size.cpp
index d1bd45a..58eafd4 100644
--- a/tools/llvm-size/llvm-size.cpp
+++ b/tools/llvm-size/llvm-size.cpp
@@ -93,7 +93,7 @@ static void PrintObjectSectionSizes(ObjectFile *Obj) {
std::string fmtbuf;
raw_string_ostream fmt(fmtbuf);
- const char *radix_fmt = 0;
+ const char *radix_fmt = nullptr;
switch (Radix) {
case octal:
radix_fmt = PRIo64;
diff --git a/tools/llvm-stress/llvm-stress.cpp b/tools/llvm-stress/llvm-stress.cpp
index 18f1e6c..23d3b63 100644
--- a/tools/llvm-stress/llvm-stress.cpp
+++ b/tools/llvm-stress/llvm-stress.cpp
@@ -22,6 +22,7 @@
#include "llvm/IR/Verifier.h"
#include "llvm/PassManager.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
@@ -245,7 +246,7 @@ protected:
/// Pick a random scalar type.
Type *pickScalarType() {
- Type *t = 0;
+ Type *t = nullptr;
do {
switch (Ran->Rand() % 30) {
case 0: t = Type::getInt1Ty(Context); break;
@@ -271,7 +272,7 @@ protected:
case 29: if (GenX86MMX) t = Type::getX86_MMXTy(Context); break;
default: llvm_unreachable("Invalid scalar value");
}
- } while (t == 0);
+ } while (t == nullptr);
return t;
}
@@ -713,6 +714,7 @@ int main(int argc, char **argv) {
PassManager Passes;
Passes.add(createVerifierPass());
+ Passes.add(createDebugInfoVerifierPass());
Passes.add(createPrintModulePass(Out->os()));
Passes.run(*M.get());
Out->keep();
diff --git a/tools/llvm-symbolizer/LLVMSymbolize.cpp b/tools/llvm-symbolizer/LLVMSymbolize.cpp
index 13f2f8f..3e71111 100644
--- a/tools/llvm-symbolizer/LLVMSymbolize.cpp
+++ b/tools/llvm-symbolizer/LLVMSymbolize.cpp
@@ -35,20 +35,11 @@ static bool error(error_code ec) {
return true;
}
-static uint32_t
-getDILineInfoSpecifierFlags(const LLVMSymbolizer::Options &Opts) {
- uint32_t Flags = llvm::DILineInfoSpecifier::FileLineInfo |
- llvm::DILineInfoSpecifier::AbsoluteFilePath;
- if (Opts.PrintFunctions)
- Flags |= llvm::DILineInfoSpecifier::FunctionName;
- return Flags;
-}
-
-static void patchFunctionNameInDILineInfo(const std::string &NewFunctionName,
- DILineInfo &LineInfo) {
- std::string FileName = LineInfo.getFileName();
- LineInfo = DILineInfo(StringRef(FileName), StringRef(NewFunctionName),
- LineInfo.getLine(), LineInfo.getColumn());
+static DILineInfoSpecifier
+getDILineInfoSpecifier(const LLVMSymbolizer::Options &Opts) {
+ return DILineInfoSpecifier(
+ DILineInfoSpecifier::FileLineInfoKind::AbsoluteFilePath,
+ Opts.PrintFunctions);
}
ModuleInfo::ModuleInfo(ObjectFile *Obj, DIContext *DICtx)
@@ -122,15 +113,15 @@ DILineInfo ModuleInfo::symbolizeCode(
DILineInfo LineInfo;
if (DebugInfoContext) {
LineInfo = DebugInfoContext->getLineInfoForAddress(
- ModuleOffset, getDILineInfoSpecifierFlags(Opts));
+ ModuleOffset, getDILineInfoSpecifier(Opts));
}
// Override function name from symbol table if necessary.
- if (Opts.PrintFunctions && Opts.UseSymbolTable) {
+ if (Opts.PrintFunctions != FunctionNameKind::None && Opts.UseSymbolTable) {
std::string FunctionName;
uint64_t Start, Size;
if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset,
FunctionName, Start, Size)) {
- patchFunctionNameInDILineInfo(FunctionName, LineInfo);
+ LineInfo.FunctionName = FunctionName;
}
}
return LineInfo;
@@ -141,14 +132,14 @@ DIInliningInfo ModuleInfo::symbolizeInlinedCode(
DIInliningInfo InlinedContext;
if (DebugInfoContext) {
InlinedContext = DebugInfoContext->getInliningInfoForAddress(
- ModuleOffset, getDILineInfoSpecifierFlags(Opts));
+ ModuleOffset, getDILineInfoSpecifier(Opts));
}
// Make sure there is at least one frame in context.
if (InlinedContext.getNumberOfFrames() == 0) {
InlinedContext.addFrame(DILineInfo());
}
// Override the function name in lower frame with name from symbol table.
- if (Opts.PrintFunctions && Opts.UseSymbolTable) {
+ if (Opts.PrintFunctions != FunctionNameKind::None && Opts.UseSymbolTable) {
DIInliningInfo PatchedInlinedContext;
for (uint32_t i = 0, n = InlinedContext.getNumberOfFrames(); i < n; i++) {
DILineInfo LineInfo = InlinedContext.getFrame(i);
@@ -157,7 +148,7 @@ DIInliningInfo ModuleInfo::symbolizeInlinedCode(
uint64_t Start, Size;
if (getNameFromSymbolTable(SymbolRef::ST_Function, ModuleOffset,
FunctionName, Start, Size)) {
- patchFunctionNameInDILineInfo(FunctionName, LineInfo);
+ LineInfo.FunctionName = FunctionName;
}
}
PatchedInlinedContext.addFrame(LineInfo);
@@ -178,7 +169,7 @@ const char LLVMSymbolizer::kBadString[] = "??";
std::string LLVMSymbolizer::symbolizeCode(const std::string &ModuleName,
uint64_t ModuleOffset) {
ModuleInfo *Info = getOrCreateModuleInfo(ModuleName);
- if (Info == 0)
+ if (!Info)
return printDILineInfo(DILineInfo());
if (Opts.PrintInlining) {
DIInliningInfo InlinedContext =
@@ -214,7 +205,6 @@ std::string LLVMSymbolizer::symbolizeData(const std::string &ModuleName,
void LLVMSymbolizer::flush() {
DeleteContainerSeconds(Modules);
- DeleteContainerPointers(ParsedBinariesAndObjects);
BinaryForPath.clear();
ObjectFileForArch.clear();
}
@@ -240,7 +230,7 @@ static bool findDebugBinary(const std::string &OrigPath,
std::string &Result) {
std::string OrigRealPath = OrigPath;
#if defined(HAVE_REALPATH)
- if (char *RP = realpath(OrigPath.c_str(), NULL)) {
+ if (char *RP = realpath(OrigPath.c_str(), nullptr)) {
OrigRealPath = RP;
free(RP);
}
@@ -306,14 +296,14 @@ LLVMSymbolizer::getOrCreateBinary(const std::string &Path) {
BinaryMapTy::iterator I = BinaryForPath.find(Path);
if (I != BinaryForPath.end())
return I->second;
- Binary *Bin = 0;
- Binary *DbgBin = 0;
+ Binary *Bin = nullptr;
+ Binary *DbgBin = nullptr;
ErrorOr<Binary *> BinaryOrErr = createBinary(Path);
if (!error(BinaryOrErr.getError())) {
std::unique_ptr<Binary> ParsedBinary(BinaryOrErr.get());
// Check if it's a universal binary.
- Bin = ParsedBinary.release();
- ParsedBinariesAndObjects.push_back(Bin);
+ Bin = ParsedBinary.get();
+ ParsedBinariesAndObjects.push_back(std::move(ParsedBinary));
if (Bin->isMachO() || Bin->isMachOUniversalBinary()) {
// On Darwin we may find DWARF in separate object file in
// resource directory.
@@ -323,11 +313,11 @@ LLVMSymbolizer::getOrCreateBinary(const std::string &Path) {
error_code EC = BinaryOrErr.getError();
if (EC != errc::no_such_file_or_directory && !error(EC)) {
DbgBin = BinaryOrErr.get();
- ParsedBinariesAndObjects.push_back(DbgBin);
+ ParsedBinariesAndObjects.push_back(std::unique_ptr<Binary>(DbgBin));
}
}
// Try to locate the debug binary using .gnu_debuglink section.
- if (DbgBin == 0) {
+ if (!DbgBin) {
std::string DebuglinkName;
uint32_t CRCHash;
std::string DebugBinaryPath;
@@ -336,12 +326,12 @@ LLVMSymbolizer::getOrCreateBinary(const std::string &Path) {
BinaryOrErr = createBinary(DebugBinaryPath);
if (!error(BinaryOrErr.getError())) {
DbgBin = BinaryOrErr.get();
- ParsedBinariesAndObjects.push_back(DbgBin);
+ ParsedBinariesAndObjects.push_back(std::unique_ptr<Binary>(DbgBin));
}
}
}
}
- if (DbgBin == 0)
+ if (!DbgBin)
DbgBin = Bin;
BinaryPair Res = std::make_pair(Bin, DbgBin);
BinaryForPath[Path] = Res;
@@ -350,9 +340,9 @@ LLVMSymbolizer::getOrCreateBinary(const std::string &Path) {
ObjectFile *
LLVMSymbolizer::getObjectFileFromBinary(Binary *Bin, const std::string &ArchName) {
- if (Bin == 0)
- return 0;
- ObjectFile *Res = 0;
+ if (!Bin)
+ return nullptr;
+ ObjectFile *Res = nullptr;
if (MachOUniversalBinary *UB = dyn_cast<MachOUniversalBinary>(Bin)) {
ObjectFileForArchMapTy::iterator I = ObjectFileForArch.find(
std::make_pair(UB, ArchName));
@@ -360,8 +350,8 @@ LLVMSymbolizer::getObjectFileFromBinary(Binary *Bin, const std::string &ArchName
return I->second;
std::unique_ptr<ObjectFile> ParsedObj;
if (!UB->getObjectForArch(Triple(ArchName).getArch(), ParsedObj)) {
- Res = ParsedObj.release();
- ParsedBinariesAndObjects.push_back(Res);
+ Res = ParsedObj.get();
+ ParsedBinariesAndObjects.push_back(std::move(ParsedObj));
}
ObjectFileForArch[std::make_pair(UB, ArchName)] = Res;
} else if (Bin->isObject()) {
@@ -390,10 +380,10 @@ LLVMSymbolizer::getOrCreateModuleInfo(const std::string &ModuleName) {
ObjectFile *Obj = getObjectFileFromBinary(Binaries.first, ArchName);
ObjectFile *DbgObj = getObjectFileFromBinary(Binaries.second, ArchName);
- if (Obj == 0) {
+ if (!Obj) {
// Failed to find valid object file.
- Modules.insert(make_pair(ModuleName, (ModuleInfo *)0));
- return 0;
+ Modules.insert(make_pair(ModuleName, (ModuleInfo *)nullptr));
+ return nullptr;
}
DIContext *Context = DIContext::getDWARFContext(DbgObj);
assert(Context);
@@ -407,19 +397,18 @@ std::string LLVMSymbolizer::printDILineInfo(DILineInfo LineInfo) const {
// cannot fetch. We replace it to "??" to make our output closer to addr2line.
static const std::string kDILineInfoBadString = "<invalid>";
std::stringstream Result;
- if (Opts.PrintFunctions) {
- std::string FunctionName = LineInfo.getFunctionName();
+ if (Opts.PrintFunctions != FunctionNameKind::None) {
+ std::string FunctionName = LineInfo.FunctionName;
if (FunctionName == kDILineInfoBadString)
FunctionName = kBadString;
else if (Opts.Demangle)
FunctionName = DemangleName(FunctionName);
Result << FunctionName << "\n";
}
- std::string Filename = LineInfo.getFileName();
+ std::string Filename = LineInfo.FileName;
if (Filename == kDILineInfoBadString)
Filename = kBadString;
- Result << Filename << ":" << LineInfo.getLine() << ":" << LineInfo.getColumn()
- << "\n";
+ Result << Filename << ":" << LineInfo.Line << ":" << LineInfo.Column << "\n";
return Result.str();
}
@@ -436,7 +425,7 @@ std::string LLVMSymbolizer::DemangleName(const std::string &Name) {
if (Name.substr(0, 2) != "_Z")
return Name;
int status = 0;
- char *DemangledName = __cxa_demangle(Name.c_str(), 0, 0, &status);
+ char *DemangledName = __cxa_demangle(Name.c_str(), nullptr, nullptr, &status);
if (status != 0)
return Name;
std::string Result = DemangledName;
diff --git a/tools/llvm-symbolizer/LLVMSymbolize.h b/tools/llvm-symbolizer/LLVMSymbolize.h
index 288be80..45febe0 100644
--- a/tools/llvm-symbolizer/LLVMSymbolize.h
+++ b/tools/llvm-symbolizer/LLVMSymbolize.h
@@ -19,10 +19,12 @@
#include "llvm/Object/ObjectFile.h"
#include "llvm/Support/MemoryBuffer.h"
#include <map>
+#include <memory>
#include <string>
namespace llvm {
+typedef DILineInfoSpecifier::FunctionNameKind FunctionNameKind;
using namespace object;
namespace symbolize {
@@ -33,17 +35,17 @@ class LLVMSymbolizer {
public:
struct Options {
bool UseSymbolTable : 1;
- bool PrintFunctions : 1;
+ FunctionNameKind PrintFunctions;
bool PrintInlining : 1;
bool Demangle : 1;
std::string DefaultArch;
- Options(bool UseSymbolTable = true, bool PrintFunctions = true,
+ Options(bool UseSymbolTable = true,
+ FunctionNameKind PrintFunctions = FunctionNameKind::LinkageName,
bool PrintInlining = true, bool Demangle = true,
std::string DefaultArch = "")
: UseSymbolTable(UseSymbolTable), PrintFunctions(PrintFunctions),
PrintInlining(PrintInlining), Demangle(Demangle),
- DefaultArch(DefaultArch) {
- }
+ DefaultArch(DefaultArch) {}
};
LLVMSymbolizer(const Options &Opts = Options()) : Opts(Opts) {}
@@ -72,7 +74,7 @@ private:
std::string printDILineInfo(DILineInfo LineInfo) const;
// Owns all the parsed binaries and object files.
- SmallVector<Binary*, 4> ParsedBinariesAndObjects;
+ SmallVector<std::unique_ptr<Binary>, 4> ParsedBinariesAndObjects;
// Owns module info objects.
typedef std::map<std::string, ModuleInfo *> ModuleMapTy;
ModuleMapTy Modules;
diff --git a/tools/llvm-symbolizer/llvm-symbolizer.cpp b/tools/llvm-symbolizer/llvm-symbolizer.cpp
index 83f5c5e..29db172 100644
--- a/tools/llvm-symbolizer/llvm-symbolizer.cpp
+++ b/tools/llvm-symbolizer/llvm-symbolizer.cpp
@@ -35,10 +35,15 @@ ClUseSymbolTable("use-symbol-table", cl::init(true),
cl::desc("Prefer names in symbol table to names "
"in debug info"));
-static cl::opt<bool>
-ClPrintFunctions("functions", cl::init(true),
- cl::desc("Print function names as well as line "
- "information for a given address"));
+static cl::opt<FunctionNameKind> ClPrintFunctions(
+ "functions", cl::init(FunctionNameKind::LinkageName),
+ cl::desc("Print function name for a given address:"),
+ cl::values(clEnumValN(FunctionNameKind::None, "none", "omit function name"),
+ clEnumValN(FunctionNameKind::ShortName, "short",
+ "print short function name"),
+ clEnumValN(FunctionNameKind::LinkageName, "linkage",
+ "print function linkage name"),
+ clEnumValEnd));
static cl::opt<bool>
ClPrintInlining("inlining", cl::init(true),
@@ -85,7 +90,7 @@ static bool parseCommand(bool &IsData, std::string &ModuleName,
char quote = *pos;
pos++;
char *end = strchr(pos, quote);
- if (end == 0)
+ if (!end)
return false;
ModuleName = std::string(pos, end - pos);
pos = end + 1;
diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp
index cc8318a..64abf5c 100644
--- a/tools/lto/lto.cpp
+++ b/tools/lto/lto.cpp
@@ -56,37 +56,45 @@ static void lto_initialize() {
}
}
-/// lto_get_version - Returns a printable string.
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LTOCodeGenerator, lto_code_gen_t)
+DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LTOModule, lto_module_t)
+
+// Convert the subtarget features into a string to pass to LTOCodeGenerator.
+static void lto_add_attrs(lto_code_gen_t cg) {
+ LTOCodeGenerator *CG = unwrap(cg);
+ if (MAttrs.size()) {
+ std::string attrs;
+ for (unsigned i = 0; i < MAttrs.size(); ++i) {
+ if (i > 0)
+ attrs.append(",");
+ attrs.append(MAttrs[i]);
+ }
+
+ CG->setAttr(attrs.c_str());
+ }
+}
+
extern const char* lto_get_version() {
return LTOCodeGenerator::getVersionString();
}
-/// lto_get_error_message - Returns the last error string or NULL if last
-/// operation was successful.
const char* lto_get_error_message() {
return sLastErrorString.c_str();
}
-/// lto_module_is_object_file - Validates if a file is a loadable object file.
bool lto_module_is_object_file(const char* path) {
return LTOModule::isBitcodeFile(path);
}
-/// lto_module_is_object_file_for_target - Validates if a file is a loadable
-/// object file compilable for requested target.
bool lto_module_is_object_file_for_target(const char* path,
const char* target_triplet_prefix) {
return LTOModule::isBitcodeFileForTarget(path, target_triplet_prefix);
}
-/// lto_module_is_object_file_in_memory - Validates if a buffer is a loadable
-/// object file.
bool lto_module_is_object_file_in_memory(const void* mem, size_t length) {
return LTOModule::isBitcodeFile(mem, length);
}
-/// lto_module_is_object_file_in_memory_for_target - Validates if a buffer is a
-/// loadable object file compilable for the target.
bool
lto_module_is_object_file_in_memory_for_target(const void* mem,
size_t length,
@@ -94,120 +102,89 @@ lto_module_is_object_file_in_memory_for_target(const void* mem,
return LTOModule::isBitcodeFileForTarget(mem, length, target_triplet_prefix);
}
-/// lto_module_create - Loads an object file from disk. Returns NULL on error
-/// (check lto_get_error_message() for details).
lto_module_t lto_module_create(const char* path) {
lto_initialize();
llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
- return LTOModule::makeLTOModule(path, Options, sLastErrorString);
+ return wrap(LTOModule::makeLTOModule(path, Options, sLastErrorString));
}
-/// lto_module_create_from_fd - Loads an object file from disk. Returns NULL on
-/// error (check lto_get_error_message() for details).
lto_module_t lto_module_create_from_fd(int fd, const char *path, size_t size) {
lto_initialize();
llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
- return LTOModule::makeLTOModule(fd, path, size, Options, sLastErrorString);
+ return wrap(
+ LTOModule::makeLTOModule(fd, path, size, Options, sLastErrorString));
}
-/// lto_module_create_from_fd_at_offset - Loads an object file from disk.
-/// Returns NULL on error (check lto_get_error_message() for details).
lto_module_t lto_module_create_from_fd_at_offset(int fd, const char *path,
size_t file_size,
size_t map_size,
off_t offset) {
lto_initialize();
llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
- return LTOModule::makeLTOModule(fd, path, map_size, offset, Options,
- sLastErrorString);
+ return wrap(LTOModule::makeLTOModule(fd, path, map_size, offset, Options,
+ sLastErrorString));
}
-/// lto_module_create_from_memory - Loads an object file from memory. Returns
-/// NULL on error (check lto_get_error_message() for details).
lto_module_t lto_module_create_from_memory(const void* mem, size_t length) {
lto_initialize();
llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
- return LTOModule::makeLTOModule(mem, length, Options, sLastErrorString);
+ return wrap(LTOModule::makeLTOModule(mem, length, Options, sLastErrorString));
}
-/// Loads an object file from memory with an extra path argument.
-/// Returns NULL on error (check lto_get_error_message() for details).
lto_module_t lto_module_create_from_memory_with_path(const void* mem,
size_t length,
const char *path) {
lto_initialize();
llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
- return LTOModule::makeLTOModule(mem, length, Options, sLastErrorString, path);
+ return wrap(
+ LTOModule::makeLTOModule(mem, length, Options, sLastErrorString, path));
}
-/// lto_module_dispose - Frees all memory for a module. Upon return the
-/// lto_module_t is no longer valid.
-void lto_module_dispose(lto_module_t mod) {
- delete mod;
-}
+void lto_module_dispose(lto_module_t mod) { delete unwrap(mod); }
-/// lto_module_get_target_triple - Returns triplet string which the object
-/// module was compiled under.
const char* lto_module_get_target_triple(lto_module_t mod) {
- return mod->getTargetTriple();
+ return unwrap(mod)->getTargetTriple();
}
-/// lto_module_set_target_triple - Sets triple string with which the object will
-/// be codegened.
void lto_module_set_target_triple(lto_module_t mod, const char *triple) {
- return mod->setTargetTriple(triple);
+ return unwrap(mod)->setTargetTriple(triple);
}
-/// lto_module_get_num_symbols - Returns the number of symbols in the object
-/// module.
unsigned int lto_module_get_num_symbols(lto_module_t mod) {
- return mod->getSymbolCount();
+ return unwrap(mod)->getSymbolCount();
}
-/// lto_module_get_symbol_name - Returns the name of the ith symbol in the
-/// object module.
const char* lto_module_get_symbol_name(lto_module_t mod, unsigned int index) {
- return mod->getSymbolName(index);
+ return unwrap(mod)->getSymbolName(index);
}
-/// lto_module_get_symbol_attribute - Returns the attributes of the ith symbol
-/// in the object module.
lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod,
unsigned int index) {
- return mod->getSymbolAttributes(index);
+ return unwrap(mod)->getSymbolAttributes(index);
}
-/// lto_module_get_num_deplibs - Returns the number of dependent libraries in
-/// the object module.
unsigned int lto_module_get_num_deplibs(lto_module_t mod) {
- return mod->getDependentLibraryCount();
+ return unwrap(mod)->getDependentLibraryCount();
}
-/// lto_module_get_deplib - Returns the ith dependent library in the module.
const char* lto_module_get_deplib(lto_module_t mod, unsigned int index) {
- return mod->getDependentLibrary(index);
+ return unwrap(mod)->getDependentLibrary(index);
}
-/// lto_module_get_num_linkeropts - Returns the number of linker options in the
-/// object module.
unsigned int lto_module_get_num_linkeropts(lto_module_t mod) {
- return mod->getLinkerOptCount();
+ return unwrap(mod)->getLinkerOptCount();
}
-/// lto_module_get_linkeropt - Returns the ith linker option in the module.
const char* lto_module_get_linkeropt(lto_module_t mod, unsigned int index) {
- return mod->getLinkerOpt(index);
+ return unwrap(mod)->getLinkerOpt(index);
}
-/// Set a diagnostic handler.
void lto_codegen_set_diagnostic_handler(lto_code_gen_t cg,
lto_diagnostic_handler_t diag_handler,
void *ctxt) {
- cg->setDiagnosticHandler(diag_handler, ctxt);
+ unwrap(cg)->setDiagnosticHandler(diag_handler, ctxt);
}
-/// lto_codegen_create - Instantiates a code generator. Returns NULL if there
-/// is an error.
lto_code_gen_t lto_codegen_create(void) {
lto_initialize();
@@ -216,102 +193,76 @@ lto_code_gen_t lto_codegen_create(void) {
LTOCodeGenerator *CodeGen = new LTOCodeGenerator();
if (CodeGen)
CodeGen->setTargetOptions(Options);
- return CodeGen;
+ return wrap(CodeGen);
}
-/// lto_codegen_dispose - Frees all memory for a code generator. Upon return the
-/// lto_code_gen_t is no longer valid.
-void lto_codegen_dispose(lto_code_gen_t cg) {
- delete cg;
-}
+void lto_codegen_dispose(lto_code_gen_t cg) { delete unwrap(cg); }
-/// lto_codegen_add_module - Add an object module to the set of modules for
-/// which code will be generated. Returns true on error (check
-/// lto_get_error_message() for details).
bool lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod) {
- return !cg->addModule(mod, sLastErrorString);
+ return !unwrap(cg)->addModule(unwrap(mod), sLastErrorString);
}
-/// lto_codegen_set_debug_model - Sets what if any format of debug info should
-/// be generated. Returns true on error (check lto_get_error_message() for
-/// details).
bool lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model debug) {
- cg->setDebugInfo(debug);
+ unwrap(cg)->setDebugInfo(debug);
return false;
}
-/// lto_codegen_set_pic_model - Sets what code model to generated. Returns true
-/// on error (check lto_get_error_message() for details).
bool lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model model) {
- cg->setCodePICModel(model);
+ unwrap(cg)->setCodePICModel(model);
return false;
}
-/// lto_codegen_set_cpu - Sets the cpu to generate code for.
void lto_codegen_set_cpu(lto_code_gen_t cg, const char *cpu) {
- return cg->setCpu(cpu);
+ return unwrap(cg)->setCpu(cpu);
+}
+
+void lto_codegen_set_attr(lto_code_gen_t cg, const char *attr) {
+ return unwrap(cg)->setAttr(attr);
}
-/// lto_codegen_set_assembler_path - Sets the path to the assembler tool.
void lto_codegen_set_assembler_path(lto_code_gen_t cg, const char *path) {
// In here only for backwards compatibility. We use MC now.
}
-/// lto_codegen_set_assembler_args - Sets extra arguments that libLTO should
-/// pass to the assembler.
void lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args,
int nargs) {
// In here only for backwards compatibility. We use MC now.
}
-/// lto_codegen_add_must_preserve_symbol - Adds to a list of all global symbols
-/// that must exist in the final generated code. If a function is not listed
-/// there, it might be inlined into every usage and optimized away.
void lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg,
const char *symbol) {
- cg->addMustPreserveSymbol(symbol);
+ unwrap(cg)->addMustPreserveSymbol(symbol);
}
-/// lto_codegen_write_merged_modules - Writes a new file at the specified path
-/// that contains the merged contents of all modules added so far. Returns true
-/// on error (check lto_get_error_message() for details).
bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) {
if (!parsedOptions) {
- cg->parseCodeGenDebugOptions();
+ unwrap(cg)->parseCodeGenDebugOptions();
+ lto_add_attrs(cg);
parsedOptions = true;
}
- return !cg->writeMergedModules(path, sLastErrorString);
+ return !unwrap(cg)->writeMergedModules(path, sLastErrorString);
}
-/// lto_codegen_compile - Generates code for all added modules into one native
-/// object file. On success returns a pointer to a generated mach-o/ELF buffer
-/// and length set to the buffer size. The buffer is owned by the lto_code_gen_t
-/// object and will be freed when lto_codegen_dispose() is called, or
-/// lto_codegen_compile() is called again. On failure, returns NULL (check
-/// lto_get_error_message() for details).
const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) {
if (!parsedOptions) {
- cg->parseCodeGenDebugOptions();
+ unwrap(cg)->parseCodeGenDebugOptions();
+ lto_add_attrs(cg);
parsedOptions = true;
}
- return cg->compile(length, DisableOpt, DisableInline, DisableGVNLoadPRE,
- sLastErrorString);
+ return unwrap(cg)->compile(length, DisableOpt, DisableInline,
+ DisableGVNLoadPRE, sLastErrorString);
}
-/// lto_codegen_compile_to_file - Generates code for all added modules into one
-/// native object file. The name of the file is written to name. Returns true on
-/// error.
bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) {
if (!parsedOptions) {
- cg->parseCodeGenDebugOptions();
+ unwrap(cg)->parseCodeGenDebugOptions();
+ lto_add_attrs(cg);
parsedOptions = true;
}
- return !cg->compile_to_file(name, DisableOpt, DisableInline, DisableGVNLoadPRE,
- sLastErrorString);
+ return !unwrap(cg)->compile_to_file(name, DisableOpt, DisableInline,
+ DisableGVNLoadPRE, sLastErrorString);
}
-/// lto_codegen_debug_options - Used to pass extra options to the code
-/// generator.
void lto_codegen_debug_options(lto_code_gen_t cg, const char *opt) {
- cg->setCodeGenDebugOptions(opt);
+ unwrap(cg)->setCodeGenDebugOptions(opt);
}
diff --git a/tools/obj2yaml/CMakeLists.txt b/tools/obj2yaml/CMakeLists.txt
index 9c10c04..f167ed5 100644
--- a/tools/obj2yaml/CMakeLists.txt
+++ b/tools/obj2yaml/CMakeLists.txt
@@ -4,5 +4,5 @@ set(LLVM_LINK_COMPONENTS
)
add_llvm_utility(obj2yaml
- obj2yaml.cpp coff2yaml.cpp
+ obj2yaml.cpp coff2yaml.cpp elf2yaml.cpp Error.cpp
)
diff --git a/tools/obj2yaml/Error.cpp b/tools/obj2yaml/Error.cpp
new file mode 100644
index 0000000..7be468d
--- /dev/null
+++ b/tools/obj2yaml/Error.cpp
@@ -0,0 +1,54 @@
+//===- Error.cpp - system_error extensions for obj2yaml ---------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Error.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+
+namespace {
+class _obj2yaml_error_category : public error_category {
+public:
+ const char *name() const override;
+ std::string message(int ev) const override;
+ error_condition default_error_condition(int ev) const override;
+};
+} // namespace
+
+const char *_obj2yaml_error_category::name() const { return "obj2yaml"; }
+
+std::string _obj2yaml_error_category::message(int ev) const {
+ switch (ev) {
+ case obj2yaml_error::success:
+ return "Success";
+ case obj2yaml_error::file_not_found:
+ return "No such file.";
+ case obj2yaml_error::unrecognized_file_format:
+ return "Unrecognized file type.";
+ case obj2yaml_error::unsupported_obj_file_format:
+ return "Unsupported object file format.";
+ default:
+ llvm_unreachable("An enumerator of obj2yaml_error does not have a message "
+ "defined.");
+ }
+}
+
+error_condition
+_obj2yaml_error_category::default_error_condition(int ev) const {
+ if (ev == obj2yaml_error::success)
+ return errc::success;
+ return errc::invalid_argument;
+}
+
+namespace llvm {
+const error_category &obj2yaml_category() {
+ static _obj2yaml_error_category o;
+ return o;
+}
+} // namespace llvm
diff --git a/tools/obj2yaml/Error.h b/tools/obj2yaml/Error.h
new file mode 100644
index 0000000..a326664
--- /dev/null
+++ b/tools/obj2yaml/Error.h
@@ -0,0 +1,42 @@
+//===- Error.h - system_error extensions for obj2yaml -----------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_ERROR_H
+#define LLVM_TOOLS_ERROR_H
+
+#include "llvm/Support/system_error.h"
+
+namespace llvm {
+
+const error_category &obj2yaml_category();
+
+struct obj2yaml_error {
+ enum _ {
+ success = 0,
+ file_not_found,
+ unrecognized_file_format,
+ unsupported_obj_file_format
+ };
+ _ v_;
+
+ obj2yaml_error(_ v) : v_(v) {}
+ explicit obj2yaml_error(int v) : v_(_(v)) {}
+ operator int() const {return v_;}
+};
+
+inline error_code make_error_code(obj2yaml_error e) {
+ return error_code(static_cast<int>(e), obj2yaml_category());
+}
+
+template <> struct is_error_code_enum<obj2yaml_error> : std::true_type { };
+template <> struct is_error_code_enum<obj2yaml_error::_> : std::true_type { };
+
+} // namespace llvm
+
+#endif
diff --git a/tools/obj2yaml/coff2yaml.cpp b/tools/obj2yaml/coff2yaml.cpp
index ef70922..42b09d3 100644
--- a/tools/obj2yaml/coff2yaml.cpp
+++ b/tools/obj2yaml/coff2yaml.cpp
@@ -210,10 +210,7 @@ COFFYAML::Object &COFFDumper::getYAMLObj() {
return YAMLObj;
}
-error_code coff2yaml(raw_ostream &Out, MemoryBuffer *Buff) {
- error_code ec;
- object::COFFObjectFile Obj(Buff, ec);
- check(ec);
+error_code coff2yaml(raw_ostream &Out, const object::COFFObjectFile &Obj) {
COFFDumper Dumper(Obj);
yaml::Output Yout(Out);
diff --git a/tools/obj2yaml/elf2yaml.cpp b/tools/obj2yaml/elf2yaml.cpp
new file mode 100644
index 0000000..7642921
--- /dev/null
+++ b/tools/obj2yaml/elf2yaml.cpp
@@ -0,0 +1,290 @@
+//===------ utils/elf2yaml.cpp - obj2yaml conversion tool -------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "Error.h"
+#include "obj2yaml.h"
+#include "llvm/ADT/STLExtras.h"
+#include "llvm/Object/ELFObjectFile.h"
+#include "llvm/Object/ELFYAML.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/YAMLTraits.h"
+
+using namespace llvm;
+
+namespace {
+
+template <class ELFT>
+class ELFDumper {
+ typedef typename object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
+ typedef typename object::ELFFile<ELFT>::Elf_Sym_Iter Elf_Sym_Iter;
+
+ const object::ELFFile<ELFT> &Obj;
+
+ error_code dumpSymbol(Elf_Sym_Iter Sym, ELFYAML::Symbol &S);
+ error_code dumpCommonSection(const Elf_Shdr *Shdr, ELFYAML::Section &S);
+ template <class RelT>
+ error_code dumpRelocation(const Elf_Shdr *Shdr, const RelT *Rel,
+ ELFYAML::Relocation &R);
+
+ ErrorOr<ELFYAML::RelocationSection *> dumpRelSection(const Elf_Shdr *Shdr);
+ ErrorOr<ELFYAML::RelocationSection *> dumpRelaSection(const Elf_Shdr *Shdr);
+ ErrorOr<ELFYAML::RawContentSection *>
+ dumpContentSection(const Elf_Shdr *Shdr);
+
+public:
+ ELFDumper(const object::ELFFile<ELFT> &O);
+ ErrorOr<ELFYAML::Object *> dump();
+};
+
+}
+
+template <class ELFT>
+ELFDumper<ELFT>::ELFDumper(const object::ELFFile<ELFT> &O)
+ : Obj(O) {}
+
+template <class ELFT>
+ErrorOr<ELFYAML::Object *> ELFDumper<ELFT>::dump() {
+ auto Y = make_unique<ELFYAML::Object>();
+
+ // Dump header
+ Y->Header.Class = ELFYAML::ELF_ELFCLASS(Obj.getHeader()->getFileClass());
+ Y->Header.Data = ELFYAML::ELF_ELFDATA(Obj.getHeader()->getDataEncoding());
+ Y->Header.OSABI = Obj.getHeader()->e_ident[ELF::EI_OSABI];
+ Y->Header.Type = Obj.getHeader()->e_type;
+ Y->Header.Machine = Obj.getHeader()->e_machine;
+ Y->Header.Flags = Obj.getHeader()->e_flags;
+ Y->Header.Entry = Obj.getHeader()->e_entry;
+
+ // Dump sections
+ for (const Elf_Shdr &Sec : Obj.sections()) {
+ switch (Sec.sh_type) {
+ case ELF::SHT_NULL:
+ case ELF::SHT_SYMTAB:
+ case ELF::SHT_DYNSYM:
+ case ELF::SHT_STRTAB:
+ // Do not dump these sections.
+ break;
+ case ELF::SHT_RELA: {
+ ErrorOr<ELFYAML::RelocationSection *> S = dumpRelaSection(&Sec);
+ if (error_code EC = S.getError())
+ return EC;
+ Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
+ break;
+ }
+ case ELF::SHT_REL: {
+ ErrorOr<ELFYAML::RelocationSection *> S = dumpRelSection(&Sec);
+ if (error_code EC = S.getError())
+ return EC;
+ Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
+ break;
+ }
+ default: {
+ ErrorOr<ELFYAML::RawContentSection *> S = dumpContentSection(&Sec);
+ if (error_code EC = S.getError())
+ return EC;
+ Y->Sections.push_back(std::unique_ptr<ELFYAML::Section>(S.get()));
+ }
+ }
+ }
+
+ // Dump symbols
+ bool IsFirstSym = true;
+ for (auto SI = Obj.begin_symbols(), SE = Obj.end_symbols(); SI != SE; ++SI) {
+ if (IsFirstSym) {
+ IsFirstSym = false;
+ continue;
+ }
+
+ ELFYAML::Symbol S;
+ if (error_code EC = ELFDumper<ELFT>::dumpSymbol(SI, S))
+ return EC;
+
+ switch (SI->getBinding())
+ {
+ case ELF::STB_LOCAL:
+ Y->Symbols.Local.push_back(S);
+ break;
+ case ELF::STB_GLOBAL:
+ Y->Symbols.Global.push_back(S);
+ break;
+ case ELF::STB_WEAK:
+ Y->Symbols.Weak.push_back(S);
+ break;
+ default:
+ llvm_unreachable("Unknown ELF symbol binding");
+ }
+ }
+
+ return Y.release();
+}
+
+template <class ELFT>
+error_code ELFDumper<ELFT>::dumpSymbol(Elf_Sym_Iter Sym, ELFYAML::Symbol &S) {
+ S.Type = Sym->getType();
+ S.Value = Sym->st_value;
+ S.Size = Sym->st_size;
+
+ ErrorOr<StringRef> NameOrErr = Obj.getSymbolName(Sym);
+ if (error_code EC = NameOrErr.getError())
+ return EC;
+ S.Name = NameOrErr.get();
+
+ const Elf_Shdr *Shdr = Obj.getSection(&*Sym);
+ if (!Shdr)
+ return obj2yaml_error::success;
+
+ NameOrErr = Obj.getSectionName(Shdr);
+ if (error_code EC = NameOrErr.getError())
+ return EC;
+ S.Section = NameOrErr.get();
+
+ return obj2yaml_error::success;
+}
+
+template <class ELFT>
+template <class RelT>
+error_code ELFDumper<ELFT>::dumpRelocation(const Elf_Shdr *Shdr,
+ const RelT *Rel,
+ ELFYAML::Relocation &R) {
+ R.Type = Rel->getType(Obj.isMips64EL());
+ R.Offset = Rel->r_offset;
+ R.Addend = 0;
+
+ auto NamePair = Obj.getRelocationSymbol(Shdr, Rel);
+ if (!NamePair.first)
+ return obj2yaml_error::success;
+
+ ErrorOr<StringRef> NameOrErr =
+ Obj.getSymbolName(NamePair.first, NamePair.second);
+ if (error_code EC = NameOrErr.getError())
+ return EC;
+ R.Symbol = NameOrErr.get();
+
+ return obj2yaml_error::success;
+}
+
+template <class ELFT>
+error_code ELFDumper<ELFT>::dumpCommonSection(const Elf_Shdr *Shdr,
+ ELFYAML::Section &S) {
+ S.Type = Shdr->sh_type;
+ S.Flags = Shdr->sh_flags;
+ S.Address = Shdr->sh_addr;
+ S.AddressAlign = Shdr->sh_addralign;
+
+ ErrorOr<StringRef> NameOrErr = Obj.getSectionName(Shdr);
+ if (error_code EC = NameOrErr.getError())
+ return EC;
+ S.Name = NameOrErr.get();
+
+ if (Shdr->sh_link != ELF::SHN_UNDEF) {
+ if (const Elf_Shdr *LinkSection = Obj.getSection(Shdr->sh_link)) {
+ NameOrErr = Obj.getSectionName(LinkSection);
+ if (error_code EC = NameOrErr.getError())
+ return EC;
+ S.Link = NameOrErr.get();
+ }
+ }
+ if (Shdr->sh_info != ELF::SHN_UNDEF) {
+ if (const Elf_Shdr *InfoSection = Obj.getSection(Shdr->sh_info)) {
+ NameOrErr = Obj.getSectionName(InfoSection);
+ if (error_code EC = NameOrErr.getError())
+ return EC;
+ S.Info = NameOrErr.get();
+ }
+ }
+ return obj2yaml_error::success;
+}
+
+template <class ELFT>
+ErrorOr<ELFYAML::RelocationSection *>
+ELFDumper<ELFT>::dumpRelSection(const Elf_Shdr *Shdr) {
+ assert(Shdr->sh_type == ELF::SHT_REL && "Section type is not SHT_REL");
+ auto S = make_unique<ELFYAML::RelocationSection>();
+
+ if (error_code EC = dumpCommonSection(Shdr, *S))
+ return EC;
+
+ for (auto RI = Obj.begin_rel(Shdr), RE = Obj.end_rel(Shdr); RI != RE;
+ ++RI) {
+ ELFYAML::Relocation R;
+ if (error_code EC = dumpRelocation(Shdr, &*RI, R))
+ return EC;
+ S->Relocations.push_back(R);
+ }
+
+ return S.release();
+}
+
+template <class ELFT>
+ErrorOr<ELFYAML::RelocationSection *>
+ELFDumper<ELFT>::dumpRelaSection(const Elf_Shdr *Shdr) {
+ assert(Shdr->sh_type == ELF::SHT_RELA && "Section type is not SHT_RELA");
+ auto S = make_unique<ELFYAML::RelocationSection>();
+
+ if (error_code EC = dumpCommonSection(Shdr, *S))
+ return EC;
+
+ for (auto RI = Obj.begin_rela(Shdr), RE = Obj.end_rela(Shdr); RI != RE;
+ ++RI) {
+ ELFYAML::Relocation R;
+ if (error_code EC = dumpRelocation(Shdr, &*RI, R))
+ return EC;
+ R.Addend = RI->r_addend;
+ S->Relocations.push_back(R);
+ }
+
+ return S.release();
+}
+
+template <class ELFT>
+ErrorOr<ELFYAML::RawContentSection *>
+ELFDumper<ELFT>::dumpContentSection(const Elf_Shdr *Shdr) {
+ auto S = make_unique<ELFYAML::RawContentSection>();
+
+ if (error_code EC = dumpCommonSection(Shdr, *S))
+ return EC;
+
+ ErrorOr<ArrayRef<uint8_t>> ContentOrErr = Obj.getSectionContents(Shdr);
+ if (error_code EC = ContentOrErr.getError())
+ return EC;
+ S->Content = object::yaml::BinaryRef(ContentOrErr.get());
+ S->Size = S->Content.binary_size();
+
+ return S.release();
+}
+
+template <class ELFT>
+static error_code elf2yaml(raw_ostream &Out, const object::ELFFile<ELFT> &Obj) {
+ ELFDumper<ELFT> Dumper(Obj);
+ ErrorOr<ELFYAML::Object *> YAMLOrErr = Dumper.dump();
+ if (error_code EC = YAMLOrErr.getError())
+ return EC;
+
+ std::unique_ptr<ELFYAML::Object> YAML(YAMLOrErr.get());
+ yaml::Output Yout(Out);
+ Yout << *YAML;
+
+ return object::object_error::success;
+}
+
+error_code elf2yaml(raw_ostream &Out, const object::ObjectFile &Obj) {
+ if (const auto *ELFObj = dyn_cast<object::ELF32LEObjectFile>(&Obj))
+ return elf2yaml(Out, *ELFObj->getELFFile());
+
+ if (const auto *ELFObj = dyn_cast<object::ELF32BEObjectFile>(&Obj))
+ return elf2yaml(Out, *ELFObj->getELFFile());
+
+ if (const auto *ELFObj = dyn_cast<object::ELF64LEObjectFile>(&Obj))
+ return elf2yaml(Out, *ELFObj->getELFFile());
+
+ if (const auto *ELFObj = dyn_cast<object::ELF64BEObjectFile>(&Obj))
+ return elf2yaml(Out, *ELFObj->getELFFile());
+
+ return obj2yaml_error::unsupported_obj_file_format;
+}
diff --git a/tools/obj2yaml/obj2yaml.cpp b/tools/obj2yaml/obj2yaml.cpp
index 38779fe..7fe034d 100644
--- a/tools/obj2yaml/obj2yaml.cpp
+++ b/tools/obj2yaml/obj2yaml.cpp
@@ -7,6 +7,7 @@
//
//===----------------------------------------------------------------------===//
+#include "Error.h"
#include "obj2yaml.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/COFF.h"
@@ -16,16 +17,32 @@
#include "llvm/Support/Signals.h"
using namespace llvm;
+using namespace llvm::object;
-namespace {
-enum ObjectFileType {
- coff
-};
+static error_code dumpObject(const ObjectFile &Obj) {
+ if (Obj.isCOFF())
+ return coff2yaml(outs(), cast<COFFObjectFile>(Obj));
+ if (Obj.isELF())
+ return elf2yaml(outs(), Obj);
+
+ return obj2yaml_error::unsupported_obj_file_format;
}
-cl::opt<ObjectFileType> InputFormat(
- cl::desc("Choose input format"),
- cl::values(clEnumVal(coff, "process COFF object files"), clEnumValEnd));
+static error_code dumpInput(StringRef File) {
+ if (File != "-" && !sys::fs::exists(File))
+ return obj2yaml_error::file_not_found;
+
+ ErrorOr<Binary *> BinaryOrErr = createBinary(File);
+ if (error_code EC = BinaryOrErr.getError())
+ return EC;
+
+ std::unique_ptr<Binary> Binary(BinaryOrErr.get());
+ // TODO: If this is an archive, then burst it and dump each entry
+ if (ObjectFile *Obj = dyn_cast<ObjectFile>(Binary.get()))
+ return dumpObject(*Obj);
+
+ return obj2yaml_error::unrecognized_file_format;
+}
cl::opt<std::string> InputFilename(cl::Positional, cl::desc("<input file>"),
cl::init("-"));
@@ -36,17 +53,9 @@ int main(int argc, char *argv[]) {
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
- // Process the input file
- std::unique_ptr<MemoryBuffer> buf;
-
- // TODO: If this is an archive, then burst it and dump each entry
- if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, buf)) {
- errs() << "Error: '" << ec.message() << "' opening file '" << InputFilename
- << "'\n";
- } else {
- ec = coff2yaml(outs(), buf.release());
- if (ec)
- errs() << "Error: " << ec.message() << " dumping COFF file\n";
+ if (error_code EC = dumpInput(InputFilename)) {
+ errs() << "Error: '" << EC.message() << "'\n";
+ return 1;
}
return 0;
diff --git a/tools/obj2yaml/obj2yaml.h b/tools/obj2yaml/obj2yaml.h
index bde82e6..73c58fa 100644
--- a/tools/obj2yaml/obj2yaml.h
+++ b/tools/obj2yaml/obj2yaml.h
@@ -13,10 +13,13 @@
#ifndef LLVM_TOOLS_OBJ2YAML_H
#define LLVM_TOOLS_OBJ2YAML_H
-#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Object/COFF.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
-llvm::error_code coff2yaml(llvm::raw_ostream &Out, llvm::MemoryBuffer *TheObj);
+llvm::error_code coff2yaml(llvm::raw_ostream &Out,
+ const llvm::object::COFFObjectFile &Obj);
+llvm::error_code elf2yaml(llvm::raw_ostream &Out,
+ const llvm::object::ObjectFile &Obj);
#endif
diff --git a/tools/opt/NewPMDriver.cpp b/tools/opt/NewPMDriver.cpp
index fc4a1bf..8076ff4 100644
--- a/tools/opt/NewPMDriver.cpp
+++ b/tools/opt/NewPMDriver.cpp
@@ -16,6 +16,7 @@
#include "NewPMDriver.h"
#include "Passes.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/Analysis/CGSCCPassManager.h"
#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
#include "llvm/IR/IRPrintingPasses.h"
@@ -34,14 +35,27 @@ bool llvm::runPassPipeline(StringRef Arg0, LLVMContext &Context, Module &M,
tool_output_file *Out, StringRef PassPipeline,
OutputKind OK, VerifierKind VK) {
FunctionAnalysisManager FAM;
+ CGSCCAnalysisManager CGAM;
ModuleAnalysisManager MAM;
- // FIXME: Lift this registration of analysis passes into a .def file adjacent
- // to the one used to associate names with passes.
- MAM.registerPass(LazyCallGraphAnalysis());
+#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
+ MAM.registerPass(CREATE_PASS);
+#include "PassRegistry.def"
+
+#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
+ CGAM.registerPass(CREATE_PASS);
+#include "PassRegistry.def"
+
+#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
+ FAM.registerPass(CREATE_PASS);
+#include "PassRegistry.def"
// Cross register the analysis managers through their proxies.
MAM.registerPass(FunctionAnalysisManagerModuleProxy(FAM));
+ MAM.registerPass(CGSCCAnalysisManagerModuleProxy(CGAM));
+ CGAM.registerPass(FunctionAnalysisManagerCGSCCProxy(FAM));
+ CGAM.registerPass(ModuleAnalysisManagerCGSCCProxy(MAM));
+ FAM.registerPass(CGSCCAnalysisManagerFunctionProxy(CGAM));
FAM.registerPass(ModuleAnalysisManagerFunctionProxy(MAM));
ModulePassManager MPM;
diff --git a/tools/opt/PassRegistry.def b/tools/opt/PassRegistry.def
new file mode 100644
index 0000000..e1e4900
--- /dev/null
+++ b/tools/opt/PassRegistry.def
@@ -0,0 +1,51 @@
+//===- PassRegistry.def - Registry of passes --------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is used as the registry of passes that are part of the core LLVM
+// libraries. This file describes both transformation passes and analyses
+// Analyses are registered while transformation passes have names registered
+// that can be used when providing a textual pass pipeline.
+//
+//===----------------------------------------------------------------------===//
+
+// NOTE: NO INCLUDE GUARD DESIRED!
+
+#ifndef MODULE_ANALYSIS
+#define MODULE_ANALYSIS(NAME, CREATE_PASS)
+#endif
+MODULE_ANALYSIS("lcg", LazyCallGraphAnalysis())
+#undef MODULE_ANALYSIS
+
+#ifndef MODULE_PASS
+#define MODULE_PASS(NAME, CREATE_PASS)
+#endif
+MODULE_PASS("print", PrintModulePass(dbgs()))
+MODULE_PASS("print-cg", LazyCallGraphPrinterPass(dbgs()))
+#undef MODULE_PASS
+
+#ifndef CGSCC_ANALYSIS
+#define CGSCC_ANALYSIS(NAME, CREATE_PASS)
+#endif
+#undef CGSCC_ANALYSIS
+
+#ifndef CGSCC_PASS
+#define CGSCC_PASS(NAME, CREATE_PASS)
+#endif
+#undef CGSCC_PASS
+
+#ifndef FUNCTION_ANALYSIS
+#define FUNCTION_ANALYSIS(NAME, CREATE_PASS)
+#endif
+#undef FUNCTION_ANALYSIS
+
+#ifndef FUNCTION_PASS
+#define FUNCTION_PASS(NAME, CREATE_PASS)
+#endif
+FUNCTION_PASS("print", PrintFunctionPass(dbgs()))
+#undef FUNCTION_PASS
diff --git a/tools/opt/Passes.cpp b/tools/opt/Passes.cpp
index ffdf9bf..a171f42 100644
--- a/tools/opt/Passes.cpp
+++ b/tools/opt/Passes.cpp
@@ -15,6 +15,7 @@
//===----------------------------------------------------------------------===//
#include "Passes.h"
+#include "llvm/Analysis/CGSCCPassManager.h"
#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/IR/IRPrintingPasses.h"
#include "llvm/IR/PassManager.h"
@@ -31,6 +32,14 @@ struct NoOpModulePass {
static StringRef name() { return "NoOpModulePass"; }
};
+/// \brief No-op CGSCC pass which does nothing.
+struct NoOpCGSCCPass {
+ PreservedAnalyses run(LazyCallGraph::SCC *C) {
+ return PreservedAnalyses::all();
+ }
+ static StringRef name() { return "NoOpCGSCCPass"; }
+};
+
/// \brief No-op function pass which does nothing.
struct NoOpFunctionPass {
PreservedAnalyses run(Function *F) { return PreservedAnalyses::all(); }
@@ -39,19 +48,29 @@ struct NoOpFunctionPass {
} // End anonymous namespace.
-// FIXME: Factor all of the parsing logic into a .def file that we include
-// under different macros.
static bool isModulePassName(StringRef Name) {
if (Name == "no-op-module") return true;
- if (Name == "print") return true;
- if (Name == "print-cg") return true;
+
+#define MODULE_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
+#include "PassRegistry.def"
+
+ return false;
+}
+
+static bool isCGSCCPassName(StringRef Name) {
+ if (Name == "no-op-cgscc") return true;
+
+#define CGSCC_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
+#include "PassRegistry.def"
return false;
}
static bool isFunctionPassName(StringRef Name) {
if (Name == "no-op-function") return true;
- if (Name == "print") return true;
+
+#define FUNCTION_PASS(NAME, CREATE_PASS) if (Name == NAME) return true;
+#include "PassRegistry.def"
return false;
}
@@ -61,14 +80,30 @@ static bool parseModulePassName(ModulePassManager &MPM, StringRef Name) {
MPM.addPass(NoOpModulePass());
return true;
}
- if (Name == "print") {
- MPM.addPass(PrintModulePass(dbgs()));
- return true;
+
+#define MODULE_PASS(NAME, CREATE_PASS) \
+ if (Name == NAME) { \
+ MPM.addPass(CREATE_PASS); \
+ return true; \
}
- if (Name == "print-cg") {
- MPM.addPass(LazyCallGraphPrinterPass(dbgs()));
+#include "PassRegistry.def"
+
+ return false;
+}
+
+static bool parseCGSCCPassName(CGSCCPassManager &CGPM, StringRef Name) {
+ if (Name == "no-op-cgscc") {
+ CGPM.addPass(NoOpCGSCCPass());
return true;
}
+
+#define CGSCC_PASS(NAME, CREATE_PASS) \
+ if (Name == NAME) { \
+ CGPM.addPass(CREATE_PASS); \
+ return true; \
+ }
+#include "PassRegistry.def"
+
return false;
}
@@ -77,10 +112,14 @@ static bool parseFunctionPassName(FunctionPassManager &FPM, StringRef Name) {
FPM.addPass(NoOpFunctionPass());
return true;
}
- if (Name == "print") {
- FPM.addPass(PrintFunctionPass(dbgs()));
- return true;
+
+#define FUNCTION_PASS(NAME, CREATE_PASS) \
+ if (Name == NAME) { \
+ FPM.addPass(CREATE_PASS); \
+ return true; \
}
+#include "PassRegistry.def"
+
return false;
}
@@ -121,6 +160,55 @@ static bool parseFunctionPassPipeline(FunctionPassManager &FPM,
}
}
+static bool parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
+ StringRef &PipelineText,
+ bool VerifyEachPass) {
+ for (;;) {
+ // Parse nested pass managers by recursing.
+ if (PipelineText.startswith("cgscc(")) {
+ CGSCCPassManager NestedCGPM;
+
+ // Parse the inner pipeline into the nested manager.
+ PipelineText = PipelineText.substr(strlen("cgscc("));
+ if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) ||
+ PipelineText.empty())
+ return false;
+ assert(PipelineText[0] == ')');
+ PipelineText = PipelineText.substr(1);
+
+ // Add the nested pass manager with the appropriate adaptor.
+ CGPM.addPass(std::move(NestedCGPM));
+ } else if (PipelineText.startswith("function(")) {
+ FunctionPassManager NestedFPM;
+
+ // Parse the inner pipeline inte the nested manager.
+ PipelineText = PipelineText.substr(strlen("function("));
+ if (!parseFunctionPassPipeline(NestedFPM, PipelineText, VerifyEachPass) ||
+ PipelineText.empty())
+ return false;
+ assert(PipelineText[0] == ')');
+ PipelineText = PipelineText.substr(1);
+
+ // Add the nested pass manager with the appropriate adaptor.
+ CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(NestedFPM)));
+ } else {
+ // Otherwise try to parse a pass name.
+ size_t End = PipelineText.find_first_of(",)");
+ if (!parseCGSCCPassName(CGPM, PipelineText.substr(0, End)))
+ return false;
+ // FIXME: No verifier support for CGSCC passes!
+
+ PipelineText = PipelineText.substr(End);
+ }
+
+ if (PipelineText.empty() || PipelineText[0] == ')')
+ return true;
+
+ assert(PipelineText[0] == ',');
+ PipelineText = PipelineText.substr(1);
+ }
+}
+
static bool parseModulePassPipeline(ModulePassManager &MPM,
StringRef &PipelineText,
bool VerifyEachPass) {
@@ -139,6 +227,20 @@ static bool parseModulePassPipeline(ModulePassManager &MPM,
// Now add the nested manager as a module pass.
MPM.addPass(std::move(NestedMPM));
+ } else if (PipelineText.startswith("cgscc(")) {
+ CGSCCPassManager NestedCGPM;
+
+ // Parse the inner pipeline inte the nested manager.
+ PipelineText = PipelineText.substr(strlen("cgscc("));
+ if (!parseCGSCCPassPipeline(NestedCGPM, PipelineText, VerifyEachPass) ||
+ PipelineText.empty())
+ return false;
+ assert(PipelineText[0] == ')');
+ PipelineText = PipelineText.substr(1);
+
+ // Add the nested pass manager with the appropriate adaptor.
+ MPM.addPass(
+ createModuleToPostOrderCGSCCPassAdaptor(std::move(NestedCGPM)));
} else if (PipelineText.startswith("function(")) {
FunctionPassManager NestedFPM;
@@ -180,6 +282,14 @@ bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
if (PipelineText.startswith("module("))
return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) &&
PipelineText.empty();
+ if (PipelineText.startswith("cgscc(")) {
+ CGSCCPassManager CGPM;
+ if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) ||
+ !PipelineText.empty())
+ return false;
+ MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
+ return true;
+ }
if (PipelineText.startswith("function(")) {
FunctionPassManager FPM;
if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
@@ -196,6 +306,15 @@ bool llvm::parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText,
return parseModulePassPipeline(MPM, PipelineText, VerifyEachPass) &&
PipelineText.empty();
+ if (isCGSCCPassName(FirstName)) {
+ CGSCCPassManager CGPM;
+ if (!parseCGSCCPassPipeline(CGPM, PipelineText, VerifyEachPass) ||
+ !PipelineText.empty())
+ return false;
+ MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
+ return true;
+ }
+
if (isFunctionPassName(FirstName)) {
FunctionPassManager FPM;
if (!parseFunctionPassPipeline(FPM, PipelineText, VerifyEachPass) ||
diff --git a/tools/opt/PrintSCC.cpp b/tools/opt/PrintSCC.cpp
index cbc0a55..78ede2b 100644
--- a/tools/opt/PrintSCC.cpp
+++ b/tools/opt/PrintSCC.cpp
@@ -39,7 +39,7 @@ namespace {
CFGSCC() : FunctionPass(ID) {}
bool runOnFunction(Function& func) override;
- void print(raw_ostream &O, const Module* = 0) const override { }
+ void print(raw_ostream &O, const Module* = nullptr) const override { }
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.setPreservesAll();
@@ -53,7 +53,7 @@ namespace {
// run - Print out SCCs in the call graph for the specified module.
bool runOnModule(Module &M) override;
- void print(raw_ostream &O, const Module* = 0) const override { }
+ void print(raw_ostream &O, const Module* = nullptr) const override { }
// getAnalysisUsage - This pass requires the CallGraph.
void getAnalysisUsage(AnalysisUsage &AU) const override {
@@ -75,7 +75,7 @@ bool CFGSCC::runOnFunction(Function &F) {
unsigned sccNum = 0;
errs() << "SCCs for Function " << F.getName() << " in PostOrder:";
for (scc_iterator<Function*> SCCI = scc_begin(&F); !SCCI.isAtEnd(); ++SCCI) {
- std::vector<BasicBlock*> &nextSCC = *SCCI;
+ const std::vector<BasicBlock *> &nextSCC = *SCCI;
errs() << "\nSCC #" << ++sccNum << " : ";
for (std::vector<BasicBlock*>::const_iterator I = nextSCC.begin(),
E = nextSCC.end(); I != E; ++I)
diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp
index 5a19881..6f0fbf6 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -35,6 +35,7 @@
#include "llvm/MC/SubtargetFeature.h"
#include "llvm/PassManager.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/PluginLoader.h"
#include "llvm/Support/PrettyStackTrace.h"
@@ -191,7 +192,10 @@ static inline void addPass(PassManagerBase &PM, Pass *P) {
PM.add(P);
// If we are verifying all of the intermediate steps, add the verifier...
- if (VerifyEach) PM.add(createVerifierPass());
+ if (VerifyEach) {
+ PM.add(createVerifierPass());
+ PM.add(createDebugInfoVerifierPass());
+ }
}
/// AddOptimizationPasses - This routine adds optimization passes
@@ -201,7 +205,8 @@ static inline void addPass(PassManagerBase &PM, Pass *P) {
/// OptLevel - Optimization Level
static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM,
unsigned OptLevel, unsigned SizeLevel) {
- FPM.add(createVerifierPass()); // Verify that input is correct
+ FPM.add(createVerifierPass()); // Verify that input is correct
+ MPM.add(createDebugInfoVerifierPass()); // Verify that debug info is correct
PassManagerBuilder Builder;
Builder.OptLevel = OptLevel;
@@ -240,6 +245,9 @@ static void AddStandardCompilePasses(PassManagerBase &PM) {
if (StripDebug)
addPass(PM, createStripSymbolsPass(true));
+ // Verify debug info only after it's (possibly) stripped.
+ PM.add(createDebugInfoVerifierPass());
+
if (DisableOptimizations) return;
// -std-compile-opts adds the same module passes as -O3.
@@ -257,6 +265,9 @@ static void AddStandardLinkPasses(PassManagerBase &PM) {
if (StripDebug)
addPass(PM, createStripSymbolsPass(true));
+ // Verify debug info only after it's (possibly) stripped.
+ PM.add(createDebugInfoVerifierPass());
+
if (DisableOptimizations) return;
PassManagerBuilder Builder;
@@ -285,7 +296,7 @@ static TargetMachine* GetTargetMachine(Triple TheTriple) {
Error);
// Some modules don't specify a triple, and this is okay.
if (!TheTarget) {
- return 0;
+ return nullptr;
}
// Package up features to be passed to target/subtarget
@@ -341,8 +352,9 @@ int main(int argc, char **argv) {
initializeInstrumentation(Registry);
initializeTarget(Registry);
// For codegen passes, only passes that do IR to IR transformation are
- // supported. For now, just add CodeGenPrepare.
+ // supported.
initializeCodeGenPreparePass(Registry);
+ initializeAtomicExpandLoadLinkedPass(Registry);
#ifdef LINK_POLLY_INTO_TOOLS
polly::initializePollyPasses(Registry);
@@ -362,7 +374,7 @@ int main(int argc, char **argv) {
std::unique_ptr<Module> M;
M.reset(ParseIRFile(InputFilename, Err, Context));
- if (M.get() == 0) {
+ if (!M.get()) {
Err.print(argv[0], errs());
return 1;
}
@@ -442,7 +454,7 @@ int main(int argc, char **argv) {
Passes.add(new DataLayoutPass(M.get()));
Triple ModuleTriple(M->getTargetTriple());
- TargetMachine *Machine = 0;
+ TargetMachine *Machine = nullptr;
if (ModuleTriple.getArch())
Machine = GetTargetMachine(Triple(ModuleTriple));
std::unique_ptr<TargetMachine> TM(Machine);
@@ -526,7 +538,7 @@ int main(int argc, char **argv) {
}
const PassInfo *PassInf = PassList[i];
- Pass *P = 0;
+ Pass *P = nullptr;
if (PassInf->getTargetMachineCtor())
P = PassInf->getTargetMachineCtor()(TM.get());
else if (PassInf->getNormalCtor())
@@ -600,8 +612,10 @@ int main(int argc, char **argv) {
}
// Check that the module is well formed on completion of optimization
- if (!NoVerify && !VerifyEach)
+ if (!NoVerify && !VerifyEach) {
Passes.add(createVerifierPass());
+ Passes.add(createDebugInfoVerifierPass());
+ }
// Write bitcode or assembly to the output as the last step...
if (!NoOutput && !AnalyzeOnly) {
diff --git a/tools/yaml2obj/yaml2elf.cpp b/tools/yaml2obj/yaml2elf.cpp
index 21506d9..bb52cda 100644
--- a/tools/yaml2obj/yaml2elf.cpp
+++ b/tools/yaml2obj/yaml2elf.cpp
@@ -16,6 +16,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Object/ELFObjectFile.h"
#include "llvm/Object/ELFYAML.h"
+#include "llvm/Object/StringTableBuilder.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/YAMLTraits.h"
@@ -23,47 +24,6 @@
using namespace llvm;
-// There is similar code in yaml2coff, but with some slight COFF-specific
-// variations like different initial state. Might be able to deduplicate
-// some day, but also want to make sure that the Mach-O use case is served.
-//
-// This class has a deliberately small interface, since a lot of
-// implementation variation is possible.
-//
-// TODO: Use an ordered container with a suffix-based comparison in order
-// to deduplicate suffixes. std::map<> with a custom comparator is likely
-// to be the simplest implementation, but a suffix trie could be more
-// suitable for the job.
-namespace {
-class StringTableBuilder {
- /// \brief Indices of strings currently present in `Buf`.
- StringMap<unsigned> StringIndices;
- /// \brief The contents of the string table as we build it.
- std::string Buf;
-public:
- StringTableBuilder() {
- Buf.push_back('\0');
- }
- /// \returns Index of string in string table.
- unsigned addString(StringRef S) {
- StringMapEntry<unsigned> &Entry = StringIndices.GetOrCreateValue(S);
- unsigned &I = Entry.getValue();
- if (I != 0)
- return I;
- I = Buf.size();
- Buf.append(S.begin(), S.end());
- Buf.push_back('\0');
- return I;
- }
- size_t size() const {
- return Buf.size();
- }
- void writeToStream(raw_ostream &OS) {
- OS.write(Buf.data(), Buf.size());
- }
-};
-} // end anonymous namespace
-
// This class is used to build up a contiguous binary blob while keeping
// track of an offset in the output (which notionally begins at
// `InitialOffset`).
@@ -94,23 +54,23 @@ public:
};
} // end anonymous namespace
-// Used to keep track of section names, so that in the YAML file sections
-// can be referenced by name instead of by index.
+// Used to keep track of section and symbol names, so that in the YAML file
+// sections and symbols can be referenced by name instead of by index.
namespace {
-class SectionNameToIdxMap {
+class NameToIdxMap {
StringMap<int> Map;
public:
/// \returns true if name is already present in the map.
- bool addName(StringRef SecName, unsigned i) {
- StringMapEntry<int> &Entry = Map.GetOrCreateValue(SecName, -1);
+ bool addName(StringRef Name, unsigned i) {
+ StringMapEntry<int> &Entry = Map.GetOrCreateValue(Name, -1);
if (Entry.getValue() != -1)
return true;
Entry.setValue((int)i);
return false;
}
/// \returns true if name is not present in the map
- bool lookupSection(StringRef SecName, unsigned &Idx) const {
- StringMap<int>::const_iterator I = Map.find(SecName);
+ bool lookup(StringRef Name, unsigned &Idx) const {
+ StringMap<int>::const_iterator I = Map.find(Name);
if (I == Map.end())
return true;
Idx = I->getValue();
@@ -143,6 +103,8 @@ class ELFState {
typedef typename object::ELFFile<ELFT>::Elf_Ehdr Elf_Ehdr;
typedef typename object::ELFFile<ELFT>::Elf_Shdr Elf_Shdr;
typedef typename object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
+ typedef typename object::ELFFile<ELFT>::Elf_Rel Elf_Rel;
+ typedef typename object::ELFFile<ELFT>::Elf_Rela Elf_Rela;
/// \brief The future ".strtab" section.
StringTableBuilder DotStrtab;
@@ -150,10 +112,13 @@ class ELFState {
/// \brief The future ".shstrtab" section.
StringTableBuilder DotShStrtab;
- SectionNameToIdxMap SN2I;
+ NameToIdxMap SN2I;
+ NameToIdxMap SymN2I;
const ELFYAML::Object &Doc;
bool buildSectionIndex();
+ bool buildSymbolIndex(std::size_t &StartIndex,
+ const std::vector<ELFYAML::Symbol> &Symbols);
void initELFHeader(Elf_Ehdr &Header);
bool initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
ContiguousBlobAccumulator &CBA);
@@ -164,6 +129,12 @@ class ELFState {
ContiguousBlobAccumulator &CBA);
void addSymbols(const std::vector<ELFYAML::Symbol> &Symbols,
std::vector<Elf_Sym> &Syms, unsigned SymbolBinding);
+ void writeSectionContent(Elf_Shdr &SHeader,
+ const ELFYAML::RawContentSection &Section,
+ ContiguousBlobAccumulator &CBA);
+ bool writeSectionContent(Elf_Shdr &SHeader,
+ const ELFYAML::RelocationSection &Section,
+ ContiguousBlobAccumulator &CBA);
// - SHT_NULL entry (placed first, i.e. 0'th entry)
// - symbol table (.symtab) (placed third to last)
@@ -217,28 +188,48 @@ bool ELFState<ELFT>::initSectionHeaders(std::vector<Elf_Shdr> &SHeaders,
zero(SHeader);
SHeaders.push_back(SHeader);
+ for (const auto &Sec : Doc.Sections)
+ DotShStrtab.add(Sec->Name);
+ DotShStrtab.finalize();
+
for (const auto &Sec : Doc.Sections) {
zero(SHeader);
- SHeader.sh_name = DotShStrtab.addString(Sec.Name);
- SHeader.sh_type = Sec.Type;
- SHeader.sh_flags = Sec.Flags;
- SHeader.sh_addr = Sec.Address;
-
- Sec.Content.writeAsBinary(CBA.getOSAndAlignedOffset(SHeader.sh_offset));
- SHeader.sh_size = Sec.Content.binary_size();
+ SHeader.sh_name = DotShStrtab.getOffset(Sec->Name);
+ SHeader.sh_type = Sec->Type;
+ SHeader.sh_flags = Sec->Flags;
+ SHeader.sh_addr = Sec->Address;
+ SHeader.sh_addralign = Sec->AddressAlign;
- if (!Sec.Link.empty()) {
+ if (!Sec->Link.empty()) {
unsigned Index;
- if (SN2I.lookupSection(Sec.Link, Index)) {
- errs() << "error: Unknown section referenced: '" << Sec.Link
- << "' at YAML section '" << Sec.Name << "'.\n";
- return false;;
+ if (SN2I.lookup(Sec->Link, Index)) {
+ errs() << "error: Unknown section referenced: '" << Sec->Link
+ << "' at YAML section '" << Sec->Name << "'.\n";
+ return false;
}
SHeader.sh_link = Index;
}
- SHeader.sh_info = 0;
- SHeader.sh_addralign = Sec.AddressAlign;
- SHeader.sh_entsize = 0;
+
+ if (auto S = dyn_cast<ELFYAML::RawContentSection>(Sec.get()))
+ writeSectionContent(SHeader, *S, CBA);
+ else if (auto S = dyn_cast<ELFYAML::RelocationSection>(Sec.get())) {
+ if (S->Link.empty())
+ // For relocation section set link to .symtab by default.
+ SHeader.sh_link = getDotSymTabSecNo();
+
+ unsigned Index;
+ if (SN2I.lookup(S->Info, Index)) {
+ errs() << "error: Unknown section referenced: '" << S->Info
+ << "' at YAML section '" << S->Name << "'.\n";
+ return false;
+ }
+ SHeader.sh_info = Index;
+
+ if (!writeSectionContent(SHeader, *S, CBA))
+ return false;
+ } else
+ llvm_unreachable("Unknown section type");
+
SHeaders.push_back(SHeader);
}
return true;
@@ -248,7 +239,7 @@ template <class ELFT>
void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader,
ContiguousBlobAccumulator &CBA) {
zero(SHeader);
- SHeader.sh_name = DotShStrtab.addString(StringRef(".symtab"));
+ SHeader.sh_name = DotShStrtab.getOffset(".symtab");
SHeader.sh_type = ELF::SHT_SYMTAB;
SHeader.sh_link = getDotStrTabSecNo();
// One greater than symbol table index of the last local symbol.
@@ -262,6 +253,16 @@ void ELFState<ELFT>::initSymtabSectionHeader(Elf_Shdr &SHeader,
zero(Sym);
Syms.push_back(Sym);
}
+
+ // Add symbol names to .strtab.
+ for (const auto &Sym : Doc.Symbols.Local)
+ DotStrtab.add(Sym.Name);
+ for (const auto &Sym : Doc.Symbols.Global)
+ DotStrtab.add(Sym.Name);
+ for (const auto &Sym : Doc.Symbols.Weak)
+ DotStrtab.add(Sym.Name);
+ DotStrtab.finalize();
+
addSymbols(Doc.Symbols.Local, Syms, ELF::STB_LOCAL);
addSymbols(Doc.Symbols.Global, Syms, ELF::STB_GLOBAL);
addSymbols(Doc.Symbols.Weak, Syms, ELF::STB_WEAK);
@@ -276,10 +277,10 @@ void ELFState<ELFT>::initStrtabSectionHeader(Elf_Shdr &SHeader, StringRef Name,
StringTableBuilder &STB,
ContiguousBlobAccumulator &CBA) {
zero(SHeader);
- SHeader.sh_name = DotShStrtab.addString(Name);
+ SHeader.sh_name = DotShStrtab.getOffset(Name);
SHeader.sh_type = ELF::SHT_STRTAB;
- STB.writeToStream(CBA.getOSAndAlignedOffset(SHeader.sh_offset));
- SHeader.sh_size = STB.size();
+ CBA.getOSAndAlignedOffset(SHeader.sh_offset) << STB.data();
+ SHeader.sh_size = STB.data().size();
SHeader.sh_addralign = 1;
}
@@ -291,11 +292,11 @@ void ELFState<ELFT>::addSymbols(const std::vector<ELFYAML::Symbol> &Symbols,
Elf_Sym Symbol;
zero(Symbol);
if (!Sym.Name.empty())
- Symbol.st_name = DotStrtab.addString(Sym.Name);
+ Symbol.st_name = DotStrtab.getOffset(Sym.Name);
Symbol.setBindingAndType(SymbolBinding, Sym.Type);
if (!Sym.Section.empty()) {
unsigned Index;
- if (SN2I.lookupSection(Sym.Section, Index)) {
+ if (SN2I.lookup(Sym.Section, Index)) {
errs() << "error: Unknown section referenced: '" << Sym.Section
<< "' by YAML symbol " << Sym.Name << ".\n";
exit(1);
@@ -308,13 +309,71 @@ void ELFState<ELFT>::addSymbols(const std::vector<ELFYAML::Symbol> &Symbols,
}
}
+template <class ELFT>
+void
+ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
+ const ELFYAML::RawContentSection &Section,
+ ContiguousBlobAccumulator &CBA) {
+ assert(Section.Size >= Section.Content.binary_size() &&
+ "Section size and section content are inconsistent");
+ raw_ostream &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset);
+ Section.Content.writeAsBinary(OS);
+ for (auto i = Section.Content.binary_size(); i < Section.Size; ++i)
+ OS.write(0);
+ SHeader.sh_entsize = 0;
+ SHeader.sh_size = Section.Size;
+}
+
+template <class ELFT>
+bool
+ELFState<ELFT>::writeSectionContent(Elf_Shdr &SHeader,
+ const ELFYAML::RelocationSection &Section,
+ ContiguousBlobAccumulator &CBA) {
+ if (Section.Type != llvm::ELF::SHT_REL &&
+ Section.Type != llvm::ELF::SHT_RELA) {
+ errs() << "error: Invalid relocation section type.\n";
+ return false;
+ }
+
+ bool IsRela = Section.Type == llvm::ELF::SHT_RELA;
+ SHeader.sh_entsize = IsRela ? sizeof(Elf_Rela) : sizeof(Elf_Rel);
+ SHeader.sh_size = SHeader.sh_entsize * Section.Relocations.size();
+
+ auto &OS = CBA.getOSAndAlignedOffset(SHeader.sh_offset);
+
+ for (const auto &Rel : Section.Relocations) {
+ unsigned SymIdx;
+ if (SymN2I.lookup(Rel.Symbol, SymIdx)) {
+ errs() << "error: Unknown symbol referenced: '" << Rel.Symbol
+ << "' at YAML relocation.\n";
+ return false;
+ }
+
+ if (IsRela) {
+ Elf_Rela REntry;
+ zero(REntry);
+ REntry.r_offset = Rel.Offset;
+ REntry.r_addend = Rel.Addend;
+ REntry.setSymbolAndType(SymIdx, Rel.Type);
+ OS.write((const char *)&REntry, sizeof(REntry));
+ } else {
+ Elf_Rel REntry;
+ zero(REntry);
+ REntry.r_offset = Rel.Offset;
+ REntry.setSymbolAndType(SymIdx, Rel.Type);
+ OS.write((const char *)&REntry, sizeof(REntry));
+ }
+ }
+ return true;
+}
+
template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() {
SN2I.addName(".symtab", getDotSymTabSecNo());
SN2I.addName(".strtab", getDotStrTabSecNo());
SN2I.addName(".shstrtab", getDotShStrTabSecNo());
for (unsigned i = 0, e = Doc.Sections.size(); i != e; ++i) {
- StringRef Name = Doc.Sections[i].Name;
+ StringRef Name = Doc.Sections[i]->Name;
if (Name.empty())
continue;
// "+ 1" to take into account the SHT_NULL entry.
@@ -328,11 +387,33 @@ template <class ELFT> bool ELFState<ELFT>::buildSectionIndex() {
}
template <class ELFT>
+bool
+ELFState<ELFT>::buildSymbolIndex(std::size_t &StartIndex,
+ const std::vector<ELFYAML::Symbol> &Symbols) {
+ for (const auto &Sym : Symbols) {
+ ++StartIndex;
+ if (Sym.Name.empty())
+ continue;
+ if (SymN2I.addName(Sym.Name, StartIndex)) {
+ errs() << "error: Repeated symbol name: '" << Sym.Name << "'.\n";
+ return false;
+ }
+ }
+ return true;
+}
+
+template <class ELFT>
int ELFState<ELFT>::writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) {
ELFState<ELFT> State(Doc);
if (!State.buildSectionIndex())
return 1;
+ std::size_t StartSymIndex = 0;
+ if (!State.buildSymbolIndex(StartSymIndex, Doc.Symbols.Local) ||
+ !State.buildSymbolIndex(StartSymIndex, Doc.Symbols.Global) ||
+ !State.buildSymbolIndex(StartSymIndex, Doc.Symbols.Weak))
+ return 1;
+
Elf_Ehdr Header;
State.initELFHeader(Header);
@@ -345,6 +426,12 @@ int ELFState<ELFT>::writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) {
Header.e_ehsize + Header.e_shentsize * Header.e_shnum;
ContiguousBlobAccumulator CBA(SectionContentBeginOffset);
+ // Doc might not contain .symtab, .strtab and .shstrtab sections,
+ // but we will emit them, so make sure to add them to ShStrTabSHeader.
+ State.DotShStrtab.add(".symtab");
+ State.DotShStrtab.add(".strtab");
+ State.DotShStrtab.add(".shstrtab");
+
std::vector<Elf_Shdr> SHeaders;
if(!State.initSectionHeaders(SHeaders, CBA))
return 1;
@@ -395,13 +482,13 @@ int yaml2elf(llvm::raw_ostream &Out, llvm::MemoryBuffer *Buf) {
typedef ELFType<support::big, 4, false> BE32;
if (is64Bit(Doc)) {
if (isLittleEndian(Doc))
- return ELFState<LE64>::writeELF(outs(), Doc);
+ return ELFState<LE64>::writeELF(Out, Doc);
else
- return ELFState<BE64>::writeELF(outs(), Doc);
+ return ELFState<BE64>::writeELF(Out, Doc);
} else {
if (isLittleEndian(Doc))
- return ELFState<LE32>::writeELF(outs(), Doc);
+ return ELFState<LE32>::writeELF(Out, Doc);
else
- return ELFState<BE32>::writeELF(outs(), Doc);
+ return ELFState<BE32>::writeELF(Out, Doc);
}
}
diff --git a/tools/yaml2obj/yaml2obj.cpp b/tools/yaml2obj/yaml2obj.cpp
index cc0fecc..2493b48 100644
--- a/tools/yaml2obj/yaml2obj.cpp
+++ b/tools/yaml2obj/yaml2obj.cpp
@@ -16,12 +16,14 @@
#include "yaml2obj.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/PrettyStackTrace.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/system_error.h"
+#include "llvm/Support/ToolOutputFile.h"
using namespace llvm;
@@ -49,6 +51,8 @@ cl::opt<YAMLObjectFormat> Format(
clEnumValN(YOF_ELF, "elf", "ELF object file format"),
clEnumValEnd));
+static cl::opt<std::string> OutputFilename("o", cl::desc("Output filename"),
+ cl::value_desc("filename"));
int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv);
@@ -56,15 +60,31 @@ int main(int argc, char **argv) {
PrettyStackTraceProgram X(argc, argv);
llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
+ if (OutputFilename.empty())
+ OutputFilename = "-";
+
+ std::string ErrorInfo;
+ std::unique_ptr<tool_output_file> Out(
+ new tool_output_file(OutputFilename.c_str(), ErrorInfo, sys::fs::F_None));
+ if (!ErrorInfo.empty()) {
+ errs() << ErrorInfo << '\n';
+ return 1;
+ }
+
std::unique_ptr<MemoryBuffer> Buf;
if (MemoryBuffer::getFileOrSTDIN(Input, Buf))
return 1;
- if (Format == YOF_COFF) {
- return yaml2coff(outs(), Buf.get());
- } else if (Format == YOF_ELF) {
- return yaml2elf(outs(), Buf.get());
- } else {
+
+ int Res = 1;
+ if (Format == YOF_COFF)
+ Res = yaml2coff(Out->os(), Buf.get());
+ else if (Format == YOF_ELF)
+ Res = yaml2elf(Out->os(), Buf.get());
+ else
errs() << "Not yet implemented\n";
- return 1;
- }
+
+ if (Res == 0)
+ Out->keep();
+
+ return Res;
}