#include "llvm/ADT/StringMap.h"
#include "llvm/DebugInfo/DIContext.h"
#include "llvm/DebugInfo/DWARF/DWARFContext.h"
#include "llvm/ExecutionEngine/RTDyldMemoryManager.h"
#include "llvm/ExecutionEngine/RuntimeDyld.h"
#include "llvm/ExecutionEngine/RuntimeDyldChecker.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCInstPrinter.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCTargetOptions.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Object/SymbolSize.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/InitLLVM.h"
#include "llvm/Support/MSVCErrorWorkarounds.h"
#include "llvm/Support/Memory.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include <future>
#include <list>
usingnamespacellvm;
usingnamespacellvm::object;
static cl::OptionCategory RTDyldCategory("RTDyld Options");
static cl::list<std::string> InputFileList(cl::Positional,
cl::desc("<input files>"),
cl::cat(RTDyldCategory));
enum ActionType { … };
static cl::opt<ActionType> Action(
cl::desc("Action to perform:"), cl::init(AC_Execute),
cl::values(
clEnumValN(AC_Execute, "execute",
"Load, link, and execute the inputs."),
clEnumValN(AC_PrintLineInfo, "printline",
"Load, link, and print line information for each function."),
clEnumValN(AC_PrintDebugLineInfo, "printdebugline",
"Load, link, and print line information for each function "
"using the debug object"),
clEnumValN(AC_PrintObjectLineInfo, "printobjline",
"Like -printlineinfo but does not load the object first"),
clEnumValN(AC_Verify, "verify",
"Load, link and verify the resulting memory image.")),
cl::cat(RTDyldCategory));
static cl::opt<std::string>
EntryPoint("entry", cl::desc("Function to call as entry point."),
cl::init("_main"), cl::cat(RTDyldCategory));
static cl::list<std::string> Dylibs("dylib", cl::desc("Add library."),
cl::cat(RTDyldCategory));
static cl::list<std::string> InputArgv("args", cl::Positional,
cl::desc("<program arguments>..."),
cl::PositionalEatsArgs,
cl::cat(RTDyldCategory));
static cl::opt<std::string>
TripleName("triple", cl::desc("Target triple for disassembler"),
cl::cat(RTDyldCategory));
static cl::opt<std::string>
MCPU("mcpu",
cl::desc("Target a specific cpu type (-mcpu=help for details)"),
cl::value_desc("cpu-name"), cl::init(""), cl::cat(RTDyldCategory));
static cl::list<std::string>
CheckFiles("check",
cl::desc("File containing RuntimeDyld verifier checks."),
cl::cat(RTDyldCategory));
static cl::opt<uint64_t>
PreallocMemory("preallocate",
cl::desc("Allocate memory upfront rather than on-demand"),
cl::init(0), cl::cat(RTDyldCategory));
static cl::opt<uint64_t> TargetAddrStart(
"target-addr-start",
cl::desc("For -verify only: start of phony target address "
"range."),
cl::init(4096),
cl::Hidden, cl::cat(RTDyldCategory));
static cl::opt<uint64_t> TargetAddrEnd(
"target-addr-end",
cl::desc("For -verify only: end of phony target address range."),
cl::init(~0ULL), cl::Hidden, cl::cat(RTDyldCategory));
static cl::opt<uint64_t> TargetSectionSep(
"target-section-sep",
cl::desc("For -verify only: Separation between sections in "
"phony target address space."),
cl::init(0), cl::Hidden, cl::cat(RTDyldCategory));
static cl::list<std::string>
SpecificSectionMappings("map-section",
cl::desc("For -verify only: Map a section to a "
"specific address."),
cl::Hidden, cl::cat(RTDyldCategory));
static cl::list<std::string> DummySymbolMappings(
"dummy-extern",
cl::desc("For -verify only: Inject a symbol into the extern "
"symbol table."),
cl::Hidden, cl::cat(RTDyldCategory));
static cl::opt<bool> PrintAllocationRequests(
"print-alloc-requests",
cl::desc("Print allocation requests made to the memory "
"manager by RuntimeDyld"),
cl::Hidden, cl::cat(RTDyldCategory));
static cl::opt<bool> ShowTimes("show-times",
cl::desc("Show times for llvm-rtdyld phases"),
cl::init(false), cl::cat(RTDyldCategory));
ExitOnError ExitOnErr;
struct RTDyldTimers { … };
std::unique_ptr<RTDyldTimers> Timers;
SectionIDMap;
FileToSectionIDMap;
void dumpFileToSectionIDMap(const FileToSectionIDMap &FileToSecIDMap) { … }
Expected<unsigned> getSectionId(const FileToSectionIDMap &FileToSecIDMap,
StringRef FileName, StringRef SectionName) { … }
class TrivialMemoryManager : public RTDyldMemoryManager { … };
uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size,
unsigned Alignment,
unsigned SectionID,
StringRef SectionName) { … }
uint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size,
unsigned Alignment,
unsigned SectionID,
StringRef SectionName,
bool IsReadOnly) { … }
#if defined(__x86_64__) && defined(__ELF__) && defined(__linux__)
extern "C" {
alignas(16) __attribute__((visibility("hidden"), tls_model("initial-exec"),
used)) thread_local char LLVMRTDyldTLSSpace[16];
}
#endif
TrivialMemoryManager::TLSSection
TrivialMemoryManager::allocateTLSSection(uintptr_t Size, unsigned Alignment,
unsigned SectionID,
StringRef SectionName) { … }
static const char *ProgramName;
static void ErrorAndExit(const Twine &Msg) { … }
static void loadDylibs() { … }
static int printLineInfoForInput(bool LoadObjects, bool UseDebugObj) { … }
static void doPreallocation(TrivialMemoryManager &MemMgr) { … }
static int executeInput() { … }
static int checkAllExpressions(RuntimeDyldChecker &Checker) { … }
void applySpecificSectionMappings(RuntimeDyld &Dyld,
const FileToSectionIDMap &FileToSecIDMap) { … }
static void remapSectionsAndSymbols(const llvm::Triple &TargetTriple,
RuntimeDyld &Dyld,
TrivialMemoryManager &MemMgr) { … }
static int linkAndVerify() { … }
int main(int argc, char **argv) { … }