From 081a1941b595f6294e4ce678fd61ef56a2ceb51e Mon Sep 17 00:00:00 2001 From: "Michael J. Spencer" Date: Thu, 8 Aug 2013 22:27:13 +0000 Subject: [Object] Split the ELF interface into 3 parts. * ELFTypes.h contains template magic for defining types based on endianess, size, and alignment. * ELFFile.h defines the ELFFile class which provides low level ELF specific access. * ELFObjectFile.h contains ELFObjectFile which uses ELFFile to implement the ObjectFile interface. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188022 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/ELFDump.cpp | 16 +- tools/llvm-readobj/ELFDumper.cpp | 300 +++++++++++++++--------------------- tools/llvm-readobj/llvm-readobj.cpp | 9 +- tools/yaml2obj/yaml2elf.cpp | 21 +-- 4 files changed, 152 insertions(+), 194 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/ELFDump.cpp b/tools/llvm-objdump/ELFDump.cpp index ef1f0e9..9c091a41 100644 --- a/tools/llvm-objdump/ELFDump.cpp +++ b/tools/llvm-objdump/ELFDump.cpp @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm-objdump.h" -#include "llvm/Object/ELF.h" +#include "llvm/Object/ELFObjectFile.h" #include "llvm/Support/Format.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" @@ -21,10 +21,8 @@ using namespace llvm; using namespace llvm::object; -template -void printProgramHeaders( - const ELFObjectFile *o) { - typedef ELFObjectFile ELFO; +template void printProgramHeaders(const ELFFile *o) { + typedef ELFFile ELFO; outs() << "Program Header:\n"; for (typename ELFO::Elf_Phdr_Iter pi = o->begin_program_headers(), pe = o->end_program_headers(); @@ -80,17 +78,17 @@ void printProgramHeaders( void llvm::printELFFileHeader(const object::ObjectFile *Obj) { // Little-endian 32-bit if (const ELF32LEObjectFile *ELFObj = dyn_cast(Obj)) - printProgramHeaders(ELFObj); + printProgramHeaders(ELFObj->getELFFile()); // Big-endian 32-bit if (const ELF32BEObjectFile *ELFObj = dyn_cast(Obj)) - printProgramHeaders(ELFObj); + printProgramHeaders(ELFObj->getELFFile()); // Little-endian 64-bit if (const ELF64LEObjectFile *ELFObj = dyn_cast(Obj)) - printProgramHeaders(ELFObj); + printProgramHeaders(ELFObj->getELFFile()); // Big-endian 64-bit if (const ELF64BEObjectFile *ELFObj = dyn_cast(Obj)) - printProgramHeaders(ELFObj); + printProgramHeaders(ELFObj->getELFFile()); } diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index 3628c3b..e909ef8 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -18,7 +18,7 @@ #include "StreamWriter.h" #include "llvm/ADT/SmallString.h" -#include "llvm/Object/ELF.h" +#include "llvm/Object/ELFObjectFile.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/Format.h" #include "llvm/Support/MathExtras.h" @@ -28,7 +28,6 @@ using namespace llvm; using namespace llvm::object; using namespace ELF; - #define LLVM_READOBJ_ENUM_CASE(ns, enum) \ case ns::enum: return #enum; @@ -37,9 +36,8 @@ namespace { template class ELFDumper : public ObjDumper { public: - ELFDumper(const ELFObjectFile *Obj, StreamWriter& Writer) - : ObjDumper(Writer) - , Obj(Obj) { } + ELFDumper(const ELFFile *Obj, StreamWriter &Writer) + : ObjDumper(Writer), Obj(Obj) {} virtual void printFileHeaders() LLVM_OVERRIDE; virtual void printSections() LLVM_OVERRIDE; @@ -53,24 +51,32 @@ public: virtual void printProgramHeaders() LLVM_OVERRIDE; private: - typedef ELFObjectFile ELFO; + typedef ELFFile ELFO; typedef typename ELFO::Elf_Shdr Elf_Shdr; typedef typename ELFO::Elf_Sym Elf_Sym; - void printSymbol(symbol_iterator SymI, bool IsDynamic = false); + void printSymbol(typename ELFO::Elf_Sym_Iter Symbol); - void printRelocation(section_iterator SecI, relocation_iterator RelI); + void printRelocations(const Elf_Shdr *Sec); + void printRelocation(const Elf_Shdr *Sec, typename ELFO::Elf_Rela Rel); const ELFO *Obj; }; -} // namespace +template T errorOrDefault(ErrorOr Val, T Default = T()) { + if (!Val) { + error(Val); + return Default; + } + return *Val; +} +} // namespace namespace llvm { template -static error_code createELFDumper(const ELFObjectFile *Obj, +static error_code createELFDumper(const ELFFile *Obj, StreamWriter &Writer, OwningPtr &Result) { Result.reset(new ELFDumper(Obj, Writer)); @@ -82,26 +88,25 @@ error_code createELFDumper(const object::ObjectFile *Obj, OwningPtr &Result) { // Little-endian 32-bit if (const ELF32LEObjectFile *ELFObj = dyn_cast(Obj)) - return createELFDumper(ELFObj, Writer, Result); + return createELFDumper(ELFObj->getELFFile(), Writer, Result); // Big-endian 32-bit if (const ELF32BEObjectFile *ELFObj = dyn_cast(Obj)) - return createELFDumper(ELFObj, Writer, Result); + return createELFDumper(ELFObj->getELFFile(), Writer, Result); // Little-endian 64-bit if (const ELF64LEObjectFile *ELFObj = dyn_cast(Obj)) - return createELFDumper(ELFObj, Writer, Result); + return createELFDumper(ELFObj->getELFFile(), Writer, Result); // Big-endian 64-bit if (const ELF64BEObjectFile *ELFObj = dyn_cast(Obj)) - return createELFDumper(ELFObj, Writer, Result); + return createELFDumper(ELFObj->getELFFile(), Writer, Result); return readobj_error::unsupported_obj_file_format; } } // namespace llvm - static const EnumEntry ElfClass[] = { { "None", ELF::ELFCLASSNONE }, { "32-bit", ELF::ELFCLASS32 }, @@ -322,7 +327,7 @@ static const EnumEntry ElfSymbolTypes[] = { static const char *getElfSectionType(unsigned Arch, unsigned Type) { switch (Arch) { - case Triple::arm: + case ELF::EM_ARM: switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_EXIDX); LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_PREEMPTMAP); @@ -330,16 +335,12 @@ static const char *getElfSectionType(unsigned Arch, unsigned Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_DEBUGOVERLAY); LLVM_READOBJ_ENUM_CASE(ELF, SHT_ARM_OVERLAYSECTION); } - case Triple::hexagon: - switch (Type) { - LLVM_READOBJ_ENUM_CASE(ELF, SHT_HEX_ORDERED); - } - case Triple::x86_64: - switch (Type) { - LLVM_READOBJ_ENUM_CASE(ELF, SHT_X86_64_UNWIND); - } - case Triple::mips: - case Triple::mipsel: + case ELF::EM_HEXAGON: + switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_HEX_ORDERED); } + case ELF::EM_X86_64: + switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_X86_64_UNWIND); } + case ELF::EM_MIPS: + case ELF::EM_MIPS_RS3_LE: switch (Type) { LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_REGINFO); LLVM_READOBJ_ENUM_CASE(ELF, SHT_MIPS_OPTIONS); @@ -416,12 +417,11 @@ static const EnumEntry ElfSegmentFlags[] = { LLVM_READOBJ_ENUM_ENT(ELF, PF_R) }; - template void ELFDumper::printFileHeaders() { error_code EC; - const typename ELFO::Elf_Ehdr *Header = Obj->getElfHeader(); + const typename ELFO::Elf_Ehdr *Header = Obj->getHeader(); { DictScope D(W, "ElfHeader"); @@ -461,24 +461,20 @@ void ELFDumper::printSections() { ListScope SectionsD(W, "Sections"); int SectionIndex = -1; - error_code EC; - for (section_iterator SecI = Obj->begin_sections(), - SecE = Obj->end_sections(); - SecI != SecE; SecI.increment(EC)) { - if (error(EC)) break; - + for (typename ELFO::Elf_Shdr_Iter SecI = Obj->begin_sections(), + SecE = Obj->end_sections(); + SecI != SecE; ++SecI) { ++SectionIndex; - const Elf_Shdr *Section = Obj->getElfSection(SecI); - StringRef Name; - if (error(SecI->getName(Name))) - Name = ""; + const Elf_Shdr *Section = &*SecI; + StringRef Name = errorOrDefault(Obj->getSectionName(Section)); DictScope SectionD(W, "Section"); W.printNumber("Index", SectionIndex); W.printNumber("Name", Name, Section->sh_name); - W.printHex ("Type", getElfSectionType(Obj->getArch(), Section->sh_type), - Section->sh_type); + W.printHex("Type", + getElfSectionType(Obj->getHeader()->e_machine, Section->sh_type), + Section->sh_type); W.printFlags ("Flags", Section->sh_flags, makeArrayRef(ElfSectionFlags)); W.printHex ("Address", Section->sh_addr); W.printHex ("Offset", Section->sh_offset); @@ -490,35 +486,23 @@ void ELFDumper::printSections() { if (opts::SectionRelocations) { ListScope D(W, "Relocations"); - for (relocation_iterator RelI = SecI->begin_relocations(), - RelE = SecI->end_relocations(); - RelI != RelE; RelI.increment(EC)) { - if (error(EC)) break; - - printRelocation(SecI, RelI); - } + printRelocations(Section); } if (opts::SectionSymbols) { ListScope D(W, "Symbols"); - for (symbol_iterator SymI = Obj->begin_symbols(), - SymE = Obj->end_symbols(); - SymI != SymE; SymI.increment(EC)) { - if (error(EC)) break; - - bool Contained = false; - if (SecI->containsSymbol(*SymI, Contained) || !Contained) - continue; - - printSymbol(SymI); + for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(), + SymE = Obj->end_symbols(); + SymI != SymE; ++SymI) { + if (Obj->getSection(&*SymI) == Section) + printSymbol(SymI); } } if (opts::SectionData) { - StringRef Data; - if (error(SecI->getContents(Data))) break; - - W.printBinaryBlock("SectionData", Data); + ArrayRef Data = errorOrDefault(Obj->getSectionContents(Section)); + W.printBinaryBlock("SectionData", + StringRef((const char *)Data.data(), Data.size())); } } } @@ -529,70 +513,73 @@ void ELFDumper::printRelocations() { error_code EC; int SectionNumber = -1; - for (section_iterator SecI = Obj->begin_sections(), - SecE = Obj->end_sections(); - SecI != SecE; SecI.increment(EC)) { - if (error(EC)) break; - + for (typename ELFO::Elf_Shdr_Iter SecI = Obj->begin_sections(), + SecE = Obj->end_sections(); + SecI != SecE; ++SecI) { ++SectionNumber; - StringRef Name; - if (error(SecI->getName(Name))) + + if (SecI->sh_type != ELF::SHT_REL && SecI->sh_type != ELF::SHT_RELA) continue; - bool PrintedGroup = false; - for (relocation_iterator RelI = SecI->begin_relocations(), - RelE = SecI->end_relocations(); - RelI != RelE; RelI.increment(EC)) { - if (error(EC)) break; + StringRef Name = errorOrDefault(Obj->getSectionName(&*SecI)); - if (!PrintedGroup) { - W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n"; - W.indent(); - PrintedGroup = true; - } + W.startLine() << "Section (" << SectionNumber << ") " << Name << " {\n"; + W.indent(); - printRelocation(SecI, RelI); - } + printRelocations(&*SecI); + + W.unindent(); + W.startLine() << "}\n"; + } +} - if (PrintedGroup) { - W.unindent(); - W.startLine() << "}\n"; +template +void ELFDumper::printRelocations(const Elf_Shdr *Sec) { + switch (Sec->sh_type) { + case ELF::SHT_REL: + for (typename ELFO::Elf_Rel_Iter RI = Obj->begin_rel(Sec), + RE = Obj->end_rel(Sec); + RI != RE; ++RI) { + typename ELFO::Elf_Rela Rela; + Rela.r_offset = RI->r_offset; + Rela.r_info = RI->r_info; + Rela.r_addend = 0; + printRelocation(Sec, Rela); + } + break; + case ELF::SHT_RELA: + for (typename ELFO::Elf_Rela_Iter RI = Obj->begin_rela(Sec), + RE = Obj->end_rela(Sec); + RI != RE; ++RI) { + printRelocation(Sec, *RI); } + break; } } -template -void ELFDumper::printRelocation(section_iterator Sec, - relocation_iterator RelI) { - uint64_t Offset; - uint64_t RelocType; +template +void ELFDumper::printRelocation(const Elf_Shdr *Sec, + typename ELFO::Elf_Rela Rel) { SmallString<32> RelocName; - int64_t Addend; + Obj->getRelocationTypeName(Rel.getType(Obj->isMips64EL()), RelocName); StringRef SymbolName; - if (Obj->getElfHeader()->e_type == ELF::ET_REL){ - if (error(RelI->getOffset(Offset))) return; - } else { - if (error(RelI->getAddress(Offset))) return; - } - if (error(RelI->getType(RelocType))) return; - if (error(RelI->getTypeName(RelocName))) return; - if (error(getELFRelocationAddend(*RelI, Addend))) return; - symbol_iterator Symbol = RelI->getSymbol(); - if (Symbol != Obj->end_symbols() && error(Symbol->getName(SymbolName))) - return; + std::pair Sym = + Obj->getRelocationSymbol(Sec, &Rel); + if (Sym.first) + SymbolName = errorOrDefault(Obj->getSymbolName(Sym.first, Sym.second)); if (opts::ExpandRelocs) { DictScope Group(W, "Relocation"); - W.printHex("Offset", Offset); - W.printNumber("Type", RelocName, RelocType); + W.printHex("Offset", Rel.r_offset); + W.printNumber("Type", RelocName, (int)Rel.getType(Obj->isMips64EL())); W.printString("Symbol", SymbolName.size() > 0 ? SymbolName : "-"); - W.printHex("Addend", Addend); + W.printHex("Addend", Rel.r_addend); } else { raw_ostream& OS = W.startLine(); - OS << W.hex(Offset) + OS << W.hex(Rel.r_offset) << " " << RelocName << " " << (SymbolName.size() > 0 ? SymbolName : "-") - << " " << W.hex(Addend) + << " " << W.hex(Rel.r_addend) << "\n"; } } @@ -600,12 +587,9 @@ void ELFDumper::printRelocation(section_iterator Sec, template void ELFDumper::printSymbols() { ListScope Group(W, "Symbols"); - - error_code EC; - for (symbol_iterator SymI = Obj->begin_symbols(), SymE = Obj->end_symbols(); - SymI != SymE; SymI.increment(EC)) { - if (error(EC)) break; - + for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_symbols(), + SymE = Obj->end_symbols(); + SymI != SymE; ++SymI) { printSymbol(SymI); } } @@ -614,41 +598,27 @@ template void ELFDumper::printDynamicSymbols() { ListScope Group(W, "DynamicSymbols"); - error_code EC; - for (symbol_iterator SymI = Obj->begin_dynamic_symbols(), - SymE = Obj->end_dynamic_symbols(); - SymI != SymE; SymI.increment(EC)) { - if (error(EC)) break; - - printSymbol(SymI, true); + for (typename ELFO::Elf_Sym_Iter SymI = Obj->begin_dynamic_symbols(), + SymE = Obj->end_dynamic_symbols(); + SymI != SymE; ++SymI) { + printSymbol(SymI); } } -template -void ELFDumper::printSymbol(symbol_iterator SymI, bool IsDynamic) { - error_code EC; - - const Elf_Sym *Symbol = Obj->getElfSymbol(SymI); - const Elf_Shdr *Section = Obj->getSection(Symbol); - - StringRef SymbolName; - if (SymI->getName(SymbolName)) - SymbolName = ""; - - StringRef SectionName = ""; - if (Section) - Obj->getSectionName(Section, SectionName); - +template +void ELFDumper::printSymbol(typename ELFO::Elf_Sym_Iter Symbol) { + StringRef SymbolName = errorOrDefault(Obj->getSymbolName(Symbol)); + const Elf_Shdr *Sec = Obj->getSection(&*Symbol); + StringRef SectionName = Sec ? errorOrDefault(Obj->getSectionName(Sec)) : ""; std::string FullSymbolName(SymbolName); - if (IsDynamic) { - StringRef Version; + if (Symbol.isDynamic()) { bool IsDefault; - if (error(Obj->getSymbolVersion(*SymI, Version, IsDefault))) - return; - if (!Version.empty()) { + ErrorOr Version = Obj->getSymbolVersion(0, &*Symbol, IsDefault); + if (Version) { FullSymbolName += (IsDefault ? "@@" : "@"); - FullSymbolName += Version; - } + FullSymbolName += *Version; + } else + error(Version); } DictScope D(W, "Symbol"); @@ -706,9 +676,9 @@ static const char *getTypeString(uint64_t Type) { #undef LLVM_READOBJ_TYPE_CASE -template -static void printValue(const ELFObjectFile *O, uint64_t Type, - uint64_t Value, bool Is64, raw_ostream &OS) { +template +static void printValue(const ELFFile *O, uint64_t Type, uint64_t Value, + bool Is64, raw_ostream &OS) { switch (Type) { case DT_PLTREL: if (Value == DT_REL) { @@ -748,12 +718,10 @@ static void printValue(const ELFObjectFile *O, uint64_t Type, OS << Value << " (bytes)"; break; case DT_NEEDED: - OS << "SharedLibrary (" - << O->getString(O->getDynamicStringTableSectionHeader(), Value) << ")"; + OS << "SharedLibrary (" << O->getDynamicString(Value) << ")"; break; case DT_SONAME: - OS << "LibrarySoname (" - << O->getString(O->getDynamicStringTableSectionHeader(), Value) << ")"; + OS << "LibrarySoname (" << O->getDynamicString(Value) << ")"; break; } } @@ -765,9 +733,8 @@ void ELFDumper::printUnwindInfo() { template void ELFDumper::printDynamicTable() { - typedef typename ELFO::Elf_Dyn_iterator EDI; - EDI Start = Obj->begin_dynamic_table(), - End = Obj->end_dynamic_table(true); + typedef typename ELFO::Elf_Dyn_Iter EDI; + EDI Start = Obj->begin_dynamic_table(), End = Obj->end_dynamic_table(true); if (Start == End) return; @@ -776,7 +743,7 @@ void ELFDumper::printDynamicTable() { raw_ostream &OS = W.getOStream(); W.startLine() << "DynamicSection [ (" << Total << " entries)\n"; - bool Is64 = Obj->getBytesInAddress() == 8; + bool Is64 = ELFT::Is64Bits; W.startLine() << " Tag" << (Is64 ? " " : " ") << "Type" @@ -793,38 +760,25 @@ void ELFDumper::printDynamicTable() { W.startLine() << "]\n"; } -static bool compareLibraryName(const LibraryRef &L, const LibraryRef &R) { - StringRef LPath, RPath; - L.getPath(LPath); - R.getPath(RPath); - return LPath < RPath; -} - template void ELFDumper::printNeededLibraries() { ListScope D(W, "NeededLibraries"); error_code EC; - typedef std::vector LibsTy; + typedef std::vector LibsTy; LibsTy Libs; - for (library_iterator I = Obj->begin_libraries_needed(), - E = Obj->end_libraries_needed(); - I != E; I.increment(EC)) { - if (EC) - report_fatal_error("Needed libraries iteration failed"); - - Libs.push_back(*I); - } + for (typename ELFO::Elf_Dyn_Iter DynI = Obj->begin_dynamic_table(), + DynE = Obj->end_dynamic_table(); + DynI != DynE; ++DynI) + if (DynI->d_tag == ELF::DT_NEEDED) + Libs.push_back(Obj->getDynamicString(DynI->d_un.d_val)); - std::sort(Libs.begin(), Libs.end(), &compareLibraryName); + std::stable_sort(Libs.begin(), Libs.end()); - for (LibsTy::const_iterator I = Libs.begin(), E = Libs.end(); - I != E; ++I) { - StringRef Path; - I->getPath(Path); - outs() << " " << Path << "\n"; + for (LibsTy::const_iterator I = Libs.begin(), E = Libs.end(); I != E; ++I) { + outs() << " " << *I << "\n"; } } diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index 2e95b6b..0e092c0 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -1,4 +1,4 @@ -//===- llvm-readobj.cpp - Dump contents of an Object File -----------------===// +//===- llvm-readobj.cpp - Dump contents of an Object File -----------------===// // // The LLVM Compiler Infrastructure // @@ -130,12 +130,15 @@ namespace opts { cl::desc("Expand each shown relocation to multiple lines")); } // namespace opts +static int ReturnValue = EXIT_SUCCESS; + namespace llvm { bool error(error_code EC) { if (!EC) return false; + ReturnValue = EXIT_FAILURE; outs() << "\nError reading file: " << EC.message() << ".\n"; outs().flush(); return true; @@ -157,6 +160,7 @@ static void reportError(StringRef Input, error_code EC) { errs() << Input << ": " << EC.message() << "\n"; errs().flush(); + ReturnValue = EXIT_FAILURE; } static void reportError(StringRef Input, StringRef Message) { @@ -164,6 +168,7 @@ static void reportError(StringRef Input, StringRef Message) { Input = ""; errs() << Input << ": " << Message << "\n"; + ReturnValue = EXIT_FAILURE; } /// @brief Creates an format-specific object file dumper. @@ -289,5 +294,5 @@ int main(int argc, const char *argv[]) { std::for_each(opts::InputFilenames.begin(), opts::InputFilenames.end(), dumpInput); - return 0; + return ReturnValue; } diff --git a/tools/yaml2obj/yaml2elf.cpp b/tools/yaml2obj/yaml2elf.cpp index 61252a4..d3b25ec 100644 --- a/tools/yaml2obj/yaml2elf.cpp +++ b/tools/yaml2obj/yaml2elf.cpp @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// #include "yaml2obj.h" -#include "llvm/Object/ELF.h" +#include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/ELFYAML.h" #include "llvm/Support/ELF.h" #include "llvm/Support/MemoryBuffer.h" @@ -157,7 +157,7 @@ class ELFState { unsigned DotStrtabSecNo; /// \brief The accumulated contents of all sections so far. ContiguousBlobAccumulator &SectionContentAccum; - typedef typename object::ELFObjectFile::Elf_Ehdr Elf_Ehdr; + typedef typename object::ELFFile::Elf_Ehdr Elf_Ehdr; /// \brief The ELF file header. Elf_Ehdr &Header; @@ -185,9 +185,9 @@ public: template static void addSymbols(const std::vector &Symbols, ELFState &State, - std::vector::Elf_Sym> &Syms, + std::vector::Elf_Sym> &Syms, unsigned SymbolBinding) { - typedef typename object::ELFObjectFile::Elf_Sym Elf_Sym; + typedef typename object::ELFFile::Elf_Sym Elf_Sym; for (unsigned i = 0, e = Symbols.size(); i != e; ++i) { const ELFYAML::Symbol &Sym = Symbols[i]; Elf_Sym Symbol; @@ -211,11 +211,12 @@ addSymbols(const std::vector &Symbols, ELFState &State, } template -static void handleSymtabSectionHeader( - const ELFYAML::LocalGlobalWeakSymbols &Symbols, ELFState &State, - typename object::ELFObjectFile::Elf_Shdr &SHeader) { +static void +handleSymtabSectionHeader(const ELFYAML::LocalGlobalWeakSymbols &Symbols, + ELFState &State, + typename object::ELFFile::Elf_Shdr &SHeader) { - typedef typename object::ELFObjectFile::Elf_Sym Elf_Sym; + typedef typename object::ELFFile::Elf_Sym Elf_Sym; SHeader.sh_type = ELF::SHT_SYMTAB; SHeader.sh_link = State.getDotStrTabSecNo(); // One greater than symbol table index of the last local symbol. @@ -241,8 +242,8 @@ static void handleSymtabSectionHeader( template static int writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) { using namespace llvm::ELF; - typedef typename object::ELFObjectFile::Elf_Ehdr Elf_Ehdr; - typedef typename object::ELFObjectFile::Elf_Shdr Elf_Shdr; + typedef typename object::ELFFile::Elf_Ehdr Elf_Ehdr; + typedef typename object::ELFFile::Elf_Shdr Elf_Shdr; const ELFYAML::FileHeader &Hdr = Doc.Header; -- cgit v1.1 From 6ba2ed53bb0b69efa4bddb317c2c859ea2bca0f5 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Thu, 8 Aug 2013 23:51:04 +0000 Subject: Revert r185882. This is causing problems with the gold linker and might be better handled by the linker. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188029 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/LTOCodeGenerator.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index 758227d..3fe7af2 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -160,10 +160,8 @@ bool LTOCodeGenerator::writeMergedModules(const char *path, if (!determineTarget(errMsg)) return false; - // Run the verifier on the merged modules. - PassManager passes; - passes.add(createVerifierPass()); - passes.run(*_linker.getModule()); + // mark which symbols can not be internalized + applyScopeRestrictions(); // create output file std::string ErrInfo; -- cgit v1.1 From 1c9cd021c8999d9c2c0786dff074d1e75bbd0eb2 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Fri, 9 Aug 2013 01:52:03 +0000 Subject: [CodeGen] prevent abnormal on invalid attributes Currently, when an invalid attribute is encountered on processing a .s file, clang will abort due to llvm_unreachable. Invalid user input should not cause an abnormal termination of the compiler. Change the interface to return a boolean to indicate the failure as a first step towards improving hanlding of malformed user input to clang. Signed-off-by: Saleem Abdulrasool git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188047 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/LTOModule.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp index e89733f..1812346 100644 --- a/tools/lto/LTOModule.cpp +++ b/tools/lto/LTOModule.cpp @@ -738,9 +738,10 @@ namespace { // FIXME: should we handle aliases? markDefined(*Symbol); } - virtual void EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) { + virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) { if (Attribute == MCSA_Global) markGlobal(*Symbol); + return true; } virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol, uint64_t Size , unsigned ByteAlignment) { -- cgit v1.1 From a9232f7f5d00d900eb10a39e0b7786954d6eac69 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Fri, 9 Aug 2013 10:31:14 +0000 Subject: Remove byte order mark from source file. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188066 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/llvm-readobj.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/llvm-readobj/llvm-readobj.cpp b/tools/llvm-readobj/llvm-readobj.cpp index 0e092c0..f84a72f 100644 --- a/tools/llvm-readobj/llvm-readobj.cpp +++ b/tools/llvm-readobj/llvm-readobj.cpp @@ -1,4 +1,4 @@ -//===- llvm-readobj.cpp - Dump contents of an Object File -----------------===// +//===- llvm-readobj.cpp - Dump contents of an Object File -----------------===// // // The LLVM Compiler Infrastructure // -- cgit v1.1 From 67d135ae40b121a138e334a175d0e02dbb54eeca Mon Sep 17 00:00:00 2001 From: Shuxin Yang Date: Mon, 12 Aug 2013 18:29:43 +0000 Subject: Misc enhancements to LTO: 1. Add some helper classes for partitions. They are designed in a way such that the top-level LTO driver will not see much difference with or without partitioning. 2. Introduce work-dir. Now all intermediate files generated during LTO phases will be saved under work-dir. User can specify the workdir via -lto-workdir=/path/to/dir. By default the work-dir will be erased before linker exit. To keep the workdir, do -lto-keep, or -lto-keep=1. TODO: Erase the workdir, if the linker exit prematurely. We are currently not able to remove directory on signal. The support routines simply ignore directory. 3. Add one new API lto_codegen_get_files_need_remove(). Linker and LTO plugin will communicate via this API about which files (including directories) need to removed before linker exit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188188 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/gold/gold-plugin.cpp | 32 +++++-- tools/lto/CMakeLists.txt | 2 + tools/lto/LTOCodeGenerator.cpp | 195 +++++++++++++++++++++++++++++++-------- tools/lto/LTOCodeGenerator.h | 39 +++++++- tools/lto/LTOPartition.cpp | 205 +++++++++++++++++++++++++++++++++++++++++ tools/lto/LTOPartition.h | 187 +++++++++++++++++++++++++++++++++++++ tools/lto/LTOPostIPODriver.cpp | 180 ++++++++++++++++++++++++++++++++++++ tools/lto/LTOPostIPODriver.h | 52 +++++++++++ tools/lto/lto.cpp | 13 +++ tools/lto/lto.exports | 1 + 10 files changed, 861 insertions(+), 45 deletions(-) create mode 100644 tools/lto/LTOPartition.cpp create mode 100644 tools/lto/LTOPartition.h create mode 100644 tools/lto/LTOPostIPODriver.cpp create mode 100644 tools/lto/LTOPostIPODriver.h (limited to 'tools') diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp index 7771709..7918324 100644 --- a/tools/gold/gold-plugin.cpp +++ b/tools/gold/gold-plugin.cpp @@ -74,7 +74,6 @@ namespace options { static bool generate_api_file = false; static generate_bc generate_bc_file = BC_NO; static std::string bc_path; - static std::string obj_path; static std::string extra_library_path; static std::string triple; static std::string mcpu; @@ -99,8 +98,6 @@ namespace options { extra_library_path = opt.substr(strlen("extra_library_path=")); } else if (opt.startswith("mtriple=")) { triple = opt.substr(strlen("mtriple=")); - } else if (opt.startswith("obj-path=")) { - obj_path = opt.substr(strlen("obj-path=")); } else if (opt == "emit-llvm") { generate_bc_file = BC_ONLY; } else if (opt == "also-emit-llvm") { @@ -425,6 +422,14 @@ static ld_plugin_status all_symbols_read_hook(void) { (*message)(LDPL_ERROR, "Could not produce a combined object file\n"); } + // Get files that need to be removed in cleanup_hook. + const char *ToRm; + lto_codegen_get_files_need_remove(code_gen, &ToRm); + while (*ToRm) { + Cleanup.push_back(std::string(ToRm)); + ToRm += strlen(ToRm) + 1; + } + lto_codegen_dispose(code_gen); for (std::list::iterator I = Modules.begin(), E = Modules.end(); I != E; ++I) { @@ -446,17 +451,28 @@ static ld_plugin_status all_symbols_read_hook(void) { return LDPS_ERR; } - if (options::obj_path.empty()) - Cleanup.push_back(objPath); - return LDPS_OK; } static ld_plugin_status cleanup_hook(void) { for (int i = 0, e = Cleanup.size(); i != e; ++i) { - error_code EC = sys::fs::remove(Cleanup[i]); + const char *FN = Cleanup[i].c_str(); + sys::fs::file_status Stat; + error_code EC = sys::fs::status(Twine(FN), Stat); + if (EC) { + (*message)(LDPL_ERROR, "Failed to stat '%s': %s", FN, + EC.message().c_str()); + continue; + } + + uint32_t Dummy; + if (sys::fs::is_directory(FN)) + EC = sys::fs::remove_all(Twine(FN), Dummy); + else + EC = sys::fs::remove(Twine(FN)); + if (EC) - (*message)(LDPL_ERROR, "Failed to delete '%s': %s", Cleanup[i].c_str(), + (*message)(LDPL_ERROR, "Failed to remove '%s': %s", FN, EC.message().c_str()); } diff --git a/tools/lto/CMakeLists.txt b/tools/lto/CMakeLists.txt index 5820b14..7667449 100644 --- a/tools/lto/CMakeLists.txt +++ b/tools/lto/CMakeLists.txt @@ -9,6 +9,8 @@ set(SOURCES LTODisassembler.cpp lto.cpp LTOModule.cpp + LTOPartition.cpp + LTOPostIPODriver.cpp ) set(LLVM_COMMON_DEPENDS intrinsics_gen) diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index 3fe7af2..bcbd017 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -14,6 +14,8 @@ #include "LTOCodeGenerator.h" #include "LTOModule.h" +#include "LTOPartition.h" +#include "LTOPostIPODriver.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Analysis/Passes.h" #include "llvm/Analysis/Verifier.h" @@ -35,11 +37,13 @@ #include "llvm/Support/FormattedStream.h" #include "llvm/Support/Host.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/Program.h" #include "llvm/Support/Signals.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/Support/system_error.h" +#include "llvm/Support/SourceMgr.h" #include "llvm/Target/Mangler.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" @@ -47,8 +51,16 @@ #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/ObjCARC.h" + using namespace llvm; +using namespace lto; +// ///////////////////////////////////////////////////////////////////////////// +// +// Internal options. To avoid collision, most options start with "lto-". +// +// ///////////////////////////////////////////////////////////////////////////// +// static cl::opt DisableOpt("disable-opt", cl::init(false), cl::desc("Do not run any optimization passes")); @@ -61,6 +73,28 @@ static cl::opt DisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false), cl::desc("Do not run the GVN load PRE pass")); +// To break merged module into partitions, and compile them independently. +static cl::opt +EnablePartition("lto-partition", cl::init(false), + cl::desc("Partition program and compile each piece in parallel")); + +// Specify the work-directory for the LTO compilation. All intermeidate +// files will be created immediately under this dir. If it is not +// specified, compiler will create an unique directory under current-dir. +// +static cl::opt +TmpWorkDir("lto-workdir", cl::init(""), cl::desc("Specify working directory")); + +static cl::opt +KeepWorkDir("lto-keep", cl::init(false), cl::desc("Keep working directory")); + + +// ///////////////////////////////////////////////////////////////////////////// +// +// Implementation of LTOCodeGenerator +// +// ///////////////////////////////////////////////////////////////////////////// +// const char* LTOCodeGenerator::getVersionString() { #ifdef LLVM_VERSION_INFO return PACKAGE_NAME " version " PACKAGE_VERSION ", " LLVM_VERSION_INFO; @@ -74,7 +108,8 @@ LTOCodeGenerator::LTOCodeGenerator() _linker(new Module("ld-temp.o", _context)), _target(NULL), _emitDwarfDebugInfo(false), _scopeRestrictionsDone(false), _codeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC), - _nativeObjectFile(NULL) { + _nativeObjectFile(NULL), PartitionMgr(FileMgr), + OptionsParsed(false) { InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); @@ -187,35 +222,41 @@ bool LTOCodeGenerator::writeMergedModules(const char *path, return true; } -bool LTOCodeGenerator::compile_to_file(const char** name, std::string& errMsg) { - // make unique temp .o file to put generated object file - SmallString<128> Filename; - int FD; - error_code EC = sys::fs::createTemporaryFile("lto-llvm", "o", FD, Filename); - if (EC) { - errMsg = EC.message(); +// This function is to ensure cl::ParseCommandLineOptions() is called no more +// than once. It would otherwise complain and exit the compilation prematurely. +// +void LTOCodeGenerator::parseOptions() { + if (OptionsParsed) + return; + + if (!_codegenOptions.empty()) + cl::ParseCommandLineOptions(_codegenOptions.size(), + const_cast(&_codegenOptions[0])); + + OptionsParsed = true; +} + +// Do some prepartion right before compilation starts. +bool LTOCodeGenerator::prepareBeforeCompile(std::string &ErrMsg) { + parseOptions(); + + if (!determineTarget(ErrMsg)) return false; - } - // generate object file - tool_output_file objFile(Filename.c_str(), FD); + FileMgr.setWorkDir(TmpWorkDir.c_str()); + FileMgr.setKeepWorkDir(KeepWorkDir); + return FileMgr.createWorkDir(ErrMsg); +} - bool genResult = generateObjectFile(objFile.os(), errMsg); - objFile.os().close(); - if (objFile.os().has_error()) { - objFile.os().clear_error(); - sys::fs::remove(Twine(Filename)); +bool LTOCodeGenerator::compile_to_file(const char** Name, std::string& ErrMsg) { + if (!prepareBeforeCompile(ErrMsg)) return false; - } - objFile.keep(); - if (!genResult) { - sys::fs::remove(Twine(Filename)); + performIPO(EnablePartition, ErrMsg); + if (!performPostIPO(ErrMsg)) return false; - } - _nativeObjectPath = Filename.c_str(); - *name = _nativeObjectPath.c_str(); + *Name = PartitionMgr.getSinglePartition()->getObjFilePath().c_str(); return true; } @@ -229,21 +270,41 @@ const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg) { // read .o file into memory buffer OwningPtr BuffPtr; + const char *BufStart = 0; + if (error_code ec = MemoryBuffer::getFile(name, BuffPtr, -1, false)) { errMsg = ec.message(); - sys::fs::remove(_nativeObjectPath); - return NULL; + _nativeObjectFile = 0; + } else { + if ((_nativeObjectFile = BuffPtr.take())) { + *length = _nativeObjectFile->getBufferSize(); + BufStart = _nativeObjectFile->getBufferStart(); + } } - _nativeObjectFile = BuffPtr.take(); - // remove temp files - sys::fs::remove(_nativeObjectPath); + // Now that the resulting single object file is handed to linker via memory + // buffer, it is safe to remove all intermediate files now. + // + FileMgr.removeAllUnneededFiles(); - // return buffer, unless error - if (_nativeObjectFile == NULL) - return NULL; - *length = _nativeObjectFile->getBufferSize(); - return _nativeObjectFile->getBufferStart(); + return BufStart; +} + +const char *LTOCodeGenerator::getFilesNeedToRemove() { + IPOFileMgr::FileNameVect ToRm; + FileMgr.getFilesNeedToRemove(ToRm); + + ConcatStrings.clear(); + for (IPOFileMgr::FileNameVect::iterator I = ToRm.begin(), E = ToRm.end(); + I != E; I++) { + StringRef S(*I); + ConcatStrings.append(S.begin(), S.end()); + ConcatStrings.push_back('\0'); + } + ConcatStrings.push_back('\0'); + ConcatStrings.push_back('\0'); + + return ConcatStrings.data(); } bool LTOCodeGenerator::determineTarget(std::string &errMsg) { @@ -251,9 +312,7 @@ bool LTOCodeGenerator::determineTarget(std::string &errMsg) { return true; // if options were requested, set them - if (!_codegenOptions.empty()) - cl::ParseCommandLineOptions(_codegenOptions.size(), - const_cast(&_codegenOptions[0])); + parseOptions(); std::string TripleStr = _linker.getModule()->getTargetTriple(); if (TripleStr.empty()) @@ -384,6 +443,70 @@ void LTOCodeGenerator::applyScopeRestrictions() { _scopeRestrictionsDone = true; } +void LTOCodeGenerator::performIPO(bool ToPartition, std::string &errMsg) { + // Mark which symbols can not be internalized + applyScopeRestrictions(); + + // Instantiate the pass manager to organize the passes. + PassManager Passes; + + // Start off with a verification pass. + Passes.add(createVerifierPass()); + + // Add an appropriate DataLayout instance for this module... + Passes.add(new DataLayout(*_target->getDataLayout())); + _target->addAnalysisPasses(Passes); + + // Enabling internalize here would use its AllButMain variant. It + // keeps only main if it exists and does nothing for libraries. Instead + // we create the pass ourselves with the symbol list provided by the linker. + if (!DisableOpt) + PassManagerBuilder().populateLTOPassManager(Passes, + /*Internalize=*/false, + !DisableInline, + DisableGVNLoadPRE); + // Make sure everything is still good. + Passes.add(createVerifierPass()); + + Module* M = _linker.getModule(); + if (ToPartition) + assert(false && "TBD"); + else { + Passes.run(*M); + + // Create a partition for the merged module. + PartitionMgr.createIPOPart(M); + } +} + +// Perform Post-IPO compilation. If the partition is enabled, there may +// be multiple partitions, and therefore there may be multiple objects. +// In this case, "MergeObjs" indicates to merge all object together (via ld -r) +// and return the path to the merged object via "MergObjPath". +// +bool LTOCodeGenerator::performPostIPO(std::string &ErrMsg, + bool MergeObjs, + const char **MergObjPath) { + // Determine the variant of post-ipo driver + PostIPODriver::VariantTy DrvTy; + if (!EnablePartition) { + assert(!MergeObjs && !MergObjPath && "Invalid parameter"); + DrvTy = PostIPODriver::PIDV_SERIAL; + } else { + DrvTy = PostIPODriver::PIDV_Invalid; + assert(false && "TBD"); + } + + PostIPODriver D(DrvTy, _target, PartitionMgr, FileMgr, MergeObjs); + if (D.Compile(ErrMsg)) { + if (MergeObjs) + *MergObjPath = D.getSingleObjFile()->getPath().c_str(); + return true; + } + + return false; +} + /// Optimize merged modules using various IPO passes bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, std::string &errMsg) { diff --git a/tools/lto/LTOCodeGenerator.h b/tools/lto/LTOCodeGenerator.h index 8f37cf0..5dda5d9 100644 --- a/tools/lto/LTOCodeGenerator.h +++ b/tools/lto/LTOCodeGenerator.h @@ -41,6 +41,7 @@ #include "llvm/Linker.h" #include #include +#include "LTOPartition.h" namespace llvm { class LLVMContext; @@ -102,16 +103,34 @@ struct LTOCodeGenerator { // const void *compile(size_t *length, std::string &errMsg); + // Return the paths of the intermediate files that linker needs to delete + // before it exits. The paths are delimited by a single '\0', and the last + // path is ended by double '\0's. The file could be a directory. In that + // case, the entire directory should be erased recusively. This function + // must be called after the compilexxx() is successfuly called, because + // only after that moment, compiler is aware which files need to be removed. + // If calling compilexxx() is not successful, it is up to compiler to clean + // up all the intermediate files generated during the compilation process. + // + const char *getFilesNeedToRemove(); + private: void initializeLTOPasses(); + bool determineTarget(std::string &errMsg); + void parseOptions(); + bool prepareBeforeCompile(std::string &ErrMsg); + void performIPO(bool PerformPartition, std::string &ErrMsg); + bool performPostIPO(std::string &ErrMsg, bool MergeObjs = false, + const char **MergObjPath = 0); bool generateObjectFile(llvm::raw_ostream &out, std::string &errMsg); + void applyScopeRestrictions(); void applyRestriction(llvm::GlobalValue &GV, std::vector &mustPreserveList, llvm::SmallPtrSet &asmUsed, llvm::Mangler &mangler); - bool determineTarget(std::string &errMsg); + typedef llvm::StringMap StringSet; @@ -127,6 +146,24 @@ private: std::vector _codegenOptions; std::string _mCpu; std::string _nativeObjectPath; + + // To manage the partitions. If partition is not enabled, the whole merged + // module is considered as a single degenerated partition, and the "manager" + // is still active. + lto::IPOPartMgr PartitionMgr; + + // To manage the intermediate files during the compilations. + lto::IPOFileMgr FileMgr; + + // Sometimes we need to return a vector of strings in a "C" way (to work with + // the C-APIs). We encode such C-thinking string vector by concatenating all + // strings tegother with a single '\0' as the delimitor, the last string ended + // by double '\0's. + SmallVector ConcatStrings; + + // Make sure command line is parsed only once. It would otherwise complain + // and quite prematurely. + bool OptionsParsed; }; #endif // LTO_CODE_GENERATOR_H diff --git a/tools/lto/LTOPartition.cpp b/tools/lto/LTOPartition.cpp new file mode 100644 index 0000000..a056b71 --- /dev/null +++ b/tools/lto/LTOPartition.cpp @@ -0,0 +1,205 @@ +//===-- LTOPartition.cpp - Parition Merged Module --------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "LTOPartition.h" +#include "llvm/ADT/SetVector.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/Analysis/CallGraph.h" +#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/IR/Module.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Path.h" +#include "llvm/Transforms/Utils/ValueMapper.h" +#include "llvm/Transforms/Utils/Cloning.h" + +using namespace llvm; +using namespace lto; + +// ///////////////////////////////////////////////////////////////////////////// +// +// Implementation of IPOPartition and IPOPartMgr +// +// ///////////////////////////////////////////////////////////////////////////// +// +IPOPartition::IPOPartition(Module *M, const char *NameWoExt, IPOFileMgr &FM) : + Mod(0), Ctx(0), IRFile(0), ObjFile(0), FileNameWoExt(NameWoExt), FileMgr(FM) { +} + +IPOFile &IPOPartition::getIRFile() const { + if (IRFile) + return *IRFile; + else { + std::string FN(FileNameWoExt + ".bc"); + return *(IRFile = FileMgr.createIRFile(FN.c_str())); + } +} + +IPOFile &IPOPartition::getObjFile() const { + if (ObjFile) + return *ObjFile; + else { + std::string FN(FileNameWoExt + ".o"); + return *(ObjFile = FileMgr.createObjFile(FN.c_str())); + } +} + +bool IPOPartition::saveBitCode() { + if (!Mod) { + // The bit-code have already saved in disk. + return true; + } + + IPOFile &F = getIRFile(); + if (F.errOccur()) + return false; + + raw_fd_ostream OF(F.getPath().c_str(), F.getLastErrStr(), + sys::fs::F_Binary); + WriteBitcodeToFile(Mod, OF); + OF.close(); + + Mod = 0; + delete Ctx; + Ctx = 0; + + return !F.errOccur(); +} + +bool IPOPartition::loadBitCode() { + if (Mod) + return true; + + IPOFile &F = getIRFile(); + if (F.errOccur()) + return false; + + Ctx = new LLVMContext; + + error_code &EC = F.getLastErrCode(); + std::string &ErrMsg = F.getLastErrStr(); + + OwningPtr Buf; + if (error_code ec = MemoryBuffer::getFile(F.getPath(), Buf, -1, false)) { + EC = ec; + ErrMsg += ec.message(); + return false; + } + + Mod = ParseBitcodeFile(Buf.get(), *Ctx, &ErrMsg); + + return Mod != 0; +} + +IPOPartition *IPOPartMgr::createIPOPart(Module *M) { + std::string PartName; + raw_string_ostream OS(PartName); + OS << "part" << NextPartId++; + + IPOPartition *P = new IPOPartition(M, OS.str().c_str(), FileMgr); + P->Mod = M; + IPOParts.push_back(P); + return P; +} + +// /////////////////////////////////////////////////////////////////////////// +// +// Implementation of IPOFile and IPOFileMgr +// +// /////////////////////////////////////////////////////////////////////////// +// +IPOFile::IPOFile(const char *DirName, const char *BaseName, bool KeepFile) + : Fname(BaseName), Keep(KeepFile) { + // Concatenate dirname and basename + StringRef D(DirName); + SmallVector Path(D.begin(), D.end()); + sys::path::append(Path, Twine(BaseName)); + Fpath = StringRef(Path.data(), Path.size()); +} + +IPOFileMgr::IPOFileMgr() { + IRFiles.reserve(20); + ObjFiles.reserve(20); + OtherFiles.reserve(8); + KeepWorkDir = false; + WorkDirCreated = false; +} + +bool IPOFileMgr::createWorkDir(std::string &ErrorInfo) { + if (WorkDirCreated) + return true; + + error_code EC; + if (WorkDir.empty()) { + // If the workdir is not specified, then create workdir under current + // directory. + // + SmallString<128> D; + if (sys::fs::current_path(D) != error_code::success()) { + ErrorInfo += "fail to get current directory"; + return false; + } + sys::path::append(D, "llvmipo"); + sys::fs::make_absolute(D); + + SmallVector ResPath; + EC = sys::fs::createUniqueDirectory(Twine(StringRef(D.data(), D.size())), + ResPath); + WorkDir = StringRef(ResPath.data(), ResPath.size()); + } else { + bool Exist; + EC = sys::fs::create_directory(Twine(WorkDir), Exist); + } + + if (EC == error_code::success()) { + WorkDirCreated = true; + return true; + } + + return false; +} + +IPOFile *IPOFileMgr::createIRFile(const char *Name) { + IPOFile *F = CreateFile(Name); + IRFiles.push_back(F); + return F; +} + +IPOFile *IPOFileMgr::createObjFile(const char *Name) { + IPOFile *F = CreateFile(Name); + ObjFiles.push_back(F); + return F; +} + +IPOFile *IPOFileMgr::createMakefile(const char *Name) { + IPOFile *F = CreateFile(Name); + OtherFiles.push_back(F); + return F; +} + +void IPOFileMgr::removeAllUnneededFiles() { + FileNameVect ToRm; + getFilesNeedToRemove(ToRm); + + for (SmallVector::iterator I = ToRm.begin(), E = ToRm.end(); + I != E; I++) { + const char *FN = *I; + sys::fs::file_status Stat; + if (sys::fs::status(Twine(FN), Stat) != error_code::success()) + continue; + + uint32_t Dummy; + if (sys::fs::is_directory(FN)) + sys::fs::remove_all(Twine(FN), Dummy); + else + sys::fs::remove(Twine(FN)); + } +} diff --git a/tools/lto/LTOPartition.h b/tools/lto/LTOPartition.h new file mode 100644 index 0000000..e251555 --- /dev/null +++ b/tools/lto/LTOPartition.h @@ -0,0 +1,187 @@ +//===-------- LTOPartition.h - Partition related classes and functions ---===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declare the partition related classes and functions. A partition +// is a portion of the merged module. In case partition is disabled, the entire +// merged module is considered as a degenerated partition. +// +// The classes declared in this file are: +// o. IPOPartition : to depicit a partition +// o. IPOFile: It is a "container" collecting miscellaneous information about +// an intermeidate file, including file name, path, last-err-message etc. +// o. IPOPartMgr, IPOFileMgr: as the name suggests, it's the manager of +// IPOPartitions and IPOFiles, respectively. +// +//===----------------------------------------------------------------------===// + +#ifndef LTO_PARTITION_H +#define LTO_PARTITION_H + +#include "llvm/Pass.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/Support/system_error.h" + +using namespace llvm; + +namespace lto { + /// \brief To collect miscellaneous information about an intermdiate file. + /// + /// These informration include file name, path, last error message etc. + /// + class IPOFile { + public: + const std::string &getName() { return Fname; } + const std::string &getPath() { return Fpath; } + + error_code &getLastErrCode() { return LastErr; } + std::string &getLastErrStr() { return LastErrStr; } + + bool errOccur() const { + return LastErr != error_code::success() || !LastErrStr.empty(); + } + + // To keep this file after compilation finish. + void setKeep() { Keep = true; } + bool isKept() const { return Keep; } + + private: + friend class IPOFileMgr; + IPOFile(const char* DirName, const char *BaseName, bool Keep=false); + ~IPOFile(); + + private: + std::string Fname; + std::string Fpath; + error_code LastErr; + std::string LastErrStr; + bool Keep; + }; + + /// \brief To manage IPOFiles, create and remove work-directory. + /// + class IPOFileMgr { + public: + typedef SmallVector FileNameVect; + + IPOFileMgr(); + + // NOTE: Do not delete intermeidate in the destructor as we never know + // if these files out-last the class or not. It is safe to let linker's + // clean-up hook to take care these files. + ~IPOFileMgr() {}; + + void setWorkDir(const char* WD) { + assert(!WorkDirCreated /* Too late to change mind */ && + WorkDir.empty() /* don't change back and forth */ && + "Cannot change work dir"); + WorkDir = WD; + } + void setKeepWorkDir(bool Keep) { KeepWorkDir = Keep; } + bool IsToKeepWorkDir() const { return KeepWorkDir; } + const std::string &getWorkDir() { return WorkDir; } + + bool createWorkDir(std::string &ErrorInfo); + + IPOFile *createIRFile(const char *Name); + IPOFile *createObjFile(const char *Name); + IPOFile *createMakefile(const char *Name); + + typedef std::vector FileVect; + FileVect &getIRFiles() { return IRFiles; } + FileVect &getObjFiles() { return ObjFiles; } + + // Get all files/dirs that need to removed after the LTO complete. + void getFilesNeedToRemove(FileNameVect &ToRm) { + ToRm.clear(); + if (!IsToKeepWorkDir() && WorkDirCreated) + ToRm.push_back(WorkDir.c_str()); + } + + // Remove all files/dirs returned from getFilesNeedToRemove(). + void removeAllUnneededFiles(); + + private: + IPOFile *CreateFile(const char *Name) { + return new IPOFile(WorkDir.c_str(), Name); + } + + private: + FileVect IRFiles; + FileVect ObjFiles; + FileVect OtherFiles; + std::string WorkDir; + bool KeepWorkDir; + bool WorkDirCreated; + }; + + /// \brief Describe a partition of the merged module. + /// + class IPOPartition { + public: + llvm::Module *getModule() const { return Mod; } + IPOFile &getIRFile() const; + IPOFile &getObjFile() const; + const std::string &getIRFilePath() const { return getIRFile().getPath(); } + const std::string &getObjFilePath() const { return getObjFile().getPath(); } + + // If the bitcode reside in memory or disk + bool isInMemory() const { return Mod != 0; } + + // Load/store bitcode from/to disk file. + bool saveBitCode(); + bool loadBitCode(); + + private: + friend class IPOPartMgr; + IPOPartition(llvm::Module *M, const char *FileNameWoExt, IPOFileMgr &FM); + + // The module associated with this partition + Module *Mod; + LLVMContext *Ctx; + + // The bitcode file and its corresponding object file associated with + // this partition. The names of these two files are different only in + // extension; the "FileNameWoExt" record their (common) name without + // extension. + // + mutable IPOFile *IRFile; + mutable IPOFile *ObjFile; + std::string FileNameWoExt; + + IPOFileMgr &FileMgr; + }; + + /// \brief To manage IPOPartitions + /// + class IPOPartMgr { + public: + IPOPartMgr(IPOFileMgr &IFM) : FileMgr(IFM), NextPartId(1) {} + + typedef std::vector IPOPartsTy; + typedef IPOPartsTy::iterator iterator; + typedef IPOPartsTy::const_iterator const_iterator; + + iterator begin() { return IPOParts.begin(); } + iterator end() { return IPOParts.end(); } + const_iterator begin() const { return IPOParts.begin(); } + const_iterator end() const { return IPOParts.end(); } + + IPOPartition *createIPOPart(Module *); + IPOPartition *getSinglePartition() { + assert(IPOParts.size() == 1 && "Has multiple partition"); + return IPOParts[0]; + } + + private: + IPOPartsTy IPOParts; + IPOFileMgr &FileMgr; + int NextPartId; + }; + +} + +#endif //LTO_PARTITION_H diff --git a/tools/lto/LTOPostIPODriver.cpp b/tools/lto/LTOPostIPODriver.cpp new file mode 100644 index 0000000..2bb833a --- /dev/null +++ b/tools/lto/LTOPostIPODriver.cpp @@ -0,0 +1,180 @@ +//===---------- LTOPostIPODriver.h - PostIPO Driver -----------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines the PostIPODriver class which is the driver for Post-IPO +// compilation. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Analysis/AliasAnalysis.h" +#include "llvm/IR/DataLayout.h" +#include "llvm/PassManager.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/FormattedStream.h" +#include "llvm/Support/Program.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/ObjCARC.h" +#include "LTOPartition.h" +#include "LTOPostIPODriver.h" + +using namespace llvm; +using namespace lto; + +// ///////////////////////////////////////////////////////////////////////////// +// +// Declare all variants of Post-IPO drivers +// +// ///////////////////////////////////////////////////////////////////////////// +// +namespace { + /// \breif Base class for all driver variants. + /// + class PostIPODrvBaseImpl { + public: + PostIPODrvBaseImpl(TargetMachine *Targ, IPOPartMgr &IPM, IPOFileMgr &IFM, + bool ToMergeObjs): + PartMgr(IPM), FileMgr(IFM), MergedObjFile(0), Target(Targ), + MergeObjs(ToMergeObjs) {} + + virtual ~PostIPODrvBaseImpl() {}; + + IPOPartMgr &getPartitionMgr() { return PartMgr; } + IPOFileMgr &getFileMgr() { return FileMgr; } + + // Implement the PostIPODriver::getSingleObjFile() + virtual IPOFile *getSingleObjFile() const = 0; + + bool IsToMergeObj() const { return MergeObjs; } + + virtual bool Compile(std::string &ErrMsg) = 0; + + protected: + // Populate post-IPO scalar optimization pass manager + bool PopulatePostIPOOptPM(PassManager &PM); + + // Populate post-IPO machine-specific CodeGen pass manager + bool PopulateCodeGenPM(PassManager &PM, formatted_raw_ostream &OutFile, + std::string &Err); + + protected: + IPOPartMgr &PartMgr; + IPOFileMgr &FileMgr; + IPOFile *MergedObjFile; + TargetMachine *Target; + bool MergeObjs; + }; + + /// \breif PostIPO driver for the compiling the entire program without + /// partition. + class PostIPODrvSerial : public PostIPODrvBaseImpl { + public: + PostIPODrvSerial(TargetMachine *T, IPOPartMgr &IPM, IPOFileMgr &IFM, + bool ToMergeObjs) : + PostIPODrvBaseImpl(T, IPM, IFM, ToMergeObjs) {} + + virtual bool Compile(std::string &ErrMsg); + virtual IPOFile *getSingleObjFile() const; + + private: + Module *getModule() const { return (*PartMgr.begin())->getModule(); } + }; +} + +// //////////////////////////////////////////////////////////////////////////// +// +// Implemetation of PostIPODriver +// +// //////////////////////////////////////////////////////////////////////////// +// +PostIPODriver::PostIPODriver(VariantTy V, TargetMachine *TM, IPOPartMgr &IPM, + IPOFileMgr &IFM, bool ToMergeObjs) { + if (V == PIDV_SERIAL) + DrvImpl = new PostIPODrvSerial(TM, IPM, IFM, ToMergeObjs); + else + assert(false && "TBD"); +} + +bool PostIPODriver::Compile(std::string &ErrMsg) { + PostIPODrvBaseImpl *P = static_cast(DrvImpl); + return P->Compile(ErrMsg); +} + +IPOFile *PostIPODriver::getSingleObjFile() const { + PostIPODrvBaseImpl *P = static_cast(DrvImpl); + return P->getSingleObjFile(); +} + +// //////////////////////////////////////////////////////////////////////////// +// +// Implemetation of PostIPODrvBaseImpl +// +// //////////////////////////////////////////////////////////////////////////// +// +bool PostIPODrvBaseImpl::PopulatePostIPOOptPM(PassManager &PM) { + (void)PM; + return true; +} + +bool PostIPODrvBaseImpl::PopulateCodeGenPM(PassManager &PM, + formatted_raw_ostream &OutFile, + std::string &Err) { + PM.add(new DataLayout(*Target->getDataLayout())); + Target->addAnalysisPasses(PM); + + // If the bitcode files contain ARC code and were compiled with optimization, + // the ObjCARCContractPass must be run, so do it unconditionally here. + PM.add(createObjCARCContractPass()); + + if (Target->addPassesToEmitFile(PM, OutFile, + TargetMachine::CGFT_ObjectFile)) { + Err = "target file type not supported"; + return false; + } + return true; +} + +// //////////////////////////////////////////////////////////////////////////// +// +// Implemetation of PostIPODrvSerial +// +// //////////////////////////////////////////////////////////////////////////// +// +bool PostIPODrvSerial::Compile(std::string &ErrMsg) { + Module *M = getModule(); + + // Step 1: Run the post-IPO scalar optimizations + { + PassManager SoptPM; + PopulatePostIPOOptPM(SoptPM); + SoptPM.run(*M); + } + + // Step 2: Run the post-IPO machine-specific code-generation passes + { + IPOFile &Obj = (*PartMgr.begin())->getObjFile(); + raw_fd_ostream ros(Obj.getPath().c_str(), Obj.getLastErrStr(), + sys::fs::F_Binary); + formatted_raw_ostream OutFile(ros); + + PassManager CodGenPM; + if (!PopulateCodeGenPM(CodGenPM, OutFile, ErrMsg)) { + ErrMsg += Obj.getLastErrStr(); + return false; + } + + CodGenPM.run(*M); + } + + return true; +} + +IPOFile *PostIPODrvSerial::getSingleObjFile() const { + assert(!MergedObjFile && "No need to *merge* a single object file"); + IPOPartition *P = *PartMgr.begin(); + return &P->getObjFile(); +} diff --git a/tools/lto/LTOPostIPODriver.h b/tools/lto/LTOPostIPODriver.h new file mode 100644 index 0000000..c1813b9 --- /dev/null +++ b/tools/lto/LTOPostIPODriver.h @@ -0,0 +1,52 @@ +//===---------- LTOPostIPODriver.h - PostIPO Driver -----------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declare the PostIPODriver class which is the driver for +// Post-IPO compilation phase. +// +//===----------------------------------------------------------------------===// + +#ifndef LTO_POSTIPO_DRIVER_H +#define LTO_POSTIPO_DRIVER_H + +#include "llvm/Target/TargetMachine.h" + +namespace lto { + class IPOPartMgr; + class IPOFileMgr; + class IPOFile; + + class PostIPODriver { + public: + typedef enum { + PIDV_Invalid, + PIDV_SERIAL, // No partition + PIDV_MultiThread, // Each partition is compiled by a thread + PIDV_MultiProc, // Each partition is compiled by a process + PIDV_MakeUtil // Partitions compilation is driven by a make-utility + } VariantTy; + + PostIPODriver(VariantTy Var, TargetMachine *TM, IPOPartMgr &IPM, + IPOFileMgr &IFM, bool ToMergeObjs = false); + + // Return the single resulting object file. If there is no prior + // compilation failure, this function may return NULL iff: + // 1) Partition is enabled, and + // 2) Multiple partitions are generated, and + // 3) It is not asked to merge together the objects corresponding to the + // the partions. + IPOFile *getSingleObjFile() const; + + bool Compile(std::string &ErrMsg); + + private: + void *DrvImpl; + VariantTy DrvStyle; + }; +} + +#endif // LTO_POSTIPO_DRIVER_H diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index db7147c..c7009d6 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -207,6 +207,19 @@ bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) { return !cg->compile_to_file(name, sLastErrorString); } +/// Get intermediate files that need to be removed before linker exit. Upon +/// return, the paths of the files need to be removed is written to "paths". The +/// paths are separated by a single '\0', and the last path is ended by double +/// '\0's. A file could be a directory; in this case, the entire directory needs +/// to be removed recursively. +/// +/// It is only necessary to call this function after \p lto_codegen_compile was +/// successfully called. +void +lto_codegen_get_files_need_remove(lto_code_gen_t cg, const char **paths) { + *paths = cg->getFilesNeedToRemove(); +} + /// 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) { diff --git a/tools/lto/lto.exports b/tools/lto/lto.exports index 46d0d74..41a81dd 100644 --- a/tools/lto/lto.exports +++ b/tools/lto/lto.exports @@ -20,6 +20,7 @@ lto_codegen_add_must_preserve_symbol lto_codegen_compile lto_codegen_create lto_codegen_dispose +lto_codegen_get_files_need_remove lto_codegen_set_debug_model lto_codegen_set_pic_model lto_codegen_write_merged_modules -- cgit v1.1 From 55e464b4056e81b6a3d976533b43e7155e5dd7c6 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Mon, 12 Aug 2013 20:27:50 +0000 Subject: Fix warning about unused member. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188200 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/LTOPostIPODriver.h | 1 - 1 file changed, 1 deletion(-) (limited to 'tools') diff --git a/tools/lto/LTOPostIPODriver.h b/tools/lto/LTOPostIPODriver.h index c1813b9..548e732 100644 --- a/tools/lto/LTOPostIPODriver.h +++ b/tools/lto/LTOPostIPODriver.h @@ -45,7 +45,6 @@ namespace lto { private: void *DrvImpl; - VariantTy DrvStyle; }; } -- cgit v1.1 From cfaa636a1d31f2db71df627e4882e9d5c066c419 Mon Sep 17 00:00:00 2001 From: Shuxin Yang Date: Mon, 12 Aug 2013 21:07:31 +0000 Subject: Revert r188188 and r188200. In order to appease people (in Apple) who accuse me for committing "huge change" (?) without proper review. Thank Eric for fixing a compile-warning. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188204 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/gold/gold-plugin.cpp | 32 ++----- tools/lto/CMakeLists.txt | 2 - tools/lto/LTOCodeGenerator.cpp | 195 ++++++++------------------------------- tools/lto/LTOCodeGenerator.h | 39 +------- tools/lto/LTOPartition.cpp | 205 ----------------------------------------- tools/lto/LTOPartition.h | 187 ------------------------------------- tools/lto/LTOPostIPODriver.cpp | 180 ------------------------------------ tools/lto/LTOPostIPODriver.h | 51 ---------- tools/lto/lto.cpp | 13 --- tools/lto/lto.exports | 1 - 10 files changed, 45 insertions(+), 860 deletions(-) delete mode 100644 tools/lto/LTOPartition.cpp delete mode 100644 tools/lto/LTOPartition.h delete mode 100644 tools/lto/LTOPostIPODriver.cpp delete mode 100644 tools/lto/LTOPostIPODriver.h (limited to 'tools') diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp index 7918324..7771709 100644 --- a/tools/gold/gold-plugin.cpp +++ b/tools/gold/gold-plugin.cpp @@ -74,6 +74,7 @@ namespace options { static bool generate_api_file = false; static generate_bc generate_bc_file = BC_NO; static std::string bc_path; + static std::string obj_path; static std::string extra_library_path; static std::string triple; static std::string mcpu; @@ -98,6 +99,8 @@ namespace options { extra_library_path = opt.substr(strlen("extra_library_path=")); } else if (opt.startswith("mtriple=")) { triple = opt.substr(strlen("mtriple=")); + } else if (opt.startswith("obj-path=")) { + obj_path = opt.substr(strlen("obj-path=")); } else if (opt == "emit-llvm") { generate_bc_file = BC_ONLY; } else if (opt == "also-emit-llvm") { @@ -422,14 +425,6 @@ static ld_plugin_status all_symbols_read_hook(void) { (*message)(LDPL_ERROR, "Could not produce a combined object file\n"); } - // Get files that need to be removed in cleanup_hook. - const char *ToRm; - lto_codegen_get_files_need_remove(code_gen, &ToRm); - while (*ToRm) { - Cleanup.push_back(std::string(ToRm)); - ToRm += strlen(ToRm) + 1; - } - lto_codegen_dispose(code_gen); for (std::list::iterator I = Modules.begin(), E = Modules.end(); I != E; ++I) { @@ -451,28 +446,17 @@ static ld_plugin_status all_symbols_read_hook(void) { return LDPS_ERR; } + if (options::obj_path.empty()) + Cleanup.push_back(objPath); + return LDPS_OK; } static ld_plugin_status cleanup_hook(void) { for (int i = 0, e = Cleanup.size(); i != e; ++i) { - const char *FN = Cleanup[i].c_str(); - sys::fs::file_status Stat; - error_code EC = sys::fs::status(Twine(FN), Stat); - if (EC) { - (*message)(LDPL_ERROR, "Failed to stat '%s': %s", FN, - EC.message().c_str()); - continue; - } - - uint32_t Dummy; - if (sys::fs::is_directory(FN)) - EC = sys::fs::remove_all(Twine(FN), Dummy); - else - EC = sys::fs::remove(Twine(FN)); - + error_code EC = sys::fs::remove(Cleanup[i]); if (EC) - (*message)(LDPL_ERROR, "Failed to remove '%s': %s", FN, + (*message)(LDPL_ERROR, "Failed to delete '%s': %s", Cleanup[i].c_str(), EC.message().c_str()); } diff --git a/tools/lto/CMakeLists.txt b/tools/lto/CMakeLists.txt index 7667449..5820b14 100644 --- a/tools/lto/CMakeLists.txt +++ b/tools/lto/CMakeLists.txt @@ -9,8 +9,6 @@ set(SOURCES LTODisassembler.cpp lto.cpp LTOModule.cpp - LTOPartition.cpp - LTOPostIPODriver.cpp ) set(LLVM_COMMON_DEPENDS intrinsics_gen) diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index bcbd017..3fe7af2 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -14,8 +14,6 @@ #include "LTOCodeGenerator.h" #include "LTOModule.h" -#include "LTOPartition.h" -#include "LTOPostIPODriver.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Analysis/Passes.h" #include "llvm/Analysis/Verifier.h" @@ -37,13 +35,11 @@ #include "llvm/Support/FormattedStream.h" #include "llvm/Support/Host.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Program.h" #include "llvm/Support/Signals.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/Support/system_error.h" -#include "llvm/Support/SourceMgr.h" #include "llvm/Target/Mangler.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" @@ -51,16 +47,8 @@ #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/ObjCARC.h" - using namespace llvm; -using namespace lto; -// ///////////////////////////////////////////////////////////////////////////// -// -// Internal options. To avoid collision, most options start with "lto-". -// -// ///////////////////////////////////////////////////////////////////////////// -// static cl::opt DisableOpt("disable-opt", cl::init(false), cl::desc("Do not run any optimization passes")); @@ -73,28 +61,6 @@ static cl::opt DisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false), cl::desc("Do not run the GVN load PRE pass")); -// To break merged module into partitions, and compile them independently. -static cl::opt -EnablePartition("lto-partition", cl::init(false), - cl::desc("Partition program and compile each piece in parallel")); - -// Specify the work-directory for the LTO compilation. All intermeidate -// files will be created immediately under this dir. If it is not -// specified, compiler will create an unique directory under current-dir. -// -static cl::opt -TmpWorkDir("lto-workdir", cl::init(""), cl::desc("Specify working directory")); - -static cl::opt -KeepWorkDir("lto-keep", cl::init(false), cl::desc("Keep working directory")); - - -// ///////////////////////////////////////////////////////////////////////////// -// -// Implementation of LTOCodeGenerator -// -// ///////////////////////////////////////////////////////////////////////////// -// const char* LTOCodeGenerator::getVersionString() { #ifdef LLVM_VERSION_INFO return PACKAGE_NAME " version " PACKAGE_VERSION ", " LLVM_VERSION_INFO; @@ -108,8 +74,7 @@ LTOCodeGenerator::LTOCodeGenerator() _linker(new Module("ld-temp.o", _context)), _target(NULL), _emitDwarfDebugInfo(false), _scopeRestrictionsDone(false), _codeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC), - _nativeObjectFile(NULL), PartitionMgr(FileMgr), - OptionsParsed(false) { + _nativeObjectFile(NULL) { InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); @@ -222,41 +187,35 @@ bool LTOCodeGenerator::writeMergedModules(const char *path, return true; } -// This function is to ensure cl::ParseCommandLineOptions() is called no more -// than once. It would otherwise complain and exit the compilation prematurely. -// -void LTOCodeGenerator::parseOptions() { - if (OptionsParsed) - return; - - if (!_codegenOptions.empty()) - cl::ParseCommandLineOptions(_codegenOptions.size(), - const_cast(&_codegenOptions[0])); - - OptionsParsed = true; -} - -// Do some prepartion right before compilation starts. -bool LTOCodeGenerator::prepareBeforeCompile(std::string &ErrMsg) { - parseOptions(); - - if (!determineTarget(ErrMsg)) +bool LTOCodeGenerator::compile_to_file(const char** name, std::string& errMsg) { + // make unique temp .o file to put generated object file + SmallString<128> Filename; + int FD; + error_code EC = sys::fs::createTemporaryFile("lto-llvm", "o", FD, Filename); + if (EC) { + errMsg = EC.message(); return false; + } - FileMgr.setWorkDir(TmpWorkDir.c_str()); - FileMgr.setKeepWorkDir(KeepWorkDir); - return FileMgr.createWorkDir(ErrMsg); -} + // generate object file + tool_output_file objFile(Filename.c_str(), FD); -bool LTOCodeGenerator::compile_to_file(const char** Name, std::string& ErrMsg) { - if (!prepareBeforeCompile(ErrMsg)) + bool genResult = generateObjectFile(objFile.os(), errMsg); + objFile.os().close(); + if (objFile.os().has_error()) { + objFile.os().clear_error(); + sys::fs::remove(Twine(Filename)); return false; + } - performIPO(EnablePartition, ErrMsg); - if (!performPostIPO(ErrMsg)) + objFile.keep(); + if (!genResult) { + sys::fs::remove(Twine(Filename)); return false; + } - *Name = PartitionMgr.getSinglePartition()->getObjFilePath().c_str(); + _nativeObjectPath = Filename.c_str(); + *name = _nativeObjectPath.c_str(); return true; } @@ -270,41 +229,21 @@ const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg) { // read .o file into memory buffer OwningPtr BuffPtr; - const char *BufStart = 0; - if (error_code ec = MemoryBuffer::getFile(name, BuffPtr, -1, false)) { errMsg = ec.message(); - _nativeObjectFile = 0; - } else { - if ((_nativeObjectFile = BuffPtr.take())) { - *length = _nativeObjectFile->getBufferSize(); - BufStart = _nativeObjectFile->getBufferStart(); - } + sys::fs::remove(_nativeObjectPath); + return NULL; } + _nativeObjectFile = BuffPtr.take(); - // Now that the resulting single object file is handed to linker via memory - // buffer, it is safe to remove all intermediate files now. - // - FileMgr.removeAllUnneededFiles(); - - return BufStart; -} - -const char *LTOCodeGenerator::getFilesNeedToRemove() { - IPOFileMgr::FileNameVect ToRm; - FileMgr.getFilesNeedToRemove(ToRm); + // remove temp files + sys::fs::remove(_nativeObjectPath); - ConcatStrings.clear(); - for (IPOFileMgr::FileNameVect::iterator I = ToRm.begin(), E = ToRm.end(); - I != E; I++) { - StringRef S(*I); - ConcatStrings.append(S.begin(), S.end()); - ConcatStrings.push_back('\0'); - } - ConcatStrings.push_back('\0'); - ConcatStrings.push_back('\0'); - - return ConcatStrings.data(); + // return buffer, unless error + if (_nativeObjectFile == NULL) + return NULL; + *length = _nativeObjectFile->getBufferSize(); + return _nativeObjectFile->getBufferStart(); } bool LTOCodeGenerator::determineTarget(std::string &errMsg) { @@ -312,7 +251,9 @@ bool LTOCodeGenerator::determineTarget(std::string &errMsg) { return true; // if options were requested, set them - parseOptions(); + if (!_codegenOptions.empty()) + cl::ParseCommandLineOptions(_codegenOptions.size(), + const_cast(&_codegenOptions[0])); std::string TripleStr = _linker.getModule()->getTargetTriple(); if (TripleStr.empty()) @@ -443,70 +384,6 @@ void LTOCodeGenerator::applyScopeRestrictions() { _scopeRestrictionsDone = true; } -void LTOCodeGenerator::performIPO(bool ToPartition, std::string &errMsg) { - // Mark which symbols can not be internalized - applyScopeRestrictions(); - - // Instantiate the pass manager to organize the passes. - PassManager Passes; - - // Start off with a verification pass. - Passes.add(createVerifierPass()); - - // Add an appropriate DataLayout instance for this module... - Passes.add(new DataLayout(*_target->getDataLayout())); - _target->addAnalysisPasses(Passes); - - // Enabling internalize here would use its AllButMain variant. It - // keeps only main if it exists and does nothing for libraries. Instead - // we create the pass ourselves with the symbol list provided by the linker. - if (!DisableOpt) - PassManagerBuilder().populateLTOPassManager(Passes, - /*Internalize=*/false, - !DisableInline, - DisableGVNLoadPRE); - // Make sure everything is still good. - Passes.add(createVerifierPass()); - - Module* M = _linker.getModule(); - if (ToPartition) - assert(false && "TBD"); - else { - Passes.run(*M); - - // Create a partition for the merged module. - PartitionMgr.createIPOPart(M); - } -} - -// Perform Post-IPO compilation. If the partition is enabled, there may -// be multiple partitions, and therefore there may be multiple objects. -// In this case, "MergeObjs" indicates to merge all object together (via ld -r) -// and return the path to the merged object via "MergObjPath". -// -bool LTOCodeGenerator::performPostIPO(std::string &ErrMsg, - bool MergeObjs, - const char **MergObjPath) { - // Determine the variant of post-ipo driver - PostIPODriver::VariantTy DrvTy; - if (!EnablePartition) { - assert(!MergeObjs && !MergObjPath && "Invalid parameter"); - DrvTy = PostIPODriver::PIDV_SERIAL; - } else { - DrvTy = PostIPODriver::PIDV_Invalid; - assert(false && "TBD"); - } - - PostIPODriver D(DrvTy, _target, PartitionMgr, FileMgr, MergeObjs); - if (D.Compile(ErrMsg)) { - if (MergeObjs) - *MergObjPath = D.getSingleObjFile()->getPath().c_str(); - return true; - } - - return false; -} - /// Optimize merged modules using various IPO passes bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, std::string &errMsg) { diff --git a/tools/lto/LTOCodeGenerator.h b/tools/lto/LTOCodeGenerator.h index 5dda5d9..8f37cf0 100644 --- a/tools/lto/LTOCodeGenerator.h +++ b/tools/lto/LTOCodeGenerator.h @@ -41,7 +41,6 @@ #include "llvm/Linker.h" #include #include -#include "LTOPartition.h" namespace llvm { class LLVMContext; @@ -103,34 +102,16 @@ struct LTOCodeGenerator { // const void *compile(size_t *length, std::string &errMsg); - // Return the paths of the intermediate files that linker needs to delete - // before it exits. The paths are delimited by a single '\0', and the last - // path is ended by double '\0's. The file could be a directory. In that - // case, the entire directory should be erased recusively. This function - // must be called after the compilexxx() is successfuly called, because - // only after that moment, compiler is aware which files need to be removed. - // If calling compilexxx() is not successful, it is up to compiler to clean - // up all the intermediate files generated during the compilation process. - // - const char *getFilesNeedToRemove(); - private: void initializeLTOPasses(); - bool determineTarget(std::string &errMsg); - void parseOptions(); - bool prepareBeforeCompile(std::string &ErrMsg); - void performIPO(bool PerformPartition, std::string &ErrMsg); - bool performPostIPO(std::string &ErrMsg, bool MergeObjs = false, - const char **MergObjPath = 0); bool generateObjectFile(llvm::raw_ostream &out, std::string &errMsg); - void applyScopeRestrictions(); void applyRestriction(llvm::GlobalValue &GV, std::vector &mustPreserveList, llvm::SmallPtrSet &asmUsed, llvm::Mangler &mangler); - + bool determineTarget(std::string &errMsg); typedef llvm::StringMap StringSet; @@ -146,24 +127,6 @@ private: std::vector _codegenOptions; std::string _mCpu; std::string _nativeObjectPath; - - // To manage the partitions. If partition is not enabled, the whole merged - // module is considered as a single degenerated partition, and the "manager" - // is still active. - lto::IPOPartMgr PartitionMgr; - - // To manage the intermediate files during the compilations. - lto::IPOFileMgr FileMgr; - - // Sometimes we need to return a vector of strings in a "C" way (to work with - // the C-APIs). We encode such C-thinking string vector by concatenating all - // strings tegother with a single '\0' as the delimitor, the last string ended - // by double '\0's. - SmallVector ConcatStrings; - - // Make sure command line is parsed only once. It would otherwise complain - // and quite prematurely. - bool OptionsParsed; }; #endif // LTO_CODE_GENERATOR_H diff --git a/tools/lto/LTOPartition.cpp b/tools/lto/LTOPartition.cpp deleted file mode 100644 index a056b71..0000000 --- a/tools/lto/LTOPartition.cpp +++ /dev/null @@ -1,205 +0,0 @@ -//===-- LTOPartition.cpp - Parition Merged Module --------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "LTOPartition.h" -#include "llvm/ADT/SetVector.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/Analysis/CallGraph.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/IR/Module.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/Path.h" -#include "llvm/Transforms/Utils/ValueMapper.h" -#include "llvm/Transforms/Utils/Cloning.h" - -using namespace llvm; -using namespace lto; - -// ///////////////////////////////////////////////////////////////////////////// -// -// Implementation of IPOPartition and IPOPartMgr -// -// ///////////////////////////////////////////////////////////////////////////// -// -IPOPartition::IPOPartition(Module *M, const char *NameWoExt, IPOFileMgr &FM) : - Mod(0), Ctx(0), IRFile(0), ObjFile(0), FileNameWoExt(NameWoExt), FileMgr(FM) { -} - -IPOFile &IPOPartition::getIRFile() const { - if (IRFile) - return *IRFile; - else { - std::string FN(FileNameWoExt + ".bc"); - return *(IRFile = FileMgr.createIRFile(FN.c_str())); - } -} - -IPOFile &IPOPartition::getObjFile() const { - if (ObjFile) - return *ObjFile; - else { - std::string FN(FileNameWoExt + ".o"); - return *(ObjFile = FileMgr.createObjFile(FN.c_str())); - } -} - -bool IPOPartition::saveBitCode() { - if (!Mod) { - // The bit-code have already saved in disk. - return true; - } - - IPOFile &F = getIRFile(); - if (F.errOccur()) - return false; - - raw_fd_ostream OF(F.getPath().c_str(), F.getLastErrStr(), - sys::fs::F_Binary); - WriteBitcodeToFile(Mod, OF); - OF.close(); - - Mod = 0; - delete Ctx; - Ctx = 0; - - return !F.errOccur(); -} - -bool IPOPartition::loadBitCode() { - if (Mod) - return true; - - IPOFile &F = getIRFile(); - if (F.errOccur()) - return false; - - Ctx = new LLVMContext; - - error_code &EC = F.getLastErrCode(); - std::string &ErrMsg = F.getLastErrStr(); - - OwningPtr Buf; - if (error_code ec = MemoryBuffer::getFile(F.getPath(), Buf, -1, false)) { - EC = ec; - ErrMsg += ec.message(); - return false; - } - - Mod = ParseBitcodeFile(Buf.get(), *Ctx, &ErrMsg); - - return Mod != 0; -} - -IPOPartition *IPOPartMgr::createIPOPart(Module *M) { - std::string PartName; - raw_string_ostream OS(PartName); - OS << "part" << NextPartId++; - - IPOPartition *P = new IPOPartition(M, OS.str().c_str(), FileMgr); - P->Mod = M; - IPOParts.push_back(P); - return P; -} - -// /////////////////////////////////////////////////////////////////////////// -// -// Implementation of IPOFile and IPOFileMgr -// -// /////////////////////////////////////////////////////////////////////////// -// -IPOFile::IPOFile(const char *DirName, const char *BaseName, bool KeepFile) - : Fname(BaseName), Keep(KeepFile) { - // Concatenate dirname and basename - StringRef D(DirName); - SmallVector Path(D.begin(), D.end()); - sys::path::append(Path, Twine(BaseName)); - Fpath = StringRef(Path.data(), Path.size()); -} - -IPOFileMgr::IPOFileMgr() { - IRFiles.reserve(20); - ObjFiles.reserve(20); - OtherFiles.reserve(8); - KeepWorkDir = false; - WorkDirCreated = false; -} - -bool IPOFileMgr::createWorkDir(std::string &ErrorInfo) { - if (WorkDirCreated) - return true; - - error_code EC; - if (WorkDir.empty()) { - // If the workdir is not specified, then create workdir under current - // directory. - // - SmallString<128> D; - if (sys::fs::current_path(D) != error_code::success()) { - ErrorInfo += "fail to get current directory"; - return false; - } - sys::path::append(D, "llvmipo"); - sys::fs::make_absolute(D); - - SmallVector ResPath; - EC = sys::fs::createUniqueDirectory(Twine(StringRef(D.data(), D.size())), - ResPath); - WorkDir = StringRef(ResPath.data(), ResPath.size()); - } else { - bool Exist; - EC = sys::fs::create_directory(Twine(WorkDir), Exist); - } - - if (EC == error_code::success()) { - WorkDirCreated = true; - return true; - } - - return false; -} - -IPOFile *IPOFileMgr::createIRFile(const char *Name) { - IPOFile *F = CreateFile(Name); - IRFiles.push_back(F); - return F; -} - -IPOFile *IPOFileMgr::createObjFile(const char *Name) { - IPOFile *F = CreateFile(Name); - ObjFiles.push_back(F); - return F; -} - -IPOFile *IPOFileMgr::createMakefile(const char *Name) { - IPOFile *F = CreateFile(Name); - OtherFiles.push_back(F); - return F; -} - -void IPOFileMgr::removeAllUnneededFiles() { - FileNameVect ToRm; - getFilesNeedToRemove(ToRm); - - for (SmallVector::iterator I = ToRm.begin(), E = ToRm.end(); - I != E; I++) { - const char *FN = *I; - sys::fs::file_status Stat; - if (sys::fs::status(Twine(FN), Stat) != error_code::success()) - continue; - - uint32_t Dummy; - if (sys::fs::is_directory(FN)) - sys::fs::remove_all(Twine(FN), Dummy); - else - sys::fs::remove(Twine(FN)); - } -} diff --git a/tools/lto/LTOPartition.h b/tools/lto/LTOPartition.h deleted file mode 100644 index e251555..0000000 --- a/tools/lto/LTOPartition.h +++ /dev/null @@ -1,187 +0,0 @@ -//===-------- LTOPartition.h - Partition related classes and functions ---===// -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declare the partition related classes and functions. A partition -// is a portion of the merged module. In case partition is disabled, the entire -// merged module is considered as a degenerated partition. -// -// The classes declared in this file are: -// o. IPOPartition : to depicit a partition -// o. IPOFile: It is a "container" collecting miscellaneous information about -// an intermeidate file, including file name, path, last-err-message etc. -// o. IPOPartMgr, IPOFileMgr: as the name suggests, it's the manager of -// IPOPartitions and IPOFiles, respectively. -// -//===----------------------------------------------------------------------===// - -#ifndef LTO_PARTITION_H -#define LTO_PARTITION_H - -#include "llvm/Pass.h" -#include "llvm/IR/LLVMContext.h" -#include "llvm/Support/system_error.h" - -using namespace llvm; - -namespace lto { - /// \brief To collect miscellaneous information about an intermdiate file. - /// - /// These informration include file name, path, last error message etc. - /// - class IPOFile { - public: - const std::string &getName() { return Fname; } - const std::string &getPath() { return Fpath; } - - error_code &getLastErrCode() { return LastErr; } - std::string &getLastErrStr() { return LastErrStr; } - - bool errOccur() const { - return LastErr != error_code::success() || !LastErrStr.empty(); - } - - // To keep this file after compilation finish. - void setKeep() { Keep = true; } - bool isKept() const { return Keep; } - - private: - friend class IPOFileMgr; - IPOFile(const char* DirName, const char *BaseName, bool Keep=false); - ~IPOFile(); - - private: - std::string Fname; - std::string Fpath; - error_code LastErr; - std::string LastErrStr; - bool Keep; - }; - - /// \brief To manage IPOFiles, create and remove work-directory. - /// - class IPOFileMgr { - public: - typedef SmallVector FileNameVect; - - IPOFileMgr(); - - // NOTE: Do not delete intermeidate in the destructor as we never know - // if these files out-last the class or not. It is safe to let linker's - // clean-up hook to take care these files. - ~IPOFileMgr() {}; - - void setWorkDir(const char* WD) { - assert(!WorkDirCreated /* Too late to change mind */ && - WorkDir.empty() /* don't change back and forth */ && - "Cannot change work dir"); - WorkDir = WD; - } - void setKeepWorkDir(bool Keep) { KeepWorkDir = Keep; } - bool IsToKeepWorkDir() const { return KeepWorkDir; } - const std::string &getWorkDir() { return WorkDir; } - - bool createWorkDir(std::string &ErrorInfo); - - IPOFile *createIRFile(const char *Name); - IPOFile *createObjFile(const char *Name); - IPOFile *createMakefile(const char *Name); - - typedef std::vector FileVect; - FileVect &getIRFiles() { return IRFiles; } - FileVect &getObjFiles() { return ObjFiles; } - - // Get all files/dirs that need to removed after the LTO complete. - void getFilesNeedToRemove(FileNameVect &ToRm) { - ToRm.clear(); - if (!IsToKeepWorkDir() && WorkDirCreated) - ToRm.push_back(WorkDir.c_str()); - } - - // Remove all files/dirs returned from getFilesNeedToRemove(). - void removeAllUnneededFiles(); - - private: - IPOFile *CreateFile(const char *Name) { - return new IPOFile(WorkDir.c_str(), Name); - } - - private: - FileVect IRFiles; - FileVect ObjFiles; - FileVect OtherFiles; - std::string WorkDir; - bool KeepWorkDir; - bool WorkDirCreated; - }; - - /// \brief Describe a partition of the merged module. - /// - class IPOPartition { - public: - llvm::Module *getModule() const { return Mod; } - IPOFile &getIRFile() const; - IPOFile &getObjFile() const; - const std::string &getIRFilePath() const { return getIRFile().getPath(); } - const std::string &getObjFilePath() const { return getObjFile().getPath(); } - - // If the bitcode reside in memory or disk - bool isInMemory() const { return Mod != 0; } - - // Load/store bitcode from/to disk file. - bool saveBitCode(); - bool loadBitCode(); - - private: - friend class IPOPartMgr; - IPOPartition(llvm::Module *M, const char *FileNameWoExt, IPOFileMgr &FM); - - // The module associated with this partition - Module *Mod; - LLVMContext *Ctx; - - // The bitcode file and its corresponding object file associated with - // this partition. The names of these two files are different only in - // extension; the "FileNameWoExt" record their (common) name without - // extension. - // - mutable IPOFile *IRFile; - mutable IPOFile *ObjFile; - std::string FileNameWoExt; - - IPOFileMgr &FileMgr; - }; - - /// \brief To manage IPOPartitions - /// - class IPOPartMgr { - public: - IPOPartMgr(IPOFileMgr &IFM) : FileMgr(IFM), NextPartId(1) {} - - typedef std::vector IPOPartsTy; - typedef IPOPartsTy::iterator iterator; - typedef IPOPartsTy::const_iterator const_iterator; - - iterator begin() { return IPOParts.begin(); } - iterator end() { return IPOParts.end(); } - const_iterator begin() const { return IPOParts.begin(); } - const_iterator end() const { return IPOParts.end(); } - - IPOPartition *createIPOPart(Module *); - IPOPartition *getSinglePartition() { - assert(IPOParts.size() == 1 && "Has multiple partition"); - return IPOParts[0]; - } - - private: - IPOPartsTy IPOParts; - IPOFileMgr &FileMgr; - int NextPartId; - }; - -} - -#endif //LTO_PARTITION_H diff --git a/tools/lto/LTOPostIPODriver.cpp b/tools/lto/LTOPostIPODriver.cpp deleted file mode 100644 index 2bb833a..0000000 --- a/tools/lto/LTOPostIPODriver.cpp +++ /dev/null @@ -1,180 +0,0 @@ -//===---------- LTOPostIPODriver.h - PostIPO Driver -----------------------===// -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file defines the PostIPODriver class which is the driver for Post-IPO -// compilation. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Analysis/AliasAnalysis.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/PassManager.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/FormattedStream.h" -#include "llvm/Support/Program.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Transforms/ObjCARC.h" -#include "LTOPartition.h" -#include "LTOPostIPODriver.h" - -using namespace llvm; -using namespace lto; - -// ///////////////////////////////////////////////////////////////////////////// -// -// Declare all variants of Post-IPO drivers -// -// ///////////////////////////////////////////////////////////////////////////// -// -namespace { - /// \breif Base class for all driver variants. - /// - class PostIPODrvBaseImpl { - public: - PostIPODrvBaseImpl(TargetMachine *Targ, IPOPartMgr &IPM, IPOFileMgr &IFM, - bool ToMergeObjs): - PartMgr(IPM), FileMgr(IFM), MergedObjFile(0), Target(Targ), - MergeObjs(ToMergeObjs) {} - - virtual ~PostIPODrvBaseImpl() {}; - - IPOPartMgr &getPartitionMgr() { return PartMgr; } - IPOFileMgr &getFileMgr() { return FileMgr; } - - // Implement the PostIPODriver::getSingleObjFile() - virtual IPOFile *getSingleObjFile() const = 0; - - bool IsToMergeObj() const { return MergeObjs; } - - virtual bool Compile(std::string &ErrMsg) = 0; - - protected: - // Populate post-IPO scalar optimization pass manager - bool PopulatePostIPOOptPM(PassManager &PM); - - // Populate post-IPO machine-specific CodeGen pass manager - bool PopulateCodeGenPM(PassManager &PM, formatted_raw_ostream &OutFile, - std::string &Err); - - protected: - IPOPartMgr &PartMgr; - IPOFileMgr &FileMgr; - IPOFile *MergedObjFile; - TargetMachine *Target; - bool MergeObjs; - }; - - /// \breif PostIPO driver for the compiling the entire program without - /// partition. - class PostIPODrvSerial : public PostIPODrvBaseImpl { - public: - PostIPODrvSerial(TargetMachine *T, IPOPartMgr &IPM, IPOFileMgr &IFM, - bool ToMergeObjs) : - PostIPODrvBaseImpl(T, IPM, IFM, ToMergeObjs) {} - - virtual bool Compile(std::string &ErrMsg); - virtual IPOFile *getSingleObjFile() const; - - private: - Module *getModule() const { return (*PartMgr.begin())->getModule(); } - }; -} - -// //////////////////////////////////////////////////////////////////////////// -// -// Implemetation of PostIPODriver -// -// //////////////////////////////////////////////////////////////////////////// -// -PostIPODriver::PostIPODriver(VariantTy V, TargetMachine *TM, IPOPartMgr &IPM, - IPOFileMgr &IFM, bool ToMergeObjs) { - if (V == PIDV_SERIAL) - DrvImpl = new PostIPODrvSerial(TM, IPM, IFM, ToMergeObjs); - else - assert(false && "TBD"); -} - -bool PostIPODriver::Compile(std::string &ErrMsg) { - PostIPODrvBaseImpl *P = static_cast(DrvImpl); - return P->Compile(ErrMsg); -} - -IPOFile *PostIPODriver::getSingleObjFile() const { - PostIPODrvBaseImpl *P = static_cast(DrvImpl); - return P->getSingleObjFile(); -} - -// //////////////////////////////////////////////////////////////////////////// -// -// Implemetation of PostIPODrvBaseImpl -// -// //////////////////////////////////////////////////////////////////////////// -// -bool PostIPODrvBaseImpl::PopulatePostIPOOptPM(PassManager &PM) { - (void)PM; - return true; -} - -bool PostIPODrvBaseImpl::PopulateCodeGenPM(PassManager &PM, - formatted_raw_ostream &OutFile, - std::string &Err) { - PM.add(new DataLayout(*Target->getDataLayout())); - Target->addAnalysisPasses(PM); - - // If the bitcode files contain ARC code and were compiled with optimization, - // the ObjCARCContractPass must be run, so do it unconditionally here. - PM.add(createObjCARCContractPass()); - - if (Target->addPassesToEmitFile(PM, OutFile, - TargetMachine::CGFT_ObjectFile)) { - Err = "target file type not supported"; - return false; - } - return true; -} - -// //////////////////////////////////////////////////////////////////////////// -// -// Implemetation of PostIPODrvSerial -// -// //////////////////////////////////////////////////////////////////////////// -// -bool PostIPODrvSerial::Compile(std::string &ErrMsg) { - Module *M = getModule(); - - // Step 1: Run the post-IPO scalar optimizations - { - PassManager SoptPM; - PopulatePostIPOOptPM(SoptPM); - SoptPM.run(*M); - } - - // Step 2: Run the post-IPO machine-specific code-generation passes - { - IPOFile &Obj = (*PartMgr.begin())->getObjFile(); - raw_fd_ostream ros(Obj.getPath().c_str(), Obj.getLastErrStr(), - sys::fs::F_Binary); - formatted_raw_ostream OutFile(ros); - - PassManager CodGenPM; - if (!PopulateCodeGenPM(CodGenPM, OutFile, ErrMsg)) { - ErrMsg += Obj.getLastErrStr(); - return false; - } - - CodGenPM.run(*M); - } - - return true; -} - -IPOFile *PostIPODrvSerial::getSingleObjFile() const { - assert(!MergedObjFile && "No need to *merge* a single object file"); - IPOPartition *P = *PartMgr.begin(); - return &P->getObjFile(); -} diff --git a/tools/lto/LTOPostIPODriver.h b/tools/lto/LTOPostIPODriver.h deleted file mode 100644 index 548e732..0000000 --- a/tools/lto/LTOPostIPODriver.h +++ /dev/null @@ -1,51 +0,0 @@ -//===---------- LTOPostIPODriver.h - PostIPO Driver -----------------------===// -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declare the PostIPODriver class which is the driver for -// Post-IPO compilation phase. -// -//===----------------------------------------------------------------------===// - -#ifndef LTO_POSTIPO_DRIVER_H -#define LTO_POSTIPO_DRIVER_H - -#include "llvm/Target/TargetMachine.h" - -namespace lto { - class IPOPartMgr; - class IPOFileMgr; - class IPOFile; - - class PostIPODriver { - public: - typedef enum { - PIDV_Invalid, - PIDV_SERIAL, // No partition - PIDV_MultiThread, // Each partition is compiled by a thread - PIDV_MultiProc, // Each partition is compiled by a process - PIDV_MakeUtil // Partitions compilation is driven by a make-utility - } VariantTy; - - PostIPODriver(VariantTy Var, TargetMachine *TM, IPOPartMgr &IPM, - IPOFileMgr &IFM, bool ToMergeObjs = false); - - // Return the single resulting object file. If there is no prior - // compilation failure, this function may return NULL iff: - // 1) Partition is enabled, and - // 2) Multiple partitions are generated, and - // 3) It is not asked to merge together the objects corresponding to the - // the partions. - IPOFile *getSingleObjFile() const; - - bool Compile(std::string &ErrMsg); - - private: - void *DrvImpl; - }; -} - -#endif // LTO_POSTIPO_DRIVER_H diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index c7009d6..db7147c 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -207,19 +207,6 @@ bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) { return !cg->compile_to_file(name, sLastErrorString); } -/// Get intermediate files that need to be removed before linker exit. Upon -/// return, the paths of the files need to be removed is written to "paths". The -/// paths are separated by a single '\0', and the last path is ended by double -/// '\0's. A file could be a directory; in this case, the entire directory needs -/// to be removed recursively. -/// -/// It is only necessary to call this function after \p lto_codegen_compile was -/// successfully called. -void -lto_codegen_get_files_need_remove(lto_code_gen_t cg, const char **paths) { - *paths = cg->getFilesNeedToRemove(); -} - /// 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) { diff --git a/tools/lto/lto.exports b/tools/lto/lto.exports index 41a81dd..46d0d74 100644 --- a/tools/lto/lto.exports +++ b/tools/lto/lto.exports @@ -20,7 +20,6 @@ lto_codegen_add_must_preserve_symbol lto_codegen_compile lto_codegen_create lto_codegen_dispose -lto_codegen_get_files_need_remove lto_codegen_set_debug_model lto_codegen_set_pic_model lto_codegen_write_merged_modules -- cgit v1.1 From b6171c529670e5c240aaf9c08f5f1b6dba9d16fc Mon Sep 17 00:00:00 2001 From: Arnold Schwaighofer Date: Tue, 13 Aug 2013 15:51:25 +0000 Subject: Remove logic that decides whether to vectorize or not depending on O-levels I have moved this logic into clang and opt. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188281 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/opt/opt.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 37637ca..ca82061 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -451,6 +451,8 @@ static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, Builder.populateFunctionPassManager(FPM); Builder.populateModulePassManager(MPM); + + Builder.LoopVectorize = OptLevel > 1 && SizeLevel < 2; } static void AddStandardCompilePasses(PassManagerBase &PM) { -- cgit v1.1 From 6889483ca4bd5f2634c9041aa076aad01ac38b39 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Wed, 14 Aug 2013 17:09:30 +0000 Subject: llvm-symbolizer: add support for .gnu_debuglink section git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188386 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-symbolizer/LLVMSymbolize.cpp | 83 +++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) (limited to 'tools') diff --git a/tools/llvm-symbolizer/LLVMSymbolize.cpp b/tools/llvm-symbolizer/LLVMSymbolize.cpp index 0346fb2..c8edde7 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.cpp +++ b/tools/llvm-symbolizer/LLVMSymbolize.cpp @@ -15,7 +15,10 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/Object/MachO.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/Compression.h" +#include "llvm/Support/DataExtractor.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include @@ -215,6 +218,74 @@ static std::string getDarwinDWARFResourceForPath(const std::string &Path) { return ResourceName.str(); } +static bool checkFileCRC(StringRef Path, uint32_t CRCHash) { + OwningPtr MB; + if (MemoryBuffer::getFileOrSTDIN(Path, MB)) + return false; + return !zlib::isAvailable() || CRCHash == zlib::crc32(MB->getBuffer()); +} + +static bool findDebugBinary(const std::string &OrigPath, + const std::string &DebuglinkName, uint32_t CRCHash, + std::string &Result) { + SmallString<16> OrigDir(OrigPath); + llvm::sys::path::remove_filename(OrigDir); + SmallString<16> DebugPath = OrigDir; + // Try /path/to/original_binary/debuglink_name + llvm::sys::path::append(DebugPath, DebuglinkName); + if (checkFileCRC(DebugPath, CRCHash)) { + Result = DebugPath.str(); + return true; + } + // Try /path/to/original_binary/.debug/debuglink_name + DebugPath = OrigPath; + llvm::sys::path::append(DebugPath, ".debug", DebuglinkName); + if (checkFileCRC(DebugPath, CRCHash)) { + Result = DebugPath.str(); + return true; + } + // Try /usr/lib/debug/path/to/original_binary/debuglink_name + DebugPath = "/usr/lib/debug"; + llvm::sys::path::append(DebugPath, llvm::sys::path::relative_path(OrigDir), + DebuglinkName); + if (checkFileCRC(DebugPath, CRCHash)) { + Result = DebugPath.str(); + return true; + } + return false; +} + +static bool getGNUDebuglinkContents(const Binary *Bin, std::string &DebugName, + uint32_t &CRCHash) { + const ObjectFile *Obj = dyn_cast(Bin); + if (!Obj) + return false; + error_code EC; + for (section_iterator I = Obj->begin_sections(), E = Obj->end_sections(); + I != E; I.increment(EC)) { + StringRef Name; + I->getName(Name); + Name = Name.substr(Name.find_first_not_of("._")); + if (Name == "gnu_debuglink") { + StringRef Data; + I->getContents(Data); + DataExtractor DE(Data, Obj->isLittleEndian(), 0); + uint32_t Offset = 0; + if (const char *DebugNameStr = DE.getCStr(&Offset)) { + // 4-byte align the offset. + Offset = (Offset + 3) & ~0x3; + if (DE.isValidOffsetForDataOfSize(Offset, 4)) { + DebugName = DebugNameStr; + CRCHash = DE.getU32(&Offset); + return true; + } + } + break; + } + } + return false; +} + LLVMSymbolizer::BinaryPair LLVMSymbolizer::getOrCreateBinary(const std::string &Path) { BinaryMapTy::iterator I = BinaryForPath.find(Path); @@ -241,6 +312,18 @@ LLVMSymbolizer::getOrCreateBinary(const std::string &Path) { ParsedBinariesAndObjects.push_back(DbgBin); } } + // Try to locate the debug binary using .gnu_debuglink section. + if (DbgBin == 0) { + std::string DebuglinkName; + uint32_t CRCHash; + std::string DebugBinaryPath; + if (getGNUDebuglinkContents(Bin, DebuglinkName, CRCHash) && + findDebugBinary(Path, DebuglinkName, CRCHash, DebugBinaryPath) && + !error(createBinary(DebugBinaryPath, ParsedDbgBinary))) { + DbgBin = ParsedDbgBinary.take(); + ParsedBinariesAndObjects.push_back(DbgBin); + } + } } if (DbgBin == 0) DbgBin = Bin; -- cgit v1.1 From 65566e1684043a41eed4376d7287254a1a12a458 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 21 Aug 2013 02:37:14 +0000 Subject: lli/RecordingMemoryManager.cpp: Make it complain if _GLOBAL_OFFSET_TABLE_ were not provided. FIXME: Would it be responsible to provide GOT? git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188855 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/RecordingMemoryManager.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'tools') diff --git a/tools/lli/RecordingMemoryManager.cpp b/tools/lli/RecordingMemoryManager.cpp index 1fa8176..ec55d2c 100644 --- a/tools/lli/RecordingMemoryManager.cpp +++ b/tools/lli/RecordingMemoryManager.cpp @@ -113,5 +113,12 @@ void *RecordingMemoryManager::getPointerToNamedFunction(const std::string &Name, // is called before ExecutionEngine::runFunctionAsMain() is called. if (Name == "__main") return (void*)(intptr_t)&jit_noop; + // FIXME: Would it be responsible to provide GOT? + if (AbortOnFailure) { + if (Name == "_GLOBAL_OFFSET_TABLE_") + report_fatal_error("Program used external function '" + Name + + "' which could not be resolved!"); + } + return NULL; } -- cgit v1.1 From 171ac8ca175bec5bc0bff8b3006850f70e0569c9 Mon Sep 17 00:00:00 2001 From: Ahmed Bougacha Date: Wed, 21 Aug 2013 07:29:02 +0000 Subject: MC CFG: Add YAML MCModule representation to enable MC CFG testing. Like yaml ObjectFiles, this will be very useful for testing the MC CFG implementation (mostly MCObjectDisassembler), by matching the output with YAML, and for potential users of the MC CFG, by using it as an input. There isn't much to the actual format, it is just a serialization of the MCModule class. Of note: - Basic block references (pred/succ, ..) are represented by the BB's start address. - Just as in the MC CFG, instructions are MCInsts with a size. - Operands have a prefix representing the type (only register and immediate supported here). - Instruction opcodes are represented by their names; enum values aren't stable, enum names mostly are: usually, a change to a name would need lots of changes in the backend anyway. Same with registers. All in all, an example is better than 1000 words, here goes: A simple binary: Disassembly of section __TEXT,__text: _main: 100000f9c: 48 8b 46 08 movq 8(%rsi), %rax 100000fa0: 0f be 00 movsbl (%rax), %eax 100000fa3: 3b 04 25 48 00 00 00 cmpl 72, %eax 100000faa: 0f 8c 07 00 00 00 jl 7 <.Lend> 100000fb0: 2b 04 25 48 00 00 00 subl 72, %eax .Lend: 100000fb7: c3 ret And the (pretty verbose) generated YAML: --- Atoms: - StartAddress: 0x0000000100000F9C Size: 20 Type: Text Content: - Inst: MOV64rm Size: 4 Ops: [ RRAX, RRSI, I1, R, I8, R ] - Inst: MOVSX32rm8 Size: 3 Ops: [ REAX, RRAX, I1, R, I0, R ] - Inst: CMP32rm Size: 7 Ops: [ REAX, R, I1, R, I72, R ] - Inst: JL_4 Size: 6 Ops: [ I7 ] - StartAddress: 0x0000000100000FB0 Size: 7 Type: Text Content: - Inst: SUB32rm Size: 7 Ops: [ REAX, REAX, R, I1, R, I72, R ] - StartAddress: 0x0000000100000FB7 Size: 1 Type: Text Content: - Inst: RET Size: 1 Ops: [ ] Functions: - Name: __text BasicBlocks: - Address: 0x0000000100000F9C Preds: [ ] Succs: [ 0x0000000100000FB7, 0x0000000100000FB0 ] ... git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188890 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/llvm-objdump.cpp | 38 ++++++++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 122ac83..a4cd6a2 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -31,6 +31,7 @@ #include "llvm/MC/MCInstrAnalysis.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCModule.h" +#include "llvm/MC/MCModuleYAML.h" #include "llvm/MC/MCObjectDisassembler.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCObjectSymbolizer.h" @@ -61,6 +62,7 @@ #include #include #include + using namespace llvm; using namespace object; @@ -139,6 +141,12 @@ static cl::opt CFG("cfg", cl::desc("Create a CFG for every function found in the object" " and write it to a graphviz file")); +// FIXME: Does it make sense to have a dedicated tool for yaml cfg output? +static cl::opt +YAMLCFG("yaml-cfg", + cl::desc("Create a CFG and write it as a YAML MCModule."), + cl::value_desc("yaml output file")); + static StringRef ToolName; bool llvm::error(error_code ec) { @@ -178,6 +186,7 @@ static const Target *getTarget(const ObjectFile *Obj = NULL) { } // Write a graphviz file for the CFG inside an MCFunction. +// FIXME: Use GraphWriter static void emitDOTFile(const char *FileName, const MCFunction &f, MCInstPrinter *IP) { // Start a new dot file. @@ -333,7 +342,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { return; } - if (CFG) { + if (CFG || !YAMLCFG.empty()) { OwningPtr OD( new MCObjectDisassembler(*Obj, *DisAsm, *MIA)); OwningPtr Mod(OD->buildModule(/* withCFG */ true)); @@ -350,14 +359,25 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { } } } - for (MCModule::const_func_iterator FI = Mod->func_begin(), - FE = Mod->func_end(); - FI != FE; ++FI) { - static int filenum = 0; - emitDOTFile((Twine((*FI)->getName()) + "_" + - utostr(filenum) + ".dot").str().c_str(), - **FI, IP.get()); - ++filenum; + if (CFG) { + for (MCModule::const_func_iterator FI = Mod->func_begin(), + FE = Mod->func_end(); + FI != FE; ++FI) { + static int filenum = 0; + emitDOTFile((Twine((*FI)->getName()) + "_" + + utostr(filenum) + ".dot").str().c_str(), + **FI, IP.get()); + ++filenum; + } + } + if (!YAMLCFG.empty()) { + std::string Error; + raw_fd_ostream YAMLOut(YAMLCFG.c_str(), Error); + if (!Error.empty()) { + errs() << "llvm-objdump: warning: " << Error << '\n'; + return; + } + mcmodule2yaml(YAMLOut, *Mod, *MII, *MRI); } } -- cgit v1.1 From 7413b54c897c9a7bd04e7b918128d0279be9a126 Mon Sep 17 00:00:00 2001 From: Ahmed Bougacha Date: Wed, 21 Aug 2013 16:13:25 +0000 Subject: Add basic YAML MC CFG testcase. Drive-by llvm-objdump cleanup (don't hardcode ToolName). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188904 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/llvm-objdump.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index a4cd6a2..8065787 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -374,7 +374,7 @@ static void DisassembleObject(const ObjectFile *Obj, bool InlineRelocs) { std::string Error; raw_fd_ostream YAMLOut(YAMLCFG.c_str(), Error); if (!Error.empty()) { - errs() << "llvm-objdump: warning: " << Error << '\n'; + errs() << ToolName << ": warning: " << Error << '\n'; return; } mcmodule2yaml(YAMLOut, *Mod, *MII, *MRI); -- cgit v1.1 From d6dbd6b88341f1f7492b8c170077cbbb2014f1e0 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Wed, 21 Aug 2013 19:13:44 +0000 Subject: [CMake] Automatically pick up subdirectories in llvm/tools as 'external projects' if they contain a 'CMakeLists.txt' file. Allow CMake to pick up external projects in llvm/tools without the need to modify the "llvm/tools/CMakeLists.txt" file. This makes it easier to work with projects that live in other repositories, without needing to specify each one in "llvm/tools/CMakeLists.txt". git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@188921 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/CMakeLists.txt | 78 +++++++++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 34 deletions(-) (limited to 'tools') diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index e663781..66271a9 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -5,64 +5,74 @@ if( NOT WIN32 OR MSYS OR CYGWIN ) # We currently require 'sed' to build llvm-config, so don't try to build it # on pure Win32. - add_subdirectory(llvm-config) + add_llvm_tool_subdirectory(llvm-config) +else() + ignore_llvm_tool_subdirectory(llvm-config) endif() -add_subdirectory(opt) -add_subdirectory(llvm-as) -add_subdirectory(llvm-dis) -add_subdirectory(llvm-mc) +add_llvm_tool_subdirectory(opt) +add_llvm_tool_subdirectory(llvm-as) +add_llvm_tool_subdirectory(llvm-dis) +add_llvm_tool_subdirectory(llvm-mc) -add_subdirectory(llc) -add_subdirectory(llvm-ar) -add_subdirectory(llvm-nm) -add_subdirectory(llvm-size) +add_llvm_tool_subdirectory(llc) +add_llvm_tool_subdirectory(llvm-ar) +add_llvm_tool_subdirectory(llvm-nm) +add_llvm_tool_subdirectory(llvm-size) -add_subdirectory(llvm-cov) -add_subdirectory(llvm-prof) -add_subdirectory(llvm-link) -add_subdirectory(lli) +add_llvm_tool_subdirectory(llvm-cov) +add_llvm_tool_subdirectory(llvm-prof) +add_llvm_tool_subdirectory(llvm-link) +add_llvm_tool_subdirectory(lli) -add_subdirectory(llvm-extract) -add_subdirectory(llvm-diff) -add_subdirectory(macho-dump) -add_subdirectory(llvm-objdump) -add_subdirectory(llvm-readobj) -add_subdirectory(llvm-rtdyld) -add_subdirectory(llvm-dwarfdump) +add_llvm_tool_subdirectory(llvm-extract) +add_llvm_tool_subdirectory(llvm-diff) +add_llvm_tool_subdirectory(macho-dump) +add_llvm_tool_subdirectory(llvm-objdump) +add_llvm_tool_subdirectory(llvm-readobj) +add_llvm_tool_subdirectory(llvm-rtdyld) +add_llvm_tool_subdirectory(llvm-dwarfdump) if( LLVM_USE_INTEL_JITEVENTS ) - add_subdirectory(llvm-jitlistener) + add_llvm_tool_subdirectory(llvm-jitlistener) +else() + ignore_llvm_tool_subdirectory(llvm-jitlistener) endif( LLVM_USE_INTEL_JITEVENTS ) -add_subdirectory(bugpoint) -add_subdirectory(bugpoint-passes) -add_subdirectory(llvm-bcanalyzer) -add_subdirectory(llvm-stress) -add_subdirectory(llvm-mcmarkup) +add_llvm_tool_subdirectory(bugpoint) +add_llvm_tool_subdirectory(bugpoint-passes) +add_llvm_tool_subdirectory(llvm-bcanalyzer) +add_llvm_tool_subdirectory(llvm-stress) +add_llvm_tool_subdirectory(llvm-mcmarkup) -add_subdirectory(llvm-symbolizer) +add_llvm_tool_subdirectory(llvm-symbolizer) -add_subdirectory(obj2yaml) -add_subdirectory(yaml2obj) +add_llvm_tool_subdirectory(obj2yaml) +add_llvm_tool_subdirectory(yaml2obj) if( NOT WIN32 ) - add_subdirectory(lto) + add_llvm_tool_subdirectory(lto) +else() + ignore_llvm_tool_subdirectory(lto) endif() if( LLVM_ENABLE_PIC ) # TODO: support other systems: if( (CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") ) - add_subdirectory(gold) + add_llvm_tool_subdirectory(gold) + else() + ignore_llvm_tool_subdirectory(gold) endif() +else() + ignore_llvm_tool_subdirectory(gold) endif() add_llvm_external_project(clang) if( NOT LLVM_INCLUDE_TOOLS STREQUAL "bootstrap-only" ) - add_llvm_external_project(lld) - add_llvm_external_project(lldb) - add_llvm_external_project(polly) + # Automatically add remaining sub-directories containing a 'CMakeLists.txt' + # file as external projects. + add_llvm_implicit_external_projects() endif() set(LLVM_COMMON_DEPENDS ${LLVM_COMMON_DEPENDS} PARENT_SCOPE) -- cgit v1.1 From 1f2c399bdb17b30217c8f9d900bde706a160bb35 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Fri, 23 Aug 2013 02:51:13 +0000 Subject: lto/CMakeLists.txt: Cut the dep to intrinsics_gen. LTO doesn't depend on it and LTO_static doesn't depend on anything. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189086 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) (limited to 'tools') diff --git a/tools/lto/CMakeLists.txt b/tools/lto/CMakeLists.txt index 5820b14..a004bad 100644 --- a/tools/lto/CMakeLists.txt +++ b/tools/lto/CMakeLists.txt @@ -11,8 +11,6 @@ set(SOURCES LTOModule.cpp ) -set(LLVM_COMMON_DEPENDS intrinsics_gen) - if( NOT WIN32 AND LLVM_ENABLE_PIC ) set(bsl ${BUILD_SHARED_LIBS}) set(BUILD_SHARED_LIBS ON) -- cgit v1.1 From 3eb7322ca15e61f002be95341f74d1df8c1146bb Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 23 Aug 2013 17:59:13 +0000 Subject: CMake: build llvm-config on Windows. It was previously not being built on Windows because the cmake file relied on a sed script to generate a .in file that llvm-config needs. By using cmake's configure_file function, we can get rid off the sed hack, and also have this work on Windows. Differential Revision: http://llvm-reviews.chandlerc.com/D1481 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189125 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/CMakeLists.txt | 8 +------- tools/llvm-config/CMakeLists.txt | 34 +++++++++++----------------------- 2 files changed, 12 insertions(+), 30 deletions(-) (limited to 'tools') diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 66271a9..8a635a5 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -2,13 +2,7 @@ # three small executables. This is done to minimize memory load in parallel # builds. Please retain this ordering. -if( NOT WIN32 OR MSYS OR CYGWIN ) - # We currently require 'sed' to build llvm-config, so don't try to build it - # on pure Win32. - add_llvm_tool_subdirectory(llvm-config) -else() - ignore_llvm_tool_subdirectory(llvm-config) -endif() +add_llvm_tool_subdirectory(llvm-config) add_llvm_tool_subdirectory(opt) add_llvm_tool_subdirectory(llvm-as) diff --git a/tools/llvm-config/CMakeLists.txt b/tools/llvm-config/CMakeLists.txt index 5ad58bf..d17a19e 100644 --- a/tools/llvm-config/CMakeLists.txt +++ b/tools/llvm-config/CMakeLists.txt @@ -1,37 +1,25 @@ set(LLVM_LINK_COMPONENTS support) -# We need to generate the BuildVariables.inc file containing values which are -# only defined when under certain build modes. Unfortunately, that precludes -# doing this inside CMake so we have to shell out to sed. For now, that means we -# can't expect to build llvm-config on Window.s set(BUILDVARIABLES_SRCPATH ${CMAKE_CURRENT_SOURCE_DIR}/BuildVariables.inc.in) set(BUILDVARIABLES_OBJPATH ${CMAKE_CURRENT_BINARY_DIR}/BuildVariables.inc) -set(SEDSCRIPT_OBJPATH ${CMAKE_CURRENT_BINARY_DIR}/BuildVariables.configure.sed) # Compute the substitution values for various items. get_system_libs(LLVM_SYSTEM_LIBS_LIST) foreach(l ${LLVM_SYSTEM_LIBS_LIST}) set(SYSTEM_LIBS ${SYSTEM_LIBS} "-l${l}") endforeach() -set(C_FLGS "${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}") -set(CXX_FLGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}") -set(CPP_FLGS "${CMAKE_CPP_FLAGS} ${CMAKE_CPP_FLAGS_${uppercase_CMAKE_BUILD_TYPE}} ${LLVM_DEFINITIONS}") -add_custom_command(OUTPUT ${BUILDVARIABLES_OBJPATH} - COMMAND echo s!@LLVM_SRC_ROOT@!${LLVM_MAIN_SRC_DIR}! > ${SEDSCRIPT_OBJPATH} - COMMAND echo s!@LLVM_OBJ_ROOT@!${LLVM_BINARY_DIR}! >> ${SEDSCRIPT_OBJPATH} - COMMAND echo s!@LLVM_CPPFLAGS@!${CPP_FLGS}! >> ${SEDSCRIPT_OBJPATH} - COMMAND echo s!@LLVM_CFLAGS@!${C_FLGS}! >> ${SEDSCRIPT_OBJPATH} - COMMAND echo s!@LLVM_CXXFLAGS@!${CXX_FLGS}! >> ${SEDSCRIPT_OBJPATH} - # TODO: Use general flags for linking! not just for shared libs: - COMMAND echo s!@LLVM_LDFLAGS@!${CMAKE_SHARED_LINKER_FLAGS}! >> ${SEDSCRIPT_OBJPATH} - COMMAND echo s!@LLVM_BUILDMODE@!${CMAKE_BUILD_TYPE}! >> ${SEDSCRIPT_OBJPATH} - COMMAND echo s!@LLVM_SYSTEM_LIBS@!${SYSTEM_LIBS}! >> ${SEDSCRIPT_OBJPATH} - COMMAND echo s!@LLVM_TARGETS_BUILT@!${LLVM_TARGETS_TO_BUILD}! >> ${SEDSCRIPT_OBJPATH} - COMMAND sed -f ${SEDSCRIPT_OBJPATH} < ${BUILDVARIABLES_SRCPATH} > ${BUILDVARIABLES_OBJPATH} - VERBATIM - COMMENT "Building BuildVariables.inc include." - ) +# Use configure_file to create BuildVariables.inc. +set(LLVM_SRC_ROOT ${LLVM_MAIN_SRC_DIR}) +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}) +set(LLVM_BUILDMODE ${CMAKE_BUILD_TYPE}) +set(LLVM_SYSTEM_LIBS ${SYSTEM_LIBS}) +set(LLVM_TARGETS_BUILT ${LLVM_TARGETS_TO_BUILD}) +configure_file(${BUILDVARIABLES_SRCPATH} ${BUILDVARIABLES_OBJPATH} @ONLY) # Add the llvm-config tool. add_llvm_tool(llvm-config -- cgit v1.1 From d19346524ce01a16dd1228fa71e3511986aa2718 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 26 Aug 2013 16:54:12 +0000 Subject: CMake: move lto.h install to tools/lto/CMakeLists.txt It looked misplaced in the main CMakeLists.txt file. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189230 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools') diff --git a/tools/lto/CMakeLists.txt b/tools/lto/CMakeLists.txt index a004bad..c71aac1 100644 --- a/tools/lto/CMakeLists.txt +++ b/tools/lto/CMakeLists.txt @@ -26,3 +26,8 @@ if( NOT BUILD_SHARED_LIBS ) add_llvm_library(${LTO_STATIC_TARGET_NAME} ${SOURCES}) set_property(TARGET ${LTO_STATIC_TARGET_NAME} PROPERTY OUTPUT_NAME "LTO") endif() + +if( NOT WIN32 ) + install(FILES ${LLVM_MAIN_INCLUDE_DIR}/llvm-c/lto.h + DESTINATION include/llvm-c) +endif() -- cgit v1.1 From 8228a8dd91fbc4c1443bc3f15847ca8be24094a2 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Mon, 26 Aug 2013 18:12:03 +0000 Subject: llvm-symbolizer: use real path when looking for debug binary location git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189250 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-symbolizer/LLVMSymbolize.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/llvm-symbolizer/LLVMSymbolize.cpp b/tools/llvm-symbolizer/LLVMSymbolize.cpp index c8edde7..45c8664 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.cpp +++ b/tools/llvm-symbolizer/LLVMSymbolize.cpp @@ -13,6 +13,7 @@ #include "LLVMSymbolize.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Config/config.h" #include "llvm/Object/MachO.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Compression.h" @@ -22,6 +23,7 @@ #include "llvm/Support/Path.h" #include +#include namespace llvm { namespace symbolize { @@ -228,7 +230,14 @@ static bool checkFileCRC(StringRef Path, uint32_t CRCHash) { static bool findDebugBinary(const std::string &OrigPath, const std::string &DebuglinkName, uint32_t CRCHash, std::string &Result) { - SmallString<16> OrigDir(OrigPath); + std::string OrigRealPath = OrigPath; +#if defined(HAVE_REALPATH) + if (char *RP = realpath(OrigPath.c_str(), NULL)) { + OrigRealPath = RP; + free(RP); + } +#endif + SmallString<16> OrigDir(OrigRealPath); llvm::sys::path::remove_filename(OrigDir); SmallString<16> DebugPath = OrigDir; // Try /path/to/original_binary/debuglink_name @@ -238,7 +247,7 @@ static bool findDebugBinary(const std::string &OrigPath, return true; } // Try /path/to/original_binary/.debug/debuglink_name - DebugPath = OrigPath; + DebugPath = OrigRealPath; llvm::sys::path::append(DebugPath, ".debug", DebuglinkName); if (checkFileCRC(DebugPath, CRCHash)) { Result = DebugPath.str(); -- cgit v1.1 From e3427a5815ca3993584af6db28524f0c424b749e Mon Sep 17 00:00:00 2001 From: Shuxin Yang Date: Tue, 27 Aug 2013 00:03:23 +0000 Subject: Add new API lto_codegen_compile_parallel(). This API is proposed by Nick Kledzik. The semantic is: -------------------------------------------------------------------------- Generate code for merged module into an array of native object files. On success returns a pointer to an array of NativeObjectFile. The count parameter returns the number of elements in the array. Each element is a pointer/length for a generated mach-o/ELF buffer. The buffer is owned by the lto_code_gen_t 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). extern const struct NativeObjectFile* lto_codegen_compile_parallel(lto_code_gen_t cg, size_t *count); --------------------------------------------------------------------------- This API is currently only called on OSX platform. Linux or other Unixes using GNU gold are not supposed to call this function, because on these systems, object files are fed back to linker via disk file instead of memory buffer. In this commit, lto_codegen_compile_parallel() simply calls lto_codegen_compile() to return a single object file. In the near future, this function is the entry point for compilation with partition. Linker can blindly call this function even if partition is turned off; in this case, compiler will return only one object file. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189297 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/LTOCodeGenerator.cpp | 20 +++++++++++++++++++- tools/lto/LTOCodeGenerator.h | 12 ++++++++++++ tools/lto/lto.cpp | 5 +++++ tools/lto/lto.exports | 1 + 4 files changed, 37 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index 3fe7af2..daeb964 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -74,7 +74,7 @@ LTOCodeGenerator::LTOCodeGenerator() _linker(new Module("ld-temp.o", _context)), _target(NULL), _emitDwarfDebugInfo(false), _scopeRestrictionsDone(false), _codeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC), - _nativeObjectFile(NULL) { + _nativeObjectFile(NULL), ObjBufVect(0) { InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); @@ -85,6 +85,7 @@ LTOCodeGenerator::~LTOCodeGenerator() { delete _target; delete _nativeObjectFile; delete _linker.getModule(); + delete[] ObjBufVect; for (std::vector::iterator I = _codegenOptions.begin(), E = _codegenOptions.end(); I != E; ++I) @@ -246,6 +247,23 @@ const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg) { return _nativeObjectFile->getBufferStart(); } +// Currently compile() and compile_parallel() have no difference. +NativeObjectFile *LTOCodeGenerator::compile_parallel(size_t *count, + std::string &ErrMsg) { + assert(ObjBufVect == 0 && "Should be NULL"); + + size_t Len; + const void *Buf = compile(&Len, ErrMsg); + if (!Buf) + return 0; + + *count = 1; + ObjBufVect = new NativeObjectFile[1]; + ObjBufVect[0].content = Buf; + ObjBufVect[0].length = Len; + return ObjBufVect; +} + bool LTOCodeGenerator::determineTarget(std::string &errMsg) { if (_target != NULL) return true; diff --git a/tools/lto/LTOCodeGenerator.h b/tools/lto/LTOCodeGenerator.h index 8f37cf0..21c6b21 100644 --- a/tools/lto/LTOCodeGenerator.h +++ b/tools/lto/LTOCodeGenerator.h @@ -102,6 +102,17 @@ struct LTOCodeGenerator { // const void *compile(size_t *length, std::string &errMsg); + // Corresponding to lto_codegen_compile_parallel() API. + // Generates code for merged module into an array of native object files. + // On success returns a pointer to an array of NativeObjectFile. The count + // parameter returns the number of elements in the array. Each element is + // a pointer/length for a generated mach-o/ELF buffer. The buffer is owned + // by the lto_code_gen_t 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). + // + NativeObjectFile *compile_parallel(size_t *count, std::string &ErrMsg); + private: void initializeLTOPasses(); @@ -127,6 +138,7 @@ private: std::vector _codegenOptions; std::string _mCpu; std::string _nativeObjectPath; + NativeObjectFile *ObjBufVect; }; #endif // LTO_CODE_GENERATOR_H diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index db7147c..bbb6071 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -207,6 +207,11 @@ bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) { return !cg->compile_to_file(name, sLastErrorString); } +extern const struct NativeObjectFile * +lto_codegen_compile_parallel(lto_code_gen_t cg, size_t *count) { + return cg->compile_parallel(count, 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) { diff --git a/tools/lto/lto.exports b/tools/lto/lto.exports index 46d0d74..61f0817 100644 --- a/tools/lto/lto.exports +++ b/tools/lto/lto.exports @@ -28,6 +28,7 @@ lto_codegen_set_assembler_args lto_codegen_set_assembler_path lto_codegen_set_cpu lto_codegen_compile_to_file +lto_codegen_compile_parallel LLVMCreateDisasm LLVMCreateDisasmCPU LLVMDisasmDispose -- cgit v1.1 From 9c3dd1b0d1e96ef408b68da3b06c6ebd6c943601 Mon Sep 17 00:00:00 2001 From: Charles Davis Date: Tue, 27 Aug 2013 05:00:43 +0000 Subject: Move everything depending on Object/MachOFormat.h over to Support/MachO.h. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189315 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/MachODump.cpp | 31 ++--- tools/llvm-readobj/MachODumper.cpp | 66 ++++----- tools/macho-dump/macho-dump.cpp | 266 +++++++++++++++++++------------------ 3 files changed, 185 insertions(+), 178 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index e0ec9cc..e78c644 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -104,7 +104,7 @@ static void DumpDataInCode(const char *bytes, uint64_t Size, uint64_t Value; switch (Kind) { - case macho::Data: + case MachO::DICE_KIND_DATA: switch (Size) { case 4: Value = bytes[3] << 24 | @@ -125,16 +125,16 @@ static void DumpDataInCode(const char *bytes, uint64_t Size, } outs() << "\t@ KIND_DATA\n"; break; - case macho::JumpTable8: + case MachO::DICE_KIND_JUMP_TABLE8: Value = bytes[0]; outs() << "\t.byte " << Value << "\t@ KIND_JUMP_TABLE8"; break; - case macho::JumpTable16: + case MachO::DICE_KIND_JUMP_TABLE16: Value = bytes[1] << 8 | bytes[0]; outs() << "\t.short " << Value << "\t@ KIND_JUMP_TABLE16"; break; - case macho::JumpTable32: + case MachO::DICE_KIND_JUMP_TABLE32: Value = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | @@ -148,7 +148,7 @@ static void DumpDataInCode(const char *bytes, uint64_t Size, } static void -getSectionsAndSymbols(const macho::Header Header, +getSectionsAndSymbols(const MachO::mach_header Header, MachOObjectFile *MachOObj, std::vector &Sections, std::vector &Symbols, @@ -171,25 +171,26 @@ getSectionsAndSymbols(const macho::Header Header, MachOObj->getFirstLoadCommandInfo(); bool BaseSegmentAddressSet = false; for (unsigned i = 0; ; ++i) { - if (Command.C.Type == macho::LCT_FunctionStarts) { + if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) { // We found a function starts segment, parse the addresses for later // consumption. - macho::LinkeditDataLoadCommand LLC = + MachO::linkedit_data_command LLC = MachOObj->getLinkeditDataLoadCommand(Command); - MachOObj->ReadULEB128s(LLC.DataOffset, FoundFns); + MachOObj->ReadULEB128s(LLC.dataoff, FoundFns); } - else if (Command.C.Type == macho::LCT_Segment) { - macho::SegmentLoadCommand SLC = + else if (Command.C.cmd == MachO::LC_SEGMENT || + Command.C.cmd == MachO::LC_SEGMENT_64) { + MachO::segment_command SLC = MachOObj->getSegmentLoadCommand(Command); - StringRef SegName = SLC.Name; + StringRef SegName = SLC.segname; if(!BaseSegmentAddressSet && SegName != "__PAGEZERO") { BaseSegmentAddressSet = true; - BaseSegmentAddress = SLC.VMAddress; + BaseSegmentAddress = SLC.vmaddr; } } - if (i == Header.NumLoadCommands - 1) + if (i == Header.ncmds - 1) break; else Command = MachOObj->getNextLoadCommandInfo(Command); @@ -244,7 +245,7 @@ static void DisassembleInputMachO2(StringRef Filename, outs() << '\n' << Filename << ":\n\n"; - macho::Header Header = MachOOF->getHeader(); + MachO::mach_header Header = MachOOF->getHeader(); // FIXME: FoundFns isn't used anymore. Using symbols/LC_FUNCTION_STARTS to // determine function locations will eventually go in MCObjectDisassembler. @@ -267,7 +268,7 @@ static void DisassembleInputMachO2(StringRef Filename, // Build a data in code table that is sorted on by the address of each entry. uint64_t BaseAddress = 0; - if (Header.FileType == macho::HFT_Object) + if (Header.filetype == MachO::MH_OBJECT) Sections[0].getAddress(BaseAddress); else BaseAddress = BaseSegmentAddress; diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index 8df6fd6..e27a58a 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -166,28 +166,28 @@ static void getSection(const MachOObjectFile *Obj, DataRefImpl Sec, MachOSection &Section) { if (!Obj->is64Bit()) { - macho::Section Sect = Obj->getSection(Sec); - Section.Address = Sect.Address; - Section.Size = Sect.Size; - Section.Offset = Sect.Offset; - Section.Alignment = Sect.Align; - Section.RelocationTableOffset = Sect.RelocationTableOffset; - Section.NumRelocationTableEntries = Sect.NumRelocationTableEntries; - Section.Flags = Sect.Flags; - Section.Reserved1 = Sect.Reserved1; - Section.Reserved2 = Sect.Reserved2; + MachO::section Sect = Obj->getSection(Sec); + Section.Address = Sect.addr; + Section.Size = Sect.size; + Section.Offset = Sect.offset; + Section.Alignment = Sect.align; + Section.RelocationTableOffset = Sect.reloff; + Section.NumRelocationTableEntries = Sect.nreloc; + Section.Flags = Sect.flags; + Section.Reserved1 = Sect.reserved1; + Section.Reserved2 = Sect.reserved2; return; } - macho::Section64 Sect = Obj->getSection64(Sec); - Section.Address = Sect.Address; - Section.Size = Sect.Size; - Section.Offset = Sect.Offset; - Section.Alignment = Sect.Align; - Section.RelocationTableOffset = Sect.RelocationTableOffset; - Section.NumRelocationTableEntries = Sect.NumRelocationTableEntries; - Section.Flags = Sect.Flags; - Section.Reserved1 = Sect.Reserved1; - Section.Reserved2 = Sect.Reserved2; + MachO::section_64 Sect = Obj->getSection64(Sec); + Section.Address = Sect.addr; + Section.Size = Sect.size; + Section.Offset = Sect.offset; + Section.Alignment = Sect.align; + Section.RelocationTableOffset = Sect.reloff; + Section.NumRelocationTableEntries = Sect.nreloc; + Section.Flags = Sect.flags; + Section.Reserved1 = Sect.reserved1; + Section.Reserved2 = Sect.reserved2; } @@ -195,20 +195,20 @@ static void getSymbol(const MachOObjectFile *Obj, DataRefImpl DRI, MachOSymbol &Symbol) { if (!Obj->is64Bit()) { - macho::SymbolTableEntry Entry = Obj->getSymbolTableEntry(DRI); - Symbol.StringIndex = Entry.StringIndex; - Symbol.Type = Entry.Type; - Symbol.SectionIndex = Entry.SectionIndex; - Symbol.Flags = Entry.Flags; - Symbol.Value = Entry.Value; + MachO::nlist Entry = Obj->getSymbolTableEntry(DRI); + Symbol.StringIndex = Entry.n_strx; + Symbol.Type = Entry.n_type; + Symbol.SectionIndex = Entry.n_sect; + Symbol.Flags = Entry.n_desc; + Symbol.Value = Entry.n_value; return; } - macho::Symbol64TableEntry Entry = Obj->getSymbol64TableEntry(DRI); - Symbol.StringIndex = Entry.StringIndex; - Symbol.Type = Entry.Type; - Symbol.SectionIndex = Entry.SectionIndex; - Symbol.Flags = Entry.Flags; - Symbol.Value = Entry.Value; + MachO::nlist_64 Entry = Obj->getSymbol64TableEntry(DRI); + Symbol.StringIndex = Entry.n_strx; + Symbol.Type = Entry.n_type; + Symbol.SectionIndex = Entry.n_sect; + Symbol.Flags = Entry.n_desc; + Symbol.Value = Entry.n_value; } void MachODumper::printFileHeaders() { @@ -349,7 +349,7 @@ void MachODumper::printRelocation(const MachOObjectFile *Obj, return; DataRefImpl DR = RelI->getRawDataRefImpl(); - macho::RelocationEntry RE = Obj->getRelocation(DR); + MachO::any_relocation_info RE = Obj->getRelocation(DR); bool IsScattered = Obj->isRelocationScattered(RE); if (opts::ExpandRelocs) { diff --git a/tools/macho-dump/macho-dump.cpp b/tools/macho-dump/macho-dump.cpp index 897a785..7c0d66c 100644 --- a/tools/macho-dump/macho-dump.cpp +++ b/tools/macho-dump/macho-dump.cpp @@ -99,10 +99,10 @@ static int DumpSectionData(const MachOObjectFile &Obj, unsigned Index, error_code EC; for (relocation_iterator I = Obj.getSectionRelBegin(Index), E = Obj.getSectionRelEnd(Index); I != E; I.increment(EC), ++RelNum) { - macho::RelocationEntry RE = Obj.getRelocation(I->getRawDataRefImpl()); + MachO::any_relocation_info RE = Obj.getRelocation(I->getRawDataRefImpl()); outs() << " # Relocation " << RelNum << "\n"; - outs() << " (('word-0', " << format("0x%x", RE.Word0) << "),\n"; - outs() << " ('word-1', " << format("0x%x", RE.Word1) << ")),\n"; + outs() << " (('word-0', " << format("0x%x", RE.r_word0) << "),\n"; + outs() << " ('word-1', " << format("0x%x", RE.r_word1) << ")),\n"; } outs() << " ])\n"; @@ -124,23 +124,21 @@ static int DumpSectionData(const MachOObjectFile &Obj, unsigned Index, static int DumpSegmentCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &LCI) { - macho::SegmentLoadCommand SLC = Obj.getSegmentLoadCommand(LCI); + MachO::segment_command SLC = Obj.getSegmentLoadCommand(LCI); - DumpSegmentCommandData(StringRef(SLC.Name, 16), SLC.VMAddress, - SLC.VMSize, SLC.FileOffset, SLC.FileSize, - SLC.MaxVMProtection, SLC.InitialVMProtection, - SLC.NumSections, SLC.Flags); + DumpSegmentCommandData(StringRef(SLC.segname, 16), SLC.vmaddr, + SLC.vmsize, SLC.fileoff, SLC.filesize, + SLC.maxprot, SLC.initprot, SLC.nsects, SLC.flags); // Dump the sections. outs() << " ('sections', [\n"; - for (unsigned i = 0; i != SLC.NumSections; ++i) { - macho::Section Sect = Obj.getSection(LCI, i); - DumpSectionData(Obj, i, StringRef(Sect.Name, 16), - StringRef(Sect.SegmentName, 16), Sect.Address, - Sect.Size, Sect.Offset, Sect.Align, - Sect.RelocationTableOffset, - Sect.NumRelocationTableEntries, Sect.Flags, - Sect.Reserved1, Sect.Reserved2); + for (unsigned i = 0; i != SLC.nsects; ++i) { + MachO::section Sect = Obj.getSection(LCI, i); + DumpSectionData(Obj, i, StringRef(Sect.sectname, 16), + StringRef(Sect.segname, 16), Sect.addr, + Sect.size, Sect.offset, Sect.align, + Sect.reloff, Sect.nreloc, Sect.flags, + Sect.reserved1, Sect.reserved2); } outs() << " ])\n"; @@ -149,24 +147,22 @@ static int DumpSegmentCommand(const MachOObjectFile &Obj, static int DumpSegment64Command(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &LCI) { - macho::Segment64LoadCommand SLC = Obj.getSegment64LoadCommand(LCI); - DumpSegmentCommandData(StringRef(SLC.Name, 16), SLC.VMAddress, - SLC.VMSize, SLC.FileOffset, SLC.FileSize, - SLC.MaxVMProtection, SLC.InitialVMProtection, - SLC.NumSections, SLC.Flags); + MachO::segment_command_64 SLC = Obj.getSegment64LoadCommand(LCI); + DumpSegmentCommandData(StringRef(SLC.segname, 16), SLC.vmaddr, + SLC.vmsize, SLC.fileoff, SLC.filesize, + SLC.maxprot, SLC.initprot, SLC.nsects, SLC.flags); // Dump the sections. outs() << " ('sections', [\n"; - for (unsigned i = 0; i != SLC.NumSections; ++i) { - macho::Section64 Sect = Obj.getSection64(LCI, i); - - DumpSectionData(Obj, i, StringRef(Sect.Name, 16), - StringRef(Sect.SegmentName, 16), Sect.Address, - Sect.Size, Sect.Offset, Sect.Align, - Sect.RelocationTableOffset, - Sect.NumRelocationTableEntries, Sect.Flags, - Sect.Reserved1, Sect.Reserved2, - Sect.Reserved3); + for (unsigned i = 0; i != SLC.nsects; ++i) { + MachO::section_64 Sect = Obj.getSection64(LCI, i); + + DumpSectionData(Obj, i, StringRef(Sect.sectname, 16), + StringRef(Sect.segname, 16), Sect.addr, + Sect.size, Sect.offset, Sect.align, + Sect.reloff, Sect.nreloc, Sect.flags, + Sect.reserved1, Sect.reserved2, + Sect.reserved3); } outs() << " ])\n"; @@ -190,12 +186,12 @@ static void DumpSymbolTableEntryData(const MachOObjectFile &Obj, } static int DumpSymtabCommand(const MachOObjectFile &Obj) { - macho::SymtabLoadCommand SLC = Obj.getSymtabLoadCommand(); + MachO::symtab_command SLC = Obj.getSymtabLoadCommand(); - outs() << " ('symoff', " << SLC.SymbolTableOffset << ")\n"; - outs() << " ('nsyms', " << SLC.NumSymbolTableEntries << ")\n"; - outs() << " ('stroff', " << SLC.StringTableOffset << ")\n"; - outs() << " ('strsize', " << SLC.StringTableSize << ")\n"; + outs() << " ('symoff', " << SLC.symoff << ")\n"; + outs() << " ('nsyms', " << SLC.nsyms << ")\n"; + outs() << " ('stroff', " << SLC.stroff << ")\n"; + outs() << " ('strsize', " << SLC.strsize << ")\n"; // Dump the string data. outs() << " ('_string_data', '"; @@ -211,14 +207,14 @@ static int DumpSymtabCommand(const MachOObjectFile &Obj) { I.increment(EC), ++SymNum) { DataRefImpl DRI = I->getRawDataRefImpl(); if (Obj.is64Bit()) { - macho::Symbol64TableEntry STE = Obj.getSymbol64TableEntry(DRI); - DumpSymbolTableEntryData(Obj, SymNum, STE.StringIndex, STE.Type, - STE.SectionIndex, STE.Flags, STE.Value, + MachO::nlist_64 STE = Obj.getSymbol64TableEntry(DRI); + DumpSymbolTableEntryData(Obj, SymNum, STE.n_strx, STE.n_type, + STE.n_sect, STE.n_desc, STE.n_value, StringTable); } else { - macho::SymbolTableEntry STE = Obj.getSymbolTableEntry(DRI); - DumpSymbolTableEntryData(Obj, SymNum, STE.StringIndex, STE.Type, - STE.SectionIndex, STE.Flags, STE.Value, + MachO::nlist STE = Obj.getSymbolTableEntry(DRI); + DumpSymbolTableEntryData(Obj, SymNum, STE.n_strx, STE.n_type, + STE.n_sect, STE.n_desc, STE.n_value, StringTable); } } @@ -228,37 +224,33 @@ static int DumpSymtabCommand(const MachOObjectFile &Obj) { } static int DumpDysymtabCommand(const MachOObjectFile &Obj) { - macho::DysymtabLoadCommand DLC = Obj.getDysymtabLoadCommand(); - - outs() << " ('ilocalsym', " << DLC.LocalSymbolsIndex << ")\n"; - outs() << " ('nlocalsym', " << DLC.NumLocalSymbols << ")\n"; - outs() << " ('iextdefsym', " << DLC.ExternalSymbolsIndex << ")\n"; - outs() << " ('nextdefsym', " << DLC.NumExternalSymbols << ")\n"; - outs() << " ('iundefsym', " << DLC.UndefinedSymbolsIndex << ")\n"; - outs() << " ('nundefsym', " << DLC.NumUndefinedSymbols << ")\n"; - outs() << " ('tocoff', " << DLC.TOCOffset << ")\n"; - outs() << " ('ntoc', " << DLC.NumTOCEntries << ")\n"; - outs() << " ('modtaboff', " << DLC.ModuleTableOffset << ")\n"; - outs() << " ('nmodtab', " << DLC.NumModuleTableEntries << ")\n"; - outs() << " ('extrefsymoff', " << DLC.ReferenceSymbolTableOffset << ")\n"; - outs() << " ('nextrefsyms', " - << DLC.NumReferencedSymbolTableEntries << ")\n"; - outs() << " ('indirectsymoff', " << DLC.IndirectSymbolTableOffset << ")\n"; - outs() << " ('nindirectsyms', " - << DLC.NumIndirectSymbolTableEntries << ")\n"; - outs() << " ('extreloff', " << DLC.ExternalRelocationTableOffset << ")\n"; - outs() << " ('nextrel', " << DLC.NumExternalRelocationTableEntries << ")\n"; - outs() << " ('locreloff', " << DLC.LocalRelocationTableOffset << ")\n"; - outs() << " ('nlocrel', " << DLC.NumLocalRelocationTableEntries << ")\n"; + MachO::dysymtab_command DLC = Obj.getDysymtabLoadCommand(); + + outs() << " ('ilocalsym', " << DLC.ilocalsym << ")\n"; + outs() << " ('nlocalsym', " << DLC.nlocalsym << ")\n"; + outs() << " ('iextdefsym', " << DLC.iextdefsym << ")\n"; + outs() << " ('nextdefsym', " << DLC.nextdefsym << ")\n"; + outs() << " ('iundefsym', " << DLC.iundefsym << ")\n"; + outs() << " ('nundefsym', " << DLC.nundefsym << ")\n"; + outs() << " ('tocoff', " << DLC.tocoff << ")\n"; + outs() << " ('ntoc', " << DLC.ntoc << ")\n"; + outs() << " ('modtaboff', " << DLC.modtaboff << ")\n"; + outs() << " ('nmodtab', " << DLC.nmodtab << ")\n"; + outs() << " ('extrefsymoff', " << DLC.extrefsymoff << ")\n"; + outs() << " ('nextrefsyms', " << DLC.nextrefsyms << ")\n"; + outs() << " ('indirectsymoff', " << DLC.indirectsymoff << ")\n"; + outs() << " ('nindirectsyms', " << DLC.nindirectsyms << ")\n"; + outs() << " ('extreloff', " << DLC.extreloff << ")\n"; + outs() << " ('nextrel', " << DLC.nextrel << ")\n"; + outs() << " ('locreloff', " << DLC.locreloff << ")\n"; + outs() << " ('nlocrel', " << DLC.nlocrel << ")\n"; // Dump the indirect symbol table. outs() << " ('_indirect_symbols', [\n"; - for (unsigned i = 0; i != DLC.NumIndirectSymbolTableEntries; ++i) { - macho::IndirectSymbolTableEntry ISTE = - Obj.getIndirectSymbolTableEntry(DLC, i); + for (unsigned i = 0; i != DLC.nindirectsyms; ++i) { + uint32_t ISTE = Obj.getIndirectSymbolTableEntry(DLC, i); outs() << " # Indirect Symbol " << i << "\n"; - outs() << " (('symbol_index', " - << format("0x%x", ISTE.Index) << "),),\n"; + outs() << " (('symbol_index', " << format("0x%x", ISTE) << "),),\n"; } outs() << " ])\n"; @@ -268,13 +260,13 @@ static int DumpDysymtabCommand(const MachOObjectFile &Obj) { static int DumpLinkeditDataCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &LCI) { - macho::LinkeditDataLoadCommand LLC = Obj.getLinkeditDataLoadCommand(LCI); - outs() << " ('dataoff', " << LLC.DataOffset << ")\n" - << " ('datasize', " << LLC.DataSize << ")\n" + MachO::linkedit_data_command LLC = Obj.getLinkeditDataLoadCommand(LCI); + outs() << " ('dataoff', " << LLC.dataoff << ")\n" + << " ('datasize', " << LLC.datasize << ")\n" << " ('_addresses', [\n"; SmallVector Addresses; - Obj.ReadULEB128s(LLC.DataOffset, Addresses); + Obj.ReadULEB128s(LLC.dataoff, Addresses); for (unsigned i = 0, e = Addresses.size(); i != e; ++i) outs() << " # Address " << i << '\n' << " ('address', " << format("0x%x", Addresses[i]) << "),\n"; @@ -287,19 +279,18 @@ DumpLinkeditDataCommand(const MachOObjectFile &Obj, static int DumpDataInCodeDataCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &LCI) { - macho::LinkeditDataLoadCommand LLC = Obj.getLinkeditDataLoadCommand(LCI); - outs() << " ('dataoff', " << LLC.DataOffset << ")\n" - << " ('datasize', " << LLC.DataSize << ")\n" + MachO::linkedit_data_command LLC = Obj.getLinkeditDataLoadCommand(LCI); + outs() << " ('dataoff', " << LLC.dataoff << ")\n" + << " ('datasize', " << LLC.datasize << ")\n" << " ('_data_regions', [\n"; - unsigned NumRegions = LLC.DataSize / sizeof(macho::DataInCodeTableEntry); + unsigned NumRegions = LLC.datasize / sizeof(MachO::data_in_code_entry); for (unsigned i = 0; i < NumRegions; ++i) { - macho::DataInCodeTableEntry DICE = - Obj.getDataInCodeTableEntry(LLC.DataOffset, i); + MachO::data_in_code_entry DICE= Obj.getDataInCodeTableEntry(LLC.dataoff, i); outs() << " # DICE " << i << "\n" - << " ('offset', " << DICE.Offset << ")\n" - << " ('length', " << DICE.Length << ")\n" - << " ('kind', " << DICE.Kind << ")\n"; + << " ('offset', " << DICE.offset << ")\n" + << " ('length', " << DICE.length << ")\n" + << " ('kind', " << DICE.kind << ")\n"; } outs() <<" ])\n"; @@ -310,74 +301,84 @@ DumpDataInCodeDataCommand(const MachOObjectFile &Obj, static int DumpLinkerOptionsCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &LCI) { - macho::LinkerOptionsLoadCommand LOLC = Obj.getLinkerOptionsLoadCommand(LCI); - outs() << " ('count', " << LOLC.Count << ")\n" - << " ('_strings', [\n"; - - uint64_t DataSize = LOLC.Size - sizeof(macho::LinkerOptionsLoadCommand); - const char *P = LCI.Ptr + sizeof(macho::LinkerOptionsLoadCommand); - StringRef Data(P, DataSize); - for (unsigned i = 0; i != LOLC.Count; ++i) { - std::pair Split = Data.split('\0'); - outs() << "\t\""; - outs().write_escaped(Split.first); - outs() << "\",\n"; - Data = Split.second; - } - outs() <<" ])\n"; + MachO::linker_options_command LOLC = Obj.getLinkerOptionsLoadCommand(LCI); + outs() << " ('count', " << LOLC.count << ")\n" + << " ('_strings', [\n"; + + uint64_t DataSize = LOLC.cmdsize - sizeof(MachO::linker_options_command); + const char *P = LCI.Ptr + sizeof(MachO::linker_options_command); + StringRef Data(P, DataSize); + for (unsigned i = 0; i != LOLC.count; ++i) { + std::pair Split = Data.split('\0'); + outs() << "\t\""; + outs().write_escaped(Split.first); + outs() << "\",\n"; + Data = Split.second; + } + outs() <<" ])\n"; return 0; } static int DumpLoadCommand(const MachOObjectFile &Obj, MachOObjectFile::LoadCommandInfo &LCI) { - switch (LCI.C.Type) { - case macho::LCT_Segment: - return DumpSegmentCommand(Obj, LCI); - case macho::LCT_Segment64: - return DumpSegment64Command(Obj, LCI); - case macho::LCT_Symtab: - return DumpSymtabCommand(Obj); - case macho::LCT_Dysymtab: - return DumpDysymtabCommand(Obj); - case macho::LCT_CodeSignature: - case macho::LCT_SegmentSplitInfo: - case macho::LCT_FunctionStarts: - return DumpLinkeditDataCommand(Obj, LCI); - case macho::LCT_DataInCode: - return DumpDataInCodeDataCommand(Obj, LCI); - case macho::LCT_LinkerOptions: - return DumpLinkerOptionsCommand(Obj, LCI); + int Res; + switch (LCI.C.cmd) { + case MachO::LC_SEGMENT: + Res = DumpSegmentCommand(Obj, LCI); + break; + case MachO::LC_SEGMENT_64: + Res = DumpSegment64Command(Obj, LCI); + break; + case MachO::LC_SYMTAB: + Res = DumpSymtabCommand(Obj); + break; + case MachO::LC_DYSYMTAB: + Res = DumpDysymtabCommand(Obj); + break; + case MachO::LC_CODE_SIGNATURE: + case MachO::LC_SEGMENT_SPLIT_INFO: + case MachO::LC_FUNCTION_STARTS: + Res = DumpLinkeditDataCommand(Obj, LCI); + break; + case MachO::LC_DATA_IN_CODE: + Res = DumpDataInCodeDataCommand(Obj, LCI); + break; + case MachO::LC_LINKER_OPTIONS: + Res = DumpLinkerOptionsCommand(Obj, LCI); + break; default: - Warning("unknown load command: " + Twine(LCI.C.Type)); - return 0; + Warning("unknown load command: " + Twine(LCI.C.cmd)); + break; } + return Res; } static int DumpLoadCommand(const MachOObjectFile &Obj, unsigned Index, MachOObjectFile::LoadCommandInfo &LCI) { outs() << " # Load Command " << Index << "\n" - << " (('command', " << LCI.C.Type << ")\n" - << " ('size', " << LCI.C.Size << ")\n"; + << " (('command', " << LCI.C.cmd << ")\n" + << " ('size', " << LCI.C.cmdsize << ")\n"; int Res = DumpLoadCommand(Obj, LCI); outs() << " ),\n"; return Res; } static void printHeader(const MachOObjectFile *Obj, - const macho::Header &Header) { - outs() << "('cputype', " << Header.CPUType << ")\n"; - outs() << "('cpusubtype', " << Header.CPUSubtype << ")\n"; - outs() << "('filetype', " << Header.FileType << ")\n"; - outs() << "('num_load_commands', " << Header.NumLoadCommands << ")\n"; - outs() << "('load_commands_size', " << Header.SizeOfLoadCommands << ")\n"; - outs() << "('flag', " << Header.Flags << ")\n"; + const MachO::mach_header &Header) { + outs() << "('cputype', " << Header.cputype << ")\n"; + outs() << "('cpusubtype', " << Header.cpusubtype << ")\n"; + outs() << "('filetype', " << Header.filetype << ")\n"; + outs() << "('num_load_commands', " << Header.ncmds << ")\n"; + outs() << "('load_commands_size', " << Header.sizeofcmds << ")\n"; + outs() << "('flag', " << Header.flags << ")\n"; // Print extended header if 64-bit. if (Obj->is64Bit()) { - macho::Header64Ext Header64Ext = Obj->getHeader64Ext(); - outs() << "('reserved', " << Header64Ext.Reserved << ")\n"; + const MachO::mach_header_64 *Header64 = + reinterpret_cast(&Header); + outs() << "('reserved', " << Header64->reserved << ")\n"; } } @@ -396,8 +397,13 @@ int main(int argc, char **argv) { return Error("Not a MachO object"); // Print the header - macho::Header Header = InputObject->getHeader(); - printHeader(InputObject, Header); + MachO::mach_header_64 Header64; + MachO::mach_header *Header = reinterpret_cast(&Header64); + if (InputObject->is64Bit()) + Header64 = InputObject->getHeader64(); + else + *Header = InputObject->getHeader(); + printHeader(InputObject, *Header); // Print the load commands. int Res = 0; @@ -408,7 +414,7 @@ int main(int argc, char **argv) { if (DumpLoadCommand(*InputObject, i, Command)) break; - if (i == Header.NumLoadCommands - 1) + if (i == Header->ncmds - 1) break; Command = InputObject->getNextLoadCommandInfo(Command); } -- cgit v1.1 From 45fbe98c21d06448d1977e8abc95972f4ad86b26 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Tue, 27 Aug 2013 05:16:07 +0000 Subject: Fix the build broken by r189315. (this triggered Clang's -Wsometimes-uninitialized on the default path through the switch) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189319 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/macho-dump/macho-dump.cpp | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) (limited to 'tools') diff --git a/tools/macho-dump/macho-dump.cpp b/tools/macho-dump/macho-dump.cpp index 7c0d66c..7ae5440 100644 --- a/tools/macho-dump/macho-dump.cpp +++ b/tools/macho-dump/macho-dump.cpp @@ -322,36 +322,27 @@ DumpLinkerOptionsCommand(const MachOObjectFile &Obj, static int DumpLoadCommand(const MachOObjectFile &Obj, MachOObjectFile::LoadCommandInfo &LCI) { - int Res; switch (LCI.C.cmd) { case MachO::LC_SEGMENT: - Res = DumpSegmentCommand(Obj, LCI); - break; + return DumpSegmentCommand(Obj, LCI); case MachO::LC_SEGMENT_64: - Res = DumpSegment64Command(Obj, LCI); - break; + return DumpSegment64Command(Obj, LCI); case MachO::LC_SYMTAB: - Res = DumpSymtabCommand(Obj); - break; + return DumpSymtabCommand(Obj); case MachO::LC_DYSYMTAB: - Res = DumpDysymtabCommand(Obj); - break; + return DumpDysymtabCommand(Obj); case MachO::LC_CODE_SIGNATURE: case MachO::LC_SEGMENT_SPLIT_INFO: case MachO::LC_FUNCTION_STARTS: - Res = DumpLinkeditDataCommand(Obj, LCI); - break; + return DumpLinkeditDataCommand(Obj, LCI); case MachO::LC_DATA_IN_CODE: - Res = DumpDataInCodeDataCommand(Obj, LCI); - break; + return DumpDataInCodeDataCommand(Obj, LCI); case MachO::LC_LINKER_OPTIONS: - Res = DumpLinkerOptionsCommand(Obj, LCI); - break; + return DumpLinkerOptionsCommand(Obj, LCI); default: Warning("unknown load command: " + Twine(LCI.C.cmd)); - break; + return 0; } - return Res; } -- cgit v1.1 From f69a29b23a116a3520f185054290c445abf9aa62 Mon Sep 17 00:00:00 2001 From: Charles Davis Date: Tue, 27 Aug 2013 05:38:30 +0000 Subject: Revert "Fix the build broken by r189315." and "Move everything depending on Object/MachOFormat.h over to Support/MachO.h." This reverts commits r189319 and r189315. r189315 broke some tests on what I believe are big-endian platforms. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189321 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/MachODump.cpp | 31 +++-- tools/llvm-readobj/MachODumper.cpp | 66 +++++----- tools/macho-dump/macho-dump.cpp | 241 +++++++++++++++++++------------------ 3 files changed, 170 insertions(+), 168 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index e78c644..e0ec9cc 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -104,7 +104,7 @@ static void DumpDataInCode(const char *bytes, uint64_t Size, uint64_t Value; switch (Kind) { - case MachO::DICE_KIND_DATA: + case macho::Data: switch (Size) { case 4: Value = bytes[3] << 24 | @@ -125,16 +125,16 @@ static void DumpDataInCode(const char *bytes, uint64_t Size, } outs() << "\t@ KIND_DATA\n"; break; - case MachO::DICE_KIND_JUMP_TABLE8: + case macho::JumpTable8: Value = bytes[0]; outs() << "\t.byte " << Value << "\t@ KIND_JUMP_TABLE8"; break; - case MachO::DICE_KIND_JUMP_TABLE16: + case macho::JumpTable16: Value = bytes[1] << 8 | bytes[0]; outs() << "\t.short " << Value << "\t@ KIND_JUMP_TABLE16"; break; - case MachO::DICE_KIND_JUMP_TABLE32: + case macho::JumpTable32: Value = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | @@ -148,7 +148,7 @@ static void DumpDataInCode(const char *bytes, uint64_t Size, } static void -getSectionsAndSymbols(const MachO::mach_header Header, +getSectionsAndSymbols(const macho::Header Header, MachOObjectFile *MachOObj, std::vector &Sections, std::vector &Symbols, @@ -171,26 +171,25 @@ getSectionsAndSymbols(const MachO::mach_header Header, MachOObj->getFirstLoadCommandInfo(); bool BaseSegmentAddressSet = false; for (unsigned i = 0; ; ++i) { - if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) { + if (Command.C.Type == macho::LCT_FunctionStarts) { // We found a function starts segment, parse the addresses for later // consumption. - MachO::linkedit_data_command LLC = + macho::LinkeditDataLoadCommand LLC = MachOObj->getLinkeditDataLoadCommand(Command); - MachOObj->ReadULEB128s(LLC.dataoff, FoundFns); + MachOObj->ReadULEB128s(LLC.DataOffset, FoundFns); } - else if (Command.C.cmd == MachO::LC_SEGMENT || - Command.C.cmd == MachO::LC_SEGMENT_64) { - MachO::segment_command SLC = + else if (Command.C.Type == macho::LCT_Segment) { + macho::SegmentLoadCommand SLC = MachOObj->getSegmentLoadCommand(Command); - StringRef SegName = SLC.segname; + StringRef SegName = SLC.Name; if(!BaseSegmentAddressSet && SegName != "__PAGEZERO") { BaseSegmentAddressSet = true; - BaseSegmentAddress = SLC.vmaddr; + BaseSegmentAddress = SLC.VMAddress; } } - if (i == Header.ncmds - 1) + if (i == Header.NumLoadCommands - 1) break; else Command = MachOObj->getNextLoadCommandInfo(Command); @@ -245,7 +244,7 @@ static void DisassembleInputMachO2(StringRef Filename, outs() << '\n' << Filename << ":\n\n"; - MachO::mach_header Header = MachOOF->getHeader(); + macho::Header Header = MachOOF->getHeader(); // FIXME: FoundFns isn't used anymore. Using symbols/LC_FUNCTION_STARTS to // determine function locations will eventually go in MCObjectDisassembler. @@ -268,7 +267,7 @@ static void DisassembleInputMachO2(StringRef Filename, // Build a data in code table that is sorted on by the address of each entry. uint64_t BaseAddress = 0; - if (Header.filetype == MachO::MH_OBJECT) + if (Header.FileType == macho::HFT_Object) Sections[0].getAddress(BaseAddress); else BaseAddress = BaseSegmentAddress; diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index e27a58a..8df6fd6 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -166,28 +166,28 @@ static void getSection(const MachOObjectFile *Obj, DataRefImpl Sec, MachOSection &Section) { if (!Obj->is64Bit()) { - MachO::section Sect = Obj->getSection(Sec); - Section.Address = Sect.addr; - Section.Size = Sect.size; - Section.Offset = Sect.offset; - Section.Alignment = Sect.align; - Section.RelocationTableOffset = Sect.reloff; - Section.NumRelocationTableEntries = Sect.nreloc; - Section.Flags = Sect.flags; - Section.Reserved1 = Sect.reserved1; - Section.Reserved2 = Sect.reserved2; + macho::Section Sect = Obj->getSection(Sec); + Section.Address = Sect.Address; + Section.Size = Sect.Size; + Section.Offset = Sect.Offset; + Section.Alignment = Sect.Align; + Section.RelocationTableOffset = Sect.RelocationTableOffset; + Section.NumRelocationTableEntries = Sect.NumRelocationTableEntries; + Section.Flags = Sect.Flags; + Section.Reserved1 = Sect.Reserved1; + Section.Reserved2 = Sect.Reserved2; return; } - MachO::section_64 Sect = Obj->getSection64(Sec); - Section.Address = Sect.addr; - Section.Size = Sect.size; - Section.Offset = Sect.offset; - Section.Alignment = Sect.align; - Section.RelocationTableOffset = Sect.reloff; - Section.NumRelocationTableEntries = Sect.nreloc; - Section.Flags = Sect.flags; - Section.Reserved1 = Sect.reserved1; - Section.Reserved2 = Sect.reserved2; + macho::Section64 Sect = Obj->getSection64(Sec); + Section.Address = Sect.Address; + Section.Size = Sect.Size; + Section.Offset = Sect.Offset; + Section.Alignment = Sect.Align; + Section.RelocationTableOffset = Sect.RelocationTableOffset; + Section.NumRelocationTableEntries = Sect.NumRelocationTableEntries; + Section.Flags = Sect.Flags; + Section.Reserved1 = Sect.Reserved1; + Section.Reserved2 = Sect.Reserved2; } @@ -195,20 +195,20 @@ static void getSymbol(const MachOObjectFile *Obj, DataRefImpl DRI, MachOSymbol &Symbol) { if (!Obj->is64Bit()) { - MachO::nlist Entry = Obj->getSymbolTableEntry(DRI); - Symbol.StringIndex = Entry.n_strx; - Symbol.Type = Entry.n_type; - Symbol.SectionIndex = Entry.n_sect; - Symbol.Flags = Entry.n_desc; - Symbol.Value = Entry.n_value; + macho::SymbolTableEntry Entry = Obj->getSymbolTableEntry(DRI); + Symbol.StringIndex = Entry.StringIndex; + Symbol.Type = Entry.Type; + Symbol.SectionIndex = Entry.SectionIndex; + Symbol.Flags = Entry.Flags; + Symbol.Value = Entry.Value; return; } - MachO::nlist_64 Entry = Obj->getSymbol64TableEntry(DRI); - Symbol.StringIndex = Entry.n_strx; - Symbol.Type = Entry.n_type; - Symbol.SectionIndex = Entry.n_sect; - Symbol.Flags = Entry.n_desc; - Symbol.Value = Entry.n_value; + macho::Symbol64TableEntry Entry = Obj->getSymbol64TableEntry(DRI); + Symbol.StringIndex = Entry.StringIndex; + Symbol.Type = Entry.Type; + Symbol.SectionIndex = Entry.SectionIndex; + Symbol.Flags = Entry.Flags; + Symbol.Value = Entry.Value; } void MachODumper::printFileHeaders() { @@ -349,7 +349,7 @@ void MachODumper::printRelocation(const MachOObjectFile *Obj, return; DataRefImpl DR = RelI->getRawDataRefImpl(); - MachO::any_relocation_info RE = Obj->getRelocation(DR); + macho::RelocationEntry RE = Obj->getRelocation(DR); bool IsScattered = Obj->isRelocationScattered(RE); if (opts::ExpandRelocs) { diff --git a/tools/macho-dump/macho-dump.cpp b/tools/macho-dump/macho-dump.cpp index 7ae5440..897a785 100644 --- a/tools/macho-dump/macho-dump.cpp +++ b/tools/macho-dump/macho-dump.cpp @@ -99,10 +99,10 @@ static int DumpSectionData(const MachOObjectFile &Obj, unsigned Index, error_code EC; for (relocation_iterator I = Obj.getSectionRelBegin(Index), E = Obj.getSectionRelEnd(Index); I != E; I.increment(EC), ++RelNum) { - MachO::any_relocation_info RE = Obj.getRelocation(I->getRawDataRefImpl()); + macho::RelocationEntry RE = Obj.getRelocation(I->getRawDataRefImpl()); outs() << " # Relocation " << RelNum << "\n"; - outs() << " (('word-0', " << format("0x%x", RE.r_word0) << "),\n"; - outs() << " ('word-1', " << format("0x%x", RE.r_word1) << ")),\n"; + outs() << " (('word-0', " << format("0x%x", RE.Word0) << "),\n"; + outs() << " ('word-1', " << format("0x%x", RE.Word1) << ")),\n"; } outs() << " ])\n"; @@ -124,21 +124,23 @@ static int DumpSectionData(const MachOObjectFile &Obj, unsigned Index, static int DumpSegmentCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &LCI) { - MachO::segment_command SLC = Obj.getSegmentLoadCommand(LCI); + macho::SegmentLoadCommand SLC = Obj.getSegmentLoadCommand(LCI); - DumpSegmentCommandData(StringRef(SLC.segname, 16), SLC.vmaddr, - SLC.vmsize, SLC.fileoff, SLC.filesize, - SLC.maxprot, SLC.initprot, SLC.nsects, SLC.flags); + DumpSegmentCommandData(StringRef(SLC.Name, 16), SLC.VMAddress, + SLC.VMSize, SLC.FileOffset, SLC.FileSize, + SLC.MaxVMProtection, SLC.InitialVMProtection, + SLC.NumSections, SLC.Flags); // Dump the sections. outs() << " ('sections', [\n"; - for (unsigned i = 0; i != SLC.nsects; ++i) { - MachO::section Sect = Obj.getSection(LCI, i); - DumpSectionData(Obj, i, StringRef(Sect.sectname, 16), - StringRef(Sect.segname, 16), Sect.addr, - Sect.size, Sect.offset, Sect.align, - Sect.reloff, Sect.nreloc, Sect.flags, - Sect.reserved1, Sect.reserved2); + for (unsigned i = 0; i != SLC.NumSections; ++i) { + macho::Section Sect = Obj.getSection(LCI, i); + DumpSectionData(Obj, i, StringRef(Sect.Name, 16), + StringRef(Sect.SegmentName, 16), Sect.Address, + Sect.Size, Sect.Offset, Sect.Align, + Sect.RelocationTableOffset, + Sect.NumRelocationTableEntries, Sect.Flags, + Sect.Reserved1, Sect.Reserved2); } outs() << " ])\n"; @@ -147,22 +149,24 @@ static int DumpSegmentCommand(const MachOObjectFile &Obj, static int DumpSegment64Command(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &LCI) { - MachO::segment_command_64 SLC = Obj.getSegment64LoadCommand(LCI); - DumpSegmentCommandData(StringRef(SLC.segname, 16), SLC.vmaddr, - SLC.vmsize, SLC.fileoff, SLC.filesize, - SLC.maxprot, SLC.initprot, SLC.nsects, SLC.flags); + macho::Segment64LoadCommand SLC = Obj.getSegment64LoadCommand(LCI); + DumpSegmentCommandData(StringRef(SLC.Name, 16), SLC.VMAddress, + SLC.VMSize, SLC.FileOffset, SLC.FileSize, + SLC.MaxVMProtection, SLC.InitialVMProtection, + SLC.NumSections, SLC.Flags); // Dump the sections. outs() << " ('sections', [\n"; - for (unsigned i = 0; i != SLC.nsects; ++i) { - MachO::section_64 Sect = Obj.getSection64(LCI, i); - - DumpSectionData(Obj, i, StringRef(Sect.sectname, 16), - StringRef(Sect.segname, 16), Sect.addr, - Sect.size, Sect.offset, Sect.align, - Sect.reloff, Sect.nreloc, Sect.flags, - Sect.reserved1, Sect.reserved2, - Sect.reserved3); + for (unsigned i = 0; i != SLC.NumSections; ++i) { + macho::Section64 Sect = Obj.getSection64(LCI, i); + + DumpSectionData(Obj, i, StringRef(Sect.Name, 16), + StringRef(Sect.SegmentName, 16), Sect.Address, + Sect.Size, Sect.Offset, Sect.Align, + Sect.RelocationTableOffset, + Sect.NumRelocationTableEntries, Sect.Flags, + Sect.Reserved1, Sect.Reserved2, + Sect.Reserved3); } outs() << " ])\n"; @@ -186,12 +190,12 @@ static void DumpSymbolTableEntryData(const MachOObjectFile &Obj, } static int DumpSymtabCommand(const MachOObjectFile &Obj) { - MachO::symtab_command SLC = Obj.getSymtabLoadCommand(); + macho::SymtabLoadCommand SLC = Obj.getSymtabLoadCommand(); - outs() << " ('symoff', " << SLC.symoff << ")\n"; - outs() << " ('nsyms', " << SLC.nsyms << ")\n"; - outs() << " ('stroff', " << SLC.stroff << ")\n"; - outs() << " ('strsize', " << SLC.strsize << ")\n"; + outs() << " ('symoff', " << SLC.SymbolTableOffset << ")\n"; + outs() << " ('nsyms', " << SLC.NumSymbolTableEntries << ")\n"; + outs() << " ('stroff', " << SLC.StringTableOffset << ")\n"; + outs() << " ('strsize', " << SLC.StringTableSize << ")\n"; // Dump the string data. outs() << " ('_string_data', '"; @@ -207,14 +211,14 @@ static int DumpSymtabCommand(const MachOObjectFile &Obj) { I.increment(EC), ++SymNum) { DataRefImpl DRI = I->getRawDataRefImpl(); if (Obj.is64Bit()) { - MachO::nlist_64 STE = Obj.getSymbol64TableEntry(DRI); - DumpSymbolTableEntryData(Obj, SymNum, STE.n_strx, STE.n_type, - STE.n_sect, STE.n_desc, STE.n_value, + macho::Symbol64TableEntry STE = Obj.getSymbol64TableEntry(DRI); + DumpSymbolTableEntryData(Obj, SymNum, STE.StringIndex, STE.Type, + STE.SectionIndex, STE.Flags, STE.Value, StringTable); } else { - MachO::nlist STE = Obj.getSymbolTableEntry(DRI); - DumpSymbolTableEntryData(Obj, SymNum, STE.n_strx, STE.n_type, - STE.n_sect, STE.n_desc, STE.n_value, + macho::SymbolTableEntry STE = Obj.getSymbolTableEntry(DRI); + DumpSymbolTableEntryData(Obj, SymNum, STE.StringIndex, STE.Type, + STE.SectionIndex, STE.Flags, STE.Value, StringTable); } } @@ -224,33 +228,37 @@ static int DumpSymtabCommand(const MachOObjectFile &Obj) { } static int DumpDysymtabCommand(const MachOObjectFile &Obj) { - MachO::dysymtab_command DLC = Obj.getDysymtabLoadCommand(); - - outs() << " ('ilocalsym', " << DLC.ilocalsym << ")\n"; - outs() << " ('nlocalsym', " << DLC.nlocalsym << ")\n"; - outs() << " ('iextdefsym', " << DLC.iextdefsym << ")\n"; - outs() << " ('nextdefsym', " << DLC.nextdefsym << ")\n"; - outs() << " ('iundefsym', " << DLC.iundefsym << ")\n"; - outs() << " ('nundefsym', " << DLC.nundefsym << ")\n"; - outs() << " ('tocoff', " << DLC.tocoff << ")\n"; - outs() << " ('ntoc', " << DLC.ntoc << ")\n"; - outs() << " ('modtaboff', " << DLC.modtaboff << ")\n"; - outs() << " ('nmodtab', " << DLC.nmodtab << ")\n"; - outs() << " ('extrefsymoff', " << DLC.extrefsymoff << ")\n"; - outs() << " ('nextrefsyms', " << DLC.nextrefsyms << ")\n"; - outs() << " ('indirectsymoff', " << DLC.indirectsymoff << ")\n"; - outs() << " ('nindirectsyms', " << DLC.nindirectsyms << ")\n"; - outs() << " ('extreloff', " << DLC.extreloff << ")\n"; - outs() << " ('nextrel', " << DLC.nextrel << ")\n"; - outs() << " ('locreloff', " << DLC.locreloff << ")\n"; - outs() << " ('nlocrel', " << DLC.nlocrel << ")\n"; + macho::DysymtabLoadCommand DLC = Obj.getDysymtabLoadCommand(); + + outs() << " ('ilocalsym', " << DLC.LocalSymbolsIndex << ")\n"; + outs() << " ('nlocalsym', " << DLC.NumLocalSymbols << ")\n"; + outs() << " ('iextdefsym', " << DLC.ExternalSymbolsIndex << ")\n"; + outs() << " ('nextdefsym', " << DLC.NumExternalSymbols << ")\n"; + outs() << " ('iundefsym', " << DLC.UndefinedSymbolsIndex << ")\n"; + outs() << " ('nundefsym', " << DLC.NumUndefinedSymbols << ")\n"; + outs() << " ('tocoff', " << DLC.TOCOffset << ")\n"; + outs() << " ('ntoc', " << DLC.NumTOCEntries << ")\n"; + outs() << " ('modtaboff', " << DLC.ModuleTableOffset << ")\n"; + outs() << " ('nmodtab', " << DLC.NumModuleTableEntries << ")\n"; + outs() << " ('extrefsymoff', " << DLC.ReferenceSymbolTableOffset << ")\n"; + outs() << " ('nextrefsyms', " + << DLC.NumReferencedSymbolTableEntries << ")\n"; + outs() << " ('indirectsymoff', " << DLC.IndirectSymbolTableOffset << ")\n"; + outs() << " ('nindirectsyms', " + << DLC.NumIndirectSymbolTableEntries << ")\n"; + outs() << " ('extreloff', " << DLC.ExternalRelocationTableOffset << ")\n"; + outs() << " ('nextrel', " << DLC.NumExternalRelocationTableEntries << ")\n"; + outs() << " ('locreloff', " << DLC.LocalRelocationTableOffset << ")\n"; + outs() << " ('nlocrel', " << DLC.NumLocalRelocationTableEntries << ")\n"; // Dump the indirect symbol table. outs() << " ('_indirect_symbols', [\n"; - for (unsigned i = 0; i != DLC.nindirectsyms; ++i) { - uint32_t ISTE = Obj.getIndirectSymbolTableEntry(DLC, i); + for (unsigned i = 0; i != DLC.NumIndirectSymbolTableEntries; ++i) { + macho::IndirectSymbolTableEntry ISTE = + Obj.getIndirectSymbolTableEntry(DLC, i); outs() << " # Indirect Symbol " << i << "\n"; - outs() << " (('symbol_index', " << format("0x%x", ISTE) << "),),\n"; + outs() << " (('symbol_index', " + << format("0x%x", ISTE.Index) << "),),\n"; } outs() << " ])\n"; @@ -260,13 +268,13 @@ static int DumpDysymtabCommand(const MachOObjectFile &Obj) { static int DumpLinkeditDataCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &LCI) { - MachO::linkedit_data_command LLC = Obj.getLinkeditDataLoadCommand(LCI); - outs() << " ('dataoff', " << LLC.dataoff << ")\n" - << " ('datasize', " << LLC.datasize << ")\n" + macho::LinkeditDataLoadCommand LLC = Obj.getLinkeditDataLoadCommand(LCI); + outs() << " ('dataoff', " << LLC.DataOffset << ")\n" + << " ('datasize', " << LLC.DataSize << ")\n" << " ('_addresses', [\n"; SmallVector Addresses; - Obj.ReadULEB128s(LLC.dataoff, Addresses); + Obj.ReadULEB128s(LLC.DataOffset, Addresses); for (unsigned i = 0, e = Addresses.size(); i != e; ++i) outs() << " # Address " << i << '\n' << " ('address', " << format("0x%x", Addresses[i]) << "),\n"; @@ -279,18 +287,19 @@ DumpLinkeditDataCommand(const MachOObjectFile &Obj, static int DumpDataInCodeDataCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &LCI) { - MachO::linkedit_data_command LLC = Obj.getLinkeditDataLoadCommand(LCI); - outs() << " ('dataoff', " << LLC.dataoff << ")\n" - << " ('datasize', " << LLC.datasize << ")\n" + macho::LinkeditDataLoadCommand LLC = Obj.getLinkeditDataLoadCommand(LCI); + outs() << " ('dataoff', " << LLC.DataOffset << ")\n" + << " ('datasize', " << LLC.DataSize << ")\n" << " ('_data_regions', [\n"; - unsigned NumRegions = LLC.datasize / sizeof(MachO::data_in_code_entry); + unsigned NumRegions = LLC.DataSize / sizeof(macho::DataInCodeTableEntry); for (unsigned i = 0; i < NumRegions; ++i) { - MachO::data_in_code_entry DICE= Obj.getDataInCodeTableEntry(LLC.dataoff, i); + macho::DataInCodeTableEntry DICE = + Obj.getDataInCodeTableEntry(LLC.DataOffset, i); outs() << " # DICE " << i << "\n" - << " ('offset', " << DICE.offset << ")\n" - << " ('length', " << DICE.length << ")\n" - << " ('kind', " << DICE.kind << ")\n"; + << " ('offset', " << DICE.Offset << ")\n" + << " ('length', " << DICE.Length << ")\n" + << " ('kind', " << DICE.Kind << ")\n"; } outs() <<" ])\n"; @@ -301,46 +310,46 @@ DumpDataInCodeDataCommand(const MachOObjectFile &Obj, static int DumpLinkerOptionsCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &LCI) { - MachO::linker_options_command LOLC = Obj.getLinkerOptionsLoadCommand(LCI); - outs() << " ('count', " << LOLC.count << ")\n" - << " ('_strings', [\n"; - - uint64_t DataSize = LOLC.cmdsize - sizeof(MachO::linker_options_command); - const char *P = LCI.Ptr + sizeof(MachO::linker_options_command); - StringRef Data(P, DataSize); - for (unsigned i = 0; i != LOLC.count; ++i) { - std::pair Split = Data.split('\0'); - outs() << "\t\""; - outs().write_escaped(Split.first); - outs() << "\",\n"; - Data = Split.second; - } - outs() <<" ])\n"; + macho::LinkerOptionsLoadCommand LOLC = Obj.getLinkerOptionsLoadCommand(LCI); + outs() << " ('count', " << LOLC.Count << ")\n" + << " ('_strings', [\n"; + + uint64_t DataSize = LOLC.Size - sizeof(macho::LinkerOptionsLoadCommand); + const char *P = LCI.Ptr + sizeof(macho::LinkerOptionsLoadCommand); + StringRef Data(P, DataSize); + for (unsigned i = 0; i != LOLC.Count; ++i) { + std::pair Split = Data.split('\0'); + outs() << "\t\""; + outs().write_escaped(Split.first); + outs() << "\",\n"; + Data = Split.second; + } + outs() <<" ])\n"; return 0; } static int DumpLoadCommand(const MachOObjectFile &Obj, MachOObjectFile::LoadCommandInfo &LCI) { - switch (LCI.C.cmd) { - case MachO::LC_SEGMENT: + switch (LCI.C.Type) { + case macho::LCT_Segment: return DumpSegmentCommand(Obj, LCI); - case MachO::LC_SEGMENT_64: + case macho::LCT_Segment64: return DumpSegment64Command(Obj, LCI); - case MachO::LC_SYMTAB: + case macho::LCT_Symtab: return DumpSymtabCommand(Obj); - case MachO::LC_DYSYMTAB: + case macho::LCT_Dysymtab: return DumpDysymtabCommand(Obj); - case MachO::LC_CODE_SIGNATURE: - case MachO::LC_SEGMENT_SPLIT_INFO: - case MachO::LC_FUNCTION_STARTS: + case macho::LCT_CodeSignature: + case macho::LCT_SegmentSplitInfo: + case macho::LCT_FunctionStarts: return DumpLinkeditDataCommand(Obj, LCI); - case MachO::LC_DATA_IN_CODE: + case macho::LCT_DataInCode: return DumpDataInCodeDataCommand(Obj, LCI); - case MachO::LC_LINKER_OPTIONS: + case macho::LCT_LinkerOptions: return DumpLinkerOptionsCommand(Obj, LCI); default: - Warning("unknown load command: " + Twine(LCI.C.cmd)); + Warning("unknown load command: " + Twine(LCI.C.Type)); return 0; } } @@ -349,27 +358,26 @@ static int DumpLoadCommand(const MachOObjectFile &Obj, static int DumpLoadCommand(const MachOObjectFile &Obj, unsigned Index, MachOObjectFile::LoadCommandInfo &LCI) { outs() << " # Load Command " << Index << "\n" - << " (('command', " << LCI.C.cmd << ")\n" - << " ('size', " << LCI.C.cmdsize << ")\n"; + << " (('command', " << LCI.C.Type << ")\n" + << " ('size', " << LCI.C.Size << ")\n"; int Res = DumpLoadCommand(Obj, LCI); outs() << " ),\n"; return Res; } static void printHeader(const MachOObjectFile *Obj, - const MachO::mach_header &Header) { - outs() << "('cputype', " << Header.cputype << ")\n"; - outs() << "('cpusubtype', " << Header.cpusubtype << ")\n"; - outs() << "('filetype', " << Header.filetype << ")\n"; - outs() << "('num_load_commands', " << Header.ncmds << ")\n"; - outs() << "('load_commands_size', " << Header.sizeofcmds << ")\n"; - outs() << "('flag', " << Header.flags << ")\n"; + const macho::Header &Header) { + outs() << "('cputype', " << Header.CPUType << ")\n"; + outs() << "('cpusubtype', " << Header.CPUSubtype << ")\n"; + outs() << "('filetype', " << Header.FileType << ")\n"; + outs() << "('num_load_commands', " << Header.NumLoadCommands << ")\n"; + outs() << "('load_commands_size', " << Header.SizeOfLoadCommands << ")\n"; + outs() << "('flag', " << Header.Flags << ")\n"; // Print extended header if 64-bit. if (Obj->is64Bit()) { - const MachO::mach_header_64 *Header64 = - reinterpret_cast(&Header); - outs() << "('reserved', " << Header64->reserved << ")\n"; + macho::Header64Ext Header64Ext = Obj->getHeader64Ext(); + outs() << "('reserved', " << Header64Ext.Reserved << ")\n"; } } @@ -388,13 +396,8 @@ int main(int argc, char **argv) { return Error("Not a MachO object"); // Print the header - MachO::mach_header_64 Header64; - MachO::mach_header *Header = reinterpret_cast(&Header64); - if (InputObject->is64Bit()) - Header64 = InputObject->getHeader64(); - else - *Header = InputObject->getHeader(); - printHeader(InputObject, *Header); + macho::Header Header = InputObject->getHeader(); + printHeader(InputObject, Header); // Print the load commands. int Res = 0; @@ -405,7 +408,7 @@ int main(int argc, char **argv) { if (DumpLoadCommand(*InputObject, i, Command)) break; - if (i == Header->ncmds - 1) + if (i == Header.NumLoadCommands - 1) break; Command = InputObject->getNextLoadCommandInfo(Command); } -- cgit v1.1 From 00c198042e22d781e46180a2aec2332945712552 Mon Sep 17 00:00:00 2001 From: Shuxin Yang Date: Tue, 27 Aug 2013 17:15:54 +0000 Subject: Revert 189297, the original commit message is following. ---- Add new API lto_codegen_compile_parallel(). This API is proposed by Nick Kledzik. The semantic is: -------------------------------------------------------------------------- Generate code for merged module into an array of native object files. On success returns a pointer to an array of NativeObjectFile. The count parameter returns the number of elements in the array. Each element is a pointer/length for a generated mach-o/ELF buffer. The buffer is owned by the lto_code_gen_t 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). extern const struct NativeObjectFile* lto_codegen_compile_parallel(lto_code_gen_t cg, size_t *count); --------------------------------------------------------------------------- This API is currently only called on OSX platform. Linux or other Unixes using GNU gold are not supposed to call this function, because on these systems, object files are fed back to linker via disk file instead of memory buffer. In this commit, lto_codegen_compile_parallel() simply calls lto_codegen_compile() to return a single object file. In the near future, this function is the entry point for compilation with partition. Linker can blindly call this function even if partition is turned off; in this case, compiler will return only one object file. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189386 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/LTOCodeGenerator.cpp | 20 +------------------- tools/lto/LTOCodeGenerator.h | 12 ------------ tools/lto/lto.cpp | 5 ----- tools/lto/lto.exports | 1 - 4 files changed, 1 insertion(+), 37 deletions(-) (limited to 'tools') diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index daeb964..3fe7af2 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -74,7 +74,7 @@ LTOCodeGenerator::LTOCodeGenerator() _linker(new Module("ld-temp.o", _context)), _target(NULL), _emitDwarfDebugInfo(false), _scopeRestrictionsDone(false), _codeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC), - _nativeObjectFile(NULL), ObjBufVect(0) { + _nativeObjectFile(NULL) { InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); @@ -85,7 +85,6 @@ LTOCodeGenerator::~LTOCodeGenerator() { delete _target; delete _nativeObjectFile; delete _linker.getModule(); - delete[] ObjBufVect; for (std::vector::iterator I = _codegenOptions.begin(), E = _codegenOptions.end(); I != E; ++I) @@ -247,23 +246,6 @@ const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg) { return _nativeObjectFile->getBufferStart(); } -// Currently compile() and compile_parallel() have no difference. -NativeObjectFile *LTOCodeGenerator::compile_parallel(size_t *count, - std::string &ErrMsg) { - assert(ObjBufVect == 0 && "Should be NULL"); - - size_t Len; - const void *Buf = compile(&Len, ErrMsg); - if (!Buf) - return 0; - - *count = 1; - ObjBufVect = new NativeObjectFile[1]; - ObjBufVect[0].content = Buf; - ObjBufVect[0].length = Len; - return ObjBufVect; -} - bool LTOCodeGenerator::determineTarget(std::string &errMsg) { if (_target != NULL) return true; diff --git a/tools/lto/LTOCodeGenerator.h b/tools/lto/LTOCodeGenerator.h index 21c6b21..8f37cf0 100644 --- a/tools/lto/LTOCodeGenerator.h +++ b/tools/lto/LTOCodeGenerator.h @@ -102,17 +102,6 @@ struct LTOCodeGenerator { // const void *compile(size_t *length, std::string &errMsg); - // Corresponding to lto_codegen_compile_parallel() API. - // Generates code for merged module into an array of native object files. - // On success returns a pointer to an array of NativeObjectFile. The count - // parameter returns the number of elements in the array. Each element is - // a pointer/length for a generated mach-o/ELF buffer. The buffer is owned - // by the lto_code_gen_t 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). - // - NativeObjectFile *compile_parallel(size_t *count, std::string &ErrMsg); - private: void initializeLTOPasses(); @@ -138,7 +127,6 @@ private: std::vector _codegenOptions; std::string _mCpu; std::string _nativeObjectPath; - NativeObjectFile *ObjBufVect; }; #endif // LTO_CODE_GENERATOR_H diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index bbb6071..db7147c 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -207,11 +207,6 @@ bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) { return !cg->compile_to_file(name, sLastErrorString); } -extern const struct NativeObjectFile * -lto_codegen_compile_parallel(lto_code_gen_t cg, size_t *count) { - return cg->compile_parallel(count, 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) { diff --git a/tools/lto/lto.exports b/tools/lto/lto.exports index 61f0817..46d0d74 100644 --- a/tools/lto/lto.exports +++ b/tools/lto/lto.exports @@ -28,7 +28,6 @@ lto_codegen_set_assembler_args lto_codegen_set_assembler_path lto_codegen_set_cpu lto_codegen_compile_to_file -lto_codegen_compile_parallel LLVMCreateDisasm LLVMCreateDisasmCPU LLVMDisasmDispose -- cgit v1.1 From 22d6eb8ca91f4ce8db6a9ce8e2663502ebcee0c2 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Tue, 27 Aug 2013 23:07:17 +0000 Subject: Add xml files for msbuild integration These files are intended to live in the msbuild toolset directory, which is somewhere like: C:\Program Files (x86)\MSBuild\Microsoft.Cpp\ v4.0\Platforms\Win32\PlatformToolsets\llvm More work is needed to install them as part of the NSIS installer. Patch by Warren Hunt! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189411 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/msbuild/Microsoft.Cpp.Win32.llvm.props | 10 ++++++++++ tools/msbuild/Microsoft.Cpp.Win32.llvm.targets | 2 ++ 2 files changed, 12 insertions(+) create mode 100644 tools/msbuild/Microsoft.Cpp.Win32.llvm.props create mode 100644 tools/msbuild/Microsoft.Cpp.Win32.llvm.targets (limited to 'tools') diff --git a/tools/msbuild/Microsoft.Cpp.Win32.llvm.props b/tools/msbuild/Microsoft.Cpp.Win32.llvm.props new file mode 100644 index 0000000..68dfa24 --- /dev/null +++ b/tools/msbuild/Microsoft.Cpp.Win32.llvm.props @@ -0,0 +1,10 @@ + + + suppress warning + suppress warning + + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\LLVM\LLVM 3.4.svn) + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\LLVM\LLVM 3.4.svn) + $(ClangInstallDir)\msbuild-bin;$(ExecutablePath) + + diff --git a/tools/msbuild/Microsoft.Cpp.Win32.llvm.targets b/tools/msbuild/Microsoft.Cpp.Win32.llvm.targets new file mode 100644 index 0000000..df41a84 --- /dev/null +++ b/tools/msbuild/Microsoft.Cpp.Win32.llvm.targets @@ -0,0 +1,2 @@ + + -- cgit v1.1 From 587e1939fa1bd2bcce764c6dc53263f9faa44ab9 Mon Sep 17 00:00:00 2001 From: Argyrios Kyrtzidis Date: Tue, 27 Aug 2013 23:27:56 +0000 Subject: [CMake] Put back the add_llvm_external_project() calls for specific projects. This allows setting-up the LLVM_EXTERNAL_* CMake variables that some people are using, e.g. to set the source directory of the project in a different place. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189415 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 8a635a5..1f15fc0 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -64,6 +64,10 @@ endif() add_llvm_external_project(clang) if( NOT LLVM_INCLUDE_TOOLS STREQUAL "bootstrap-only" ) + add_llvm_external_project(lld) + add_llvm_external_project(lldb) + add_llvm_external_project(polly) + # Automatically add remaining sub-directories containing a 'CMakeLists.txt' # file as external projects. add_llvm_implicit_external_projects() -- cgit v1.1 From 110b5209d92f224050f2755539bda8f1d801f94b Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 28 Aug 2013 01:19:26 +0000 Subject: cmake: Add msbuild integration to the install This adds the msbuild integration files to the install, provides batch scripts for (un)installing it in a convenient way, and hooks up the nsis installer to run those scripts. Differential Revision: http://llvm-reviews.chandlerc.com/D1537 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189434 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/msbuild/CMakeLists.txt | 10 ++++++++++ tools/msbuild/install.bat | 34 ++++++++++++++++++++++++++++++++++ tools/msbuild/uninstall.bat | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+) create mode 100644 tools/msbuild/CMakeLists.txt create mode 100644 tools/msbuild/install.bat create mode 100644 tools/msbuild/uninstall.bat (limited to 'tools') diff --git a/tools/msbuild/CMakeLists.txt b/tools/msbuild/CMakeLists.txt new file mode 100644 index 0000000..a1dca8a --- /dev/null +++ b/tools/msbuild/CMakeLists.txt @@ -0,0 +1,10 @@ +if (WIN32) + install(DIRECTORY . + DESTINATION tools/msbuild + FILES_MATCHING + PATTERN "*.targets" + PATTERN "*.props" + PATTERN "*.bat" + PATTERN ".svn" EXCLUDE + ) +endif() diff --git a/tools/msbuild/install.bat b/tools/msbuild/install.bat new file mode 100644 index 0000000..db11c86 --- /dev/null +++ b/tools/msbuild/install.bat @@ -0,0 +1,34 @@ +@echo off + +echo Installing MSVC integration... + +REM Change to the directory of this batch file. +cd /d %~dp0 + +REM Search for the MSBuild toolsets directory. +SET D="%ProgramFiles%\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\PlatformToolsets" +IF EXIST %D% GOTO FOUND_MSBUILD +SET D="%ProgramFiles(x86)%\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\PlatformToolsets" +IF EXIST %D% GOTO FOUND_MSBUILD + +echo Failed to find MSBuild toolsets directory. +goto FAILED + +:FOUND_MSBUILD +IF NOT EXIST %D%\llvm mkdir %D%\llvm +IF NOT %ERRORLEVEL% == 0 GOTO FAILED + +copy Microsoft.Cpp.Win32.llvm.props %D%\llvm +IF NOT %ERRORLEVEL% == 0 GOTO FAILED +copy Microsoft.Cpp.Win32.llvm.targets %D%\llvm +IF NOT %ERRORLEVEL% == 0 GOTO FAILED + +echo Done! +goto END + +:FAILED +echo MSVC integration install failed. +pause +goto END + +:END diff --git a/tools/msbuild/uninstall.bat b/tools/msbuild/uninstall.bat new file mode 100644 index 0000000..8bc304e --- /dev/null +++ b/tools/msbuild/uninstall.bat @@ -0,0 +1,34 @@ +@echo off + +echo Uninstalling MSVC integration... + +REM CD to the directory of this batch file. +cd /d %~dp0 + +REM Search for the MSBuild toolsets directory. +SET D="%ProgramFiles%\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\PlatformToolsets" +IF EXIST %D% GOTO FOUND_MSBUILD +SET D="%ProgramFiles(x86)%\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\PlatformToolsets" +IF EXIST %D% GOTO FOUND_MSBUILD + +echo Failed to find MSBuild toolsets directory. +goto FAILED + +:FOUND_MSBUILD + +del %D%\llvm\Microsoft.Cpp.Win32.llvm.props +IF NOT %ERRORLEVEL% == 0 GOTO FAILED +del %D%\llvm\Microsoft.Cpp.Win32.llvm.targets +IF NOT %ERRORLEVEL% == 0 GOTO FAILED +rmdir %D%\llvm +IF NOT %ERRORLEVEL% == 0 GOTO FAILED + +echo Done! +goto END + +:FAILED +echo MSVC integration uninstall failed. +pause +goto END + +:END -- cgit v1.1 From aeb0f0cdd28011a34be3772bb7a77292eaf18f9c Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 28 Aug 2013 16:22:16 +0000 Subject: Add a minimal implementation of ranlib. This is just enough to get "llvm-ranlib foo.a" working and tested. Making llvm-ranlib a symbolic link to llvm-ar doesn't work so well with llvm's option parsing, but ar's option parsing is mostly custom anyway. This patch also removes the -X32_64 option. Looks like it was just added in r10297 as part of implementing the current command line parsing. I can add it back (with a test) if someone really has AIX portability problems without it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189489 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-ar/CMakeLists.txt | 18 ++++++++++++++++ tools/llvm-ar/Makefile | 1 + tools/llvm-ar/llvm-ar.cpp | 50 ++++++++++++++++++++++++++++++++------------ 3 files changed, 56 insertions(+), 13 deletions(-) (limited to 'tools') diff --git a/tools/llvm-ar/CMakeLists.txt b/tools/llvm-ar/CMakeLists.txt index 503999c..f15a1e2 100644 --- a/tools/llvm-ar/CMakeLists.txt +++ b/tools/llvm-ar/CMakeLists.txt @@ -4,4 +4,22 @@ add_llvm_tool(llvm-ar llvm-ar.cpp ) +# FIXME: this is duplicated from the clang CMakeLists.txt +# FIXME: bin/llvm-ranlib is not a valid build target with this setup (pr17024) + +if(UNIX) + set(LLVM_LINK_OR_COPY create_symlink) + set(llvm_ar_binary "llvm-ar${CMAKE_EXECUTABLE_SUFFIX}") +else() + set(LLVM_LINK_OR_COPY copy) + set(llvm_ar_binary "${LLVM_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/llvm-ar${CMAKE_EXECUTABLE_SUFFIX}") +endif() + +set(llvm_ranlib "${LLVM_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/llvm-ranlib${CMAKE_EXECUTABLE_SUFFIX}") +add_custom_command(TARGET llvm-ar POST_BUILD + COMMAND ${CMAKE_COMMAND} -E ${LLVM_LINK_OR_COPY} "${llvm_ar_binary}" "${llvm_ranlib}") + +set_property(DIRECTORY APPEND + PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${llvm_ranlib}) + # TODO: Support check-local. diff --git a/tools/llvm-ar/Makefile b/tools/llvm-ar/Makefile index 15fb090..16a8283 100644 --- a/tools/llvm-ar/Makefile +++ b/tools/llvm-ar/Makefile @@ -9,6 +9,7 @@ LEVEL := ../.. TOOLNAME := llvm-ar +TOOLALIAS = llvm-ranlib LINK_COMPONENTS := bitreader support object # This tool has no plugins, optimize startup time. diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp index 6026fa7..f47b0a6 100644 --- a/tools/llvm-ar/llvm-ar.cpp +++ b/tools/llvm-ar/llvm-ar.cpp @@ -63,20 +63,13 @@ static void failIfError(error_code EC, Twine Context = "") { fail(Context + ": " + EC.message()); } -// Option for compatibility with AIX, not used but must allow it to be present. -static cl::opt -X32Option ("X32_64", cl::Hidden, - cl::desc("Ignored option for compatibility with AIX")); - -// llvm-ar operation code and modifier flags. This must come first. -static cl::opt -Options(cl::Positional, cl::Required, cl::desc("{operation}[modifiers]...")); - -// llvm-ar remaining positional arguments. +// llvm-ar/llvm-ranlib remaining positional arguments. static cl::list RestOfArgs(cl::Positional, cl::OneOrMore, cl::desc("[relpos] [count] [members]...")); +std::string Options; + // MoreHelp - Provide additional help output explaining the operations and // modifiers of llvm-ar. This object instructs the CommandLine library // to print the text of the constructor when the --help option is given. @@ -156,6 +149,13 @@ static void getRelPos() { RestOfArgs.erase(RestOfArgs.begin()); } +static void getOptions() { + if(RestOfArgs.size() == 0) + show_help("Expected options"); + Options = RestOfArgs[0]; + RestOfArgs.erase(RestOfArgs.begin()); +} + // getArchive - Get the archive file name from the command line static void getArchive() { if(RestOfArgs.size() == 0) @@ -175,6 +175,7 @@ static void getMembers() { // operation specified. Process all modifiers and check to make sure that // constraints on modifier/operation pairs have not been violated. static ArchiveOperation parseCommandLine() { + getOptions(); // Keep track of number of operations. We can only specify one // per execution. @@ -857,6 +858,9 @@ static void performOperation(ArchiveOperation Operation, llvm_unreachable("Unknown operation."); } +static int ar_main(char **argv); +static int ranlib_main(); + // main - main program for llvm-ar .. see comments in the code int main(int argc, char **argv) { ToolName = argv[0]; @@ -872,15 +876,35 @@ int main(int argc, char **argv) { " This program archives bitcode files into single libraries\n" ); + if (ToolName.endswith("ar")) + return ar_main(argv); + if (ToolName.endswith("ranlib")) + return ranlib_main(); + fail("Not ranlib or ar!"); +} + +static int performOperation(ArchiveOperation Operation); + +int ranlib_main() { + if (RestOfArgs.size() != 1) + fail(ToolName + "takes just one archive as argument"); + ArchiveName = RestOfArgs[0]; + return performOperation(CreateSymTab); +} + +int ar_main(char **argv) { // Do our own parsing of the command line because the CommandLine utility // can't handle the grouped positional parameters without a dash. ArchiveOperation Operation = parseCommandLine(); + return performOperation(Operation); +} +static int performOperation(ArchiveOperation Operation) { // Create or open the archive object. OwningPtr Buf; error_code EC = MemoryBuffer::getFile(ArchiveName, Buf, -1, false); if (EC && EC != llvm::errc::no_such_file_or_directory) { - errs() << argv[0] << ": error opening '" << ArchiveName + errs() << ToolName << ": error opening '" << ArchiveName << "': " << EC.message() << "!\n"; return 1; } @@ -889,7 +913,7 @@ int main(int argc, char **argv) { object::Archive Archive(Buf.take(), EC); if (EC) { - errs() << argv[0] << ": error loading '" << ArchiveName + errs() << ToolName << ": error loading '" << ArchiveName << "': " << EC.message() << "!\n"; return 1; } @@ -904,7 +928,7 @@ int main(int argc, char **argv) { } else { if (!Create) { // Produce a warning if we should and we're creating the archive - errs() << argv[0] << ": creating " << ArchiveName << "\n"; + errs() << ToolName << ": creating " << ArchiveName << "\n"; } } -- cgit v1.1 From cfe7a7c7e3846aa5548cb9cbcbd8fbf5c9c0b751 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Wed, 28 Aug 2013 17:04:06 +0000 Subject: cmake: Prevent semicolon separated lists in llvm-config (PR17020) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189491 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-config/CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/llvm-config/CMakeLists.txt b/tools/llvm-config/CMakeLists.txt index d17a19e..c651833 100644 --- a/tools/llvm-config/CMakeLists.txt +++ b/tools/llvm-config/CMakeLists.txt @@ -8,6 +8,7 @@ get_system_libs(LLVM_SYSTEM_LIBS_LIST) foreach(l ${LLVM_SYSTEM_LIBS_LIST}) set(SYSTEM_LIBS ${SYSTEM_LIBS} "-l${l}") endforeach() +string(REPLACE ";" " " SYSTEM_LIBS "${SYSTEM_LIBS}") # Use configure_file to create BuildVariables.inc. set(LLVM_SRC_ROOT ${LLVM_MAIN_SRC_DIR}) @@ -18,7 +19,7 @@ set(LLVM_CXXFLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_ set(LLVM_LDFLAGS ${CMAKE_SHARED_LINKER_FLAGS}) set(LLVM_BUILDMODE ${CMAKE_BUILD_TYPE}) set(LLVM_SYSTEM_LIBS ${SYSTEM_LIBS}) -set(LLVM_TARGETS_BUILT ${LLVM_TARGETS_TO_BUILD}) +string(REPLACE ";" " " LLVM_TARGETS_BUILT "${LLVM_TARGETS_TO_BUILD}") configure_file(${BUILDVARIABLES_SRCPATH} ${BUILDVARIABLES_OBJPATH} @ONLY) # Add the llvm-config tool. -- cgit v1.1 From 435798e96a64738b55a01055dde1bc9a88a15191 Mon Sep 17 00:00:00 2001 From: Hal Finkel Date: Wed, 28 Aug 2013 18:33:10 +0000 Subject: Disable unrolling in the loop vectorizer when disabled in the pass manager When unrolling is disabled in the pass manager, the loop vectorizer should also not unroll loops. This will allow the -fno-unroll-loops option in Clang to behave as expected (even for vectorizable loops). The loop vectorizer's -force-vector-unroll option will (continue to) override the pass-manager setting (including -force-vector-unroll=0 to force use of the internal auto-selection logic). In order to test this, I added a flag to opt (-disable-loop-unrolling) to force disable unrolling through opt (the analog of -fno-unroll-loops in Clang). Also, this fixes a small bug in opt where the loop vectorizer was enabled only after the pass manager populated the queue of passes (the global_alias.ll test needed a slight update to the RUN line as a result of this fix). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189499 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/opt/opt.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index ca82061..691080a 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -136,6 +136,11 @@ UnitAtATime("funit-at-a-time", cl::init(true)); static cl::opt +DisableLoopUnrolling("disable-loop-unrolling", + cl::desc("Disable loop unrolling in all relevant passes"), + cl::init(false)); + +static cl::opt DisableSimplifyLibCalls("disable-simplify-libcalls", cl::desc("Disable simplify-libcalls")); @@ -447,12 +452,13 @@ static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, Builder.Inliner = createAlwaysInlinerPass(); } Builder.DisableUnitAtATime = !UnitAtATime; - Builder.DisableUnrollLoops = OptLevel == 0; + Builder.DisableUnrollLoops = (DisableLoopUnrolling.getNumOccurrences() > 0) ? + DisableLoopUnrolling : OptLevel == 0; + Builder.LoopVectorize = OptLevel > 1 && SizeLevel < 2; + Builder.populateFunctionPassManager(FPM); Builder.populateModulePassManager(MPM); - - Builder.LoopVectorize = OptLevel > 1 && SizeLevel < 2; } static void AddStandardCompilePasses(PassManagerBase &PM) { -- cgit v1.1 From 98b5be8062d33bde9a963c00326ce2483db18f9f Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 28 Aug 2013 21:00:03 +0000 Subject: Fix name matching to work on windows. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189517 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-ar/llvm-ar.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp index f47b0a6..e56e49ad 100644 --- a/tools/llvm-ar/llvm-ar.cpp +++ b/tools/llvm-ar/llvm-ar.cpp @@ -876,9 +876,10 @@ int main(int argc, char **argv) { " This program archives bitcode files into single libraries\n" ); - if (ToolName.endswith("ar")) + StringRef Stem = sys::path::stem(ToolName); + if (Stem.endswith("ar")) return ar_main(argv); - if (ToolName.endswith("ranlib")) + if (Stem.endswith("ranlib")) return ranlib_main(); fail("Not ranlib or ar!"); } -- cgit v1.1 From 09174f8833a86766aad6bb0307352a7d9fe9e22b Mon Sep 17 00:00:00 2001 From: Warren Hunt Date: Wed, 28 Aug 2013 22:54:13 +0000 Subject: Adding VCIncludeDir and WindowsSDKDir to the msbuild configuration file. This allows clang to find windows.h and other files in the sdk and visutal studio includes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189528 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/msbuild/Microsoft.Cpp.Win32.llvm.props | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/msbuild/Microsoft.Cpp.Win32.llvm.props b/tools/msbuild/Microsoft.Cpp.Win32.llvm.props index 68dfa24..43164c9 100644 --- a/tools/msbuild/Microsoft.Cpp.Win32.llvm.props +++ b/tools/msbuild/Microsoft.Cpp.Win32.llvm.props @@ -1,10 +1,26 @@  - suppress warning - suppress warning + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\11.0\Setup\VC@ProductDir) + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\11.0\Setup\VC@ProductDir) + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VCExpress\11.0\Setup\VC@ProductDir) + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VCExpress\11.0\Setup\VC@ProductDir) + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0\Setup\VC@ProductDir) + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\Setup\VC@ProductDir) + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VCExpress\10.0\Setup\VC@ProductDir) + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VCExpress\10.0\Setup\VC@ProductDir) + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Setup\VC@ProductDir) + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\9.0\Setup\VC@ProductDir) + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VCExpress\9.0\Setup\VC@ProductDir) + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VCExpress\9.0\Setup\VC@ProductDir) + + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows@CurrentInstallFolder) + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows@CurrentInstallFolder) $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\LLVM\LLVM 3.4.svn) $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\LLVM\LLVM 3.4.svn) $(ClangInstallDir)\msbuild-bin;$(ExecutablePath) + + $(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSdkDir)include + $(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib -- cgit v1.1 From 6d3bbc05a79c5bfe1e7a17acb913d8d09c45b50b Mon Sep 17 00:00:00 2001 From: Warren Hunt Date: Thu, 29 Aug 2013 21:23:53 +0000 Subject: Modified ms-build configuration file to be version locked to the VS2010 toolchain, this avoids conflicts with having VS2012 and Win7SDK used at the same time. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189613 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/msbuild/Microsoft.Cpp.Win32.llvm.props | 21 ++------------------- 1 file changed, 2 insertions(+), 19 deletions(-) (limited to 'tools') diff --git a/tools/msbuild/Microsoft.Cpp.Win32.llvm.props b/tools/msbuild/Microsoft.Cpp.Win32.llvm.props index 43164c9..12938f4 100644 --- a/tools/msbuild/Microsoft.Cpp.Win32.llvm.props +++ b/tools/msbuild/Microsoft.Cpp.Win32.llvm.props @@ -1,26 +1,9 @@  - - $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\11.0\Setup\VC@ProductDir) - $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\11.0\Setup\VC@ProductDir) - $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VCExpress\11.0\Setup\VC@ProductDir) - $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VCExpress\11.0\Setup\VC@ProductDir) - $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0\Setup\VC@ProductDir) - $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\Setup\VC@ProductDir) - $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VCExpress\10.0\Setup\VC@ProductDir) - $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VCExpress\10.0\Setup\VC@ProductDir) - $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\9.0\Setup\VC@ProductDir) - $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\9.0\Setup\VC@ProductDir) - $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VCExpress\9.0\Setup\VC@ProductDir) - $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VCExpress\9.0\Setup\VC@ProductDir) + - $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SDKs\Windows@CurrentInstallFolder) - $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Microsoft SDKs\Windows@CurrentInstallFolder) - + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\LLVM\LLVM 3.4.svn) $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\LLVM\LLVM 3.4.svn) $(ClangInstallDir)\msbuild-bin;$(ExecutablePath) - - $(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSdkDir)include - $(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib -- cgit v1.1 From 002062b024c094279d4b0ed7db13a69159b2d8ba Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 29 Aug 2013 22:09:43 +0000 Subject: Substitute LLVM's version into the msbuild property file at config time Requires shuffling the CPack code up before add_subdirectory(tools), but that's where the version settings are anyway. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189615 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/msbuild/CMakeLists.txt | 8 +++++++- tools/msbuild/Microsoft.Cpp.Win32.llvm.props | 9 --------- tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in | 9 +++++++++ 3 files changed, 16 insertions(+), 10 deletions(-) delete mode 100644 tools/msbuild/Microsoft.Cpp.Win32.llvm.props create mode 100644 tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in (limited to 'tools') diff --git a/tools/msbuild/CMakeLists.txt b/tools/msbuild/CMakeLists.txt index a1dca8a..393b22a 100644 --- a/tools/msbuild/CMakeLists.txt +++ b/tools/msbuild/CMakeLists.txt @@ -1,9 +1,15 @@ if (WIN32) + set(prop_file "Microsoft.Cpp.Win32.llvm.props") + + # CPack will install a registry key in this format that we wish to reference. + set(REG_KEY "${CMAKE_PROJECT_NAME} ${CPACK_PACKAGE_VERSION}") + configure_file(${prop_file}.in ${prop_file}) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${prop_file}" DESTINATION tools/msbuild) + install(DIRECTORY . DESTINATION tools/msbuild FILES_MATCHING PATTERN "*.targets" - PATTERN "*.props" PATTERN "*.bat" PATTERN ".svn" EXCLUDE ) diff --git a/tools/msbuild/Microsoft.Cpp.Win32.llvm.props b/tools/msbuild/Microsoft.Cpp.Win32.llvm.props deleted file mode 100644 index 12938f4..0000000 --- a/tools/msbuild/Microsoft.Cpp.Win32.llvm.props +++ /dev/null @@ -1,9 +0,0 @@ - - - - - $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\LLVM\LLVM 3.4.svn) - $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\LLVM\LLVM 3.4.svn) - $(ClangInstallDir)\msbuild-bin;$(ExecutablePath) - - diff --git a/tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in b/tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in new file mode 100644 index 0000000..0f474c0 --- /dev/null +++ b/tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in @@ -0,0 +1,9 @@ + + + + + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\LLVM\@REG_KEY@) + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\LLVM\@REG_KEY@) + $(LLVMInstallDir)\msbuild-bin;$(ExecutablePath) + + -- cgit v1.1 From 5510728d28bb1ee04abc32da3d21b7df12948053 Mon Sep 17 00:00:00 2001 From: Charles Davis Date: Sun, 1 Sep 2013 04:28:48 +0000 Subject: Move everything depending on Object/MachOFormat.h over to Support/MachO.h. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189728 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/MachODump.cpp | 30 ++--- tools/llvm-readobj/MachODumper.cpp | 66 +++++----- tools/macho-dump/macho-dump.cpp | 241 ++++++++++++++++++------------------- 3 files changed, 167 insertions(+), 170 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index e0ec9cc..403be5a 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -104,7 +104,7 @@ static void DumpDataInCode(const char *bytes, uint64_t Size, uint64_t Value; switch (Kind) { - case macho::Data: + case MachO::DICE_KIND_DATA: switch (Size) { case 4: Value = bytes[3] << 24 | @@ -125,16 +125,16 @@ static void DumpDataInCode(const char *bytes, uint64_t Size, } outs() << "\t@ KIND_DATA\n"; break; - case macho::JumpTable8: + case MachO::DICE_KIND_JUMP_TABLE8: Value = bytes[0]; outs() << "\t.byte " << Value << "\t@ KIND_JUMP_TABLE8"; break; - case macho::JumpTable16: + case MachO::DICE_KIND_JUMP_TABLE16: Value = bytes[1] << 8 | bytes[0]; outs() << "\t.short " << Value << "\t@ KIND_JUMP_TABLE16"; break; - case macho::JumpTable32: + case MachO::DICE_KIND_JUMP_TABLE32: Value = bytes[3] << 24 | bytes[2] << 16 | bytes[1] << 8 | @@ -148,7 +148,7 @@ static void DumpDataInCode(const char *bytes, uint64_t Size, } static void -getSectionsAndSymbols(const macho::Header Header, +getSectionsAndSymbols(const MachO::mach_header Header, MachOObjectFile *MachOObj, std::vector &Sections, std::vector &Symbols, @@ -171,25 +171,25 @@ getSectionsAndSymbols(const macho::Header Header, MachOObj->getFirstLoadCommandInfo(); bool BaseSegmentAddressSet = false; for (unsigned i = 0; ; ++i) { - if (Command.C.Type == macho::LCT_FunctionStarts) { + if (Command.C.cmd == MachO::LC_FUNCTION_STARTS) { // We found a function starts segment, parse the addresses for later // consumption. - macho::LinkeditDataLoadCommand LLC = + MachO::linkedit_data_command LLC = MachOObj->getLinkeditDataLoadCommand(Command); - MachOObj->ReadULEB128s(LLC.DataOffset, FoundFns); + MachOObj->ReadULEB128s(LLC.dataoff, FoundFns); } - else if (Command.C.Type == macho::LCT_Segment) { - macho::SegmentLoadCommand SLC = + else if (Command.C.cmd == MachO::LC_SEGMENT) { + MachO::segment_command SLC = MachOObj->getSegmentLoadCommand(Command); - StringRef SegName = SLC.Name; + StringRef SegName = SLC.segname; if(!BaseSegmentAddressSet && SegName != "__PAGEZERO") { BaseSegmentAddressSet = true; - BaseSegmentAddress = SLC.VMAddress; + BaseSegmentAddress = SLC.vmaddr; } } - if (i == Header.NumLoadCommands - 1) + if (i == Header.ncmds - 1) break; else Command = MachOObj->getNextLoadCommandInfo(Command); @@ -244,7 +244,7 @@ static void DisassembleInputMachO2(StringRef Filename, outs() << '\n' << Filename << ":\n\n"; - macho::Header Header = MachOOF->getHeader(); + MachO::mach_header Header = MachOOF->getHeader(); // FIXME: FoundFns isn't used anymore. Using symbols/LC_FUNCTION_STARTS to // determine function locations will eventually go in MCObjectDisassembler. @@ -267,7 +267,7 @@ static void DisassembleInputMachO2(StringRef Filename, // Build a data in code table that is sorted on by the address of each entry. uint64_t BaseAddress = 0; - if (Header.FileType == macho::HFT_Object) + if (Header.filetype == MachO::MH_OBJECT) Sections[0].getAddress(BaseAddress); else BaseAddress = BaseSegmentAddress; diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index 8df6fd6..e27a58a 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -166,28 +166,28 @@ static void getSection(const MachOObjectFile *Obj, DataRefImpl Sec, MachOSection &Section) { if (!Obj->is64Bit()) { - macho::Section Sect = Obj->getSection(Sec); - Section.Address = Sect.Address; - Section.Size = Sect.Size; - Section.Offset = Sect.Offset; - Section.Alignment = Sect.Align; - Section.RelocationTableOffset = Sect.RelocationTableOffset; - Section.NumRelocationTableEntries = Sect.NumRelocationTableEntries; - Section.Flags = Sect.Flags; - Section.Reserved1 = Sect.Reserved1; - Section.Reserved2 = Sect.Reserved2; + MachO::section Sect = Obj->getSection(Sec); + Section.Address = Sect.addr; + Section.Size = Sect.size; + Section.Offset = Sect.offset; + Section.Alignment = Sect.align; + Section.RelocationTableOffset = Sect.reloff; + Section.NumRelocationTableEntries = Sect.nreloc; + Section.Flags = Sect.flags; + Section.Reserved1 = Sect.reserved1; + Section.Reserved2 = Sect.reserved2; return; } - macho::Section64 Sect = Obj->getSection64(Sec); - Section.Address = Sect.Address; - Section.Size = Sect.Size; - Section.Offset = Sect.Offset; - Section.Alignment = Sect.Align; - Section.RelocationTableOffset = Sect.RelocationTableOffset; - Section.NumRelocationTableEntries = Sect.NumRelocationTableEntries; - Section.Flags = Sect.Flags; - Section.Reserved1 = Sect.Reserved1; - Section.Reserved2 = Sect.Reserved2; + MachO::section_64 Sect = Obj->getSection64(Sec); + Section.Address = Sect.addr; + Section.Size = Sect.size; + Section.Offset = Sect.offset; + Section.Alignment = Sect.align; + Section.RelocationTableOffset = Sect.reloff; + Section.NumRelocationTableEntries = Sect.nreloc; + Section.Flags = Sect.flags; + Section.Reserved1 = Sect.reserved1; + Section.Reserved2 = Sect.reserved2; } @@ -195,20 +195,20 @@ static void getSymbol(const MachOObjectFile *Obj, DataRefImpl DRI, MachOSymbol &Symbol) { if (!Obj->is64Bit()) { - macho::SymbolTableEntry Entry = Obj->getSymbolTableEntry(DRI); - Symbol.StringIndex = Entry.StringIndex; - Symbol.Type = Entry.Type; - Symbol.SectionIndex = Entry.SectionIndex; - Symbol.Flags = Entry.Flags; - Symbol.Value = Entry.Value; + MachO::nlist Entry = Obj->getSymbolTableEntry(DRI); + Symbol.StringIndex = Entry.n_strx; + Symbol.Type = Entry.n_type; + Symbol.SectionIndex = Entry.n_sect; + Symbol.Flags = Entry.n_desc; + Symbol.Value = Entry.n_value; return; } - macho::Symbol64TableEntry Entry = Obj->getSymbol64TableEntry(DRI); - Symbol.StringIndex = Entry.StringIndex; - Symbol.Type = Entry.Type; - Symbol.SectionIndex = Entry.SectionIndex; - Symbol.Flags = Entry.Flags; - Symbol.Value = Entry.Value; + MachO::nlist_64 Entry = Obj->getSymbol64TableEntry(DRI); + Symbol.StringIndex = Entry.n_strx; + Symbol.Type = Entry.n_type; + Symbol.SectionIndex = Entry.n_sect; + Symbol.Flags = Entry.n_desc; + Symbol.Value = Entry.n_value; } void MachODumper::printFileHeaders() { @@ -349,7 +349,7 @@ void MachODumper::printRelocation(const MachOObjectFile *Obj, return; DataRefImpl DR = RelI->getRawDataRefImpl(); - macho::RelocationEntry RE = Obj->getRelocation(DR); + MachO::any_relocation_info RE = Obj->getRelocation(DR); bool IsScattered = Obj->isRelocationScattered(RE); if (opts::ExpandRelocs) { diff --git a/tools/macho-dump/macho-dump.cpp b/tools/macho-dump/macho-dump.cpp index 897a785..7ae5440 100644 --- a/tools/macho-dump/macho-dump.cpp +++ b/tools/macho-dump/macho-dump.cpp @@ -99,10 +99,10 @@ static int DumpSectionData(const MachOObjectFile &Obj, unsigned Index, error_code EC; for (relocation_iterator I = Obj.getSectionRelBegin(Index), E = Obj.getSectionRelEnd(Index); I != E; I.increment(EC), ++RelNum) { - macho::RelocationEntry RE = Obj.getRelocation(I->getRawDataRefImpl()); + MachO::any_relocation_info RE = Obj.getRelocation(I->getRawDataRefImpl()); outs() << " # Relocation " << RelNum << "\n"; - outs() << " (('word-0', " << format("0x%x", RE.Word0) << "),\n"; - outs() << " ('word-1', " << format("0x%x", RE.Word1) << ")),\n"; + outs() << " (('word-0', " << format("0x%x", RE.r_word0) << "),\n"; + outs() << " ('word-1', " << format("0x%x", RE.r_word1) << ")),\n"; } outs() << " ])\n"; @@ -124,23 +124,21 @@ static int DumpSectionData(const MachOObjectFile &Obj, unsigned Index, static int DumpSegmentCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &LCI) { - macho::SegmentLoadCommand SLC = Obj.getSegmentLoadCommand(LCI); + MachO::segment_command SLC = Obj.getSegmentLoadCommand(LCI); - DumpSegmentCommandData(StringRef(SLC.Name, 16), SLC.VMAddress, - SLC.VMSize, SLC.FileOffset, SLC.FileSize, - SLC.MaxVMProtection, SLC.InitialVMProtection, - SLC.NumSections, SLC.Flags); + DumpSegmentCommandData(StringRef(SLC.segname, 16), SLC.vmaddr, + SLC.vmsize, SLC.fileoff, SLC.filesize, + SLC.maxprot, SLC.initprot, SLC.nsects, SLC.flags); // Dump the sections. outs() << " ('sections', [\n"; - for (unsigned i = 0; i != SLC.NumSections; ++i) { - macho::Section Sect = Obj.getSection(LCI, i); - DumpSectionData(Obj, i, StringRef(Sect.Name, 16), - StringRef(Sect.SegmentName, 16), Sect.Address, - Sect.Size, Sect.Offset, Sect.Align, - Sect.RelocationTableOffset, - Sect.NumRelocationTableEntries, Sect.Flags, - Sect.Reserved1, Sect.Reserved2); + for (unsigned i = 0; i != SLC.nsects; ++i) { + MachO::section Sect = Obj.getSection(LCI, i); + DumpSectionData(Obj, i, StringRef(Sect.sectname, 16), + StringRef(Sect.segname, 16), Sect.addr, + Sect.size, Sect.offset, Sect.align, + Sect.reloff, Sect.nreloc, Sect.flags, + Sect.reserved1, Sect.reserved2); } outs() << " ])\n"; @@ -149,24 +147,22 @@ static int DumpSegmentCommand(const MachOObjectFile &Obj, static int DumpSegment64Command(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &LCI) { - macho::Segment64LoadCommand SLC = Obj.getSegment64LoadCommand(LCI); - DumpSegmentCommandData(StringRef(SLC.Name, 16), SLC.VMAddress, - SLC.VMSize, SLC.FileOffset, SLC.FileSize, - SLC.MaxVMProtection, SLC.InitialVMProtection, - SLC.NumSections, SLC.Flags); + MachO::segment_command_64 SLC = Obj.getSegment64LoadCommand(LCI); + DumpSegmentCommandData(StringRef(SLC.segname, 16), SLC.vmaddr, + SLC.vmsize, SLC.fileoff, SLC.filesize, + SLC.maxprot, SLC.initprot, SLC.nsects, SLC.flags); // Dump the sections. outs() << " ('sections', [\n"; - for (unsigned i = 0; i != SLC.NumSections; ++i) { - macho::Section64 Sect = Obj.getSection64(LCI, i); - - DumpSectionData(Obj, i, StringRef(Sect.Name, 16), - StringRef(Sect.SegmentName, 16), Sect.Address, - Sect.Size, Sect.Offset, Sect.Align, - Sect.RelocationTableOffset, - Sect.NumRelocationTableEntries, Sect.Flags, - Sect.Reserved1, Sect.Reserved2, - Sect.Reserved3); + for (unsigned i = 0; i != SLC.nsects; ++i) { + MachO::section_64 Sect = Obj.getSection64(LCI, i); + + DumpSectionData(Obj, i, StringRef(Sect.sectname, 16), + StringRef(Sect.segname, 16), Sect.addr, + Sect.size, Sect.offset, Sect.align, + Sect.reloff, Sect.nreloc, Sect.flags, + Sect.reserved1, Sect.reserved2, + Sect.reserved3); } outs() << " ])\n"; @@ -190,12 +186,12 @@ static void DumpSymbolTableEntryData(const MachOObjectFile &Obj, } static int DumpSymtabCommand(const MachOObjectFile &Obj) { - macho::SymtabLoadCommand SLC = Obj.getSymtabLoadCommand(); + MachO::symtab_command SLC = Obj.getSymtabLoadCommand(); - outs() << " ('symoff', " << SLC.SymbolTableOffset << ")\n"; - outs() << " ('nsyms', " << SLC.NumSymbolTableEntries << ")\n"; - outs() << " ('stroff', " << SLC.StringTableOffset << ")\n"; - outs() << " ('strsize', " << SLC.StringTableSize << ")\n"; + outs() << " ('symoff', " << SLC.symoff << ")\n"; + outs() << " ('nsyms', " << SLC.nsyms << ")\n"; + outs() << " ('stroff', " << SLC.stroff << ")\n"; + outs() << " ('strsize', " << SLC.strsize << ")\n"; // Dump the string data. outs() << " ('_string_data', '"; @@ -211,14 +207,14 @@ static int DumpSymtabCommand(const MachOObjectFile &Obj) { I.increment(EC), ++SymNum) { DataRefImpl DRI = I->getRawDataRefImpl(); if (Obj.is64Bit()) { - macho::Symbol64TableEntry STE = Obj.getSymbol64TableEntry(DRI); - DumpSymbolTableEntryData(Obj, SymNum, STE.StringIndex, STE.Type, - STE.SectionIndex, STE.Flags, STE.Value, + MachO::nlist_64 STE = Obj.getSymbol64TableEntry(DRI); + DumpSymbolTableEntryData(Obj, SymNum, STE.n_strx, STE.n_type, + STE.n_sect, STE.n_desc, STE.n_value, StringTable); } else { - macho::SymbolTableEntry STE = Obj.getSymbolTableEntry(DRI); - DumpSymbolTableEntryData(Obj, SymNum, STE.StringIndex, STE.Type, - STE.SectionIndex, STE.Flags, STE.Value, + MachO::nlist STE = Obj.getSymbolTableEntry(DRI); + DumpSymbolTableEntryData(Obj, SymNum, STE.n_strx, STE.n_type, + STE.n_sect, STE.n_desc, STE.n_value, StringTable); } } @@ -228,37 +224,33 @@ static int DumpSymtabCommand(const MachOObjectFile &Obj) { } static int DumpDysymtabCommand(const MachOObjectFile &Obj) { - macho::DysymtabLoadCommand DLC = Obj.getDysymtabLoadCommand(); - - outs() << " ('ilocalsym', " << DLC.LocalSymbolsIndex << ")\n"; - outs() << " ('nlocalsym', " << DLC.NumLocalSymbols << ")\n"; - outs() << " ('iextdefsym', " << DLC.ExternalSymbolsIndex << ")\n"; - outs() << " ('nextdefsym', " << DLC.NumExternalSymbols << ")\n"; - outs() << " ('iundefsym', " << DLC.UndefinedSymbolsIndex << ")\n"; - outs() << " ('nundefsym', " << DLC.NumUndefinedSymbols << ")\n"; - outs() << " ('tocoff', " << DLC.TOCOffset << ")\n"; - outs() << " ('ntoc', " << DLC.NumTOCEntries << ")\n"; - outs() << " ('modtaboff', " << DLC.ModuleTableOffset << ")\n"; - outs() << " ('nmodtab', " << DLC.NumModuleTableEntries << ")\n"; - outs() << " ('extrefsymoff', " << DLC.ReferenceSymbolTableOffset << ")\n"; - outs() << " ('nextrefsyms', " - << DLC.NumReferencedSymbolTableEntries << ")\n"; - outs() << " ('indirectsymoff', " << DLC.IndirectSymbolTableOffset << ")\n"; - outs() << " ('nindirectsyms', " - << DLC.NumIndirectSymbolTableEntries << ")\n"; - outs() << " ('extreloff', " << DLC.ExternalRelocationTableOffset << ")\n"; - outs() << " ('nextrel', " << DLC.NumExternalRelocationTableEntries << ")\n"; - outs() << " ('locreloff', " << DLC.LocalRelocationTableOffset << ")\n"; - outs() << " ('nlocrel', " << DLC.NumLocalRelocationTableEntries << ")\n"; + MachO::dysymtab_command DLC = Obj.getDysymtabLoadCommand(); + + outs() << " ('ilocalsym', " << DLC.ilocalsym << ")\n"; + outs() << " ('nlocalsym', " << DLC.nlocalsym << ")\n"; + outs() << " ('iextdefsym', " << DLC.iextdefsym << ")\n"; + outs() << " ('nextdefsym', " << DLC.nextdefsym << ")\n"; + outs() << " ('iundefsym', " << DLC.iundefsym << ")\n"; + outs() << " ('nundefsym', " << DLC.nundefsym << ")\n"; + outs() << " ('tocoff', " << DLC.tocoff << ")\n"; + outs() << " ('ntoc', " << DLC.ntoc << ")\n"; + outs() << " ('modtaboff', " << DLC.modtaboff << ")\n"; + outs() << " ('nmodtab', " << DLC.nmodtab << ")\n"; + outs() << " ('extrefsymoff', " << DLC.extrefsymoff << ")\n"; + outs() << " ('nextrefsyms', " << DLC.nextrefsyms << ")\n"; + outs() << " ('indirectsymoff', " << DLC.indirectsymoff << ")\n"; + outs() << " ('nindirectsyms', " << DLC.nindirectsyms << ")\n"; + outs() << " ('extreloff', " << DLC.extreloff << ")\n"; + outs() << " ('nextrel', " << DLC.nextrel << ")\n"; + outs() << " ('locreloff', " << DLC.locreloff << ")\n"; + outs() << " ('nlocrel', " << DLC.nlocrel << ")\n"; // Dump the indirect symbol table. outs() << " ('_indirect_symbols', [\n"; - for (unsigned i = 0; i != DLC.NumIndirectSymbolTableEntries; ++i) { - macho::IndirectSymbolTableEntry ISTE = - Obj.getIndirectSymbolTableEntry(DLC, i); + for (unsigned i = 0; i != DLC.nindirectsyms; ++i) { + uint32_t ISTE = Obj.getIndirectSymbolTableEntry(DLC, i); outs() << " # Indirect Symbol " << i << "\n"; - outs() << " (('symbol_index', " - << format("0x%x", ISTE.Index) << "),),\n"; + outs() << " (('symbol_index', " << format("0x%x", ISTE) << "),),\n"; } outs() << " ])\n"; @@ -268,13 +260,13 @@ static int DumpDysymtabCommand(const MachOObjectFile &Obj) { static int DumpLinkeditDataCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &LCI) { - macho::LinkeditDataLoadCommand LLC = Obj.getLinkeditDataLoadCommand(LCI); - outs() << " ('dataoff', " << LLC.DataOffset << ")\n" - << " ('datasize', " << LLC.DataSize << ")\n" + MachO::linkedit_data_command LLC = Obj.getLinkeditDataLoadCommand(LCI); + outs() << " ('dataoff', " << LLC.dataoff << ")\n" + << " ('datasize', " << LLC.datasize << ")\n" << " ('_addresses', [\n"; SmallVector Addresses; - Obj.ReadULEB128s(LLC.DataOffset, Addresses); + Obj.ReadULEB128s(LLC.dataoff, Addresses); for (unsigned i = 0, e = Addresses.size(); i != e; ++i) outs() << " # Address " << i << '\n' << " ('address', " << format("0x%x", Addresses[i]) << "),\n"; @@ -287,19 +279,18 @@ DumpLinkeditDataCommand(const MachOObjectFile &Obj, static int DumpDataInCodeDataCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &LCI) { - macho::LinkeditDataLoadCommand LLC = Obj.getLinkeditDataLoadCommand(LCI); - outs() << " ('dataoff', " << LLC.DataOffset << ")\n" - << " ('datasize', " << LLC.DataSize << ")\n" + MachO::linkedit_data_command LLC = Obj.getLinkeditDataLoadCommand(LCI); + outs() << " ('dataoff', " << LLC.dataoff << ")\n" + << " ('datasize', " << LLC.datasize << ")\n" << " ('_data_regions', [\n"; - unsigned NumRegions = LLC.DataSize / sizeof(macho::DataInCodeTableEntry); + unsigned NumRegions = LLC.datasize / sizeof(MachO::data_in_code_entry); for (unsigned i = 0; i < NumRegions; ++i) { - macho::DataInCodeTableEntry DICE = - Obj.getDataInCodeTableEntry(LLC.DataOffset, i); + MachO::data_in_code_entry DICE= Obj.getDataInCodeTableEntry(LLC.dataoff, i); outs() << " # DICE " << i << "\n" - << " ('offset', " << DICE.Offset << ")\n" - << " ('length', " << DICE.Length << ")\n" - << " ('kind', " << DICE.Kind << ")\n"; + << " ('offset', " << DICE.offset << ")\n" + << " ('length', " << DICE.length << ")\n" + << " ('kind', " << DICE.kind << ")\n"; } outs() <<" ])\n"; @@ -310,46 +301,46 @@ DumpDataInCodeDataCommand(const MachOObjectFile &Obj, static int DumpLinkerOptionsCommand(const MachOObjectFile &Obj, const MachOObjectFile::LoadCommandInfo &LCI) { - macho::LinkerOptionsLoadCommand LOLC = Obj.getLinkerOptionsLoadCommand(LCI); - outs() << " ('count', " << LOLC.Count << ")\n" - << " ('_strings', [\n"; - - uint64_t DataSize = LOLC.Size - sizeof(macho::LinkerOptionsLoadCommand); - const char *P = LCI.Ptr + sizeof(macho::LinkerOptionsLoadCommand); - StringRef Data(P, DataSize); - for (unsigned i = 0; i != LOLC.Count; ++i) { - std::pair Split = Data.split('\0'); - outs() << "\t\""; - outs().write_escaped(Split.first); - outs() << "\",\n"; - Data = Split.second; - } - outs() <<" ])\n"; + MachO::linker_options_command LOLC = Obj.getLinkerOptionsLoadCommand(LCI); + outs() << " ('count', " << LOLC.count << ")\n" + << " ('_strings', [\n"; + + uint64_t DataSize = LOLC.cmdsize - sizeof(MachO::linker_options_command); + const char *P = LCI.Ptr + sizeof(MachO::linker_options_command); + StringRef Data(P, DataSize); + for (unsigned i = 0; i != LOLC.count; ++i) { + std::pair Split = Data.split('\0'); + outs() << "\t\""; + outs().write_escaped(Split.first); + outs() << "\",\n"; + Data = Split.second; + } + outs() <<" ])\n"; return 0; } static int DumpLoadCommand(const MachOObjectFile &Obj, MachOObjectFile::LoadCommandInfo &LCI) { - switch (LCI.C.Type) { - case macho::LCT_Segment: + switch (LCI.C.cmd) { + case MachO::LC_SEGMENT: return DumpSegmentCommand(Obj, LCI); - case macho::LCT_Segment64: + case MachO::LC_SEGMENT_64: return DumpSegment64Command(Obj, LCI); - case macho::LCT_Symtab: + case MachO::LC_SYMTAB: return DumpSymtabCommand(Obj); - case macho::LCT_Dysymtab: + case MachO::LC_DYSYMTAB: return DumpDysymtabCommand(Obj); - case macho::LCT_CodeSignature: - case macho::LCT_SegmentSplitInfo: - case macho::LCT_FunctionStarts: + case MachO::LC_CODE_SIGNATURE: + case MachO::LC_SEGMENT_SPLIT_INFO: + case MachO::LC_FUNCTION_STARTS: return DumpLinkeditDataCommand(Obj, LCI); - case macho::LCT_DataInCode: + case MachO::LC_DATA_IN_CODE: return DumpDataInCodeDataCommand(Obj, LCI); - case macho::LCT_LinkerOptions: + case MachO::LC_LINKER_OPTIONS: return DumpLinkerOptionsCommand(Obj, LCI); default: - Warning("unknown load command: " + Twine(LCI.C.Type)); + Warning("unknown load command: " + Twine(LCI.C.cmd)); return 0; } } @@ -358,26 +349,27 @@ static int DumpLoadCommand(const MachOObjectFile &Obj, static int DumpLoadCommand(const MachOObjectFile &Obj, unsigned Index, MachOObjectFile::LoadCommandInfo &LCI) { outs() << " # Load Command " << Index << "\n" - << " (('command', " << LCI.C.Type << ")\n" - << " ('size', " << LCI.C.Size << ")\n"; + << " (('command', " << LCI.C.cmd << ")\n" + << " ('size', " << LCI.C.cmdsize << ")\n"; int Res = DumpLoadCommand(Obj, LCI); outs() << " ),\n"; return Res; } static void printHeader(const MachOObjectFile *Obj, - const macho::Header &Header) { - outs() << "('cputype', " << Header.CPUType << ")\n"; - outs() << "('cpusubtype', " << Header.CPUSubtype << ")\n"; - outs() << "('filetype', " << Header.FileType << ")\n"; - outs() << "('num_load_commands', " << Header.NumLoadCommands << ")\n"; - outs() << "('load_commands_size', " << Header.SizeOfLoadCommands << ")\n"; - outs() << "('flag', " << Header.Flags << ")\n"; + const MachO::mach_header &Header) { + outs() << "('cputype', " << Header.cputype << ")\n"; + outs() << "('cpusubtype', " << Header.cpusubtype << ")\n"; + outs() << "('filetype', " << Header.filetype << ")\n"; + outs() << "('num_load_commands', " << Header.ncmds << ")\n"; + outs() << "('load_commands_size', " << Header.sizeofcmds << ")\n"; + outs() << "('flag', " << Header.flags << ")\n"; // Print extended header if 64-bit. if (Obj->is64Bit()) { - macho::Header64Ext Header64Ext = Obj->getHeader64Ext(); - outs() << "('reserved', " << Header64Ext.Reserved << ")\n"; + const MachO::mach_header_64 *Header64 = + reinterpret_cast(&Header); + outs() << "('reserved', " << Header64->reserved << ")\n"; } } @@ -396,8 +388,13 @@ int main(int argc, char **argv) { return Error("Not a MachO object"); // Print the header - macho::Header Header = InputObject->getHeader(); - printHeader(InputObject, Header); + MachO::mach_header_64 Header64; + MachO::mach_header *Header = reinterpret_cast(&Header64); + if (InputObject->is64Bit()) + Header64 = InputObject->getHeader64(); + else + *Header = InputObject->getHeader(); + printHeader(InputObject, *Header); // Print the load commands. int Res = 0; @@ -408,7 +405,7 @@ int main(int argc, char **argv) { if (DumpLoadCommand(*InputObject, i, Command)) break; - if (i == Header.NumLoadCommands - 1) + if (i == Header->ncmds - 1) break; Command = InputObject->getNextLoadCommandInfo(Command); } -- cgit v1.1 From bf2f2708e122d3a12bf300c0dec537da6dafae2b Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Mon, 2 Sep 2013 01:18:56 +0000 Subject: Added std:: qualifier to find() invocation Iterator of std::vector may be implemented as a raw pointer. In this case ADL does not find the find() function in the std namespace. For example, this is the case with STDCXX implementation of vector. Patch by Konstantin Tokarev. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189733 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/bugpoint/CrashDebugger.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/bugpoint/CrashDebugger.cpp b/tools/bugpoint/CrashDebugger.cpp index c8b4f6f..b90fc61 100644 --- a/tools/bugpoint/CrashDebugger.cpp +++ b/tools/bugpoint/CrashDebugger.cpp @@ -195,10 +195,10 @@ namespace { } bool ReduceCrashingFunctions::TestFuncs(std::vector &Funcs) { - - //if main isn't present, claim there is no problem - if (KeepMain && find(Funcs.begin(), Funcs.end(), - BD.getProgram()->getFunction("main")) == Funcs.end()) + // If main isn't present, claim there is no problem. + if (KeepMain && std::find(Funcs.begin(), Funcs.end(), + BD.getProgram()->getFunction("main")) == + Funcs.end()) return false; // Clone the program to try hacking it apart... -- cgit v1.1 From 6217187ff202cb919257abc32782faa35c29f5d9 Mon Sep 17 00:00:00 2001 From: Joerg Sonnenberger Date: Tue, 3 Sep 2013 17:13:53 +0000 Subject: Print string value for DT_RPATH and DT_RUNPATH. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189829 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/ELFDumper.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'tools') diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index e909ef8..502fe67 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -723,6 +723,10 @@ static void printValue(const ELFFile *O, uint64_t Type, uint64_t Value, case DT_SONAME: OS << "LibrarySoname (" << O->getDynamicString(Value) << ")"; break; + case DT_RPATH: + case DT_RUNPATH: + OS << O->getDynamicString(Value); + break; } } -- cgit v1.1 From 66efc63d87a371891cac3d1a2fab114a6ab0fa64 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 4 Sep 2013 17:44:24 +0000 Subject: Rename variables to match the style guide and clang-format. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189962 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/LTOCodeGenerator.cpp | 111 +++++++++++++++++++++-------------------- tools/lto/LTOCodeGenerator.h | 30 ++++++----- 2 files changed, 70 insertions(+), 71 deletions(-) (limited to 'tools') diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index 3fe7af2..e3e1ab3 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -70,11 +70,9 @@ const char* LTOCodeGenerator::getVersionString() { } LTOCodeGenerator::LTOCodeGenerator() - : _context(getGlobalContext()), - _linker(new Module("ld-temp.o", _context)), _target(NULL), - _emitDwarfDebugInfo(false), _scopeRestrictionsDone(false), - _codeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC), - _nativeObjectFile(NULL) { + : Context(getGlobalContext()), Linker(new Module("ld-temp.o", Context)), + TargetMach(NULL), EmitDwarfDebugInfo(false), ScopeRestrictionsDone(false), + CodeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC), NativeObjectFile(NULL) { InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); @@ -82,12 +80,13 @@ LTOCodeGenerator::LTOCodeGenerator() } LTOCodeGenerator::~LTOCodeGenerator() { - delete _target; - delete _nativeObjectFile; - delete _linker.getModule(); + delete TargetMach; + delete NativeObjectFile; + delete Linker.getModule(); - for (std::vector::iterator I = _codegenOptions.begin(), - E = _codegenOptions.end(); I != E; ++I) + for (std::vector::iterator I = CodegenOptions.begin(), + E = CodegenOptions.end(); + I != E; ++I) free(*I); } @@ -122,11 +121,11 @@ void LTOCodeGenerator::initializeLTOPasses() { } bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg) { - bool ret = _linker.linkInModule(mod->getLLVVMModule(), &errMsg); + bool ret = Linker.linkInModule(mod->getLLVVMModule(), &errMsg); const std::vector &undefs = mod->getAsmUndefinedRefs(); for (int i = 0, e = undefs.size(); i != e; ++i) - _asmUndefinedRefs[undefs[i]] = 1; + AsmUndefinedRefs[undefs[i]] = 1; return !ret; } @@ -134,11 +133,11 @@ bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg) { void LTOCodeGenerator::setDebugInfo(lto_debug_model debug) { switch (debug) { case LTO_DEBUG_MODEL_NONE: - _emitDwarfDebugInfo = false; + EmitDwarfDebugInfo = false; return; case LTO_DEBUG_MODEL_DWARF: - _emitDwarfDebugInfo = true; + EmitDwarfDebugInfo = true; return; } llvm_unreachable("Unknown debug format!"); @@ -149,7 +148,7 @@ void LTOCodeGenerator::setCodePICModel(lto_codegen_model model) { case LTO_CODEGEN_PIC_MODEL_STATIC: case LTO_CODEGEN_PIC_MODEL_DYNAMIC: case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC: - _codeModel = model; + CodeModel = model; return; } llvm_unreachable("Unknown PIC model!"); @@ -173,7 +172,7 @@ bool LTOCodeGenerator::writeMergedModules(const char *path, } // write bitcode to it - WriteBitcodeToFile(_linker.getModule(), Out.os()); + WriteBitcodeToFile(Linker.getModule(), Out.os()); Out.os().close(); if (Out.os().has_error()) { @@ -214,8 +213,8 @@ bool LTOCodeGenerator::compile_to_file(const char** name, std::string& errMsg) { return false; } - _nativeObjectPath = Filename.c_str(); - *name = _nativeObjectPath.c_str(); + NativeObjectPath = Filename.c_str(); + *name = NativeObjectPath.c_str(); return true; } @@ -225,37 +224,37 @@ const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg) { return NULL; // remove old buffer if compile() called twice - delete _nativeObjectFile; + delete NativeObjectFile; // read .o file into memory buffer OwningPtr BuffPtr; if (error_code ec = MemoryBuffer::getFile(name, BuffPtr, -1, false)) { errMsg = ec.message(); - sys::fs::remove(_nativeObjectPath); + sys::fs::remove(NativeObjectPath); return NULL; } - _nativeObjectFile = BuffPtr.take(); + NativeObjectFile = BuffPtr.take(); // remove temp files - sys::fs::remove(_nativeObjectPath); + sys::fs::remove(NativeObjectPath); // return buffer, unless error - if (_nativeObjectFile == NULL) + if (NativeObjectFile == NULL) return NULL; - *length = _nativeObjectFile->getBufferSize(); - return _nativeObjectFile->getBufferStart(); + *length = NativeObjectFile->getBufferSize(); + return NativeObjectFile->getBufferStart(); } bool LTOCodeGenerator::determineTarget(std::string &errMsg) { - if (_target != NULL) + if (TargetMach != NULL) return true; // if options were requested, set them - if (!_codegenOptions.empty()) - cl::ParseCommandLineOptions(_codegenOptions.size(), - const_cast(&_codegenOptions[0])); + if (!CodegenOptions.empty()) + cl::ParseCommandLineOptions(CodegenOptions.size(), + const_cast(&CodegenOptions[0])); - std::string TripleStr = _linker.getModule()->getTargetTriple(); + std::string TripleStr = Linker.getModule()->getTargetTriple(); if (TripleStr.empty()) TripleStr = sys::getDefaultTargetTriple(); llvm::Triple Triple(TripleStr); @@ -268,7 +267,7 @@ bool LTOCodeGenerator::determineTarget(std::string &errMsg) { // The relocation model is actually a static member of TargetMachine and // needs to be set before the TargetMachine is instantiated. Reloc::Model RelocModel = Reloc::Default; - switch (_codeModel) { + switch (CodeModel) { case LTO_CODEGEN_PIC_MODEL_STATIC: RelocModel = Reloc::Static; break; @@ -285,17 +284,17 @@ bool LTOCodeGenerator::determineTarget(std::string &errMsg) { Features.getDefaultSubtargetFeatures(Triple); std::string FeatureStr = Features.getString(); // Set a default CPU for Darwin triples. - if (_mCpu.empty() && Triple.isOSDarwin()) { + if (MCpu.empty() && Triple.isOSDarwin()) { if (Triple.getArch() == llvm::Triple::x86_64) - _mCpu = "core2"; + MCpu = "core2"; else if (Triple.getArch() == llvm::Triple::x86) - _mCpu = "yonah"; + MCpu = "yonah"; } TargetOptions Options; LTOModule::getTargetOptions(Options); - _target = march->createTargetMachine(TripleStr, _mCpu, FeatureStr, Options, - RelocModel, CodeModel::Default, - CodeGenOpt::Aggressive); + TargetMach = march->createTargetMachine(TripleStr, MCpu, FeatureStr, Options, + RelocModel, CodeModel::Default, + CodeGenOpt::Aggressive); return true; } @@ -309,9 +308,9 @@ applyRestriction(GlobalValue &GV, if (GV.isDeclaration()) return; - if (_mustPreserveSymbols.count(Buffer)) + if (MustPreserveSymbols.count(Buffer)) mustPreserveList.push_back(GV.getName().data()); - if (_asmUndefinedRefs.count(Buffer)) + if (AsmUndefinedRefs.count(Buffer)) asmUsed.insert(&GV); } @@ -327,16 +326,18 @@ static void findUsedValues(GlobalVariable *LLVMUsed, } void LTOCodeGenerator::applyScopeRestrictions() { - if (_scopeRestrictionsDone) return; - Module *mergedModule = _linker.getModule(); + if (ScopeRestrictionsDone) + return; + Module *mergedModule = Linker.getModule(); // Start off with a verification pass. PassManager passes; passes.add(createVerifierPass()); // mark which symbols can not be internalized - MCContext Context(_target->getMCAsmInfo(), _target->getRegisterInfo(), NULL); - Mangler mangler(Context, _target); + MCContext MContext(TargetMach->getMCAsmInfo(), TargetMach->getRegisterInfo(), + NULL); + Mangler mangler(MContext, TargetMach); std::vector mustPreserveList; SmallPtrSet asmUsed; @@ -357,7 +358,7 @@ void LTOCodeGenerator::applyScopeRestrictions() { LLVMCompilerUsed->eraseFromParent(); if (!asmUsed.empty()) { - llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(_context); + llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(Context); std::vector asmUsed2; for (SmallPtrSet::const_iterator i = asmUsed.begin(), e = asmUsed.end(); i !=e; ++i) { @@ -381,7 +382,7 @@ void LTOCodeGenerator::applyScopeRestrictions() { // apply scope restrictions passes.run(*mergedModule); - _scopeRestrictionsDone = true; + ScopeRestrictionsDone = true; } /// Optimize merged modules using various IPO passes @@ -390,7 +391,7 @@ bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, if (!this->determineTarget(errMsg)) return false; - Module* mergedModule = _linker.getModule(); + Module *mergedModule = Linker.getModule(); // Mark which symbols can not be internalized this->applyScopeRestrictions(); @@ -402,8 +403,8 @@ bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, passes.add(createVerifierPass()); // Add an appropriate DataLayout instance for this module... - passes.add(new DataLayout(*_target->getDataLayout())); - _target->addAnalysisPasses(passes); + passes.add(new DataLayout(*TargetMach->getDataLayout())); + TargetMach->addAnalysisPasses(passes); // Enabling internalize here would use its AllButMain variant. It // keeps only main if it exists and does nothing for libraries. Instead @@ -419,8 +420,8 @@ bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, PassManager codeGenPasses; - codeGenPasses.add(new DataLayout(*_target->getDataLayout())); - _target->addAnalysisPasses(codeGenPasses); + codeGenPasses.add(new DataLayout(*TargetMach->getDataLayout())); + TargetMach->addAnalysisPasses(codeGenPasses); formatted_raw_ostream Out(out); @@ -428,8 +429,8 @@ bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, // the ObjCARCContractPass must be run, so do it unconditionally here. codeGenPasses.add(createObjCARCContractPass()); - if (_target->addPassesToEmitFile(codeGenPasses, Out, - TargetMachine::CGFT_ObjectFile)) { + if (TargetMach->addPassesToEmitFile(codeGenPasses, Out, + TargetMachine::CGFT_ObjectFile)) { errMsg = "target file type not supported"; return false; } @@ -450,8 +451,8 @@ void LTOCodeGenerator::setCodeGenDebugOptions(const char *options) { !o.first.empty(); o = getToken(o.second)) { // ParseCommandLineOptions() expects argv[0] to be program name. Lazily add // that. - if (_codegenOptions.empty()) - _codegenOptions.push_back(strdup("libLTO")); - _codegenOptions.push_back(strdup(o.first.str().c_str())); + if (CodegenOptions.empty()) + CodegenOptions.push_back(strdup("libLTO")); + CodegenOptions.push_back(strdup(o.first.str().c_str())); } } diff --git a/tools/lto/LTOCodeGenerator.h b/tools/lto/LTOCodeGenerator.h index 8f37cf0..8f551f8 100644 --- a/tools/lto/LTOCodeGenerator.h +++ b/tools/lto/LTOCodeGenerator.h @@ -67,11 +67,9 @@ struct LTOCodeGenerator { void setDebugInfo(lto_debug_model); void setCodePICModel(lto_codegen_model); - void setCpu(const char* mCpu) { _mCpu = mCpu; } + void setCpu(const char *mCpu) { MCpu = mCpu; } - void addMustPreserveSymbol(const char* sym) { - _mustPreserveSymbols[sym] = 1; - } + void addMustPreserveSymbol(const char *sym) { MustPreserveSymbols[sym] = 1; } // To pass options to the driver and optimization passes. These options are // not necessarily for debugging purpose (The function name is misleading). @@ -115,18 +113,18 @@ private: typedef llvm::StringMap StringSet; - llvm::LLVMContext& _context; - llvm::Linker _linker; - llvm::TargetMachine* _target; - bool _emitDwarfDebugInfo; - bool _scopeRestrictionsDone; - lto_codegen_model _codeModel; - StringSet _mustPreserveSymbols; - StringSet _asmUndefinedRefs; - llvm::MemoryBuffer* _nativeObjectFile; - std::vector _codegenOptions; - std::string _mCpu; - std::string _nativeObjectPath; + llvm::LLVMContext &Context; + llvm::Linker Linker; + llvm::TargetMachine *TargetMach; + bool EmitDwarfDebugInfo; + bool ScopeRestrictionsDone; + lto_codegen_model CodeModel; + StringSet MustPreserveSymbols; + StringSet AsmUndefinedRefs; + llvm::MemoryBuffer *NativeObjectFile; + std::vector CodegenOptions; + std::string MCpu; + std::string NativeObjectPath; }; #endif // LTO_CODE_GENERATOR_H -- cgit v1.1 From 775079c227083be3fe22f6ae071d5b74a7ade745 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 4 Sep 2013 20:08:46 +0000 Subject: Rename some variables to match the style guide. I am about to patch this code, and this makes the diff far more readable. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@189982 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/LTOCodeGenerator.cpp | 34 +++++++++++++++++----------------- tools/lto/LTOCodeGenerator.h | 6 +++--- 2 files changed, 20 insertions(+), 20 deletions(-) (limited to 'tools') diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index e3e1ab3..19e8c4c 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -300,18 +300,18 @@ bool LTOCodeGenerator::determineTarget(std::string &errMsg) { void LTOCodeGenerator:: applyRestriction(GlobalValue &GV, - std::vector &mustPreserveList, - SmallPtrSet &asmUsed, - Mangler &mangler) { + std::vector &MustPreserveList, + SmallPtrSet &AsmUsed, + Mangler &Mangler) { SmallString<64> Buffer; - mangler.getNameWithPrefix(Buffer, &GV, false); + Mangler.getNameWithPrefix(Buffer, &GV, false); if (GV.isDeclaration()) return; if (MustPreserveSymbols.count(Buffer)) - mustPreserveList.push_back(GV.getName().data()); + MustPreserveList.push_back(GV.getName().data()); if (AsmUndefinedRefs.count(Buffer)) - asmUsed.insert(&GV); + AsmUsed.insert(&GV); } static void findUsedValues(GlobalVariable *LLVMUsed, @@ -337,31 +337,31 @@ void LTOCodeGenerator::applyScopeRestrictions() { // mark which symbols can not be internalized MCContext MContext(TargetMach->getMCAsmInfo(), TargetMach->getRegisterInfo(), NULL); - Mangler mangler(MContext, TargetMach); - std::vector mustPreserveList; - SmallPtrSet asmUsed; + Mangler Mangler(MContext, TargetMach); + std::vector MustPreserveList; + SmallPtrSet AsmUsed; for (Module::iterator f = mergedModule->begin(), e = mergedModule->end(); f != e; ++f) - applyRestriction(*f, mustPreserveList, asmUsed, mangler); + applyRestriction(*f, MustPreserveList, AsmUsed, Mangler); for (Module::global_iterator v = mergedModule->global_begin(), e = mergedModule->global_end(); v != e; ++v) - applyRestriction(*v, mustPreserveList, asmUsed, mangler); + applyRestriction(*v, MustPreserveList, AsmUsed, Mangler); for (Module::alias_iterator a = mergedModule->alias_begin(), e = mergedModule->alias_end(); a != e; ++a) - applyRestriction(*a, mustPreserveList, asmUsed, mangler); + applyRestriction(*a, MustPreserveList, AsmUsed, Mangler); GlobalVariable *LLVMCompilerUsed = mergedModule->getGlobalVariable("llvm.compiler.used"); - findUsedValues(LLVMCompilerUsed, asmUsed); + findUsedValues(LLVMCompilerUsed, AsmUsed); if (LLVMCompilerUsed) LLVMCompilerUsed->eraseFromParent(); - if (!asmUsed.empty()) { + if (!AsmUsed.empty()) { llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(Context); std::vector asmUsed2; - for (SmallPtrSet::const_iterator i = asmUsed.begin(), - e = asmUsed.end(); i !=e; ++i) { + for (SmallPtrSet::const_iterator i = AsmUsed.begin(), + e = AsmUsed.end(); i !=e; ++i) { GlobalValue *GV = *i; Constant *c = ConstantExpr::getBitCast(GV, i8PTy); asmUsed2.push_back(c); @@ -377,7 +377,7 @@ void LTOCodeGenerator::applyScopeRestrictions() { LLVMCompilerUsed->setSection("llvm.metadata"); } - passes.add(createInternalizePass(mustPreserveList)); + passes.add(createInternalizePass(MustPreserveList)); // apply scope restrictions passes.run(*mergedModule); diff --git a/tools/lto/LTOCodeGenerator.h b/tools/lto/LTOCodeGenerator.h index 8f551f8..0263362 100644 --- a/tools/lto/LTOCodeGenerator.h +++ b/tools/lto/LTOCodeGenerator.h @@ -106,9 +106,9 @@ private: bool generateObjectFile(llvm::raw_ostream &out, std::string &errMsg); void applyScopeRestrictions(); void applyRestriction(llvm::GlobalValue &GV, - std::vector &mustPreserveList, - llvm::SmallPtrSet &asmUsed, - llvm::Mangler &mangler); + std::vector &MustPreserveList, + llvm::SmallPtrSet &AsmUsed, + llvm::Mangler &Mangler); bool determineTarget(std::string &errMsg); typedef llvm::StringMap StringSet; -- cgit v1.1 From 2909c9801979f41a85166f3381d0d3c577a7e89c Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 5 Sep 2013 02:09:34 +0000 Subject: msbuild: Add clang's compiler-rt libs to the LibraryPath This allows linking libraries like the asan RTL. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190028 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in b/tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in index 0f474c0..3020d79 100644 --- a/tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in +++ b/tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in @@ -5,5 +5,6 @@ $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\LLVM\@REG_KEY@) $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\LLVM\@REG_KEY@) $(LLVMInstallDir)\msbuild-bin;$(ExecutablePath) + $(LLVMInstallDir)\lib\clang\3.4\lib\windows;$(LibraryPath) -- cgit v1.1 From 1bcff6cffa30c2fdcf0eac80ef9551429b38f25d Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Fri, 6 Sep 2013 17:05:46 +0000 Subject: msbuild integration: provide separate files for VS2010 and VS2012 The previous msbuild integration only worked if VS2010 was installed. This patch renames the current integration to LLVM-vs2010 and adds LLVM-vs2012. Differential Revision: http://llvm-reviews.chandlerc.com/D1614 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190173 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/msbuild/CMakeLists.txt | 18 ++++++++--- .../Microsoft.Cpp.Win32.LLVM-vs2010.targets | 2 ++ .../Microsoft.Cpp.Win32.LLVM-vs2012.targets | 3 ++ tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in | 2 +- tools/msbuild/Microsoft.Cpp.Win32.llvm.targets | 2 -- tools/msbuild/install.bat | 34 ++++++++++++++------ tools/msbuild/uninstall.bat | 36 +++++++++------------- 7 files changed, 60 insertions(+), 37 deletions(-) create mode 100644 tools/msbuild/Microsoft.Cpp.Win32.LLVM-vs2010.targets create mode 100644 tools/msbuild/Microsoft.Cpp.Win32.LLVM-vs2012.targets delete mode 100644 tools/msbuild/Microsoft.Cpp.Win32.llvm.targets (limited to 'tools') diff --git a/tools/msbuild/CMakeLists.txt b/tools/msbuild/CMakeLists.txt index 393b22a..860ed22 100644 --- a/tools/msbuild/CMakeLists.txt +++ b/tools/msbuild/CMakeLists.txt @@ -1,10 +1,20 @@ if (WIN32) - set(prop_file "Microsoft.Cpp.Win32.llvm.props") + set(prop_file_in "Microsoft.Cpp.Win32.llvm.props.in") + set(prop_file_v100 "Microsoft.Cpp.Win32.LLVM-vs2010.props") + set(prop_file_v110 "Microsoft.Cpp.Win32.LLVM-vs2012.props") # CPack will install a registry key in this format that we wish to reference. set(REG_KEY "${CMAKE_PROJECT_NAME} ${CPACK_PACKAGE_VERSION}") - configure_file(${prop_file}.in ${prop_file}) - install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${prop_file}" DESTINATION tools/msbuild) + + set(VS_VERSION "v100") + configure_file(${prop_file_in} ${prop_file_v100}) + set(VS_VERSION "v110") + configure_file(${prop_file_in} ${prop_file_v110}) + + set(REG_KEY) + set(VS_VERSION) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${prop_file_v100}" DESTINATION tools/msbuild) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${prop_file_v110}" DESTINATION tools/msbuild) install(DIRECTORY . DESTINATION tools/msbuild @@ -13,4 +23,4 @@ if (WIN32) PATTERN "*.bat" PATTERN ".svn" EXCLUDE ) -endif() +endif() diff --git a/tools/msbuild/Microsoft.Cpp.Win32.LLVM-vs2010.targets b/tools/msbuild/Microsoft.Cpp.Win32.LLVM-vs2010.targets new file mode 100644 index 0000000..df41a84 --- /dev/null +++ b/tools/msbuild/Microsoft.Cpp.Win32.LLVM-vs2010.targets @@ -0,0 +1,2 @@ + + diff --git a/tools/msbuild/Microsoft.Cpp.Win32.LLVM-vs2012.targets b/tools/msbuild/Microsoft.Cpp.Win32.LLVM-vs2012.targets new file mode 100644 index 0000000..f7432f2 --- /dev/null +++ b/tools/msbuild/Microsoft.Cpp.Win32.LLVM-vs2012.targets @@ -0,0 +1,3 @@ + + + diff --git a/tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in b/tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in index 3020d79..07e931f 100644 --- a/tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in +++ b/tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in @@ -1,5 +1,5 @@  - + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\LLVM\@REG_KEY@) diff --git a/tools/msbuild/Microsoft.Cpp.Win32.llvm.targets b/tools/msbuild/Microsoft.Cpp.Win32.llvm.targets deleted file mode 100644 index df41a84..0000000 --- a/tools/msbuild/Microsoft.Cpp.Win32.llvm.targets +++ /dev/null @@ -1,2 +0,0 @@ - - diff --git a/tools/msbuild/install.bat b/tools/msbuild/install.bat index db11c86..2d5af62 100644 --- a/tools/msbuild/install.bat +++ b/tools/msbuild/install.bat @@ -1,28 +1,44 @@ @echo off echo Installing MSVC integration... +set SUCCESS=0 REM Change to the directory of this batch file. cd /d %~dp0 REM Search for the MSBuild toolsets directory. SET D="%ProgramFiles%\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\PlatformToolsets" -IF EXIST %D% GOTO FOUND_MSBUILD +IF EXIST %D% GOTO FOUND_V100 SET D="%ProgramFiles(x86)%\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\PlatformToolsets" -IF EXIST %D% GOTO FOUND_MSBUILD +IF EXIST %D% GOTO FOUND_V100 -echo Failed to find MSBuild toolsets directory. -goto FAILED +:TRY_V110 +SET D="%ProgramFiles%\MSBuild\Microsoft.Cpp\v4.0\V110\Platforms\Win32\PlatformToolsets" +IF EXIST %D% GOTO FOUND_V110 +SET D="%ProgramFiles(x86)%\MSBuild\Microsoft.Cpp\v4.0\V110\Platforms\Win32\PlatformToolsets" +IF EXIST %D% GOTO FOUND_V110 + +IF NOT SUCCESS == 1 echo Failed to find MSBuild toolsets directory. +IF NOT SUCCESS == 1 goto FAILED -:FOUND_MSBUILD -IF NOT EXIST %D%\llvm mkdir %D%\llvm -IF NOT %ERRORLEVEL% == 0 GOTO FAILED -copy Microsoft.Cpp.Win32.llvm.props %D%\llvm +:FOUND_V100 +IF NOT EXIST %D%\LLVM-vs2010 mkdir %D%\LLVM-vs2010 +IF NOT %ERRORLEVEL% == 0 GOTO FAILED +copy Microsoft.Cpp.Win32.LLVM-vs2010.props %D%\LLVM-vs2010 IF NOT %ERRORLEVEL% == 0 GOTO FAILED -copy Microsoft.Cpp.Win32.llvm.targets %D%\llvm +copy Microsoft.Cpp.Win32.LLVM-vs2010.targets %D%\LLVM-vs2010 IF NOT %ERRORLEVEL% == 0 GOTO FAILED +set SUCCESS=1 +GOTO TRY_V110 +:FOUND_V110 +IF NOT EXIST %D%\LLVM-vs2012 mkdir %D%\LLVM-vs2012 +IF NOT %ERRORLEVEL% == 0 GOTO FAILED +copy Microsoft.Cpp.Win32.LLVM-vs2012.props %D%\LLVM-vs2012 +IF NOT %ERRORLEVEL% == 0 GOTO FAILED +copy Microsoft.Cpp.Win32.LLVM-vs2012.targets %D%\LLVM-vs2012 +IF NOT %ERRORLEVEL% == 0 GOTO FAILED echo Done! goto END diff --git a/tools/msbuild/uninstall.bat b/tools/msbuild/uninstall.bat index 8bc304e..c697239 100644 --- a/tools/msbuild/uninstall.bat +++ b/tools/msbuild/uninstall.bat @@ -5,30 +5,24 @@ echo Uninstalling MSVC integration... REM CD to the directory of this batch file. cd /d %~dp0 -REM Search for the MSBuild toolsets directory. SET D="%ProgramFiles%\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\PlatformToolsets" -IF EXIST %D% GOTO FOUND_MSBUILD -SET D="%ProgramFiles(x86)%\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\PlatformToolsets" -IF EXIST %D% GOTO FOUND_MSBUILD +IF EXIST %D%\LLVM-vs2010 del %D%\LLVM-vs2010\Microsoft.Cpp.Win32.LLVM-vs2010.props +IF EXIST %D%\LLVM-vs2010 del %D%\LLVM-vs2010\Microsoft.Cpp.Win32.LLVM-vs2010.targets +IF EXIST %D%\LLVM-vs2010 rmdir %D%\LLVM-vs2010 -echo Failed to find MSBuild toolsets directory. -goto FAILED +SET D="%ProgramFiles(x86)%\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\PlatformToolsets" +IF EXIST %D%\LLVM-vs2010 del %D%\LLVM-vs2010\Microsoft.Cpp.Win32.LLVM-vs2010.props +IF EXIST %D%\LLVM-vs2010 del %D%\LLVM-vs2010\Microsoft.Cpp.Win32.LLVM-vs2010.targets +IF EXIST %D%\LLVM-vs2010 rmdir %D%\LLVM-vs2010 -:FOUND_MSBUILD +SET D="%ProgramFiles%\MSBuild\Microsoft.Cpp\v4.0\V110\Platforms\Win32\PlatformToolsets" +IF EXIST %D%\LLVM-vs2012 del %D%\LLVM-vs2012\Microsoft.Cpp.Win32.LLVM-vs2012.props +IF EXIST %D%\LLVM-vs2012 del %D%\LLVM-vs2012\Microsoft.Cpp.Win32.LLVM-vs2012.targets +IF EXIST %D%\LLVM-vs2012 rmdir %D%\LLVM-vs2012 -del %D%\llvm\Microsoft.Cpp.Win32.llvm.props -IF NOT %ERRORLEVEL% == 0 GOTO FAILED -del %D%\llvm\Microsoft.Cpp.Win32.llvm.targets -IF NOT %ERRORLEVEL% == 0 GOTO FAILED -rmdir %D%\llvm -IF NOT %ERRORLEVEL% == 0 GOTO FAILED +SET D="%ProgramFiles(x86)%\MSBuild\Microsoft.Cpp\v4.0\V110\Platforms\Win32\PlatformToolsets" +IF EXIST %D%\LLVM-vs2012 del %D%\LLVM-vs2012\Microsoft.Cpp.Win32.LLVM-vs2012.props +IF EXIST %D%\LLVM-vs2012 del %D%\LLVM-vs2012\Microsoft.Cpp.Win32.LLVM-vs2012.targets +IF EXIST %D%\LLVM-vs2012 rmdir %D%\LLVM-vs2012 echo Done! -goto END - -:FAILED -echo MSVC integration uninstall failed. -pause -goto END - -:END -- cgit v1.1 From c3cee57f7d20f69a84fd88464ed8cf050e63c7ad Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Mon, 9 Sep 2013 02:37:14 +0000 Subject: Generate compact unwind encoding from CFI directives. We used to generate the compact unwind encoding from the machine instructions. However, this had the problem that if the user used `-save-temps' or compiled their hand-written `.s' file (with CFI directives), we wouldn't generate the compact unwind encoding. Move the algorithm that generates the compact unwind encoding into the MCAsmBackend. This way we can generate the encoding whether the code is from a `.ll' or `.s' file. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190290 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-mc/llvm-mc.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index f10a614..4828737 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -432,7 +432,7 @@ int main(int argc, char **argv) { MCAsmBackend *MAB = 0; if (ShowEncoding) { CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx); - MAB = TheTarget->createMCAsmBackend(TripleName, MCPU); + MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU); } bool UseCFI = !DisableCFI; Str.reset(TheTarget->createAsmStreamer(Ctx, FOS, /*asmverbose*/true, @@ -446,7 +446,7 @@ int main(int argc, char **argv) { } else { assert(FileType == OFT_ObjectFile && "Invalid file type!"); MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, *STI, Ctx); - MCAsmBackend *MAB = TheTarget->createMCAsmBackend(TripleName, MCPU); + MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU); Str.reset(TheTarget->createMCObjectStreamer(TripleName, Ctx, *MAB, FOS, CE, RelaxAll, NoExecStack)); -- cgit v1.1 From db3a9e64f856e3a233a427da1f3969fd3a65a438 Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Mon, 9 Sep 2013 19:14:35 +0000 Subject: Revert patches to add case-range support for PR1255. The work on this project was left in an unfinished and inconsistent state. Hopefully someone will eventually get a chance to implement this feature, but in the meantime, it is better to put things back the way the were. I have left support in the bitcode reader to handle the case-range bitcode format, so that we do not lose bitcode compatibility with the llvm 3.3 release. This reverts the following commits: 155464, 156374, 156377, 156613, 156704, 156757, 156804 156808, 156985, 157046, 157112, 157183, 157315, 157384, 157575, 157576, 157586, 157612, 157810, 157814, 157815, 157880, 157881, 157882, 157884, 157887, 157901, 158979, 157987, 157989, 158986, 158997, 159076, 159101, 159100, 159200, 159201, 159207, 159527, 159532, 159540, 159583, 159618, 159658, 159659, 159660, 159661, 159703, 159704, 160076, 167356, 172025, 186736 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190328 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-diff/DifferenceEngine.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/llvm-diff/DifferenceEngine.cpp b/tools/llvm-diff/DifferenceEngine.cpp index 4b11315..ba15667 100644 --- a/tools/llvm-diff/DifferenceEngine.cpp +++ b/tools/llvm-diff/DifferenceEngine.cpp @@ -316,15 +316,15 @@ class FunctionDifferenceEngine { bool Difference = false; - DenseMap LCases; + DenseMap LCases; for (SwitchInst::CaseIt I = LI->case_begin(), E = LI->case_end(); I != E; ++I) - LCases[I.getCaseValueEx()] = I.getCaseSuccessor(); + LCases[I.getCaseValue()] = I.getCaseSuccessor(); for (SwitchInst::CaseIt I = RI->case_begin(), E = RI->case_end(); I != E; ++I) { - IntegersSubset CaseValue = I.getCaseValueEx(); + ConstantInt *CaseValue = I.getCaseValue(); BasicBlock *LCase = LCases[CaseValue]; if (LCase) { if (TryUnify) tryUnify(LCase, I.getCaseSuccessor()); @@ -336,7 +336,7 @@ class FunctionDifferenceEngine { } } if (!Difference) - for (DenseMap::iterator + for (DenseMap::iterator I = LCases.begin(), E = LCases.end(); I != E; ++I) { if (Complain) Engine.logf("left switch has extra case %l") << I->first; -- cgit v1.1 From 2c9905a1f3bcf22cc2f93332cc8411d11798ba07 Mon Sep 17 00:00:00 2001 From: Manman Ren Date: Mon, 9 Sep 2013 19:47:11 +0000 Subject: Debug Info: Use DIScopeRef for DIType::getContext. In DIBuilder, the context field of a TAG_member is updated to use the scope reference. Verifier is updated accordingly. DebugInfoFinder now needs to generate a type identifier map to have access to the actual scope. Same applies for BreakpointPrinter. processModule of DebugInfoFinder is called during initialization phase of the verifier to make sure the type identifier map is constructed early enough. We are now able to unique a simple class as demonstrated by the added testing case. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190334 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/opt/opt.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 691080a..94f4cca 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -367,6 +367,7 @@ char BasicBlockPassPrinter::ID = 0; struct BreakpointPrinter : public ModulePass { raw_ostream &Out; static char ID; + DITypeIdentifierMap TypeIdentifierMap; BreakpointPrinter(raw_ostream &out) : ModulePass(ID), Out(out) { @@ -382,13 +383,18 @@ struct BreakpointPrinter : public ModulePass { } else if (Context.isType()) { DIType TY(Context); if (!TY.getName().empty()) { - getContextName(TY.getContext(), N); + getContextName(TY.getContext().resolve(TypeIdentifierMap), N); N = N + TY.getName().str() + "::"; } } } virtual bool runOnModule(Module &M) { + TypeIdentifierMap.clear(); + NamedMDNode *CU_Nodes = M.getNamedMetadata("llvm.dbg.cu"); + if (CU_Nodes) + TypeIdentifierMap = generateDITypeIdentifierMap(CU_Nodes); + StringSet<> Processed; if (NamedMDNode *NMD = M.getNamedMetadata("llvm.dbg.sp")) for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) { -- cgit v1.1 From 715d98d657491b3fb8ea0e14643e9801b2f9628c Mon Sep 17 00:00:00 2001 From: Joey Gouly Date: Thu, 12 Sep 2013 10:28:05 +0000 Subject: Add an instruction deprecation feature to TableGen. The 'Deprecated' class allows you to specify a SubtargetFeature that the instruction is deprecated on. The 'ComplexDeprecationPredicate' class allows you to define a custom predicate that is called to check for deprecation. For example: ComplexDeprecationPredicate<"MCR"> would mean you would have to define the following function: bool getMCRDeprecationInfo(MCInst &MI, MCSubtargetInfo &STI, std::string &Info) Which returns 'false' for not deprecated, and 'true' for deprecated and store the warning message in 'Info'. The MCTargetAsmParser constructor was chaned to take an extra argument of the MCInstrInfo class, so out-of-tree targets will need to be changed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190598 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-mc/llvm-mc.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index 4828737..7ec2bba 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -319,10 +319,10 @@ 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) { + MCAsmInfo &MAI, MCSubtargetInfo &STI, MCInstrInfo &MCII) { OwningPtr Parser(createMCAsmParser(SrcMgr, Ctx, Str, MAI)); - OwningPtr TAP(TheTarget->createMCAsmParser(STI, *Parser)); + OwningPtr TAP(TheTarget->createMCAsmParser(STI, *Parser, MCII)); if (!TAP) { errs() << ProgName << ": error: this target does not support assembly parsing.\n"; @@ -459,7 +459,7 @@ int main(int argc, char **argv) { Res = AsLexInput(SrcMgr, *MAI, Out.get()); break; case AC_Assemble: - Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI); + Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI, *MCII); break; case AC_MDisassemble: assert(IP && "Expected assembly output"); -- cgit v1.1 From 9de16c1008e11633ea3df8e095e25f3082c11c32 Mon Sep 17 00:00:00 2001 From: Joey Gouly Date: Thu, 12 Sep 2013 12:55:29 +0000 Subject: [LTO] Fix the LTO tool, after my API breakage. Thanks to Zonr Chang! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190602 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/LTOModule.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp index 1812346..1a9d8f5 100644 --- a/tools/lto/LTOModule.cpp +++ b/tools/lto/LTOModule.cpp @@ -21,6 +21,7 @@ #include "llvm/IR/Module.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" +#include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCParser/MCAsmParser.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" @@ -813,11 +814,12 @@ bool LTOModule::addAsmGlobalSymbols(std::string &errMsg) { _context, *Streamer, *_target->getMCAsmInfo())); const Target &T = _target->getTarget(); + OwningPtr MCII(T.createMCInstrInfo()); OwningPtr STI(T.createMCSubtargetInfo(_target->getTargetTriple(), _target->getTargetCPU(), _target->getTargetFeatureString())); - OwningPtr TAP(T.createMCAsmParser(*STI, *Parser.get())); + OwningPtr TAP(T.createMCAsmParser(*STI, *Parser.get(), *MCII)); if (!TAP) { errMsg = "target " + std::string(T.getName()) + " does not define AsmParser."; -- cgit v1.1 From 766f25306af343fb2784350cb4d8cd9ca180f0d3 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sun, 15 Sep 2013 19:53:20 +0000 Subject: ELF: Add support for the exclude section bit for gas compat. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190769 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/ELFDumper.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index 502fe67..71f03bc 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -377,6 +377,7 @@ static const char *getElfSectionType(unsigned Arch, unsigned Type) { static const EnumEntry ElfSectionFlags[] = { LLVM_READOBJ_ENUM_ENT(ELF, SHF_WRITE ), LLVM_READOBJ_ENUM_ENT(ELF, SHF_ALLOC ), + LLVM_READOBJ_ENUM_ENT(ELF, SHF_EXCLUDE ), LLVM_READOBJ_ENUM_ENT(ELF, SHF_EXECINSTR ), LLVM_READOBJ_ENUM_ENT(ELF, SHF_MERGE ), LLVM_READOBJ_ENUM_ENT(ELF, SHF_STRINGS ), -- cgit v1.1 From 4acd20a20be9f7d91ed35c1c6a501cec1605e854 Mon Sep 17 00:00:00 2001 From: Craig Topper Date: Wed, 18 Sep 2013 03:55:53 +0000 Subject: Lift alignment restrictions for load/store folding on VINSERTF128/VEXTRACTF128. Fixes PR17268. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190916 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/opt/opt.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 94f4cca..71a9c02 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -462,6 +462,7 @@ static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, DisableLoopUnrolling : OptLevel == 0; Builder.LoopVectorize = OptLevel > 1 && SizeLevel < 2; + Builder.SLPVectorize = true; Builder.populateFunctionPassManager(FPM); Builder.populateModulePassManager(MPM); -- cgit v1.1 From 2cccc6220cc351b52d2cd2d0b7139502e854b68d Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Wed, 18 Sep 2013 23:31:10 +0000 Subject: whitespace git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190973 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-diff/llvm-diff.cpp | 2 +- tools/llvm-extract/llvm-extract.cpp | 2 +- tools/llvm-link/llvm-link.cpp | 2 +- tools/llvm-prof/llvm-prof.cpp | 16 ++++++++-------- 4 files changed, 11 insertions(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/llvm-diff/llvm-diff.cpp b/tools/llvm-diff/llvm-diff.cpp index 6eca1e2..f70219e 100644 --- a/tools/llvm-diff/llvm-diff.cpp +++ b/tools/llvm-diff/llvm-diff.cpp @@ -70,7 +70,7 @@ int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv); LLVMContext Context; - + // Load both modules. Die if that fails. Module *LModule = ReadModule(Context, LeftFilename); Module *RModule = ReadModule(Context, RightFilename); diff --git a/tools/llvm-extract/llvm-extract.cpp b/tools/llvm-extract/llvm-extract.cpp index 9ba68b4..dc1a410 100644 --- a/tools/llvm-extract/llvm-extract.cpp +++ b/tools/llvm-extract/llvm-extract.cpp @@ -53,7 +53,7 @@ static cl::list ExtractFuncs("func", cl::desc("Specify function to extract"), cl::ZeroOrMore, cl::value_desc("function")); -// ExtractRegExpFuncs - The functions, matched via regular expression, to +// ExtractRegExpFuncs - The functions, matched via regular expression, to // extract from the module. static cl::list ExtractRegExpFuncs("rfunc", cl::desc("Specify function(s) to extract using a " diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp index 652c414..99cca23 100644 --- a/tools/llvm-link/llvm-link.cpp +++ b/tools/llvm-link/llvm-link.cpp @@ -70,7 +70,7 @@ int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); - + LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. cl::ParseCommandLineOptions(argc, argv, "llvm linker\n"); diff --git a/tools/llvm-prof/llvm-prof.cpp b/tools/llvm-prof/llvm-prof.cpp index b2c3f06..52d0130 100644 --- a/tools/llvm-prof/llvm-prof.cpp +++ b/tools/llvm-prof/llvm-prof.cpp @@ -131,7 +131,7 @@ namespace { ProfileInfoLoader &PIL; public: static char ID; // Class identification, replacement for typeinfo. - explicit ProfileInfoPrinterPass(ProfileInfoLoader &_PIL) + explicit ProfileInfoPrinterPass(ProfileInfoLoader &_PIL) : ModulePass(ID), PIL(_PIL) {} virtual void getAnalysisUsage(AnalysisUsage &AU) const { @@ -161,7 +161,7 @@ bool ProfileInfoPrinterPass::runOnModule(Module &M) { if (FI->isDeclaration()) continue; double w = ignoreMissing(PI.getExecutionCount(FI)); FunctionCounts.push_back(std::make_pair(FI, w)); - for (Function::iterator BB = FI->begin(), BBE = FI->end(); + for (Function::iterator BB = FI->begin(), BBE = FI->end(); BB != BBE; ++BB) { double w = ignoreMissing(PI.getExecutionCount(BB)); Counts.push_back(std::make_pair(BB, w)); @@ -194,7 +194,7 @@ bool ProfileInfoPrinterPass::runOnModule(Module &M) { outs() << " ## Frequency\n"; for (unsigned i = 0, e = FunctionCounts.size(); i != e; ++i) { if (FunctionCounts[i].second == 0) { - outs() << "\n NOTE: " << e-i << " function" + outs() << "\n NOTE: " << e-i << " function" << (e-i-1 ? "s were" : " was") << " never executed!\n"; break; } @@ -210,14 +210,14 @@ bool ProfileInfoPrinterPass::runOnModule(Module &M) { TotalExecutions = 0; for (unsigned i = 0, e = Counts.size(); i != e; ++i) TotalExecutions += Counts[i].second; - + // Sort by the frequency, backwards. sort(Counts.begin(), Counts.end(), PairSecondSortReverse()); - + outs() << "\n===" << std::string(73, '-') << "===\n"; outs() << "Top 20 most frequently executed basic blocks:\n\n"; - + // Print out the function frequencies... outs() <<" ## %% \tFrequency\n"; unsigned BlocksToPrint = Counts.size(); @@ -237,7 +237,7 @@ bool ProfileInfoPrinterPass::runOnModule(Module &M) { if (PrintAnnotatedLLVM || PrintAllCode) { outs() << "\n===" << std::string(73, '-') << "===\n"; outs() << "Annotated LLVM code for the module:\n\n"; - + ProfileAnnotator PA(PI); if (FunctionsToPrint.empty() || PrintAllCode) @@ -259,7 +259,7 @@ int main(int argc, char **argv) { LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - + cl::ParseCommandLineOptions(argc, argv, "llvm profile dump decoder\n"); // Read in the bitcode file... -- cgit v1.1 From 7d4e9934e7ca83094c5cf41346966c8350179ff2 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Wed, 18 Sep 2013 23:31:16 +0000 Subject: Encapsulate PassManager debug flags to avoid static init and cxa_exit. This puts all the global PassManager debugging flags, like -print-after-all and -time-passes, behind a managed static. This eliminates their static initializers and, more importantly, exit-time destructors. The only behavioral change I anticipate is that tools need to initialize the PassManager before parsing the command line in order to export these options, which makes sense. Tools that already initialize the standard passes (opt/llc) don't need to do anything new. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190974 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-as/llvm-as.cpp | 5 +++++ tools/llvm-diff/llvm-diff.cpp | 4 ++++ tools/llvm-dis/llvm-dis.cpp | 3 +++ tools/llvm-extract/llvm-extract.cpp | 4 ++++ tools/llvm-link/llvm-link.cpp | 5 +++++ tools/llvm-nm/llvm-nm.cpp | 5 +++++ tools/llvm-prof/llvm-prof.cpp | 3 +++ tools/llvm-stress/llvm-stress.cpp | 4 ++++ 8 files changed, 33 insertions(+) (limited to 'tools') diff --git a/tools/llvm-as/llvm-as.cpp b/tools/llvm-as/llvm-as.cpp index b2e44ef..9d5e96d 100644 --- a/tools/llvm-as/llvm-as.cpp +++ b/tools/llvm-as/llvm-as.cpp @@ -20,6 +20,7 @@ #include "llvm/Assembly/Parser.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/IR/Module.h" +#include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/PrettyStackTrace.h" @@ -89,6 +90,10 @@ int main(int argc, char **argv) { PrettyStackTraceProgram X(argc, argv); LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + + // Initialize PassManager for -time-passes support. + initializePassManager(); + cl::ParseCommandLineOptions(argc, argv, "llvm .ll -> .bc assembler\n"); // Parse the file now... diff --git a/tools/llvm-diff/llvm-diff.cpp b/tools/llvm-diff/llvm-diff.cpp index f70219e..62fc026 100644 --- a/tools/llvm-diff/llvm-diff.cpp +++ b/tools/llvm-diff/llvm-diff.cpp @@ -20,6 +20,7 @@ #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" #include "llvm/IRReader/IRReader.h" +#include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" @@ -67,6 +68,9 @@ static cl::list GlobalsToCompare(cl::Positional, cl::desc("")); int main(int argc, char **argv) { + // Initialize PassManager for -time-passes support. + initializePassManager(); + cl::ParseCommandLineOptions(argc, argv); LLVMContext Context; diff --git a/tools/llvm-dis/llvm-dis.cpp b/tools/llvm-dis/llvm-dis.cpp index 87eb347..f31cbd4 100644 --- a/tools/llvm-dis/llvm-dis.cpp +++ b/tools/llvm-dis/llvm-dis.cpp @@ -23,6 +23,7 @@ #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" +#include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/DataStream.h" #include "llvm/Support/FormattedStream.h" @@ -119,6 +120,8 @@ int main(int argc, char **argv) { LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + // Initialize PassManager for -time-passes support. + initializePassManager(); cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n"); diff --git a/tools/llvm-extract/llvm-extract.cpp b/tools/llvm-extract/llvm-extract.cpp index dc1a410..9913176 100644 --- a/tools/llvm-extract/llvm-extract.cpp +++ b/tools/llvm-extract/llvm-extract.cpp @@ -96,6 +96,10 @@ int main(int argc, char **argv) { LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + + // Initialize PassManager for -time-passes support. + initializePassManager(); + cl::ParseCommandLineOptions(argc, argv, "llvm extractor\n"); // Use lazy loading, since we only care about selected global values. diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp index 99cca23..8e7d4b0 100644 --- a/tools/llvm-link/llvm-link.cpp +++ b/tools/llvm-link/llvm-link.cpp @@ -18,6 +18,7 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IRReader/IRReader.h" +#include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Path.h" @@ -73,6 +74,10 @@ int main(int argc, char **argv) { LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + + // Initialize PassManager for -time-passes support. + initializePassManager(); + cl::ParseCommandLineOptions(argc, argv, "llvm linker\n"); unsigned BaseArg = 0; diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index 01dd1c3..45309c0 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -22,6 +22,7 @@ #include "llvm/Object/Archive.h" #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/ObjectFile.h" +#include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" @@ -446,6 +447,10 @@ int main(int argc, char **argv) { PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + + // Initialize PassManager for -time-passes support. + initializePassManager(); + cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n"); // llvm-nm only reads binary files. diff --git a/tools/llvm-prof/llvm-prof.cpp b/tools/llvm-prof/llvm-prof.cpp index 52d0130..e36441d 100644 --- a/tools/llvm-prof/llvm-prof.cpp +++ b/tools/llvm-prof/llvm-prof.cpp @@ -260,6 +260,9 @@ int main(int argc, char **argv) { LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + // Initialize PassManager for -time-passes support. + initializePassManager(); + cl::ParseCommandLineOptions(argc, argv, "llvm profile dump decoder\n"); // Read in the bitcode file... diff --git a/tools/llvm-stress/llvm-stress.cpp b/tools/llvm-stress/llvm-stress.cpp index 15f7abf..6f22242 100644 --- a/tools/llvm-stress/llvm-stress.cpp +++ b/tools/llvm-stress/llvm-stress.cpp @@ -681,6 +681,10 @@ void IntroduceControlFlow(Function *F, Random &R) { int main(int argc, char **argv) { // Init LLVM, call llvm_shutdown() on exit, parse args, etc. llvm::PrettyStackTraceProgram X(argc, argv); + + // Initialize PassManager for -time-passes support. + initializePassManager(); + cl::ParseCommandLineOptions(argc, argv, "llvm codegen stress-tester\n"); llvm_shutdown_obj Y; -- cgit v1.1 From abe68f59174c7418ae73de0a87587abe0be1fb03 Mon Sep 17 00:00:00 2001 From: Andrew Trick Date: Thu, 19 Sep 2013 06:02:43 +0000 Subject: Revert "Encapsulate PassManager debug flags to avoid static init and cxa_exit." Working on a better solution to this. This reverts commit 7d4e9934e7ca83094c5cf41346966c8350179ff2. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@190990 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-as/llvm-as.cpp | 5 ----- tools/llvm-diff/llvm-diff.cpp | 4 ---- tools/llvm-dis/llvm-dis.cpp | 3 --- tools/llvm-extract/llvm-extract.cpp | 4 ---- tools/llvm-link/llvm-link.cpp | 5 ----- tools/llvm-nm/llvm-nm.cpp | 5 ----- tools/llvm-prof/llvm-prof.cpp | 3 --- tools/llvm-stress/llvm-stress.cpp | 4 ---- 8 files changed, 33 deletions(-) (limited to 'tools') diff --git a/tools/llvm-as/llvm-as.cpp b/tools/llvm-as/llvm-as.cpp index 9d5e96d..b2e44ef 100644 --- a/tools/llvm-as/llvm-as.cpp +++ b/tools/llvm-as/llvm-as.cpp @@ -20,7 +20,6 @@ #include "llvm/Assembly/Parser.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/IR/Module.h" -#include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/PrettyStackTrace.h" @@ -90,10 +89,6 @@ int main(int argc, char **argv) { PrettyStackTraceProgram X(argc, argv); LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - - // Initialize PassManager for -time-passes support. - initializePassManager(); - cl::ParseCommandLineOptions(argc, argv, "llvm .ll -> .bc assembler\n"); // Parse the file now... diff --git a/tools/llvm-diff/llvm-diff.cpp b/tools/llvm-diff/llvm-diff.cpp index 62fc026..f70219e 100644 --- a/tools/llvm-diff/llvm-diff.cpp +++ b/tools/llvm-diff/llvm-diff.cpp @@ -20,7 +20,6 @@ #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" #include "llvm/IRReader/IRReader.h" -#include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SourceMgr.h" @@ -68,9 +67,6 @@ static cl::list GlobalsToCompare(cl::Positional, cl::desc("")); int main(int argc, char **argv) { - // Initialize PassManager for -time-passes support. - initializePassManager(); - cl::ParseCommandLineOptions(argc, argv); LLVMContext Context; diff --git a/tools/llvm-dis/llvm-dis.cpp b/tools/llvm-dis/llvm-dis.cpp index f31cbd4..87eb347 100644 --- a/tools/llvm-dis/llvm-dis.cpp +++ b/tools/llvm-dis/llvm-dis.cpp @@ -23,7 +23,6 @@ #include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" -#include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/DataStream.h" #include "llvm/Support/FormattedStream.h" @@ -120,8 +119,6 @@ int main(int argc, char **argv) { LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - // Initialize PassManager for -time-passes support. - initializePassManager(); cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n"); diff --git a/tools/llvm-extract/llvm-extract.cpp b/tools/llvm-extract/llvm-extract.cpp index 9913176..dc1a410 100644 --- a/tools/llvm-extract/llvm-extract.cpp +++ b/tools/llvm-extract/llvm-extract.cpp @@ -96,10 +96,6 @@ int main(int argc, char **argv) { LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - - // Initialize PassManager for -time-passes support. - initializePassManager(); - cl::ParseCommandLineOptions(argc, argv, "llvm extractor\n"); // Use lazy loading, since we only care about selected global values. diff --git a/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp index 8e7d4b0..99cca23 100644 --- a/tools/llvm-link/llvm-link.cpp +++ b/tools/llvm-link/llvm-link.cpp @@ -18,7 +18,6 @@ #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IRReader/IRReader.h" -#include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Path.h" @@ -74,10 +73,6 @@ int main(int argc, char **argv) { LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - - // Initialize PassManager for -time-passes support. - initializePassManager(); - cl::ParseCommandLineOptions(argc, argv, "llvm linker\n"); unsigned BaseArg = 0; diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index 45309c0..01dd1c3 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -22,7 +22,6 @@ #include "llvm/Object/Archive.h" #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/ObjectFile.h" -#include "llvm/PassManager.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Format.h" @@ -447,10 +446,6 @@ int main(int argc, char **argv) { PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - - // Initialize PassManager for -time-passes support. - initializePassManager(); - cl::ParseCommandLineOptions(argc, argv, "llvm symbol table dumper\n"); // llvm-nm only reads binary files. diff --git a/tools/llvm-prof/llvm-prof.cpp b/tools/llvm-prof/llvm-prof.cpp index e36441d..52d0130 100644 --- a/tools/llvm-prof/llvm-prof.cpp +++ b/tools/llvm-prof/llvm-prof.cpp @@ -260,9 +260,6 @@ int main(int argc, char **argv) { LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - // Initialize PassManager for -time-passes support. - initializePassManager(); - cl::ParseCommandLineOptions(argc, argv, "llvm profile dump decoder\n"); // Read in the bitcode file... diff --git a/tools/llvm-stress/llvm-stress.cpp b/tools/llvm-stress/llvm-stress.cpp index 6f22242..15f7abf 100644 --- a/tools/llvm-stress/llvm-stress.cpp +++ b/tools/llvm-stress/llvm-stress.cpp @@ -681,10 +681,6 @@ void IntroduceControlFlow(Function *F, Random &R) { int main(int argc, char **argv) { // Init LLVM, call llvm_shutdown() on exit, parse args, etc. llvm::PrettyStackTraceProgram X(argc, argv); - - // Initialize PassManager for -time-passes support. - initializePassManager(); - cl::ParseCommandLineOptions(argc, argv, "llvm codegen stress-tester\n"); llvm_shutdown_obj Y; -- cgit v1.1 From a22ff961db47ffff4f1e795d810aa102edb9b79b Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 19 Sep 2013 16:50:40 +0000 Subject: Include an LLVM-vs2012_xp toolset in the MSBuild integration Patch by Paul Hampson! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191010 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/msbuild/CMakeLists.txt | 4 ++++ .../Microsoft.Cpp.Win32.LLVM-vs2012_xp.targets | 21 +++++++++++++++++++++ tools/msbuild/install.bat | 6 ++++++ tools/msbuild/uninstall.bat | 6 ++++++ 4 files changed, 37 insertions(+) create mode 100644 tools/msbuild/Microsoft.Cpp.Win32.LLVM-vs2012_xp.targets (limited to 'tools') diff --git a/tools/msbuild/CMakeLists.txt b/tools/msbuild/CMakeLists.txt index 860ed22..8de3b88 100644 --- a/tools/msbuild/CMakeLists.txt +++ b/tools/msbuild/CMakeLists.txt @@ -2,6 +2,7 @@ if (WIN32) set(prop_file_in "Microsoft.Cpp.Win32.llvm.props.in") set(prop_file_v100 "Microsoft.Cpp.Win32.LLVM-vs2010.props") set(prop_file_v110 "Microsoft.Cpp.Win32.LLVM-vs2012.props") + set(prop_file_v110_xp "Microsoft.Cpp.Win32.LLVM-vs2012_xp.props") # CPack will install a registry key in this format that we wish to reference. set(REG_KEY "${CMAKE_PROJECT_NAME} ${CPACK_PACKAGE_VERSION}") @@ -10,11 +11,14 @@ if (WIN32) configure_file(${prop_file_in} ${prop_file_v100}) set(VS_VERSION "v110") configure_file(${prop_file_in} ${prop_file_v110}) + set(VS_VERSION "v110_xp") + configure_file(${prop_file_in} ${prop_file_v110_xp}) set(REG_KEY) set(VS_VERSION) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${prop_file_v100}" DESTINATION tools/msbuild) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${prop_file_v110}" DESTINATION tools/msbuild) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${prop_file_v110_xp}" DESTINATION tools/msbuild) install(DIRECTORY . DESTINATION tools/msbuild diff --git a/tools/msbuild/Microsoft.Cpp.Win32.LLVM-vs2012_xp.targets b/tools/msbuild/Microsoft.Cpp.Win32.LLVM-vs2012_xp.targets new file mode 100644 index 0000000..e8250d8 --- /dev/null +++ b/tools/msbuild/Microsoft.Cpp.Win32.LLVM-vs2012_xp.targets @@ -0,0 +1,21 @@ + + + + v4.0 + NoSupportCodeAnalysisXP;$(BeforeClCompileTargets) + + + + + + + + + + CheckWindowsSDK71A;$(PrepareForBuildDependsOn) + + + + + + diff --git a/tools/msbuild/install.bat b/tools/msbuild/install.bat index 2d5af62..2b66a6c 100644 --- a/tools/msbuild/install.bat +++ b/tools/msbuild/install.bat @@ -39,6 +39,12 @@ copy Microsoft.Cpp.Win32.LLVM-vs2012.props %D%\LLVM-vs2012 IF NOT %ERRORLEVEL% == 0 GOTO FAILED copy Microsoft.Cpp.Win32.LLVM-vs2012.targets %D%\LLVM-vs2012 IF NOT %ERRORLEVEL% == 0 GOTO FAILED +IF NOT EXIST %D%\LLVM-vs2012_xp mkdir %D%\LLVM-vs2012_xp +IF NOT %ERRORLEVEL% == 0 GOTO FAILED +copy Microsoft.Cpp.Win32.LLVM-vs2012_xp.props %D%\LLVM-vs2012_xp +IF NOT %ERRORLEVEL% == 0 GOTO FAILED +copy Microsoft.Cpp.Win32.LLVM-vs2012_xp.targets %D%\LLVM-vs2012_xp +IF NOT %ERRORLEVEL% == 0 GOTO FAILED echo Done! goto END diff --git a/tools/msbuild/uninstall.bat b/tools/msbuild/uninstall.bat index c697239..f1f5619 100644 --- a/tools/msbuild/uninstall.bat +++ b/tools/msbuild/uninstall.bat @@ -19,10 +19,16 @@ SET D="%ProgramFiles%\MSBuild\Microsoft.Cpp\v4.0\V110\Platforms\Win32\PlatformTo IF EXIST %D%\LLVM-vs2012 del %D%\LLVM-vs2012\Microsoft.Cpp.Win32.LLVM-vs2012.props IF EXIST %D%\LLVM-vs2012 del %D%\LLVM-vs2012\Microsoft.Cpp.Win32.LLVM-vs2012.targets IF EXIST %D%\LLVM-vs2012 rmdir %D%\LLVM-vs2012 +IF EXIST %D%\LLVM-vs2012_xp del %D%\LLVM-vs2012_xp\Microsoft.Cpp.Win32.LLVM-vs2012_xp.props +IF EXIST %D%\LLVM-vs2012_xp del %D%\LLVM-vs2012_xp\Microsoft.Cpp.Win32.LLVM-vs2012_xp.targets +IF EXIST %D%\LLVM-vs2012_xp rmdir %D%\LLVM-vs2012_xp SET D="%ProgramFiles(x86)%\MSBuild\Microsoft.Cpp\v4.0\V110\Platforms\Win32\PlatformToolsets" IF EXIST %D%\LLVM-vs2012 del %D%\LLVM-vs2012\Microsoft.Cpp.Win32.LLVM-vs2012.props IF EXIST %D%\LLVM-vs2012 del %D%\LLVM-vs2012\Microsoft.Cpp.Win32.LLVM-vs2012.targets IF EXIST %D%\LLVM-vs2012 rmdir %D%\LLVM-vs2012 +IF EXIST %D%\LLVM-vs2012_xp del %D%\LLVM-vs2012_xp\Microsoft.Cpp.Win32.LLVM-vs2012_xp.props +IF EXIST %D%\LLVM-vs2012_xp del %D%\LLVM-vs2012_xp\Microsoft.Cpp.Win32.LLVM-vs2012_xp.targets +IF EXIST %D%\LLVM-vs2012_xp rmdir %D%\LLVM-vs2012_xp echo Done! -- cgit v1.1 From 31eb340cb68172874f5ad6d1fd7b3cb286a8615c Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 19 Sep 2013 17:18:35 +0000 Subject: msbuild: Set _MSC_VER to match the CRT we're using Various Windows SDK headers use _MSC_VER values to figure out what version of the VC++ headers they're using, in particular for SAL macros. Patch by Paul Hampson! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191015 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/msbuild/CMakeLists.txt | 3 +++ tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in | 7 +++++++ 2 files changed, 10 insertions(+) (limited to 'tools') diff --git a/tools/msbuild/CMakeLists.txt b/tools/msbuild/CMakeLists.txt index 8de3b88..894645a 100644 --- a/tools/msbuild/CMakeLists.txt +++ b/tools/msbuild/CMakeLists.txt @@ -8,14 +8,17 @@ if (WIN32) set(REG_KEY "${CMAKE_PROJECT_NAME} ${CPACK_PACKAGE_VERSION}") set(VS_VERSION "v100") + set(MSC_VERSION "1600") configure_file(${prop_file_in} ${prop_file_v100}) set(VS_VERSION "v110") + set(MSC_VERSION "1700") configure_file(${prop_file_in} ${prop_file_v110}) set(VS_VERSION "v110_xp") configure_file(${prop_file_in} ${prop_file_v110_xp}) set(REG_KEY) set(VS_VERSION) + set(MSC_VERSION) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${prop_file_v100}" DESTINATION tools/msbuild) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${prop_file_v110}" DESTINATION tools/msbuild) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${prop_file_v110_xp}" DESTINATION tools/msbuild) diff --git a/tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in b/tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in index 07e931f..fce6011 100644 --- a/tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in +++ b/tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in @@ -7,4 +7,11 @@ $(LLVMInstallDir)\msbuild-bin;$(ExecutablePath) $(LLVMInstallDir)\lib\clang\3.4\lib\windows;$(LibraryPath) + + + + + -fmsc-version=@MSC_VERSION@ %(AdditionalOptions) + + -- cgit v1.1 From 88fae0edcce84920ba7c5685c36f6bd6cfb9b86d Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Thu, 19 Sep 2013 22:15:52 +0000 Subject: Fix LTO handling of module-level assembly (PR14152). Patch by Tom Roeder! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191042 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/CMakeLists.txt | 2 + tools/Makefile | 7 ++- tools/llvm-lto/CMakeLists.txt | 7 +++ tools/llvm-lto/Makefile | 22 +++++++++ tools/llvm-lto/llvm-lto.cpp | 103 ++++++++++++++++++++++++++++++++++++++++++ tools/lto/LTOModule.cpp | 3 ++ 6 files changed, 140 insertions(+), 4 deletions(-) create mode 100644 tools/llvm-lto/CMakeLists.txt create mode 100644 tools/llvm-lto/Makefile create mode 100644 tools/llvm-lto/llvm-lto.cpp (limited to 'tools') diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 1f15fc0..468d396 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -45,8 +45,10 @@ add_llvm_tool_subdirectory(yaml2obj) if( NOT WIN32 ) add_llvm_tool_subdirectory(lto) + add_llvm_tool_subdirectory(llvm-lto) else() ignore_llvm_tool_subdirectory(lto) + ignore_llvm_tool_subdirectory(llvm-lto) endif() if( LLVM_ENABLE_PIC ) diff --git a/tools/Makefile b/tools/Makefile index b7375c9..d3d4593 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -54,11 +54,10 @@ endif ifndef ONLY_TOOLS ifeq ($(ENABLE_PIC),1) # gold only builds if binutils is around. It requires "lto" to build before - # it so it is added to DIRS. + # it so it is added to DIRS. llvm-lto also requires lto + DIRS += lto llvm-lto ifdef BINUTILS_INCDIR - DIRS += lto gold - else - PARALLEL_DIRS += lto + DIRS += gold endif PARALLEL_DIRS += bugpoint-passes diff --git a/tools/llvm-lto/CMakeLists.txt b/tools/llvm-lto/CMakeLists.txt new file mode 100644 index 0000000..b253b69 --- /dev/null +++ b/tools/llvm-lto/CMakeLists.txt @@ -0,0 +1,7 @@ +add_llvm_tool(llvm-lto + llvm-lto.cpp + ) + +target_link_libraries(llvm-lto LTO LLVMSupport) + +add_dependencies(llvm-lto lto) diff --git a/tools/llvm-lto/Makefile b/tools/llvm-lto/Makefile new file mode 100644 index 0000000..1b1a1f8 --- /dev/null +++ b/tools/llvm-lto/Makefile @@ -0,0 +1,22 @@ +##===- tools/llvm-lto/Makefile -----------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL := ../.. +TOOLNAME := llvm-lto +LINK_COMPONENTS := support + +# This tool has no plugins, optimize startup time. +TOOL_NO_EXPORTS := 1 + +NO_INSTALL := 1 + +include $(LEVEL)/Makefile.common + +LDFLAGS += -L$(LibDir) +LIBS += -lLTO diff --git a/tools/llvm-lto/llvm-lto.cpp b/tools/llvm-lto/llvm-lto.cpp new file mode 100644 index 0000000..f25037c --- /dev/null +++ b/tools/llvm-lto/llvm-lto.cpp @@ -0,0 +1,103 @@ +//===-- llvm-lto: a simple command-line program to link modules with LTO --===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This program takes in a list of bitcode files, links them, performs link-time +// optimization, and outputs an object file. +// +//===----------------------------------------------------------------------===// + +#include "llvm-c/lto.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; + +static cl::list InputFilenames(cl::Positional, cl::OneOrMore, + cl::desc("")); + +static cl::opt OutputFilename("o", + cl::desc("Override output filename"), + cl::init(""), + cl::value_desc("filename")); + +int main(int argc, char **argv) { + // Print a stack trace if we signal out. + sys::PrintStackTraceOnErrorSignal(); + PrettyStackTraceProgram X(argc, argv); + + llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. + cl::ParseCommandLineOptions(argc, argv, "llvm LTO linker\n"); + + unsigned BaseArg = 0; + std::string ErrorMessage; + + lto_code_gen_t code_gen = lto_codegen_create(); + if (code_gen == NULL) + errs() << argv[0] << ": error creating a code generation module: " + << lto_get_error_message() << "\n"; + + lto_codegen_set_pic_model(code_gen, LTO_CODEGEN_PIC_MODEL_DYNAMIC); + lto_codegen_set_debug_model(code_gen, LTO_DEBUG_MODEL_DWARF); + + for (unsigned i = BaseArg; i < InputFilenames.size(); ++i) { + lto_module_t BitcodeModule = lto_module_create(InputFilenames[i].c_str()); + if (BitcodeModule == NULL) { + errs() << argv[0] << ": error loading file '" << InputFilenames[i] + << "': " << lto_get_error_message() << "\n"; + return 1; + } + + if (lto_codegen_add_module(code_gen, BitcodeModule)) { + errs() << argv[0] << ": error adding file '" << InputFilenames[i] + << "': " << lto_get_error_message() << "\n"; + lto_module_dispose(BitcodeModule); + return 1; + } + + lto_module_dispose(BitcodeModule); + } + + if (!OutputFilename.empty()) { + size_t len = 0; + const void *Code = lto_codegen_compile(code_gen, &len); + if (Code == NULL) { + errs() << argv[0] + << ": error compiling the code: " << lto_get_error_message() + << "\n"; + return 1; + } + + std::string ErrorInfo; + raw_fd_ostream FileStream(OutputFilename.c_str(), ErrorInfo); + if (!ErrorInfo.empty()) { + errs() << argv[0] << ": error opening the file '" << OutputFilename + << "': " << ErrorInfo << "\n"; + return 1; + } + + FileStream.write(reinterpret_cast(Code), len); + } else { + const char *OutputName = NULL; + if (lto_codegen_compile_to_file(code_gen, &OutputName)) { + errs() << argv[0] + << ": error compiling the code: " << lto_get_error_message() + << "\n"; + return 1; + } + + outs() << "Wrote native object file '" << OutputName << "'\n"; + } + + lto_codegen_dispose(code_gen); + + return 0; +} diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp index 1a9d8f5..87e3573 100644 --- a/tools/lto/LTOModule.cpp +++ b/tools/lto/LTOModule.cpp @@ -792,6 +792,9 @@ namespace { const MCSymbol *Label, unsigned PointerSize) {} virtual void FinishImpl() {} + virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { + RecordProcEnd(Frame); + } static bool classof(const MCStreamer *S) { return S->getKind() == SK_RecordStreamer; -- cgit v1.1 From 86075251108afff556420effa670e7d07b203555 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Fri, 20 Sep 2013 13:12:24 +0000 Subject: llvm/tools/Makefile: Suppress building llvm-lto on cygming, for now, probably due to LTO.dll. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191088 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/Makefile b/tools/Makefile index d3d4593..4e7ef5d 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -71,6 +71,8 @@ endif # On Win32, loadable modules can be built with ENABLE_SHARED. ifneq ($(ENABLE_SHARED),1) ifneq (,$(filter $(HOST_OS), Cygwin MingW)) + DIRS := $(filter-out llvm-lto, \ + $(DIRS)) PARALLEL_DIRS := $(filter-out bugpoint-passes, \ $(PARALLEL_DIRS)) endif -- cgit v1.1 From cc48854d5d51a2d7557f1040a61f160ad86c9729 Mon Sep 17 00:00:00 2001 From: Peter Collingbourne Date: Tue, 24 Sep 2013 23:52:22 +0000 Subject: Move LTO support library to a component, allowing it to be tested more reliably across platforms. Patch by Tom Roeder! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191343 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/LLVMBuild.txt | 2 +- tools/llvm-lto/CMakeLists.txt | 5 +- tools/llvm-lto/LLVMBuild.txt | 22 + tools/llvm-lto/Makefile | 5 +- tools/llvm-lto/llvm-lto.cpp | 49 +-- tools/lto/CMakeLists.txt | 4 +- tools/lto/LTOCodeGenerator.cpp | 458 --------------------- tools/lto/LTOCodeGenerator.h | 130 ------ tools/lto/LTOModule.cpp | 908 ----------------------------------------- tools/lto/LTOModule.h | 190 --------- tools/lto/Makefile | 2 +- tools/lto/lto.cpp | 27 +- 12 files changed, 79 insertions(+), 1723 deletions(-) create mode 100644 tools/llvm-lto/LLVMBuild.txt delete mode 100644 tools/lto/LTOCodeGenerator.cpp delete mode 100644 tools/lto/LTOCodeGenerator.h delete mode 100644 tools/lto/LTOModule.cpp delete mode 100644 tools/lto/LTOModule.h (limited to 'tools') diff --git a/tools/LLVMBuild.txt b/tools/LLVMBuild.txt index 9ec89f3..fa10b99 100644 --- a/tools/LLVMBuild.txt +++ b/tools/LLVMBuild.txt @@ -16,7 +16,7 @@ ;===------------------------------------------------------------------------===; [common] -subdirectories = bugpoint llc lli llvm-ar llvm-as llvm-bcanalyzer llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-jitlistener llvm-link llvm-mc llvm-nm llvm-objdump llvm-prof llvm-rtdyld llvm-size macho-dump opt llvm-mcmarkup +subdirectories = bugpoint llc lli llvm-ar llvm-as llvm-bcanalyzer llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-jitlistener llvm-link llvm-lto llvm-mc llvm-nm llvm-objdump llvm-prof llvm-rtdyld llvm-size macho-dump opt llvm-mcmarkup [component_0] type = Group diff --git a/tools/llvm-lto/CMakeLists.txt b/tools/llvm-lto/CMakeLists.txt index b253b69..348976c 100644 --- a/tools/llvm-lto/CMakeLists.txt +++ b/tools/llvm-lto/CMakeLists.txt @@ -1,7 +1,6 @@ +set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} lto support) + add_llvm_tool(llvm-lto llvm-lto.cpp ) -target_link_libraries(llvm-lto LTO LLVMSupport) - -add_dependencies(llvm-lto lto) diff --git a/tools/llvm-lto/LLVMBuild.txt b/tools/llvm-lto/LLVMBuild.txt new file mode 100644 index 0000000..c1613a3 --- /dev/null +++ b/tools/llvm-lto/LLVMBuild.txt @@ -0,0 +1,22 @@ +;===- ./tools/llvm-lto/LLVMBuild.txt ----------------------------*- Conf -*--===; +; +; The LLVM Compiler Infrastructure +; +; This file is distributed under the University of Illinois Open Source +; License. See LICENSE.TXT for details. +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Tool +name = llvm-lto +parent = Tools +required_libraries = LTO Support all-targets diff --git a/tools/llvm-lto/Makefile b/tools/llvm-lto/Makefile index 1b1a1f8..f1801b4 100644 --- a/tools/llvm-lto/Makefile +++ b/tools/llvm-lto/Makefile @@ -9,7 +9,7 @@ LEVEL := ../.. TOOLNAME := llvm-lto -LINK_COMPONENTS := support +LINK_COMPONENTS := lto ipo scalaropts linker bitreader bitwriter mcdisassembler support target vectorize all-targets # This tool has no plugins, optimize startup time. TOOL_NO_EXPORTS := 1 @@ -17,6 +17,3 @@ TOOL_NO_EXPORTS := 1 NO_INSTALL := 1 include $(LEVEL)/Makefile.common - -LDFLAGS += -L$(LibDir) -LIBS += -lLTO diff --git a/tools/llvm-lto/llvm-lto.cpp b/tools/llvm-lto/llvm-lto.cpp index f25037c..82a2c82 100644 --- a/tools/llvm-lto/llvm-lto.cpp +++ b/tools/llvm-lto/llvm-lto.cpp @@ -12,12 +12,14 @@ // //===----------------------------------------------------------------------===// -#include "llvm-c/lto.h" +#include "llvm/LTO/LTOCodeGenerator.h" +#include "llvm/LTO/LTOModule.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Signals.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/TargetSelect.h" using namespace llvm; @@ -37,46 +39,48 @@ int main(int argc, char **argv) { llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. cl::ParseCommandLineOptions(argc, argv, "llvm LTO linker\n"); + // Initialize the configured targets. + InitializeAllTargets(); + InitializeAllTargetMCs(); + InitializeAllAsmPrinters(); + InitializeAllAsmParsers(); + unsigned BaseArg = 0; std::string ErrorMessage; - lto_code_gen_t code_gen = lto_codegen_create(); - if (code_gen == NULL) - errs() << argv[0] << ": error creating a code generation module: " - << lto_get_error_message() << "\n"; + LTOCodeGenerator CodeGen; - lto_codegen_set_pic_model(code_gen, LTO_CODEGEN_PIC_MODEL_DYNAMIC); - lto_codegen_set_debug_model(code_gen, LTO_DEBUG_MODEL_DWARF); + CodeGen.setCodePICModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC); + CodeGen.setDebugInfo(LTO_DEBUG_MODEL_DWARF); for (unsigned i = BaseArg; i < InputFilenames.size(); ++i) { - lto_module_t BitcodeModule = lto_module_create(InputFilenames[i].c_str()); - if (BitcodeModule == NULL) { + std::string error; + OwningPtr Module(LTOModule::makeLTOModule(InputFilenames[i].c_str(), + error)); + if (!error.empty()) { errs() << argv[0] << ": error loading file '" << InputFilenames[i] - << "': " << lto_get_error_message() << "\n"; + << "': " << error << "\n"; return 1; } - if (lto_codegen_add_module(code_gen, BitcodeModule)) { + + if (!CodeGen.addModule(Module.get(), error)) { errs() << argv[0] << ": error adding file '" << InputFilenames[i] - << "': " << lto_get_error_message() << "\n"; - lto_module_dispose(BitcodeModule); + << "': " << error << "\n"; return 1; } - - lto_module_dispose(BitcodeModule); } if (!OutputFilename.empty()) { size_t len = 0; - const void *Code = lto_codegen_compile(code_gen, &len); + std::string ErrorInfo; + const void *Code = CodeGen.compile(&len, ErrorInfo); if (Code == NULL) { errs() << argv[0] - << ": error compiling the code: " << lto_get_error_message() - << "\n"; + << ": error compiling the code: " << ErrorInfo << "\n"; return 1; } - std::string ErrorInfo; raw_fd_ostream FileStream(OutputFilename.c_str(), ErrorInfo); if (!ErrorInfo.empty()) { errs() << argv[0] << ": error opening the file '" << OutputFilename @@ -86,10 +90,11 @@ int main(int argc, char **argv) { FileStream.write(reinterpret_cast(Code), len); } else { + std::string ErrorInfo; const char *OutputName = NULL; - if (lto_codegen_compile_to_file(code_gen, &OutputName)) { + if (!CodeGen.compile_to_file(&OutputName, ErrorInfo)) { errs() << argv[0] - << ": error compiling the code: " << lto_get_error_message() + << ": error compiling the code: " << ErrorInfo << "\n"; return 1; } @@ -97,7 +102,5 @@ int main(int argc, char **argv) { outs() << "Wrote native object file '" << OutputName << "'\n"; } - lto_codegen_dispose(code_gen); - return 0; } diff --git a/tools/lto/CMakeLists.txt b/tools/lto/CMakeLists.txt index c71aac1..8b26ddd 100644 --- a/tools/lto/CMakeLists.txt +++ b/tools/lto/CMakeLists.txt @@ -1,14 +1,12 @@ set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} - ipo scalaropts linker bitreader bitwriter mcdisassembler vectorize) + ipo scalaropts linker bitreader bitwriter lto mcdisassembler vectorize) add_definitions( -DLLVM_VERSION_INFO=\"${PACKAGE_VERSION}\" ) set(SOURCES - LTOCodeGenerator.cpp LTODisassembler.cpp lto.cpp - LTOModule.cpp ) if( NOT WIN32 AND LLVM_ENABLE_PIC ) diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp deleted file mode 100644 index 19e8c4c..0000000 --- a/tools/lto/LTOCodeGenerator.cpp +++ /dev/null @@ -1,458 +0,0 @@ -//===-LTOCodeGenerator.cpp - LLVM Link Time Optimizer ---------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Link Time Optimization library. This library is -// intended to be used by linker to optimize code at link time. -// -//===----------------------------------------------------------------------===// - -#include "LTOCodeGenerator.h" -#include "LTOModule.h" -#include "llvm/ADT/StringExtras.h" -#include "llvm/Analysis/Passes.h" -#include "llvm/Analysis/Verifier.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/Config/config.h" -#include "llvm/IR/Constants.h" -#include "llvm/IR/DataLayout.h" -#include "llvm/IR/DerivedTypes.h" -#include "llvm/IR/LLVMContext.h" -#include "llvm/IR/Module.h" -#include "llvm/InitializePasses.h" -#include "llvm/Linker.h" -#include "llvm/MC/MCAsmInfo.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/SubtargetFeature.h" -#include "llvm/PassManager.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/FormattedStream.h" -#include "llvm/Support/Host.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Signals.h" -#include "llvm/Support/TargetRegistry.h" -#include "llvm/Support/TargetSelect.h" -#include "llvm/Support/ToolOutputFile.h" -#include "llvm/Support/system_error.h" -#include "llvm/Target/Mangler.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" -#include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Transforms/IPO.h" -#include "llvm/Transforms/IPO/PassManagerBuilder.h" -#include "llvm/Transforms/ObjCARC.h" -using namespace llvm; - -static cl::opt -DisableOpt("disable-opt", cl::init(false), - cl::desc("Do not run any optimization passes")); - -static cl::opt -DisableInline("disable-inlining", cl::init(false), - cl::desc("Do not run the inliner pass")); - -static cl::opt -DisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false), - cl::desc("Do not run the GVN load PRE pass")); - -const char* LTOCodeGenerator::getVersionString() { -#ifdef LLVM_VERSION_INFO - return PACKAGE_NAME " version " PACKAGE_VERSION ", " LLVM_VERSION_INFO; -#else - return PACKAGE_NAME " version " PACKAGE_VERSION; -#endif -} - -LTOCodeGenerator::LTOCodeGenerator() - : Context(getGlobalContext()), Linker(new Module("ld-temp.o", Context)), - TargetMach(NULL), EmitDwarfDebugInfo(false), ScopeRestrictionsDone(false), - CodeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC), NativeObjectFile(NULL) { - InitializeAllTargets(); - InitializeAllTargetMCs(); - InitializeAllAsmPrinters(); - initializeLTOPasses(); -} - -LTOCodeGenerator::~LTOCodeGenerator() { - delete TargetMach; - delete NativeObjectFile; - delete Linker.getModule(); - - for (std::vector::iterator I = CodegenOptions.begin(), - E = CodegenOptions.end(); - I != E; ++I) - free(*I); -} - -// Initialize LTO passes. Please keep this funciton in sync with -// PassManagerBuilder::populateLTOPassManager(), and make sure all LTO -// passes are initialized. -// -void LTOCodeGenerator::initializeLTOPasses() { - PassRegistry &R = *PassRegistry::getPassRegistry(); - - initializeInternalizePassPass(R); - initializeIPSCCPPass(R); - initializeGlobalOptPass(R); - initializeConstantMergePass(R); - initializeDAHPass(R); - initializeInstCombinerPass(R); - initializeSimpleInlinerPass(R); - initializePruneEHPass(R); - initializeGlobalDCEPass(R); - initializeArgPromotionPass(R); - initializeJumpThreadingPass(R); - initializeSROAPass(R); - initializeSROA_DTPass(R); - initializeSROA_SSAUpPass(R); - initializeFunctionAttrsPass(R); - initializeGlobalsModRefPass(R); - initializeLICMPass(R); - initializeGVNPass(R); - initializeMemCpyOptPass(R); - initializeDCEPass(R); - initializeCFGSimplifyPassPass(R); -} - -bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg) { - bool ret = Linker.linkInModule(mod->getLLVVMModule(), &errMsg); - - const std::vector &undefs = mod->getAsmUndefinedRefs(); - for (int i = 0, e = undefs.size(); i != e; ++i) - AsmUndefinedRefs[undefs[i]] = 1; - - return !ret; -} - -void LTOCodeGenerator::setDebugInfo(lto_debug_model debug) { - switch (debug) { - case LTO_DEBUG_MODEL_NONE: - EmitDwarfDebugInfo = false; - return; - - case LTO_DEBUG_MODEL_DWARF: - EmitDwarfDebugInfo = true; - return; - } - llvm_unreachable("Unknown debug format!"); -} - -void LTOCodeGenerator::setCodePICModel(lto_codegen_model model) { - switch (model) { - case LTO_CODEGEN_PIC_MODEL_STATIC: - case LTO_CODEGEN_PIC_MODEL_DYNAMIC: - case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC: - CodeModel = model; - return; - } - llvm_unreachable("Unknown PIC model!"); -} - -bool LTOCodeGenerator::writeMergedModules(const char *path, - std::string &errMsg) { - if (!determineTarget(errMsg)) - return false; - - // mark which symbols can not be internalized - applyScopeRestrictions(); - - // create output file - std::string ErrInfo; - tool_output_file Out(path, ErrInfo, sys::fs::F_Binary); - if (!ErrInfo.empty()) { - errMsg = "could not open bitcode file for writing: "; - errMsg += path; - return false; - } - - // write bitcode to it - WriteBitcodeToFile(Linker.getModule(), Out.os()); - Out.os().close(); - - if (Out.os().has_error()) { - errMsg = "could not write bitcode file: "; - errMsg += path; - Out.os().clear_error(); - return false; - } - - Out.keep(); - return true; -} - -bool LTOCodeGenerator::compile_to_file(const char** name, std::string& errMsg) { - // make unique temp .o file to put generated object file - SmallString<128> Filename; - int FD; - error_code EC = sys::fs::createTemporaryFile("lto-llvm", "o", FD, Filename); - if (EC) { - errMsg = EC.message(); - return false; - } - - // generate object file - tool_output_file objFile(Filename.c_str(), FD); - - bool genResult = generateObjectFile(objFile.os(), errMsg); - objFile.os().close(); - if (objFile.os().has_error()) { - objFile.os().clear_error(); - sys::fs::remove(Twine(Filename)); - return false; - } - - objFile.keep(); - if (!genResult) { - sys::fs::remove(Twine(Filename)); - return false; - } - - NativeObjectPath = Filename.c_str(); - *name = NativeObjectPath.c_str(); - return true; -} - -const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg) { - const char *name; - if (!compile_to_file(&name, errMsg)) - return NULL; - - // remove old buffer if compile() called twice - delete NativeObjectFile; - - // read .o file into memory buffer - OwningPtr BuffPtr; - if (error_code ec = MemoryBuffer::getFile(name, BuffPtr, -1, false)) { - errMsg = ec.message(); - sys::fs::remove(NativeObjectPath); - return NULL; - } - NativeObjectFile = BuffPtr.take(); - - // remove temp files - sys::fs::remove(NativeObjectPath); - - // return buffer, unless error - if (NativeObjectFile == NULL) - return NULL; - *length = NativeObjectFile->getBufferSize(); - return NativeObjectFile->getBufferStart(); -} - -bool LTOCodeGenerator::determineTarget(std::string &errMsg) { - if (TargetMach != NULL) - return true; - - // if options were requested, set them - if (!CodegenOptions.empty()) - cl::ParseCommandLineOptions(CodegenOptions.size(), - const_cast(&CodegenOptions[0])); - - std::string TripleStr = Linker.getModule()->getTargetTriple(); - if (TripleStr.empty()) - TripleStr = sys::getDefaultTargetTriple(); - llvm::Triple Triple(TripleStr); - - // create target machine from info for merged modules - const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg); - if (march == NULL) - return false; - - // The relocation model is actually a static member of TargetMachine and - // needs to be set before the TargetMachine is instantiated. - Reloc::Model RelocModel = Reloc::Default; - switch (CodeModel) { - case LTO_CODEGEN_PIC_MODEL_STATIC: - RelocModel = Reloc::Static; - break; - case LTO_CODEGEN_PIC_MODEL_DYNAMIC: - RelocModel = Reloc::PIC_; - break; - case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC: - RelocModel = Reloc::DynamicNoPIC; - break; - } - - // construct LTOModule, hand over ownership of module and target - SubtargetFeatures Features; - Features.getDefaultSubtargetFeatures(Triple); - std::string FeatureStr = Features.getString(); - // Set a default CPU for Darwin triples. - if (MCpu.empty() && Triple.isOSDarwin()) { - if (Triple.getArch() == llvm::Triple::x86_64) - MCpu = "core2"; - else if (Triple.getArch() == llvm::Triple::x86) - MCpu = "yonah"; - } - TargetOptions Options; - LTOModule::getTargetOptions(Options); - TargetMach = march->createTargetMachine(TripleStr, MCpu, FeatureStr, Options, - RelocModel, CodeModel::Default, - CodeGenOpt::Aggressive); - return true; -} - -void LTOCodeGenerator:: -applyRestriction(GlobalValue &GV, - std::vector &MustPreserveList, - SmallPtrSet &AsmUsed, - Mangler &Mangler) { - SmallString<64> Buffer; - Mangler.getNameWithPrefix(Buffer, &GV, false); - - if (GV.isDeclaration()) - return; - if (MustPreserveSymbols.count(Buffer)) - MustPreserveList.push_back(GV.getName().data()); - if (AsmUndefinedRefs.count(Buffer)) - AsmUsed.insert(&GV); -} - -static void findUsedValues(GlobalVariable *LLVMUsed, - SmallPtrSet &UsedValues) { - if (LLVMUsed == 0) return; - - ConstantArray *Inits = cast(LLVMUsed->getInitializer()); - for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i) - if (GlobalValue *GV = - dyn_cast(Inits->getOperand(i)->stripPointerCasts())) - UsedValues.insert(GV); -} - -void LTOCodeGenerator::applyScopeRestrictions() { - if (ScopeRestrictionsDone) - return; - Module *mergedModule = Linker.getModule(); - - // Start off with a verification pass. - PassManager passes; - passes.add(createVerifierPass()); - - // mark which symbols can not be internalized - MCContext MContext(TargetMach->getMCAsmInfo(), TargetMach->getRegisterInfo(), - NULL); - Mangler Mangler(MContext, TargetMach); - std::vector MustPreserveList; - SmallPtrSet AsmUsed; - - for (Module::iterator f = mergedModule->begin(), - e = mergedModule->end(); f != e; ++f) - applyRestriction(*f, MustPreserveList, AsmUsed, Mangler); - for (Module::global_iterator v = mergedModule->global_begin(), - e = mergedModule->global_end(); v != e; ++v) - applyRestriction(*v, MustPreserveList, AsmUsed, Mangler); - for (Module::alias_iterator a = mergedModule->alias_begin(), - e = mergedModule->alias_end(); a != e; ++a) - applyRestriction(*a, MustPreserveList, AsmUsed, Mangler); - - GlobalVariable *LLVMCompilerUsed = - mergedModule->getGlobalVariable("llvm.compiler.used"); - findUsedValues(LLVMCompilerUsed, AsmUsed); - if (LLVMCompilerUsed) - LLVMCompilerUsed->eraseFromParent(); - - if (!AsmUsed.empty()) { - llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(Context); - std::vector asmUsed2; - for (SmallPtrSet::const_iterator i = AsmUsed.begin(), - e = AsmUsed.end(); i !=e; ++i) { - GlobalValue *GV = *i; - Constant *c = ConstantExpr::getBitCast(GV, i8PTy); - asmUsed2.push_back(c); - } - - llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, asmUsed2.size()); - LLVMCompilerUsed = - new llvm::GlobalVariable(*mergedModule, ATy, false, - llvm::GlobalValue::AppendingLinkage, - llvm::ConstantArray::get(ATy, asmUsed2), - "llvm.compiler.used"); - - LLVMCompilerUsed->setSection("llvm.metadata"); - } - - passes.add(createInternalizePass(MustPreserveList)); - - // apply scope restrictions - passes.run(*mergedModule); - - ScopeRestrictionsDone = true; -} - -/// Optimize merged modules using various IPO passes -bool LTOCodeGenerator::generateObjectFile(raw_ostream &out, - std::string &errMsg) { - if (!this->determineTarget(errMsg)) - return false; - - Module *mergedModule = Linker.getModule(); - - // Mark which symbols can not be internalized - this->applyScopeRestrictions(); - - // Instantiate the pass manager to organize the passes. - PassManager passes; - - // Start off with a verification pass. - passes.add(createVerifierPass()); - - // Add an appropriate DataLayout instance for this module... - passes.add(new DataLayout(*TargetMach->getDataLayout())); - TargetMach->addAnalysisPasses(passes); - - // Enabling internalize here would use its AllButMain variant. It - // keeps only main if it exists and does nothing for libraries. Instead - // we create the pass ourselves with the symbol list provided by the linker. - if (!DisableOpt) - PassManagerBuilder().populateLTOPassManager(passes, - /*Internalize=*/false, - !DisableInline, - DisableGVNLoadPRE); - - // Make sure everything is still good. - passes.add(createVerifierPass()); - - PassManager codeGenPasses; - - codeGenPasses.add(new DataLayout(*TargetMach->getDataLayout())); - TargetMach->addAnalysisPasses(codeGenPasses); - - formatted_raw_ostream Out(out); - - // If the bitcode files contain ARC code and were compiled with optimization, - // the ObjCARCContractPass must be run, so do it unconditionally here. - codeGenPasses.add(createObjCARCContractPass()); - - if (TargetMach->addPassesToEmitFile(codeGenPasses, Out, - TargetMachine::CGFT_ObjectFile)) { - errMsg = "target file type not supported"; - return false; - } - - // Run our queue of passes all at once now, efficiently. - passes.run(*mergedModule); - - // Run the code generator, and write assembly file - codeGenPasses.run(*mergedModule); - - return true; -} - -/// setCodeGenDebugOptions - Set codegen debugging options to aid in debugging -/// LTO problems. -void LTOCodeGenerator::setCodeGenDebugOptions(const char *options) { - for (std::pair o = getToken(options); - !o.first.empty(); o = getToken(o.second)) { - // ParseCommandLineOptions() expects argv[0] to be program name. Lazily add - // that. - if (CodegenOptions.empty()) - CodegenOptions.push_back(strdup("libLTO")); - CodegenOptions.push_back(strdup(o.first.str().c_str())); - } -} diff --git a/tools/lto/LTOCodeGenerator.h b/tools/lto/LTOCodeGenerator.h deleted file mode 100644 index 0263362..0000000 --- a/tools/lto/LTOCodeGenerator.h +++ /dev/null @@ -1,130 +0,0 @@ -//===-LTOCodeGenerator.h - LLVM Link Time Optimizer -----------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the LTOCodeGenerator class. -// -// LTO compilation consists of three phases: Pre-IPO, IPO and Post-IPO. -// -// The Pre-IPO phase compiles source code into bitcode file. The resulting -// bitcode files, along with object files and libraries, will be fed to the -// linker to through the IPO and Post-IPO phases. By using obj-file extension, -// the resulting bitcode file disguises itself as an object file, and therefore -// obviates the need of writing a special set of the make-rules only for LTO -// compilation. -// -// The IPO phase perform inter-procedural analyses and optimizations, and -// the Post-IPO consists two sub-phases: intra-procedural scalar optimizations -// (SOPT), and intra-procedural target-dependent code generator (CG). -// -// As of this writing, we don't separate IPO and the Post-IPO SOPT. They -// are intermingled together, and are driven by a single pass manager (see -// PassManagerBuilder::populateLTOPassManager()). -// -// The "LTOCodeGenerator" is the driver for the IPO and Post-IPO stages. -// The "CodeGenerator" here is bit confusing. Don't confuse the "CodeGenerator" -// with the machine specific code generator. -// -//===----------------------------------------------------------------------===// - -#ifndef LTO_CODE_GENERATOR_H -#define LTO_CODE_GENERATOR_H - -#include "llvm-c/lto.h" -#include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/Linker.h" -#include -#include - -namespace llvm { - class LLVMContext; - class GlobalValue; - class Mangler; - class MemoryBuffer; - class TargetMachine; - class raw_ostream; -} - -//===----------------------------------------------------------------------===// -/// LTOCodeGenerator - C++ class which implements the opaque lto_code_gen_t -/// type. -/// -struct LTOCodeGenerator { - static const char *getVersionString(); - - LTOCodeGenerator(); - ~LTOCodeGenerator(); - - // Merge given module, return true on success. - bool addModule(struct LTOModule*, std::string &errMsg); - - void setDebugInfo(lto_debug_model); - void setCodePICModel(lto_codegen_model); - - void setCpu(const char *mCpu) { MCpu = mCpu; } - - void addMustPreserveSymbol(const char *sym) { MustPreserveSymbols[sym] = 1; } - - // To pass options to the driver and optimization passes. These options are - // not necessarily for debugging purpose (The function name is misleading). - // This function should be called before LTOCodeGenerator::compilexxx(), - // and LTOCodeGenerator::writeMergedModules(). - // - void setCodeGenDebugOptions(const char *opts); - - // Write the merged module to the file specified by the given path. - // Return true on success. - bool writeMergedModules(const char *path, std::string &errMsg); - - // Compile the merged module into a *single* object file; the path to object - // file is returned to the caller via argument "name". Return true on - // success. - // - // NOTE that it is up to the linker to remove the intermediate object file. - // Do not try to remove the object file in LTOCodeGenerator's destructor - // as we don't who (LTOCodeGenerator or the obj file) will last longer. - // - bool compile_to_file(const char **name, std::string &errMsg); - - // As with compile_to_file(), this function compiles the merged module into - // single object file. Instead of returning the object-file-path to the caller - // (linker), it brings the object to a buffer, and return the buffer to the - // caller. This function should delete intermediate object file once its content - // is brought to memory. Return NULL is the compilation was not successful. - // - const void *compile(size_t *length, std::string &errMsg); - -private: - void initializeLTOPasses(); - - bool generateObjectFile(llvm::raw_ostream &out, std::string &errMsg); - void applyScopeRestrictions(); - void applyRestriction(llvm::GlobalValue &GV, - std::vector &MustPreserveList, - llvm::SmallPtrSet &AsmUsed, - llvm::Mangler &Mangler); - bool determineTarget(std::string &errMsg); - - typedef llvm::StringMap StringSet; - - llvm::LLVMContext &Context; - llvm::Linker Linker; - llvm::TargetMachine *TargetMach; - bool EmitDwarfDebugInfo; - bool ScopeRestrictionsDone; - lto_codegen_model CodeModel; - StringSet MustPreserveSymbols; - StringSet AsmUndefinedRefs; - llvm::MemoryBuffer *NativeObjectFile; - std::vector CodegenOptions; - std::string MCpu; - std::string NativeObjectPath; -}; - -#endif // LTO_CODE_GENERATOR_H diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp deleted file mode 100644 index 87e3573..0000000 --- a/tools/lto/LTOModule.cpp +++ /dev/null @@ -1,908 +0,0 @@ -//===-- LTOModule.cpp - LLVM Link Time Optimizer --------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file implements the Link Time Optimization library. This library is -// intended to be used by linker to optimize code at link time. -// -//===----------------------------------------------------------------------===// - -#include "LTOModule.h" -#include "llvm/ADT/OwningPtr.h" -#include "llvm/ADT/Triple.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/IR/Constants.h" -#include "llvm/IR/LLVMContext.h" -#include "llvm/IR/Module.h" -#include "llvm/MC/MCExpr.h" -#include "llvm/MC/MCInst.h" -#include "llvm/MC/MCInstrInfo.h" -#include "llvm/MC/MCParser/MCAsmParser.h" -#include "llvm/MC/MCStreamer.h" -#include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/MC/MCSymbol.h" -#include "llvm/MC/MCTargetAsmParser.h" -#include "llvm/MC/SubtargetFeature.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Host.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Support/TargetRegistry.h" -#include "llvm/Support/TargetSelect.h" -#include "llvm/Support/system_error.h" -#include "llvm/Target/TargetRegisterInfo.h" -using namespace llvm; - -static cl::opt -EnableFPMAD("enable-fp-mad", - cl::desc("Enable less precise MAD instructions to be generated"), - cl::init(false)); - -static cl::opt -DisableFPElim("disable-fp-elim", - cl::desc("Disable frame pointer elimination optimization"), - cl::init(false)); - -static cl::opt -EnableUnsafeFPMath("enable-unsafe-fp-math", - cl::desc("Enable optimizations that may decrease FP precision"), - cl::init(false)); - -static cl::opt -EnableNoInfsFPMath("enable-no-infs-fp-math", - cl::desc("Enable FP math optimizations that assume no +-Infs"), - cl::init(false)); - -static cl::opt -EnableNoNaNsFPMath("enable-no-nans-fp-math", - cl::desc("Enable FP math optimizations that assume no NaNs"), - cl::init(false)); - -static cl::opt -EnableHonorSignDependentRoundingFPMath("enable-sign-dependent-rounding-fp-math", - cl::Hidden, - cl::desc("Force codegen to assume rounding mode can change dynamically"), - cl::init(false)); - -static cl::opt -GenerateSoftFloatCalls("soft-float", - cl::desc("Generate software floating point library calls"), - cl::init(false)); - -static cl::opt -FloatABIForCalls("float-abi", - cl::desc("Choose float ABI type"), - cl::init(FloatABI::Default), - cl::values( - clEnumValN(FloatABI::Default, "default", - "Target default float ABI type"), - clEnumValN(FloatABI::Soft, "soft", - "Soft float ABI (implied by -soft-float)"), - clEnumValN(FloatABI::Hard, "hard", - "Hard float ABI (uses FP registers)"), - clEnumValEnd)); - -static cl::opt -FuseFPOps("fp-contract", - cl::desc("Enable aggresive formation of fused FP ops"), - cl::init(FPOpFusion::Standard), - cl::values( - clEnumValN(FPOpFusion::Fast, "fast", - "Fuse FP ops whenever profitable"), - clEnumValN(FPOpFusion::Standard, "on", - "Only fuse 'blessed' FP ops."), - clEnumValN(FPOpFusion::Strict, "off", - "Only fuse FP ops when the result won't be effected."), - clEnumValEnd)); - -static cl::opt -DontPlaceZerosInBSS("nozero-initialized-in-bss", - cl::desc("Don't place zero-initialized symbols into bss section"), - cl::init(false)); - -static cl::opt -EnableGuaranteedTailCallOpt("tailcallopt", - cl::desc("Turn fastcc calls into tail calls by (potentially) changing ABI."), - cl::init(false)); - -static cl::opt -DisableTailCalls("disable-tail-calls", - cl::desc("Never emit tail calls"), - cl::init(false)); - -static cl::opt -OverrideStackAlignment("stack-alignment", - cl::desc("Override default stack alignment"), - cl::init(0)); - -static cl::opt -TrapFuncName("trap-func", cl::Hidden, - cl::desc("Emit a call to trap function rather than a trap instruction"), - cl::init("")); - -static cl::opt -EnablePIE("enable-pie", - cl::desc("Assume the creation of a position independent executable."), - cl::init(false)); - -static cl::opt -SegmentedStacks("segmented-stacks", - cl::desc("Use segmented stacks if possible."), - cl::init(false)); - -static cl::opt -UseInitArray("use-init-array", - cl::desc("Use .init_array instead of .ctors."), - cl::init(false)); - -LTOModule::LTOModule(llvm::Module *m, llvm::TargetMachine *t) - : _module(m), _target(t), - _context(_target->getMCAsmInfo(), _target->getRegisterInfo(), NULL), - _mangler(_context, t) {} - -/// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM -/// bitcode. -bool LTOModule::isBitcodeFile(const void *mem, size_t length) { - return sys::fs::identify_magic(StringRef((const char *)mem, length)) == - sys::fs::file_magic::bitcode; -} - -bool LTOModule::isBitcodeFile(const char *path) { - sys::fs::file_magic type; - if (sys::fs::identify_magic(path, type)) - return false; - return type == sys::fs::file_magic::bitcode; -} - -/// isBitcodeFileForTarget - Returns 'true' if the file (or memory contents) is -/// LLVM bitcode for the specified triple. -bool LTOModule::isBitcodeFileForTarget(const void *mem, size_t length, - const char *triplePrefix) { - MemoryBuffer *buffer = makeBuffer(mem, length); - if (!buffer) - return false; - return isTargetMatch(buffer, triplePrefix); -} - -bool LTOModule::isBitcodeFileForTarget(const char *path, - const char *triplePrefix) { - OwningPtr buffer; - if (MemoryBuffer::getFile(path, buffer)) - return false; - return isTargetMatch(buffer.take(), triplePrefix); -} - -/// isTargetMatch - Returns 'true' if the memory buffer is for the specified -/// target triple. -bool LTOModule::isTargetMatch(MemoryBuffer *buffer, const char *triplePrefix) { - std::string Triple = getBitcodeTargetTriple(buffer, getGlobalContext()); - delete buffer; - return strncmp(Triple.c_str(), triplePrefix, strlen(triplePrefix)) == 0; -} - -/// makeLTOModule - Create an LTOModule. N.B. These methods take ownership of -/// the buffer. -LTOModule *LTOModule::makeLTOModule(const char *path, std::string &errMsg) { - OwningPtr buffer; - if (error_code ec = MemoryBuffer::getFile(path, buffer)) { - errMsg = ec.message(); - return NULL; - } - return makeLTOModule(buffer.take(), errMsg); -} - -LTOModule *LTOModule::makeLTOModule(int fd, const char *path, - size_t size, std::string &errMsg) { - return makeLTOModule(fd, path, size, 0, errMsg); -} - -LTOModule *LTOModule::makeLTOModule(int fd, const char *path, - size_t map_size, - off_t offset, - std::string &errMsg) { - OwningPtr buffer; - if (error_code ec = - MemoryBuffer::getOpenFileSlice(fd, path, buffer, map_size, offset)) { - errMsg = ec.message(); - return NULL; - } - return makeLTOModule(buffer.take(), errMsg); -} - -LTOModule *LTOModule::makeLTOModule(const void *mem, size_t length, - std::string &errMsg) { - OwningPtr buffer(makeBuffer(mem, length)); - if (!buffer) - return NULL; - return makeLTOModule(buffer.take(), errMsg); -} - -void LTOModule::getTargetOptions(TargetOptions &Options) { - Options.LessPreciseFPMADOption = EnableFPMAD; - Options.NoFramePointerElim = DisableFPElim; - Options.AllowFPOpFusion = FuseFPOps; - Options.UnsafeFPMath = EnableUnsafeFPMath; - Options.NoInfsFPMath = EnableNoInfsFPMath; - Options.NoNaNsFPMath = EnableNoNaNsFPMath; - Options.HonorSignDependentRoundingFPMathOption = - EnableHonorSignDependentRoundingFPMath; - Options.UseSoftFloat = GenerateSoftFloatCalls; - if (FloatABIForCalls != FloatABI::Default) - Options.FloatABIType = FloatABIForCalls; - Options.NoZerosInBSS = DontPlaceZerosInBSS; - Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt; - Options.DisableTailCalls = DisableTailCalls; - Options.StackAlignmentOverride = OverrideStackAlignment; - Options.TrapFuncName = TrapFuncName; - Options.PositionIndependentExecutable = EnablePIE; - Options.EnableSegmentedStacks = SegmentedStacks; - Options.UseInitArray = UseInitArray; -} - -LTOModule *LTOModule::makeLTOModule(MemoryBuffer *buffer, - std::string &errMsg) { - static bool Initialized = false; - if (!Initialized) { - InitializeAllTargets(); - InitializeAllTargetMCs(); - InitializeAllAsmParsers(); - Initialized = true; - } - - // parse bitcode buffer - OwningPtr m(getLazyBitcodeModule(buffer, getGlobalContext(), - &errMsg)); - if (!m) { - delete buffer; - return NULL; - } - - std::string TripleStr = m->getTargetTriple(); - if (TripleStr.empty()) - TripleStr = sys::getDefaultTargetTriple(); - llvm::Triple Triple(TripleStr); - - // find machine architecture for this module - const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg); - if (!march) - return NULL; - - // construct LTOModule, hand over ownership of module and target - SubtargetFeatures Features; - Features.getDefaultSubtargetFeatures(Triple); - std::string FeatureStr = Features.getString(); - // Set a default CPU for Darwin triples. - std::string CPU; - if (Triple.isOSDarwin()) { - if (Triple.getArch() == llvm::Triple::x86_64) - CPU = "core2"; - else if (Triple.getArch() == llvm::Triple::x86) - CPU = "yonah"; - } - TargetOptions Options; - getTargetOptions(Options); - TargetMachine *target = march->createTargetMachine(TripleStr, CPU, FeatureStr, - Options); - LTOModule *Ret = new LTOModule(m.take(), target); - if (Ret->parseSymbols(errMsg)) { - delete Ret; - return NULL; - } - - return Ret; -} - -/// makeBuffer - Create a MemoryBuffer from a memory range. -MemoryBuffer *LTOModule::makeBuffer(const void *mem, size_t length) { - const char *startPtr = (const char*)mem; - return MemoryBuffer::getMemBuffer(StringRef(startPtr, length), "", false); -} - -/// objcClassNameFromExpression - Get string that the data pointer points to. -bool -LTOModule::objcClassNameFromExpression(const Constant *c, std::string &name) { - if (const ConstantExpr *ce = dyn_cast(c)) { - Constant *op = ce->getOperand(0); - if (GlobalVariable *gvn = dyn_cast(op)) { - Constant *cn = gvn->getInitializer(); - if (ConstantDataArray *ca = dyn_cast(cn)) { - if (ca->isCString()) { - name = ".objc_class_name_" + ca->getAsCString().str(); - return true; - } - } - } - } - return false; -} - -/// addObjCClass - Parse i386/ppc ObjC class data structure. -void LTOModule::addObjCClass(const GlobalVariable *clgv) { - const ConstantStruct *c = dyn_cast(clgv->getInitializer()); - if (!c) return; - - // second slot in __OBJC,__class is pointer to superclass name - std::string superclassName; - if (objcClassNameFromExpression(c->getOperand(1), superclassName)) { - NameAndAttributes info; - StringMap::value_type &entry = - _undefines.GetOrCreateValue(superclassName); - if (!entry.getValue().name) { - const char *symbolName = entry.getKey().data(); - info.name = symbolName; - info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; - info.isFunction = false; - info.symbol = clgv; - entry.setValue(info); - } - } - - // third slot in __OBJC,__class is pointer to class name - std::string className; - if (objcClassNameFromExpression(c->getOperand(2), className)) { - StringSet::value_type &entry = _defines.GetOrCreateValue(className); - entry.setValue(1); - - NameAndAttributes info; - info.name = entry.getKey().data(); - info.attributes = LTO_SYMBOL_PERMISSIONS_DATA | - LTO_SYMBOL_DEFINITION_REGULAR | LTO_SYMBOL_SCOPE_DEFAULT; - info.isFunction = false; - info.symbol = clgv; - _symbols.push_back(info); - } -} - -/// addObjCCategory - Parse i386/ppc ObjC category data structure. -void LTOModule::addObjCCategory(const GlobalVariable *clgv) { - const ConstantStruct *c = dyn_cast(clgv->getInitializer()); - if (!c) return; - - // second slot in __OBJC,__category is pointer to target class name - std::string targetclassName; - if (!objcClassNameFromExpression(c->getOperand(1), targetclassName)) - return; - - NameAndAttributes info; - StringMap::value_type &entry = - _undefines.GetOrCreateValue(targetclassName); - - if (entry.getValue().name) - return; - - const char *symbolName = entry.getKey().data(); - info.name = symbolName; - info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; - info.isFunction = false; - info.symbol = clgv; - entry.setValue(info); -} - -/// addObjCClassRef - Parse i386/ppc ObjC class list data structure. -void LTOModule::addObjCClassRef(const GlobalVariable *clgv) { - std::string targetclassName; - if (!objcClassNameFromExpression(clgv->getInitializer(), targetclassName)) - return; - - NameAndAttributes info; - StringMap::value_type &entry = - _undefines.GetOrCreateValue(targetclassName); - if (entry.getValue().name) - return; - - const char *symbolName = entry.getKey().data(); - info.name = symbolName; - info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; - info.isFunction = false; - info.symbol = clgv; - entry.setValue(info); -} - -/// addDefinedDataSymbol - Add a data symbol as defined to the list. -void LTOModule::addDefinedDataSymbol(const GlobalValue *v) { - // Add to list of defined symbols. - addDefinedSymbol(v, false); - - if (!v->hasSection() /* || !isTargetDarwin */) - return; - - // Special case i386/ppc ObjC data structures in magic sections: - // The issue is that the old ObjC object format did some strange - // contortions to avoid real linker symbols. For instance, the - // ObjC class data structure is allocated statically in the executable - // that defines that class. That data structures contains a pointer to - // its superclass. But instead of just initializing that part of the - // struct to the address of its superclass, and letting the static and - // dynamic linkers do the rest, the runtime works by having that field - // instead point to a C-string that is the name of the superclass. - // At runtime the objc initialization updates that pointer and sets - // it to point to the actual super class. As far as the linker - // knows it is just a pointer to a string. But then someone wanted the - // linker to issue errors at build time if the superclass was not found. - // So they figured out a way in mach-o object format to use an absolute - // symbols (.objc_class_name_Foo = 0) and a floating reference - // (.reference .objc_class_name_Bar) to cause the linker into erroring when - // a class was missing. - // The following synthesizes the implicit .objc_* symbols for the linker - // from the ObjC data structures generated by the front end. - - // special case if this data blob is an ObjC class definition - if (v->getSection().compare(0, 15, "__OBJC,__class,") == 0) { - if (const GlobalVariable *gv = dyn_cast(v)) { - addObjCClass(gv); - } - } - - // special case if this data blob is an ObjC category definition - else if (v->getSection().compare(0, 18, "__OBJC,__category,") == 0) { - if (const GlobalVariable *gv = dyn_cast(v)) { - addObjCCategory(gv); - } - } - - // special case if this data blob is the list of referenced classes - else if (v->getSection().compare(0, 18, "__OBJC,__cls_refs,") == 0) { - if (const GlobalVariable *gv = dyn_cast(v)) { - addObjCClassRef(gv); - } - } -} - -/// addDefinedFunctionSymbol - Add a function symbol as defined to the list. -void LTOModule::addDefinedFunctionSymbol(const Function *f) { - // add to list of defined symbols - addDefinedSymbol(f, true); -} - -/// addDefinedSymbol - Add a defined symbol to the list. -void LTOModule::addDefinedSymbol(const GlobalValue *def, bool isFunction) { - // ignore all llvm.* symbols - if (def->getName().startswith("llvm.")) - return; - - // string is owned by _defines - SmallString<64> Buffer; - _mangler.getNameWithPrefix(Buffer, def, false); - - // set alignment part log2() can have rounding errors - uint32_t align = def->getAlignment(); - uint32_t attr = align ? countTrailingZeros(def->getAlignment()) : 0; - - // set permissions part - if (isFunction) { - attr |= LTO_SYMBOL_PERMISSIONS_CODE; - } else { - const GlobalVariable *gv = dyn_cast(def); - if (gv && gv->isConstant()) - attr |= LTO_SYMBOL_PERMISSIONS_RODATA; - else - attr |= LTO_SYMBOL_PERMISSIONS_DATA; - } - - // set definition part - if (def->hasWeakLinkage() || def->hasLinkOnceLinkage() || - def->hasLinkerPrivateWeakLinkage()) - attr |= LTO_SYMBOL_DEFINITION_WEAK; - else if (def->hasCommonLinkage()) - attr |= LTO_SYMBOL_DEFINITION_TENTATIVE; - else - attr |= LTO_SYMBOL_DEFINITION_REGULAR; - - // set scope part - if (def->hasHiddenVisibility()) - attr |= LTO_SYMBOL_SCOPE_HIDDEN; - else if (def->hasProtectedVisibility()) - attr |= LTO_SYMBOL_SCOPE_PROTECTED; - else if (def->hasExternalLinkage() || def->hasWeakLinkage() || - def->hasLinkOnceLinkage() || def->hasCommonLinkage() || - def->hasLinkerPrivateWeakLinkage()) - attr |= LTO_SYMBOL_SCOPE_DEFAULT; - else if (def->hasLinkOnceODRAutoHideLinkage()) - attr |= LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN; - else - attr |= LTO_SYMBOL_SCOPE_INTERNAL; - - StringSet::value_type &entry = _defines.GetOrCreateValue(Buffer); - entry.setValue(1); - - // fill information structure - NameAndAttributes info; - StringRef Name = entry.getKey(); - info.name = Name.data(); - assert(info.name[Name.size()] == '\0'); - info.attributes = attr; - info.isFunction = isFunction; - info.symbol = def; - - // add to table of symbols - _symbols.push_back(info); -} - -/// addAsmGlobalSymbol - Add a global symbol from module-level ASM to the -/// defined list. -void LTOModule::addAsmGlobalSymbol(const char *name, - lto_symbol_attributes scope) { - StringSet::value_type &entry = _defines.GetOrCreateValue(name); - - // only add new define if not already defined - if (entry.getValue()) - return; - - entry.setValue(1); - - NameAndAttributes &info = _undefines[entry.getKey().data()]; - - if (info.symbol == 0) { - // FIXME: This is trying to take care of module ASM like this: - // - // module asm ".zerofill __FOO, __foo, _bar_baz_qux, 0" - // - // but is gross and its mother dresses it funny. Have the ASM parser give us - // more details for this type of situation so that we're not guessing so - // much. - - // fill information structure - info.name = entry.getKey().data(); - info.attributes = - LTO_SYMBOL_PERMISSIONS_DATA | LTO_SYMBOL_DEFINITION_REGULAR | scope; - info.isFunction = false; - info.symbol = 0; - - // add to table of symbols - _symbols.push_back(info); - return; - } - - if (info.isFunction) - addDefinedFunctionSymbol(cast(info.symbol)); - else - addDefinedDataSymbol(info.symbol); - - _symbols.back().attributes &= ~LTO_SYMBOL_SCOPE_MASK; - _symbols.back().attributes |= scope; -} - -/// addAsmGlobalSymbolUndef - Add a global symbol from module-level ASM to the -/// undefined list. -void LTOModule::addAsmGlobalSymbolUndef(const char *name) { - StringMap::value_type &entry = - _undefines.GetOrCreateValue(name); - - _asm_undefines.push_back(entry.getKey().data()); - - // we already have the symbol - if (entry.getValue().name) - return; - - uint32_t attr = LTO_SYMBOL_DEFINITION_UNDEFINED;; - attr |= LTO_SYMBOL_SCOPE_DEFAULT; - NameAndAttributes info; - info.name = entry.getKey().data(); - info.attributes = attr; - info.isFunction = false; - info.symbol = 0; - - entry.setValue(info); -} - -/// addPotentialUndefinedSymbol - Add a symbol which isn't defined just yet to a -/// list to be resolved later. -void -LTOModule::addPotentialUndefinedSymbol(const GlobalValue *decl, bool isFunc) { - // ignore all llvm.* symbols - if (decl->getName().startswith("llvm.")) - return; - - // ignore all aliases - if (isa(decl)) - return; - - SmallString<64> name; - _mangler.getNameWithPrefix(name, decl, false); - - StringMap::value_type &entry = - _undefines.GetOrCreateValue(name); - - // we already have the symbol - if (entry.getValue().name) - return; - - NameAndAttributes info; - - info.name = entry.getKey().data(); - - if (decl->hasExternalWeakLinkage()) - info.attributes = LTO_SYMBOL_DEFINITION_WEAKUNDEF; - else - info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; - - info.isFunction = isFunc; - info.symbol = decl; - - entry.setValue(info); -} - -namespace { - class RecordStreamer : public MCStreamer { - public: - enum State { NeverSeen, Global, Defined, DefinedGlobal, Used }; - - private: - StringMap Symbols; - - void markDefined(const MCSymbol &Symbol) { - State &S = Symbols[Symbol.getName()]; - switch (S) { - case DefinedGlobal: - case Global: - S = DefinedGlobal; - break; - case NeverSeen: - case Defined: - case Used: - S = Defined; - break; - } - } - void markGlobal(const MCSymbol &Symbol) { - State &S = Symbols[Symbol.getName()]; - switch (S) { - case DefinedGlobal: - case Defined: - S = DefinedGlobal; - break; - - case NeverSeen: - case Global: - case Used: - S = Global; - break; - } - } - void markUsed(const MCSymbol &Symbol) { - State &S = Symbols[Symbol.getName()]; - switch (S) { - case DefinedGlobal: - case Defined: - case Global: - break; - - case NeverSeen: - case Used: - S = Used; - break; - } - } - - // FIXME: mostly copied for the obj streamer. - void AddValueSymbols(const MCExpr *Value) { - switch (Value->getKind()) { - case MCExpr::Target: - // FIXME: What should we do in here? - break; - - case MCExpr::Constant: - break; - - case MCExpr::Binary: { - const MCBinaryExpr *BE = cast(Value); - AddValueSymbols(BE->getLHS()); - AddValueSymbols(BE->getRHS()); - break; - } - - case MCExpr::SymbolRef: - markUsed(cast(Value)->getSymbol()); - break; - - case MCExpr::Unary: - AddValueSymbols(cast(Value)->getSubExpr()); - break; - } - } - - public: - typedef StringMap::const_iterator const_iterator; - - const_iterator begin() { - return Symbols.begin(); - } - - const_iterator end() { - return Symbols.end(); - } - - RecordStreamer(MCContext &Context) - : MCStreamer(SK_RecordStreamer, Context) {} - - virtual void EmitInstruction(const MCInst &Inst) { - // Scan for values. - for (unsigned i = Inst.getNumOperands(); i--; ) - if (Inst.getOperand(i).isExpr()) - AddValueSymbols(Inst.getOperand(i).getExpr()); - } - virtual void EmitLabel(MCSymbol *Symbol) { - Symbol->setSection(*getCurrentSection().first); - markDefined(*Symbol); - } - virtual void EmitDebugLabel(MCSymbol *Symbol) { - EmitLabel(Symbol); - } - virtual void EmitAssignment(MCSymbol *Symbol, const MCExpr *Value) { - // FIXME: should we handle aliases? - markDefined(*Symbol); - } - virtual bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) { - if (Attribute == MCSA_Global) - markGlobal(*Symbol); - return true; - } - virtual void EmitZerofill(const MCSection *Section, MCSymbol *Symbol, - uint64_t Size , unsigned ByteAlignment) { - markDefined(*Symbol); - } - virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment) { - markDefined(*Symbol); - } - - virtual void EmitBundleAlignMode(unsigned AlignPow2) {} - virtual void EmitBundleLock(bool AlignToEnd) {} - virtual void EmitBundleUnlock() {} - - // Noop calls. - virtual void ChangeSection(const MCSection *Section, - const MCExpr *Subsection) {} - virtual void InitToTextSection() {} - virtual void InitSections() {} - virtual void EmitAssemblerFlag(MCAssemblerFlag Flag) {} - virtual void EmitThumbFunc(MCSymbol *Func) {} - virtual void EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {} - virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol) {} - virtual void BeginCOFFSymbolDef(const MCSymbol *Symbol) {} - virtual void EmitCOFFSymbolStorageClass(int StorageClass) {} - virtual void EmitCOFFSymbolType(int Type) {} - virtual void EndCOFFSymbolDef() {} - virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) {} - virtual void EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size, - unsigned ByteAlignment) {} - virtual void EmitTBSSSymbol(const MCSection *Section, MCSymbol *Symbol, - uint64_t Size, unsigned ByteAlignment) {} - virtual void EmitBytes(StringRef Data) {} - virtual void EmitValueImpl(const MCExpr *Value, unsigned Size) {} - virtual void EmitULEB128Value(const MCExpr *Value) {} - virtual void EmitSLEB128Value(const MCExpr *Value) {} - virtual void EmitValueToAlignment(unsigned ByteAlignment, int64_t Value, - unsigned ValueSize, - unsigned MaxBytesToEmit) {} - virtual void EmitCodeAlignment(unsigned ByteAlignment, - unsigned MaxBytesToEmit) {} - virtual bool EmitValueToOffset(const MCExpr *Offset, - unsigned char Value ) { return false; } - virtual void EmitFileDirective(StringRef Filename) {} - virtual void EmitDwarfAdvanceLineAddr(int64_t LineDelta, - const MCSymbol *LastLabel, - const MCSymbol *Label, - unsigned PointerSize) {} - virtual void FinishImpl() {} - virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) { - RecordProcEnd(Frame); - } - - static bool classof(const MCStreamer *S) { - return S->getKind() == SK_RecordStreamer; - } - }; -} // end anonymous namespace - -/// addAsmGlobalSymbols - Add global symbols from module-level ASM to the -/// defined or undefined lists. -bool LTOModule::addAsmGlobalSymbols(std::string &errMsg) { - const std::string &inlineAsm = _module->getModuleInlineAsm(); - if (inlineAsm.empty()) - return false; - - OwningPtr Streamer(new RecordStreamer(_context)); - MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(inlineAsm); - SourceMgr SrcMgr; - SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); - OwningPtr Parser(createMCAsmParser(SrcMgr, - _context, *Streamer, - *_target->getMCAsmInfo())); - const Target &T = _target->getTarget(); - OwningPtr MCII(T.createMCInstrInfo()); - OwningPtr - STI(T.createMCSubtargetInfo(_target->getTargetTriple(), - _target->getTargetCPU(), - _target->getTargetFeatureString())); - OwningPtr TAP(T.createMCAsmParser(*STI, *Parser.get(), *MCII)); - if (!TAP) { - errMsg = "target " + std::string(T.getName()) + - " does not define AsmParser."; - return true; - } - - Parser->setTargetParser(*TAP); - if (Parser->Run(false)) - return true; - - for (RecordStreamer::const_iterator i = Streamer->begin(), - e = Streamer->end(); i != e; ++i) { - StringRef Key = i->first(); - RecordStreamer::State Value = i->second; - if (Value == RecordStreamer::DefinedGlobal) - addAsmGlobalSymbol(Key.data(), LTO_SYMBOL_SCOPE_DEFAULT); - else if (Value == RecordStreamer::Defined) - addAsmGlobalSymbol(Key.data(), LTO_SYMBOL_SCOPE_INTERNAL); - else if (Value == RecordStreamer::Global || - Value == RecordStreamer::Used) - addAsmGlobalSymbolUndef(Key.data()); - } - - return false; -} - -/// isDeclaration - Return 'true' if the global value is a declaration. -static bool isDeclaration(const GlobalValue &V) { - if (V.hasAvailableExternallyLinkage()) - return true; - - if (V.isMaterializable()) - return false; - - return V.isDeclaration(); -} - -/// parseSymbols - Parse the symbols from the module and model-level ASM and add -/// them to either the defined or undefined lists. -bool LTOModule::parseSymbols(std::string &errMsg) { - // add functions - for (Module::iterator f = _module->begin(), e = _module->end(); f != e; ++f) { - if (isDeclaration(*f)) - addPotentialUndefinedSymbol(f, true); - else - addDefinedFunctionSymbol(f); - } - - // add data - for (Module::global_iterator v = _module->global_begin(), - e = _module->global_end(); v != e; ++v) { - if (isDeclaration(*v)) - addPotentialUndefinedSymbol(v, false); - else - addDefinedDataSymbol(v); - } - - // add asm globals - if (addAsmGlobalSymbols(errMsg)) - return true; - - // add aliases - for (Module::alias_iterator a = _module->alias_begin(), - e = _module->alias_end(); a != e; ++a) { - if (isDeclaration(*a->getAliasedGlobal())) - // Is an alias to a declaration. - addPotentialUndefinedSymbol(a, false); - else - addDefinedDataSymbol(a); - } - - // make symbols for all undefines - for (StringMap::iterator u =_undefines.begin(), - e = _undefines.end(); u != e; ++u) { - // If this symbol also has a definition, then don't make an undefine because - // it is a tentative definition. - if (_defines.count(u->getKey())) continue; - NameAndAttributes info = u->getValue(); - _symbols.push_back(info); - } - - return false; -} diff --git a/tools/lto/LTOModule.h b/tools/lto/LTOModule.h deleted file mode 100644 index 902e9c5..0000000 --- a/tools/lto/LTOModule.h +++ /dev/null @@ -1,190 +0,0 @@ -//===-LTOModule.h - LLVM Link Time Optimizer ------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file declares the LTOModule class. -// -//===----------------------------------------------------------------------===// - -#ifndef LTO_MODULE_H -#define LTO_MODULE_H - -#include "llvm-c/lto.h" -#include "llvm/ADT/OwningPtr.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/IR/Module.h" -#include "llvm/MC/MCContext.h" -#include "llvm/Target/Mangler.h" -#include "llvm/Target/TargetMachine.h" -#include -#include - -// Forward references to llvm classes. -namespace llvm { - class Function; - class GlobalValue; - class MemoryBuffer; - class TargetOptions; - class Value; -} - -//===----------------------------------------------------------------------===// -/// LTOModule - C++ class which implements the opaque lto_module_t type. -/// -struct LTOModule { -private: - typedef llvm::StringMap StringSet; - - struct NameAndAttributes { - const char *name; - uint32_t attributes; - bool isFunction; - const llvm::GlobalValue *symbol; - }; - - llvm::OwningPtr _module; - llvm::OwningPtr _target; - std::vector _symbols; - - // _defines and _undefines only needed to disambiguate tentative definitions - StringSet _defines; - llvm::StringMap _undefines; - std::vector _asm_undefines; - llvm::MCContext _context; - - // Use mangler to add GlobalPrefix to names to match linker names. - llvm::Mangler _mangler; - - LTOModule(llvm::Module *m, llvm::TargetMachine *t); -public: - /// isBitcodeFile - Returns 'true' if the file or memory contents is LLVM - /// bitcode. - static bool isBitcodeFile(const void *mem, size_t length); - static bool isBitcodeFile(const char *path); - - /// isBitcodeFileForTarget - Returns 'true' if the file or memory contents - /// is LLVM bitcode for the specified triple. - static bool isBitcodeFileForTarget(const void *mem, - size_t length, - const char *triplePrefix); - static bool isBitcodeFileForTarget(const char *path, - const char *triplePrefix); - - /// makeLTOModule - Create an LTOModule. N.B. These methods take ownership - /// of the buffer. - static LTOModule *makeLTOModule(const char* path, - std::string &errMsg); - static LTOModule *makeLTOModule(int fd, const char *path, - size_t size, std::string &errMsg); - static LTOModule *makeLTOModule(int fd, const char *path, - size_t map_size, - off_t offset, - std::string& errMsg); - static LTOModule *makeLTOModule(const void *mem, size_t length, - std::string &errMsg); - - /// getTargetTriple - Return the Module's target triple. - const char *getTargetTriple() { - return _module->getTargetTriple().c_str(); - } - - /// setTargetTriple - Set the Module's target triple. - void setTargetTriple(const char *triple) { - _module->setTargetTriple(triple); - } - - /// getSymbolCount - Get the number of symbols - uint32_t getSymbolCount() { - return _symbols.size(); - } - - /// getSymbolAttributes - Get the attributes for a symbol at the specified - /// index. - lto_symbol_attributes getSymbolAttributes(uint32_t index) { - if (index < _symbols.size()) - return lto_symbol_attributes(_symbols[index].attributes); - return lto_symbol_attributes(0); - } - - /// getSymbolName - Get the name of the symbol at the specified index. - const char *getSymbolName(uint32_t index) { - if (index < _symbols.size()) - return _symbols[index].name; - return NULL; - } - - /// getLLVVMModule - Return the Module. - llvm::Module *getLLVVMModule() { return _module.get(); } - - /// getAsmUndefinedRefs - - const std::vector &getAsmUndefinedRefs() { - return _asm_undefines; - } - - /// getTargetOptions - Fill the TargetOptions object with the options - /// specified on the command line. - static void getTargetOptions(llvm::TargetOptions &Options); - -private: - /// parseSymbols - Parse the symbols from the module and model-level ASM and - /// add them to either the defined or undefined lists. - bool parseSymbols(std::string &errMsg); - - /// addPotentialUndefinedSymbol - Add a symbol which isn't defined just yet - /// to a list to be resolved later. - void addPotentialUndefinedSymbol(const llvm::GlobalValue *dcl, bool isFunc); - - /// addDefinedSymbol - Add a defined symbol to the list. - void addDefinedSymbol(const llvm::GlobalValue *def, bool isFunction); - - /// addDefinedFunctionSymbol - Add a function symbol as defined to the list. - void addDefinedFunctionSymbol(const llvm::Function *f); - - /// addDefinedDataSymbol - Add a data symbol as defined to the list. - void addDefinedDataSymbol(const llvm::GlobalValue *v); - - /// addAsmGlobalSymbols - Add global symbols from module-level ASM to the - /// defined or undefined lists. - bool addAsmGlobalSymbols(std::string &errMsg); - - /// addAsmGlobalSymbol - Add a global symbol from module-level ASM to the - /// defined list. - void addAsmGlobalSymbol(const char *, lto_symbol_attributes scope); - - /// addAsmGlobalSymbolUndef - Add a global symbol from module-level ASM to - /// the undefined list. - void addAsmGlobalSymbolUndef(const char *); - - /// addObjCClass - Parse i386/ppc ObjC class data structure. - void addObjCClass(const llvm::GlobalVariable *clgv); - - /// addObjCCategory - Parse i386/ppc ObjC category data structure. - void addObjCCategory(const llvm::GlobalVariable *clgv); - - /// addObjCClassRef - Parse i386/ppc ObjC class list data structure. - void addObjCClassRef(const llvm::GlobalVariable *clgv); - - /// objcClassNameFromExpression - Get string that the data pointer points - /// to. - bool objcClassNameFromExpression(const llvm::Constant* c, std::string &name); - - /// isTargetMatch - Returns 'true' if the memory buffer is for the specified - /// target triple. - static bool isTargetMatch(llvm::MemoryBuffer *memBuffer, - const char *triplePrefix); - - /// makeLTOModule - Create an LTOModule (private version). N.B. This - /// method takes ownership of the buffer. - static LTOModule *makeLTOModule(llvm::MemoryBuffer *buffer, - std::string &errMsg); - - /// makeBuffer - Create a MemoryBuffer from a memory range. - static llvm::MemoryBuffer *makeBuffer(const void *mem, size_t length); -}; - -#endif // LTO_MODULE_H diff --git a/tools/lto/Makefile b/tools/lto/Makefile index 56c67df..672fef4 100644 --- a/tools/lto/Makefile +++ b/tools/lto/Makefile @@ -10,7 +10,7 @@ LEVEL := ../.. LIBRARYNAME := LTO LINK_COMPONENTS := all-targets ipo scalaropts linker bitreader bitwriter \ - mcdisassembler vectorize + lto mcdisassembler vectorize LINK_LIBS_IN_SHARED := 1 SHARED_LIBRARY := 1 diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index db7147c..441bc77 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -13,15 +13,33 @@ //===----------------------------------------------------------------------===// #include "llvm-c/lto.h" -#include "LTOCodeGenerator.h" -#include "LTOModule.h" +#include "llvm/LTO/LTOCodeGenerator.h" +#include "llvm/LTO/LTOModule.h" #include "llvm-c/Core.h" +#include "llvm-c/Target.h" // Holds most recent error string. // *** Not thread safe *** static std::string sLastErrorString; +// Holds the initialization state of the LTO module. +// *** Not thread safe *** +static bool initialized = false; + +// Initialize the configured targets if they have not been initialized. +static void lto_initialize() { + if (!initialized) { + LLVMInitializeAllTargetInfos(); + LLVMInitializeAllTargets(); + LLVMInitializeAllTargetMCs(); + LLVMInitializeAllAsmParsers(); + LLVMInitializeAllAsmPrinters(); + LLVMInitializeAllDisassemblers(); + initialized = true; + } +} + /// lto_get_version - Returns a printable string. extern const char* lto_get_version() { return LTOCodeGenerator::getVersionString(); @@ -63,12 +81,14 @@ lto_module_is_object_file_in_memory_for_target(const void* mem, /// 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(); return LTOModule::makeLTOModule(path, 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(); return LTOModule::makeLTOModule(fd, path, size, sLastErrorString); } @@ -78,12 +98,14 @@ 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(); return LTOModule::makeLTOModule(fd, path, map_size, offset, 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(); return LTOModule::makeLTOModule(mem, length, sLastErrorString); } @@ -127,6 +149,7 @@ lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod, /// lto_codegen_create - Instantiates a code generator. Returns NULL if there /// is an error. lto_code_gen_t lto_codegen_create(void) { + lto_initialize(); return new LTOCodeGenerator(); } -- cgit v1.1 From 7357f03e888e7d95066ca1bbb26994c278eb465c Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Wed, 25 Sep 2013 23:02:41 +0000 Subject: Dump the normal dwarf pubtypes section as well. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191408 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index eef6f79..f863fd9 100644 --- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -67,6 +67,7 @@ DumpType("debug-dump", cl::init(DIDT_All), clEnumValN(DIDT_Frames, "frames", ".debug_frame"), clEnumValN(DIDT_Ranges, "ranges", ".debug_ranges"), clEnumValN(DIDT_Pubnames, "pubnames", ".debug_pubnames"), + clEnumValN(DIDT_Pubtypes, "pubtypes", ".debug_pubtypes"), clEnumValN(DIDT_Str, "str", ".debug_str"), clEnumValN(DIDT_StrDwo, "str.dwo", ".debug_str.dwo"), clEnumValN(DIDT_StrOffsetsDwo, "str_offsets.dwo", ".debug_str_offsets.dwo"), -- cgit v1.1 From 498ffb8a568992d613e654ddec69b04d350aec20 Mon Sep 17 00:00:00 2001 From: Eric Christopher Date: Wed, 25 Sep 2013 23:02:44 +0000 Subject: Add gnu pubsections as options to llvm-dwarfdump. Argument spelling feedback welcome. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191409 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index f863fd9..c46bd6b 100644 --- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -68,6 +68,8 @@ DumpType("debug-dump", cl::init(DIDT_All), clEnumValN(DIDT_Ranges, "ranges", ".debug_ranges"), clEnumValN(DIDT_Pubnames, "pubnames", ".debug_pubnames"), clEnumValN(DIDT_Pubtypes, "pubtypes", ".debug_pubtypes"), + clEnumValN(DIDT_GnuPubnames, "gnu_pubnames", ".debug_gnu_pubnames"), + clEnumValN(DIDT_GnuPubtypes, "gnu_pubtypes", ".debug_gnu_pubtypes"), clEnumValN(DIDT_Str, "str", ".debug_str"), clEnumValN(DIDT_StrDwo, "str.dwo", ".debug_str.dwo"), clEnumValN(DIDT_StrOffsetsDwo, "str_offsets.dwo", ".debug_str_offsets.dwo"), -- cgit v1.1 From 0c873adc82a81b0bce317c3e2cb3139e990a0f9e Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Fri, 27 Sep 2013 00:07:01 +0000 Subject: llvm-objdump: Dump COFF import table if -private-headers option is given. This is a patch to add capability to llvm-objdump to dump COFF Import Table entries, so that we can write tests for LLD checking Import Table contents. llvm-objdump did not print anything but just file name if the format is COFF and -private-headers option is given. This is a patch adds capability for dumping DLL Import Table, which is specific to the COFF format. In this patch I defined a new iterator to iterate over import table entries. Also added a few functions to COFFObjectFile.cpp to access fields of the entry. Differential Revision: http://llvm-reviews.chandlerc.com/D1719 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191472 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/COFFDump.cpp | 46 +++++++++++++++++++++++++++++++++++++ tools/llvm-objdump/llvm-objdump.cpp | 12 ++++++++-- tools/llvm-objdump/llvm-objdump.h | 3 ++- 3 files changed, 58 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/COFFDump.cpp b/tools/llvm-objdump/COFFDump.cpp index bca6fc9..968e20c 100644 --- a/tools/llvm-objdump/COFFDump.cpp +++ b/tools/llvm-objdump/COFFDump.cpp @@ -227,6 +227,48 @@ static void printCOFFSymbolAddress(llvm::raw_ostream &Out, Out << format(" + 0x%04x", Disp); } +// Prints import tables. The import table is a table containing the list of +// DLL name and symbol names which will be linked by the loader. +static void printImportTables(const COFFObjectFile *Obj) { + outs() << "The Import Tables:\n"; + error_code ec; + for (import_directory_iterator i = Obj->getImportDirectoryBegin(), + e = Obj->getImportDirectoryEnd(); + i != e; i = i.increment(ec)) { + if (ec) + return; + + const import_directory_table_entry *Dir; + StringRef Name; + if (i->getImportTableEntry(Dir)) return; + if (i->getName(Name)) return; + + outs() << format(" lookup %08x", Dir->ImportLookupTableRVA); + outs() << format(" time %08x", Dir->TimeDateStamp); + outs() << format(" fwd %08x", Dir->ForwarderChain); + outs() << format(" name %08x", Dir->NameRVA); + outs() << format(" addr %08x\n\n", Dir->ImportAddressTableRVA); + + outs() << " DLL Name: " << Name << "\n"; + outs() << " Hint/Ord Name\n"; + const COFF::ImportLookupTableEntry32 *entry; + if (i->getImportLookupEntry(entry)) + return; + for (; entry->data; ++entry) { + if (entry->isOrdinal()) { + outs() << format(" % 6d\n", entry->getOrdinal()); + continue; + } + uint16_t Hint; + StringRef Name; + if (Obj->getHintName(entry->getHintNameRVA(), Hint, Name)) + return; + outs() << format(" % 6d %s\n", Hint, Name); + } + outs() << "\n"; + } +} + void llvm::printCOFFUnwindInfo(const COFFObjectFile *Obj) { const coff_file_header *Header; if (error(Obj->getCOFFHeader(Header))) return; @@ -353,3 +395,7 @@ void llvm::printCOFFUnwindInfo(const COFFObjectFile *Obj) { } } } + +void llvm::printCOFFFileHeader(const object::ObjectFile *Obj) { + printImportTables(dyn_cast(Obj)); +} diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 8065787..9bc092e 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -770,6 +770,14 @@ static void PrintUnwindInfo(const ObjectFile *o) { } } +static void printPrivateFileHeader(const ObjectFile *o) { + if (o->isELF()) { + printELFFileHeader(o); + } else if (o->isCOFF()) { + printCOFFFileHeader(o); + } +} + static void DumpObject(const ObjectFile *o) { outs() << '\n'; outs() << o->getFileName() @@ -787,8 +795,8 @@ static void DumpObject(const ObjectFile *o) { PrintSymbolTable(o); if (UnwindInfo) PrintUnwindInfo(o); - if (PrivateHeaders && o->isELF()) - printELFFileHeader(o); + if (PrivateHeaders) + printPrivateFileHeader(o); } /// @brief Dump each object file in \a a; diff --git a/tools/llvm-objdump/llvm-objdump.h b/tools/llvm-objdump/llvm-objdump.h index 87f19ba..b716a26 100644 --- a/tools/llvm-objdump/llvm-objdump.h +++ b/tools/llvm-objdump/llvm-objdump.h @@ -34,7 +34,8 @@ void DumpBytes(StringRef bytes); void DisassembleInputMachO(StringRef Filename); void printCOFFUnwindInfo(const object::COFFObjectFile* o); void printELFFileHeader(const object::ObjectFile *o); +void printCOFFFileHeader(const object::ObjectFile *o); -} +} // end namespace llvm #endif -- cgit v1.1 From 2f00626f7ef9fbd4dde08c5848e517ad92c7752d Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Fri, 27 Sep 2013 00:20:53 +0000 Subject: Fix -Wnon-pod-varargs error in r191472. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191473 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/COFFDump.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/COFFDump.cpp b/tools/llvm-objdump/COFFDump.cpp index 968e20c..a43150d 100644 --- a/tools/llvm-objdump/COFFDump.cpp +++ b/tools/llvm-objdump/COFFDump.cpp @@ -243,12 +243,12 @@ static void printImportTables(const COFFObjectFile *Obj) { if (i->getImportTableEntry(Dir)) return; if (i->getName(Name)) return; - outs() << format(" lookup %08x", Dir->ImportLookupTableRVA); - outs() << format(" time %08x", Dir->TimeDateStamp); - outs() << format(" fwd %08x", Dir->ForwarderChain); - outs() << format(" name %08x", Dir->NameRVA); - outs() << format(" addr %08x\n\n", Dir->ImportAddressTableRVA); - + outs() << format(" lookup %08x time %08x fwd %08x name %08x addr %08x\n\n", + static_cast(Dir->ImportLookupTableRVA), + static_cast(Dir->TimeDateStamp), + static_cast(Dir->ForwarderChain), + static_cast(Dir->NameRVA), + static_cast(Dir->ImportAddressTableRVA)); outs() << " DLL Name: " << Name << "\n"; outs() << " Hint/Ord Name\n"; const COFF::ImportLookupTableEntry32 *entry; -- cgit v1.1 From 10965f2045e28836b213a78d971f4e68d4d46c0e Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Fri, 27 Sep 2013 00:53:07 +0000 Subject: Fix another -Wnon-pod-varargs error in r191472. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191474 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/COFFDump.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/llvm-objdump/COFFDump.cpp b/tools/llvm-objdump/COFFDump.cpp index a43150d..522d48d 100644 --- a/tools/llvm-objdump/COFFDump.cpp +++ b/tools/llvm-objdump/COFFDump.cpp @@ -263,7 +263,7 @@ static void printImportTables(const COFFObjectFile *Obj) { StringRef Name; if (Obj->getHintName(entry->getHintNameRVA(), Hint, Name)) return; - outs() << format(" % 6d %s\n", Hint, Name); + outs() << format(" % 6d ", Hint) << Name << "\n"; } outs() << "\n"; } -- cgit v1.1 From 4715a11dcfe79de2a7a8b0b633d6ca272eea0bc3 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Fri, 27 Sep 2013 01:29:36 +0000 Subject: Revert "llvm-objdump: Dump COFF import table if -private-headers option is given." This reverts commit r191472 because it's failing on BE machine. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191480 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/COFFDump.cpp | 46 ------------------------------------- tools/llvm-objdump/llvm-objdump.cpp | 12 ++-------- tools/llvm-objdump/llvm-objdump.h | 3 +-- 3 files changed, 3 insertions(+), 58 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/COFFDump.cpp b/tools/llvm-objdump/COFFDump.cpp index 522d48d..bca6fc9 100644 --- a/tools/llvm-objdump/COFFDump.cpp +++ b/tools/llvm-objdump/COFFDump.cpp @@ -227,48 +227,6 @@ static void printCOFFSymbolAddress(llvm::raw_ostream &Out, Out << format(" + 0x%04x", Disp); } -// Prints import tables. The import table is a table containing the list of -// DLL name and symbol names which will be linked by the loader. -static void printImportTables(const COFFObjectFile *Obj) { - outs() << "The Import Tables:\n"; - error_code ec; - for (import_directory_iterator i = Obj->getImportDirectoryBegin(), - e = Obj->getImportDirectoryEnd(); - i != e; i = i.increment(ec)) { - if (ec) - return; - - const import_directory_table_entry *Dir; - StringRef Name; - if (i->getImportTableEntry(Dir)) return; - if (i->getName(Name)) return; - - outs() << format(" lookup %08x time %08x fwd %08x name %08x addr %08x\n\n", - static_cast(Dir->ImportLookupTableRVA), - static_cast(Dir->TimeDateStamp), - static_cast(Dir->ForwarderChain), - static_cast(Dir->NameRVA), - static_cast(Dir->ImportAddressTableRVA)); - outs() << " DLL Name: " << Name << "\n"; - outs() << " Hint/Ord Name\n"; - const COFF::ImportLookupTableEntry32 *entry; - if (i->getImportLookupEntry(entry)) - return; - for (; entry->data; ++entry) { - if (entry->isOrdinal()) { - outs() << format(" % 6d\n", entry->getOrdinal()); - continue; - } - uint16_t Hint; - StringRef Name; - if (Obj->getHintName(entry->getHintNameRVA(), Hint, Name)) - return; - outs() << format(" % 6d ", Hint) << Name << "\n"; - } - outs() << "\n"; - } -} - void llvm::printCOFFUnwindInfo(const COFFObjectFile *Obj) { const coff_file_header *Header; if (error(Obj->getCOFFHeader(Header))) return; @@ -395,7 +353,3 @@ void llvm::printCOFFUnwindInfo(const COFFObjectFile *Obj) { } } } - -void llvm::printCOFFFileHeader(const object::ObjectFile *Obj) { - printImportTables(dyn_cast(Obj)); -} diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 9bc092e..8065787 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -770,14 +770,6 @@ static void PrintUnwindInfo(const ObjectFile *o) { } } -static void printPrivateFileHeader(const ObjectFile *o) { - if (o->isELF()) { - printELFFileHeader(o); - } else if (o->isCOFF()) { - printCOFFFileHeader(o); - } -} - static void DumpObject(const ObjectFile *o) { outs() << '\n'; outs() << o->getFileName() @@ -795,8 +787,8 @@ static void DumpObject(const ObjectFile *o) { PrintSymbolTable(o); if (UnwindInfo) PrintUnwindInfo(o); - if (PrivateHeaders) - printPrivateFileHeader(o); + if (PrivateHeaders && o->isELF()) + printELFFileHeader(o); } /// @brief Dump each object file in \a a; diff --git a/tools/llvm-objdump/llvm-objdump.h b/tools/llvm-objdump/llvm-objdump.h index b716a26..87f19ba 100644 --- a/tools/llvm-objdump/llvm-objdump.h +++ b/tools/llvm-objdump/llvm-objdump.h @@ -34,8 +34,7 @@ void DumpBytes(StringRef bytes); void DisassembleInputMachO(StringRef Filename); void printCOFFUnwindInfo(const object::COFFObjectFile* o); void printELFFileHeader(const object::ObjectFile *o); -void printCOFFFileHeader(const object::ObjectFile *o); -} // end namespace llvm +} #endif -- cgit v1.1 From a6610ee882fcb8bcad60d53fc52b80f00a3fddae Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Fri, 27 Sep 2013 21:04:00 +0000 Subject: Re-submit r191472 with a fix for big endian. llvm-objdump: Dump COFF import table if -private-headers option is given. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191557 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/COFFDump.cpp | 46 +++++++++++++++++++++++++++++++++++++ tools/llvm-objdump/llvm-objdump.cpp | 12 ++++++++-- tools/llvm-objdump/llvm-objdump.h | 3 ++- 3 files changed, 58 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/COFFDump.cpp b/tools/llvm-objdump/COFFDump.cpp index bca6fc9..ba26ff0 100644 --- a/tools/llvm-objdump/COFFDump.cpp +++ b/tools/llvm-objdump/COFFDump.cpp @@ -227,6 +227,48 @@ static void printCOFFSymbolAddress(llvm::raw_ostream &Out, Out << format(" + 0x%04x", Disp); } +// Prints import tables. The import table is a table containing the list of +// DLL name and symbol names which will be linked by the loader. +static void printImportTables(const COFFObjectFile *Obj) { + outs() << "The Import Tables:\n"; + error_code ec; + for (import_directory_iterator i = Obj->getImportDirectoryBegin(), + e = Obj->getImportDirectoryEnd(); + i != e; i = i.increment(ec)) { + if (ec) + return; + + const import_directory_table_entry *Dir; + StringRef Name; + if (i->getImportTableEntry(Dir)) return; + if (i->getName(Name)) return; + + outs() << format(" lookup %08x time %08x fwd %08x name %08x addr %08x\n\n", + static_cast(Dir->ImportLookupTableRVA), + static_cast(Dir->TimeDateStamp), + static_cast(Dir->ForwarderChain), + static_cast(Dir->NameRVA), + static_cast(Dir->ImportAddressTableRVA)); + outs() << " DLL Name: " << Name << "\n"; + outs() << " Hint/Ord Name\n"; + const import_lookup_table_entry32 *entry; + if (i->getImportLookupEntry(entry)) + return; + for (; entry->data; ++entry) { + if (entry->isOrdinal()) { + outs() << format(" % 6d\n", entry->getOrdinal()); + continue; + } + uint16_t Hint; + StringRef Name; + if (Obj->getHintName(entry->getHintNameRVA(), Hint, Name)) + return; + outs() << format(" % 6d ", Hint) << Name << "\n"; + } + outs() << "\n"; + } +} + void llvm::printCOFFUnwindInfo(const COFFObjectFile *Obj) { const coff_file_header *Header; if (error(Obj->getCOFFHeader(Header))) return; @@ -353,3 +395,7 @@ void llvm::printCOFFUnwindInfo(const COFFObjectFile *Obj) { } } } + +void llvm::printCOFFFileHeader(const object::ObjectFile *Obj) { + printImportTables(dyn_cast(Obj)); +} diff --git a/tools/llvm-objdump/llvm-objdump.cpp b/tools/llvm-objdump/llvm-objdump.cpp index 8065787..9bc092e 100644 --- a/tools/llvm-objdump/llvm-objdump.cpp +++ b/tools/llvm-objdump/llvm-objdump.cpp @@ -770,6 +770,14 @@ static void PrintUnwindInfo(const ObjectFile *o) { } } +static void printPrivateFileHeader(const ObjectFile *o) { + if (o->isELF()) { + printELFFileHeader(o); + } else if (o->isCOFF()) { + printCOFFFileHeader(o); + } +} + static void DumpObject(const ObjectFile *o) { outs() << '\n'; outs() << o->getFileName() @@ -787,8 +795,8 @@ static void DumpObject(const ObjectFile *o) { PrintSymbolTable(o); if (UnwindInfo) PrintUnwindInfo(o); - if (PrivateHeaders && o->isELF()) - printELFFileHeader(o); + if (PrivateHeaders) + printPrivateFileHeader(o); } /// @brief Dump each object file in \a a; diff --git a/tools/llvm-objdump/llvm-objdump.h b/tools/llvm-objdump/llvm-objdump.h index 87f19ba..b716a26 100644 --- a/tools/llvm-objdump/llvm-objdump.h +++ b/tools/llvm-objdump/llvm-objdump.h @@ -34,7 +34,8 @@ void DumpBytes(StringRef bytes); void DisassembleInputMachO(StringRef Filename); void printCOFFUnwindInfo(const object::COFFObjectFile* o); void printELFFileHeader(const object::ObjectFile *o); +void printCOFFFileHeader(const object::ObjectFile *o); -} +} // end namespace llvm #endif -- cgit v1.1 From 29552222c2e7cbeb37fcd15d247597467f7b8544 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Fri, 27 Sep 2013 21:47:05 +0000 Subject: Object/COFF: Rename getXXX{Begin,End} -> xxx_{begin,end}. It is mentioned in the LLVM coding standard that _begin() and _end() suffixes should be used. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191569 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-objdump/COFFDump.cpp | 4 ++-- tools/macho-dump/macho-dump.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/llvm-objdump/COFFDump.cpp b/tools/llvm-objdump/COFFDump.cpp index ba26ff0..5f0bcbb 100644 --- a/tools/llvm-objdump/COFFDump.cpp +++ b/tools/llvm-objdump/COFFDump.cpp @@ -232,8 +232,8 @@ static void printCOFFSymbolAddress(llvm::raw_ostream &Out, static void printImportTables(const COFFObjectFile *Obj) { outs() << "The Import Tables:\n"; error_code ec; - for (import_directory_iterator i = Obj->getImportDirectoryBegin(), - e = Obj->getImportDirectoryEnd(); + for (import_directory_iterator i = Obj->import_directory_begin(), + e = Obj->import_directory_end(); i != e; i = i.increment(ec)) { if (ec) return; diff --git a/tools/macho-dump/macho-dump.cpp b/tools/macho-dump/macho-dump.cpp index 7ae5440..0dfbd5f 100644 --- a/tools/macho-dump/macho-dump.cpp +++ b/tools/macho-dump/macho-dump.cpp @@ -97,8 +97,8 @@ static int DumpSectionData(const MachOObjectFile &Obj, unsigned Index, outs() << " ('_relocations', [\n"; unsigned RelNum = 0; error_code EC; - for (relocation_iterator I = Obj.getSectionRelBegin(Index), - E = Obj.getSectionRelEnd(Index); I != E; I.increment(EC), ++RelNum) { + for (relocation_iterator I = Obj.section_rel_begin(Index), + E = Obj.section_rel_end(Index); I != E; I.increment(EC), ++RelNum) { MachO::any_relocation_info RE = Obj.getRelocation(I->getRawDataRefImpl()); outs() << " # Relocation " << RelNum << "\n"; outs() << " (('word-0', " << format("0x%x", RE.r_word0) << "),\n"; -- cgit v1.1 From a5b9cd1c68eda914ffcf133228824ca58e1ba518 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 30 Sep 2013 15:28:14 +0000 Subject: Enable building LTO on WIN32. Enable building the LTO library (.lib and.dll) and llvm-lto.exe on Windows with MSVC and Mingw as well as re-enabling the associated test. Patch by Greg Bedwell! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191670 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/CMakeLists.txt | 2 +- tools/lto/CMakeLists.txt | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 468d396..d8001e7 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -43,7 +43,7 @@ add_llvm_tool_subdirectory(llvm-symbolizer) add_llvm_tool_subdirectory(obj2yaml) add_llvm_tool_subdirectory(yaml2obj) -if( NOT WIN32 ) +if( NOT CYGWIN ) add_llvm_tool_subdirectory(lto) add_llvm_tool_subdirectory(llvm-lto) else() diff --git a/tools/lto/CMakeLists.txt b/tools/lto/CMakeLists.txt index 8b26ddd..5e5d8ad 100644 --- a/tools/lto/CMakeLists.txt +++ b/tools/lto/CMakeLists.txt @@ -9,7 +9,19 @@ set(SOURCES lto.cpp ) -if( NOT WIN32 AND LLVM_ENABLE_PIC ) +if( NOT CYGWIN AND LLVM_ENABLE_PIC ) + if ( WIN32 ) + # Create .def file containing a list of exports preceeded by + # 'EXPORTS'. The file "lto.exports" already contains the list, so we + # massage it into the correct format here to create "lto.exports.def". + set(LTO_EXPORTS_DEF ${CMAKE_CURRENT_BINARY_DIR}/lto.exports.def) + file(READ "lto.exports" exports_list) + file(WRITE ${LTO_EXPORTS_DEF} "LIBRARY LTO\n") + file(APPEND ${LTO_EXPORTS_DEF} "EXPORTS\n") + file(APPEND ${LTO_EXPORTS_DEF} ${exports_list}) + set(SOURCES ${SOURCES} ${LTO_EXPORTS_DEF}) + endif() + set(bsl ${BUILD_SHARED_LIBS}) set(BUILD_SHARED_LIBS ON) add_llvm_library(LTO ${SOURCES}) @@ -25,7 +37,7 @@ if( NOT BUILD_SHARED_LIBS ) set_property(TARGET ${LTO_STATIC_TARGET_NAME} PROPERTY OUTPUT_NAME "LTO") endif() -if( NOT WIN32 ) +if( NOT CYGWIN ) install(FILES ${LLVM_MAIN_INCLUDE_DIR}/llvm-c/lto.h DESTINATION include/llvm-c) endif() -- cgit v1.1 From 4b5205d2a3e0df909f29de0bff8ea775ad21fe0f Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 30 Sep 2013 16:32:51 +0000 Subject: Revert "Enable building LTO on WIN32." This reverts commit r191670. It was causing build failures on the msvc bots: http://bb.pgr.jp/builders/ninja-clang-i686-msc17-R/builds/5166/steps/compile/logs/stdio git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191679 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/CMakeLists.txt | 2 +- tools/lto/CMakeLists.txt | 16 ++-------------- 2 files changed, 3 insertions(+), 15 deletions(-) (limited to 'tools') diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index d8001e7..468d396 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -43,7 +43,7 @@ add_llvm_tool_subdirectory(llvm-symbolizer) add_llvm_tool_subdirectory(obj2yaml) add_llvm_tool_subdirectory(yaml2obj) -if( NOT CYGWIN ) +if( NOT WIN32 ) add_llvm_tool_subdirectory(lto) add_llvm_tool_subdirectory(llvm-lto) else() diff --git a/tools/lto/CMakeLists.txt b/tools/lto/CMakeLists.txt index 5e5d8ad..8b26ddd 100644 --- a/tools/lto/CMakeLists.txt +++ b/tools/lto/CMakeLists.txt @@ -9,19 +9,7 @@ set(SOURCES lto.cpp ) -if( NOT CYGWIN AND LLVM_ENABLE_PIC ) - if ( WIN32 ) - # Create .def file containing a list of exports preceeded by - # 'EXPORTS'. The file "lto.exports" already contains the list, so we - # massage it into the correct format here to create "lto.exports.def". - set(LTO_EXPORTS_DEF ${CMAKE_CURRENT_BINARY_DIR}/lto.exports.def) - file(READ "lto.exports" exports_list) - file(WRITE ${LTO_EXPORTS_DEF} "LIBRARY LTO\n") - file(APPEND ${LTO_EXPORTS_DEF} "EXPORTS\n") - file(APPEND ${LTO_EXPORTS_DEF} ${exports_list}) - set(SOURCES ${SOURCES} ${LTO_EXPORTS_DEF}) - endif() - +if( NOT WIN32 AND LLVM_ENABLE_PIC ) set(bsl ${BUILD_SHARED_LIBS}) set(BUILD_SHARED_LIBS ON) add_llvm_library(LTO ${SOURCES}) @@ -37,7 +25,7 @@ if( NOT BUILD_SHARED_LIBS ) set_property(TARGET ${LTO_STATIC_TARGET_NAME} PROPERTY OUTPUT_NAME "LTO") endif() -if( NOT CYGWIN ) +if( NOT WIN32 ) install(FILES ${LLVM_MAIN_INCLUDE_DIR}/llvm-c/lto.h DESTINATION include/llvm-c) endif() -- cgit v1.1 From c13c9e5a9d288eac494a38f0710d34446167f940 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Mon, 30 Sep 2013 16:39:19 +0000 Subject: Move command line options to the users of libLTO. Fixes --enable-shared build. Patch by Richard Sandiford. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191680 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-lto/llvm-lto.cpp | 57 ++++++++++++++++++++++++++++++++------ tools/lto/lto.cpp | 67 ++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 108 insertions(+), 16 deletions(-) (limited to 'tools') diff --git a/tools/llvm-lto/llvm-lto.cpp b/tools/llvm-lto/llvm-lto.cpp index 82a2c82..2f51c0c 100644 --- a/tools/llvm-lto/llvm-lto.cpp +++ b/tools/llvm-lto/llvm-lto.cpp @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/CodeGen/CommandFlags.h" #include "llvm/LTO/LTOCodeGenerator.h" #include "llvm/LTO/LTOModule.h" #include "llvm/Support/CommandLine.h" @@ -23,13 +24,26 @@ using namespace llvm; -static cl::list InputFilenames(cl::Positional, cl::OneOrMore, - cl::desc("")); +static cl::opt +DisableOpt("disable-opt", cl::init(false), + cl::desc("Do not run any optimization passes")); -static cl::opt OutputFilename("o", - cl::desc("Override output filename"), - cl::init(""), - cl::value_desc("filename")); +static cl::opt +DisableInline("disable-inlining", cl::init(false), + cl::desc("Do not run the inliner pass")); + +static cl::opt +DisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false), + cl::desc("Do not run the GVN load PRE pass")); + +static cl::list +InputFilenames(cl::Positional, cl::OneOrMore, + cl::desc("")); + +static cl::opt +OutputFilename("o", cl::init(""), + cl::desc("Override output filename"), + cl::value_desc("filename")); int main(int argc, char **argv) { // Print a stack trace if we signal out. @@ -45,6 +59,28 @@ int main(int argc, char **argv) { InitializeAllAsmPrinters(); InitializeAllAsmParsers(); + // set up the TargetOptions for the machine + TargetOptions Options; + Options.LessPreciseFPMADOption = EnableFPMAD; + Options.NoFramePointerElim = DisableFPElim; + Options.AllowFPOpFusion = FuseFPOps; + Options.UnsafeFPMath = EnableUnsafeFPMath; + Options.NoInfsFPMath = EnableNoInfsFPMath; + Options.NoNaNsFPMath = EnableNoNaNsFPMath; + Options.HonorSignDependentRoundingFPMathOption = + EnableHonorSignDependentRoundingFPMath; + Options.UseSoftFloat = GenerateSoftFloatCalls; + if (FloatABIForCalls != FloatABI::Default) + Options.FloatABIType = FloatABIForCalls; + Options.NoZerosInBSS = DontPlaceZerosInBSS; + Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt; + Options.DisableTailCalls = DisableTailCalls; + Options.StackAlignmentOverride = OverrideStackAlignment; + Options.TrapFuncName = TrapFuncName; + Options.PositionIndependentExecutable = EnablePIE; + Options.EnableSegmentedStacks = SegmentedStacks; + Options.UseInitArray = UseInitArray; + unsigned BaseArg = 0; std::string ErrorMessage; @@ -52,11 +88,12 @@ int main(int argc, char **argv) { CodeGen.setCodePICModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC); CodeGen.setDebugInfo(LTO_DEBUG_MODEL_DWARF); + CodeGen.setTargetOptions(Options); for (unsigned i = BaseArg; i < InputFilenames.size(); ++i) { std::string error; OwningPtr Module(LTOModule::makeLTOModule(InputFilenames[i].c_str(), - error)); + Options, error)); if (!error.empty()) { errs() << argv[0] << ": error loading file '" << InputFilenames[i] << "': " << error << "\n"; @@ -74,7 +111,8 @@ int main(int argc, char **argv) { if (!OutputFilename.empty()) { size_t len = 0; std::string ErrorInfo; - const void *Code = CodeGen.compile(&len, ErrorInfo); + const void *Code = CodeGen.compile(&len, DisableOpt, DisableInline, + DisableGVNLoadPRE, ErrorInfo); if (Code == NULL) { errs() << argv[0] << ": error compiling the code: " << ErrorInfo << "\n"; @@ -92,7 +130,8 @@ int main(int argc, char **argv) { } else { std::string ErrorInfo; const char *OutputName = NULL; - if (!CodeGen.compile_to_file(&OutputName, ErrorInfo)) { + if (!CodeGen.compile_to_file(&OutputName, DisableOpt, DisableInline, + DisableGVNLoadPRE, ErrorInfo)) { errs() << argv[0] << ": error compiling the code: " << ErrorInfo << "\n"; diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index 441bc77..7996720 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -13,11 +13,24 @@ //===----------------------------------------------------------------------===// #include "llvm-c/lto.h" +#include "llvm/CodeGen/CommandFlags.h" #include "llvm/LTO/LTOCodeGenerator.h" #include "llvm/LTO/LTOModule.h" #include "llvm-c/Core.h" #include "llvm-c/Target.h" +// extra command-line flags needed for LTOCodeGenerator +static cl::opt +DisableOpt("disable-opt", cl::init(false), + cl::desc("Do not run any optimization passes")); + +static cl::opt +DisableInline("disable-inlining", cl::init(false), + cl::desc("Do not run the inliner pass")); + +static cl::opt +DisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false), + cl::desc("Do not run the GVN load PRE pass")); // Holds most recent error string. // *** Not thread safe *** @@ -40,6 +53,28 @@ static void lto_initialize() { } } +static void lto_set_target_options(llvm::TargetOptions &Options) { + Options.LessPreciseFPMADOption = EnableFPMAD; + Options.NoFramePointerElim = DisableFPElim; + Options.AllowFPOpFusion = FuseFPOps; + Options.UnsafeFPMath = EnableUnsafeFPMath; + Options.NoInfsFPMath = EnableNoInfsFPMath; + Options.NoNaNsFPMath = EnableNoNaNsFPMath; + Options.HonorSignDependentRoundingFPMathOption = + EnableHonorSignDependentRoundingFPMath; + Options.UseSoftFloat = GenerateSoftFloatCalls; + if (FloatABIForCalls != llvm::FloatABI::Default) + Options.FloatABIType = FloatABIForCalls; + Options.NoZerosInBSS = DontPlaceZerosInBSS; + Options.GuaranteedTailCallOpt = EnableGuaranteedTailCallOpt; + Options.DisableTailCalls = DisableTailCalls; + Options.StackAlignmentOverride = OverrideStackAlignment; + Options.TrapFuncName = TrapFuncName; + Options.PositionIndependentExecutable = EnablePIE; + Options.EnableSegmentedStacks = SegmentedStacks; + Options.UseInitArray = UseInitArray; +} + /// lto_get_version - Returns a printable string. extern const char* lto_get_version() { return LTOCodeGenerator::getVersionString(); @@ -82,14 +117,18 @@ lto_module_is_object_file_in_memory_for_target(const void* mem, /// (check lto_get_error_message() for details). lto_module_t lto_module_create(const char* path) { lto_initialize(); - return LTOModule::makeLTOModule(path, sLastErrorString); + llvm::TargetOptions Options; + lto_set_target_options(Options); + return 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(); - return LTOModule::makeLTOModule(fd, path, size, sLastErrorString); + llvm::TargetOptions Options; + lto_set_target_options(Options); + return LTOModule::makeLTOModule(fd, path, size, Options, sLastErrorString); } /// lto_module_create_from_fd_at_offset - Loads an object file from disk. @@ -99,14 +138,19 @@ lto_module_t lto_module_create_from_fd_at_offset(int fd, const char *path, size_t map_size, off_t offset) { lto_initialize(); - return LTOModule::makeLTOModule(fd, path, map_size, offset, sLastErrorString); + llvm::TargetOptions Options; + lto_set_target_options(Options); + return 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(); - return LTOModule::makeLTOModule(mem, length, sLastErrorString); + llvm::TargetOptions Options; + lto_set_target_options(Options); + return LTOModule::makeLTOModule(mem, length, Options, sLastErrorString); } /// lto_module_dispose - Frees all memory for a module. Upon return the @@ -150,7 +194,14 @@ lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod, /// is an error. lto_code_gen_t lto_codegen_create(void) { lto_initialize(); - return new LTOCodeGenerator(); + + TargetOptions Options; + lto_set_target_options(Options); + + LTOCodeGenerator *CodeGen = new LTOCodeGenerator(); + if (CodeGen) + CodeGen->setTargetOptions(Options); + return CodeGen; } /// lto_codegen_dispose - Frees all memory for a code generator. Upon return the @@ -220,14 +271,16 @@ bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) { /// 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) { - return cg->compile(length, sLastErrorString); + return 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) { - return !cg->compile_to_file(name, sLastErrorString); + return !cg->compile_to_file(name, DisableOpt, DisableInline, DisableGVNLoadPRE, + sLastErrorString); } /// lto_codegen_debug_options - Used to pass extra options to the code -- cgit v1.1 From 8e9ec015348c5419b905c2ca6e39534429eda073 Mon Sep 17 00:00:00 2001 From: Andrew Kaylor Date: Tue, 1 Oct 2013 01:47:35 +0000 Subject: Adding multiple module support for MCJIT. Tests to follow. PIC with small code model and EH frame handling will not work with multiple modules. There are also some rough edges to be smoothed out for remote target support. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191722 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/lli.cpp | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) (limited to 'tools') diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index 8d74b23..ba9cb99 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -460,18 +460,18 @@ int main(int argc, char **argv, char * const *envp) { // // Run static constructors. if (!RemoteMCJIT) { - if (UseMCJIT && !ForceInterpreter) { - // Give MCJIT a chance to apply relocations and set page permissions. - EE->finalizeObject(); - } - EE->runStaticConstructorsDestructors(false); - } + if (UseMCJIT && !ForceInterpreter) { + // Give MCJIT a chance to apply relocations and set page permissions. + EE->finalizeObject(); + } + EE->runStaticConstructorsDestructors(false); - if (NoLazyCompilation) { - for (Module::iterator I = Mod->begin(), E = Mod->end(); I != E; ++I) { - Function *Fn = &*I; - if (Fn != EntryFn && !Fn->isDeclaration()) - EE->getPointerToFunction(Fn); + if (!UseMCJIT && NoLazyCompilation) { + for (Module::iterator I = Mod->begin(), E = Mod->end(); I != E; ++I) { + Function *Fn = &*I; + if (Fn != EntryFn && !Fn->isDeclaration()) + EE->getPointerToFunction(Fn); + } } } @@ -484,12 +484,10 @@ int main(int argc, char **argv, char * const *envp) { RemoteTarget Target; Target.create(); - // Ask for a pointer to the entry function. This triggers the actual - // compilation. - (void)EE->getPointerToFunction(EntryFn); + // Trigger compilation. + EE->generateCodeForModule(Mod); - // Enough has been compiled to execute the entry function now, so - // layout the target memory. + // Layout the target memory. layoutRemoteTargetMemory(&Target, MM); // Since we're executing in a (at least simulated) remote address space, -- cgit v1.1 From 8819c84aed10777ba91d4e862229882b8da0b272 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 1 Oct 2013 13:32:03 +0000 Subject: Remove several unused variables. Patch by Alp Toker. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191757 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/bugpoint/ExecutionDriver.cpp | 1 - tools/llvm-diff/DifferenceEngine.cpp | 2 -- tools/llvm-lto/llvm-lto.cpp | 1 - tools/llvm-objdump/MachODump.cpp | 2 -- tools/llvm-prof/llvm-prof.cpp | 3 --- tools/llvm-readobj/ELFDumper.cpp | 5 ----- tools/llvm-readobj/MachODumper.cpp | 2 -- tools/obj2yaml/coff2yaml.cpp | 1 - 8 files changed, 17 deletions(-) (limited to 'tools') diff --git a/tools/bugpoint/ExecutionDriver.cpp b/tools/bugpoint/ExecutionDriver.cpp index 3d3dac3..c05c8d7 100644 --- a/tools/bugpoint/ExecutionDriver.cpp +++ b/tools/bugpoint/ExecutionDriver.cpp @@ -301,7 +301,6 @@ std::string BugDriver::executeProgram(const Module *Program, if (AI == 0) AI = Interpreter; assert(AI && "Interpreter should have been created already!"); bool CreatedBitcode = false; - std::string ErrMsg; if (BitcodeFile.empty()) { // Emit the program to a bitcode file... SmallString<128> UniqueFilename; diff --git a/tools/llvm-diff/DifferenceEngine.cpp b/tools/llvm-diff/DifferenceEngine.cpp index ba15667..768b94b 100644 --- a/tools/llvm-diff/DifferenceEngine.cpp +++ b/tools/llvm-diff/DifferenceEngine.cpp @@ -195,8 +195,6 @@ class FunctionDifferenceEngine { BasicBlock::iterator LI = L->begin(), LE = L->end(); BasicBlock::iterator RI = R->begin(); - llvm::SmallVector, 20> TentativePairs; - do { assert(LI != LE && RI != R->end()); Instruction *LeftI = &*LI, *RightI = &*RI; diff --git a/tools/llvm-lto/llvm-lto.cpp b/tools/llvm-lto/llvm-lto.cpp index 2f51c0c..ab1e162 100644 --- a/tools/llvm-lto/llvm-lto.cpp +++ b/tools/llvm-lto/llvm-lto.cpp @@ -82,7 +82,6 @@ int main(int argc, char **argv) { Options.UseInitArray = UseInitArray; unsigned BaseArg = 0; - std::string ErrorMessage; LTOCodeGenerator CodeGen; diff --git a/tools/llvm-objdump/MachODump.cpp b/tools/llvm-objdump/MachODump.cpp index 403be5a..86923fd 100644 --- a/tools/llvm-objdump/MachODump.cpp +++ b/tools/llvm-objdump/MachODump.cpp @@ -260,8 +260,6 @@ static void DisassembleInputMachO2(StringRef Filename, getSectionsAndSymbols(Header, MachOOF, Sections, Symbols, FoundFns, BaseSegmentAddress); - // Make a copy of the unsorted symbol list. FIXME: duplication - std::vector UnsortedSymbols(Symbols); // Sort the symbols by address, just in case they didn't come in that way. std::sort(Symbols.begin(), Symbols.end(), SymbolSorter()); diff --git a/tools/llvm-prof/llvm-prof.cpp b/tools/llvm-prof/llvm-prof.cpp index 52d0130..6c340b8 100644 --- a/tools/llvm-prof/llvm-prof.cpp +++ b/tools/llvm-prof/llvm-prof.cpp @@ -147,9 +147,6 @@ char ProfileInfoPrinterPass::ID = 0; bool ProfileInfoPrinterPass::runOnModule(Module &M) { ProfileInfo &PI = getAnalysis(); - std::map FuncFreqs; - std::map BlockFreqs; - std::map EdgeFreqs; // Output a report. Eventually, there will be multiple reports selectable on // the command line, for now, just keep things simple. diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index 71f03bc..ffa0e01 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -420,8 +420,6 @@ static const EnumEntry ElfSegmentFlags[] = { template void ELFDumper::printFileHeaders() { - error_code EC; - const typename ELFO::Elf_Ehdr *Header = Obj->getHeader(); { @@ -512,7 +510,6 @@ template void ELFDumper::printRelocations() { ListScope D(W, "Relocations"); - error_code EC; int SectionNumber = -1; for (typename ELFO::Elf_Shdr_Iter SecI = Obj->begin_sections(), SecE = Obj->end_sections(); @@ -769,8 +766,6 @@ template void ELFDumper::printNeededLibraries() { ListScope D(W, "NeededLibraries"); - error_code EC; - typedef std::vector LibsTy; LibsTy Libs; diff --git a/tools/llvm-readobj/MachODumper.cpp b/tools/llvm-readobj/MachODumper.cpp index e27a58a..b97166b 100644 --- a/tools/llvm-readobj/MachODumper.cpp +++ b/tools/llvm-readobj/MachODumper.cpp @@ -398,8 +398,6 @@ void MachODumper::printDynamicSymbols() { } void MachODumper::printSymbol(symbol_iterator SymI) { - error_code EC; - StringRef SymbolName; if (SymI->getName(SymbolName)) SymbolName = ""; diff --git a/tools/obj2yaml/coff2yaml.cpp b/tools/obj2yaml/coff2yaml.cpp index 1e28c4e..02d7ebf 100644 --- a/tools/obj2yaml/coff2yaml.cpp +++ b/tools/obj2yaml/coff2yaml.cpp @@ -72,7 +72,6 @@ void COFFDumper::dumpSections(unsigned NumSections) { const object::coff_relocation *reloc = Obj.getCOFFRelocation(rIter); COFFYAML::Relocation Rel; object::symbol_iterator Sym = rIter->getSymbol(); - StringRef Name; Sym->getName(Rel.SymbolName); Rel.VirtualAddress = reloc->VirtualAddress; Rel.Type = reloc->Type; -- cgit v1.1 From 6eb43d295625cd2ff314c59b49d4fd11f3348cad Mon Sep 17 00:00:00 2001 From: Filip Pizlo Date: Wed, 2 Oct 2013 00:59:25 +0000 Subject: This threads SectionName through the allocateCodeSection/allocateDataSection APIs, both in C++ and C land. It's useful for the memory managers that are allocating a section to know what the name of the section is. At a minimum, this is useful for low-level debugging - it's customary for JITs to be able to tell you what memory they allocated, and as part of any such dump, they should be able to tell you some meta-data about what each allocation is for. This allows clients that supply their own memory managers to do this. Additionally, we also envision the SectionName being useful for passing meta-data from within LLVM to an LLVM client. This changes both the C and C++ APIs, and all of the clients of those APIs within LLVM. I'm assuming that it's safe to change the C++ API because that API is allowed to change. I'm assuming that it's safe to change the C API because we haven't shipped the API in a release yet (LLVM 3.3 doesn't include the MCJIT memory management C API). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191804 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/RecordingMemoryManager.cpp | 6 ++++-- tools/lli/RecordingMemoryManager.h | 5 +++-- tools/llvm-rtdyld/llvm-rtdyld.cpp | 9 ++++++--- 3 files changed, 13 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/lli/RecordingMemoryManager.cpp b/tools/lli/RecordingMemoryManager.cpp index ec55d2c..d54b8e4 100644 --- a/tools/lli/RecordingMemoryManager.cpp +++ b/tools/lli/RecordingMemoryManager.cpp @@ -27,7 +27,8 @@ RecordingMemoryManager::~RecordingMemoryManager() { } uint8_t *RecordingMemoryManager:: -allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) { +allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, + StringRef SectionName) { // The recording memory manager is just a local copy of the remote target. // The alignment requirement is just stored here for later use. Regular // heap storage is sufficient here, but we're using mapped memory to work @@ -39,7 +40,8 @@ allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) { uint8_t *RecordingMemoryManager:: allocateDataSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID, bool IsReadOnly) { + unsigned SectionID, StringRef SectionName, + bool IsReadOnly) { // The recording memory manager is just a local copy of the remote target. // The alignment requirement is just stored here for later use. Regular // heap storage is sufficient here, but we're using mapped memory to work diff --git a/tools/lli/RecordingMemoryManager.h b/tools/lli/RecordingMemoryManager.h index b2919c3..05f4807 100644 --- a/tools/lli/RecordingMemoryManager.h +++ b/tools/lli/RecordingMemoryManager.h @@ -50,10 +50,11 @@ public: const_code_iterator code_end() const { return AllocatedCodeMem.end(); } uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID); + unsigned SectionID, StringRef SectionName); uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID, bool IsReadOnly); + unsigned SectionID, StringRef SectionName, + bool IsReadOnly); void *getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure = true); diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp index 7f042d2..c5c2854 100644 --- a/tools/llvm-rtdyld/llvm-rtdyld.cpp +++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -60,9 +60,10 @@ public: SmallVector DataMemory; uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID); + unsigned SectionID, StringRef SectionName); uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID, bool IsReadOnly); + unsigned SectionID, StringRef SectionName, + bool IsReadOnly); virtual void *getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure = true) { @@ -80,7 +81,8 @@ public: uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID) { + unsigned SectionID, + StringRef SectionName) { sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, 0, 0); FunctionMemory.push_back(MB); return (uint8_t*)MB.base(); @@ -89,6 +91,7 @@ uint8_t *TrivialMemoryManager::allocateCodeSection(uintptr_t Size, uint8_t *TrivialMemoryManager::allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, + StringRef SectionName, bool IsReadOnly) { sys::MemoryBlock MB = sys::Memory::AllocateRWX(Size, 0, 0); DataMemory.push_back(MB); -- cgit v1.1 From 2be8ab460378455f82d719a872420fb5053f1bd5 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 2 Oct 2013 14:04:38 +0000 Subject: Enable building LTO on WIN32. Enable building the LTO library (.lib and.dll) and llvm-lto.exe on Windows with MSVC and Mingw as well as re-enabling the associated test. Patch by Greg Bedwell! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191823 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/CMakeLists.txt | 2 +- tools/lto/CMakeLists.txt | 20 +++++++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 468d396..d8001e7 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -43,7 +43,7 @@ add_llvm_tool_subdirectory(llvm-symbolizer) add_llvm_tool_subdirectory(obj2yaml) add_llvm_tool_subdirectory(yaml2obj) -if( NOT WIN32 ) +if( NOT CYGWIN ) add_llvm_tool_subdirectory(lto) add_llvm_tool_subdirectory(llvm-lto) else() diff --git a/tools/lto/CMakeLists.txt b/tools/lto/CMakeLists.txt index 8b26ddd..89160ee 100644 --- a/tools/lto/CMakeLists.txt +++ b/tools/lto/CMakeLists.txt @@ -9,10 +9,24 @@ set(SOURCES lto.cpp ) -if( NOT WIN32 AND LLVM_ENABLE_PIC ) +if( NOT CYGWIN AND LLVM_ENABLE_PIC ) + if ( WIN32 ) + # Create .def file containing a list of exports preceeded by + # 'EXPORTS'. The file "lto.exports" already contains the list, so we + # massage it into the correct format here to create "lto.exports.def". + set(LTO_EXPORTS_DEF ${CMAKE_CURRENT_BINARY_DIR}/lto.exports.def) + file(READ "lto.exports" exports_list) + file(WRITE ${LTO_EXPORTS_DEF} "LIBRARY LTO\n") + file(APPEND ${LTO_EXPORTS_DEF} "EXPORTS\n") + file(APPEND ${LTO_EXPORTS_DEF} ${exports_list}) + set(SHARED_LIB_SOURCES ${SOURCES} ${LTO_EXPORTS_DEF}) + else() + set(SHARED_LIB_SOURCES ${SOURCES}) + endif() + set(bsl ${BUILD_SHARED_LIBS}) set(BUILD_SHARED_LIBS ON) - add_llvm_library(LTO ${SOURCES}) + add_llvm_library(LTO ${SHARED_LIB_SOURCES}) set_property(TARGET LTO PROPERTY OUTPUT_NAME "LTO") set(BUILD_SHARED_LIBS ${bsl}) set(LTO_STATIC_TARGET_NAME LTO_static) @@ -25,7 +39,7 @@ if( NOT BUILD_SHARED_LIBS ) set_property(TARGET ${LTO_STATIC_TARGET_NAME} PROPERTY OUTPUT_NAME "LTO") endif() -if( NOT WIN32 ) +if( NOT CYGWIN ) install(FILES ${LLVM_MAIN_INCLUDE_DIR}/llvm-c/lto.h DESTINATION include/llvm-c) endif() -- cgit v1.1 From b964366a9a282dee620651611c97c80311b11a8b Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 2 Oct 2013 14:12:56 +0000 Subject: Add a -exported-symbol option to llvm-lto. Patch by Tom Roeder. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191825 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-lto/llvm-lto.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'tools') diff --git a/tools/llvm-lto/llvm-lto.cpp b/tools/llvm-lto/llvm-lto.cpp index ab1e162..3ecd13f 100644 --- a/tools/llvm-lto/llvm-lto.cpp +++ b/tools/llvm-lto/llvm-lto.cpp @@ -45,6 +45,12 @@ OutputFilename("o", cl::init(""), cl::desc("Override output filename"), cl::value_desc("filename")); +static cl::list +ExportedSymbols("exported-symbol", + cl::desc("Symbol to export from the resulting object file"), + cl::ZeroOrMore); + + int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); @@ -107,6 +113,10 @@ int main(int argc, char **argv) { } } + // Add all the exported symbols to the table of symbols to preserve. + for (unsigned i = 0; i < ExportedSymbols.size(); ++i) + CodeGen.addMustPreserveSymbol(ExportedSymbols[i].c_str()); + if (!OutputFilename.empty()) { size_t len = 0; std::string ErrorInfo; -- cgit v1.1 From 0e95b3aba9b2039ae3af617e681aacca2ff81f79 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 2 Oct 2013 14:36:23 +0000 Subject: Fix option parsing in the gold plugin. This was broken when options were moved up in r191680. No test because this is specific LLVMgold.so/libLTO.so. Patch by Tom Roeder! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191829 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/lto.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'tools') diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index 7996720..7bfddcd 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -40,6 +40,9 @@ static std::string sLastErrorString; // *** Not thread safe *** static bool initialized = false; +// Holds the command-line option parsing state of the LTO module. +static bool parsedOptions = false; + // Initialize the configured targets if they have not been initialized. static void lto_initialize() { if (!initialized) { @@ -261,6 +264,10 @@ void lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, /// 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(); + parsedOptions = true; + } return !cg->writeMergedModules(path, sLastErrorString); } @@ -271,6 +278,10 @@ bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) { /// 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(); + parsedOptions = true; + } return cg->compile(length, DisableOpt, DisableInline, DisableGVNLoadPRE, sLastErrorString); } @@ -279,6 +290,10 @@ const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) { /// 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(); + parsedOptions = true; + } return !cg->compile_to_file(name, DisableOpt, DisableInline, DisableGVNLoadPRE, sLastErrorString); } -- cgit v1.1 From b6adb4216cbc466cae62eff75ec9b2b552ecf866 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Wed, 2 Oct 2013 15:14:13 +0000 Subject: Tidy up this line of the Makefile before I start hacking on it. I really should sort it or do something more sustainable, but I couldn't work up the energy to do it... Sorry. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191832 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/Makefile | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/Makefile b/tools/Makefile index 4e7ef5d..bacca71 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -27,15 +27,11 @@ OPTIONAL_DIRS := lldb # large and three small executables. This is done to minimize memory load # in parallel builds. Please retain this ordering. DIRS := llvm-config -PARALLEL_DIRS := opt llvm-as llvm-dis \ - llc llvm-ar llvm-nm \ - llvm-prof llvm-link \ - lli llvm-extract llvm-mc \ - bugpoint llvm-bcanalyzer \ - llvm-diff macho-dump llvm-objdump llvm-readobj \ - llvm-rtdyld llvm-dwarfdump llvm-cov \ - llvm-size llvm-stress llvm-mcmarkup \ - llvm-symbolizer obj2yaml yaml2obj +PARALLEL_DIRS := opt llvm-as llvm-dis llc llvm-ar llvm-nm llvm-prof llvm-link \ + lli llvm-extract llvm-mc bugpoint llvm-bcanalyzer llvm-diff \ + macho-dump llvm-objdump llvm-readobj llvm-rtdyld \ + llvm-dwarfdump llvm-cov llvm-size llvm-stress llvm-mcmarkup \ + llvm-symbolizer obj2yaml yaml2obj # If Intel JIT Events support is configured, build an extra tool to test it. ifeq ($(USE_INTEL_JITEVENTS), 1) -- cgit v1.1 From dd5d86d992eb129ecd0bb013d2db2d6a0e8d2605 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Wed, 2 Oct 2013 15:42:23 +0000 Subject: Remove the very substantial, largely unmaintained legacy PGO infrastructure. This was essentially work toward PGO based on a design that had several flaws, partially dating from a time when LLVM had a different architecture, and with an effort to modernize it abandoned without being completed. Since then, it has bitrotted for several years further. The result is nearly unusable, and isn't helping any of the modern PGO efforts. Instead, it is getting in the way, adding confusion about PGO in LLVM and distracting everyone with maintenance on essentially dead code. Removing it paves the way for modern efforts around PGO. Among other effects, this removes the last of the runtime libraries from LLVM. Those are being developed in the separate 'compiler-rt' project now, with somewhat different licensing specifically more approriate for runtimes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191835 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/CMakeLists.txt | 1 - tools/LLVMBuild.txt | 2 +- tools/Makefile | 2 +- tools/llvm-prof/CMakeLists.txt | 5 - tools/llvm-prof/LLVMBuild.txt | 22 ---- tools/llvm-prof/Makefile | 17 --- tools/llvm-prof/llvm-prof.cpp | 290 ----------------------------------------- 7 files changed, 2 insertions(+), 337 deletions(-) delete mode 100644 tools/llvm-prof/CMakeLists.txt delete mode 100644 tools/llvm-prof/LLVMBuild.txt delete mode 100644 tools/llvm-prof/Makefile delete mode 100644 tools/llvm-prof/llvm-prof.cpp (limited to 'tools') diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index d8001e7..69c4050 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -15,7 +15,6 @@ add_llvm_tool_subdirectory(llvm-nm) add_llvm_tool_subdirectory(llvm-size) add_llvm_tool_subdirectory(llvm-cov) -add_llvm_tool_subdirectory(llvm-prof) add_llvm_tool_subdirectory(llvm-link) add_llvm_tool_subdirectory(lli) diff --git a/tools/LLVMBuild.txt b/tools/LLVMBuild.txt index fa10b99..93b8d98 100644 --- a/tools/LLVMBuild.txt +++ b/tools/LLVMBuild.txt @@ -16,7 +16,7 @@ ;===------------------------------------------------------------------------===; [common] -subdirectories = bugpoint llc lli llvm-ar llvm-as llvm-bcanalyzer llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-jitlistener llvm-link llvm-lto llvm-mc llvm-nm llvm-objdump llvm-prof llvm-rtdyld llvm-size macho-dump opt llvm-mcmarkup +subdirectories = bugpoint llc lli llvm-ar llvm-as llvm-bcanalyzer llvm-cov llvm-diff llvm-dis llvm-dwarfdump llvm-extract llvm-jitlistener llvm-link llvm-lto llvm-mc llvm-nm llvm-objdump llvm-rtdyld llvm-size macho-dump opt llvm-mcmarkup [component_0] type = Group diff --git a/tools/Makefile b/tools/Makefile index bacca71..11e417a 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -27,7 +27,7 @@ OPTIONAL_DIRS := lldb # large and three small executables. This is done to minimize memory load # in parallel builds. Please retain this ordering. DIRS := llvm-config -PARALLEL_DIRS := opt llvm-as llvm-dis llc llvm-ar llvm-nm llvm-prof llvm-link \ +PARALLEL_DIRS := opt llvm-as llvm-dis llc llvm-ar llvm-nm llvm-link \ lli llvm-extract llvm-mc bugpoint llvm-bcanalyzer llvm-diff \ macho-dump llvm-objdump llvm-readobj llvm-rtdyld \ llvm-dwarfdump llvm-cov llvm-size llvm-stress llvm-mcmarkup \ diff --git a/tools/llvm-prof/CMakeLists.txt b/tools/llvm-prof/CMakeLists.txt deleted file mode 100644 index 442112b..0000000 --- a/tools/llvm-prof/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(LLVM_LINK_COMPONENTS bitreader analysis) - -add_llvm_tool(llvm-prof - llvm-prof.cpp - ) diff --git a/tools/llvm-prof/LLVMBuild.txt b/tools/llvm-prof/LLVMBuild.txt deleted file mode 100644 index d59127c..0000000 --- a/tools/llvm-prof/LLVMBuild.txt +++ /dev/null @@ -1,22 +0,0 @@ -;===- ./tools/llvm-prof/LLVMBuild.txt --------------------------*- Conf -*--===; -; -; The LLVM Compiler Infrastructure -; -; This file is distributed under the University of Illinois Open Source -; License. See LICENSE.TXT for details. -; -;===------------------------------------------------------------------------===; -; -; This is an LLVMBuild description file for the components in this subdirectory. -; -; For more information on the LLVMBuild system, please see: -; -; http://llvm.org/docs/LLVMBuild.html -; -;===------------------------------------------------------------------------===; - -[component_0] -type = Tool -name = llvm-prof -parent = Tools -required_libraries = Analysis BitReader diff --git a/tools/llvm-prof/Makefile b/tools/llvm-prof/Makefile deleted file mode 100644 index f829786..0000000 --- a/tools/llvm-prof/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -##===- tools/llvm-prof/Makefile ----------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL := ../.. -TOOLNAME := llvm-prof -LINK_COMPONENTS := bitreader analysis - -# This tool has no plugins, optimize startup time. -TOOL_NO_EXPORTS = 1 - -include $(LEVEL)/Makefile.common diff --git a/tools/llvm-prof/llvm-prof.cpp b/tools/llvm-prof/llvm-prof.cpp deleted file mode 100644 index 6c340b8..0000000 --- a/tools/llvm-prof/llvm-prof.cpp +++ /dev/null @@ -1,290 +0,0 @@ -//===- llvm-prof.cpp - Read in and process llvmprof.out data files --------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This tools is meant for use with the various LLVM profiling instrumentation -// passes. It reads in the data file produced by executing an instrumented -// program, and outputs a nice report. -// -//===----------------------------------------------------------------------===// - -#include "llvm/IR/LLVMContext.h" -#include "llvm/Analysis/Passes.h" -#include "llvm/Analysis/ProfileInfo.h" -#include "llvm/Analysis/ProfileInfoLoader.h" -#include "llvm/Assembly/AssemblyAnnotationWriter.h" -#include "llvm/Bitcode/ReaderWriter.h" -#include "llvm/IR/InstrTypes.h" -#include "llvm/IR/Module.h" -#include "llvm/PassManager.h" -#include "llvm/Support/CommandLine.h" -#include "llvm/Support/Format.h" -#include "llvm/Support/FormattedStream.h" -#include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/PrettyStackTrace.h" -#include "llvm/Support/Signals.h" -#include "llvm/Support/raw_ostream.h" -#include "llvm/Support/system_error.h" -#include -#include -#include -#include - -using namespace llvm; - -namespace { - cl::opt - BitcodeFile(cl::Positional, cl::desc(""), - cl::Required); - - cl::opt - ProfileDataFile(cl::Positional, cl::desc(""), - cl::Optional, cl::init("llvmprof.out")); - - cl::opt - PrintAnnotatedLLVM("annotated-llvm", - cl::desc("Print LLVM code with frequency annotations")); - cl::alias PrintAnnotated2("A", cl::desc("Alias for --annotated-llvm"), - cl::aliasopt(PrintAnnotatedLLVM)); - cl::opt - PrintAllCode("print-all-code", - cl::desc("Print annotated code for the entire program")); -} - -// PairSecondSort - A sorting predicate to sort by the second element of a pair. -template -struct PairSecondSortReverse - : public std::binary_function, - std::pair, bool> { - bool operator()(const std::pair &LHS, - const std::pair &RHS) const { - return LHS.second > RHS.second; - } -}; - -static double ignoreMissing(double w) { - if (w == ProfileInfo::MissingValue) return 0; - return w; -} - -namespace { - class ProfileAnnotator : public AssemblyAnnotationWriter { - ProfileInfo &PI; - public: - ProfileAnnotator(ProfileInfo &pi) : PI(pi) {} - - virtual void emitFunctionAnnot(const Function *F, - formatted_raw_ostream &OS) { - double w = PI.getExecutionCount(F); - if (w != ProfileInfo::MissingValue) { - OS << ";;; %" << F->getName() << " called "<<(unsigned)w - <<" times.\n;;;\n"; - } - } - virtual void emitBasicBlockStartAnnot(const BasicBlock *BB, - formatted_raw_ostream &OS) { - double w = PI.getExecutionCount(BB); - if (w != ProfileInfo::MissingValue) { - if (w != 0) { - OS << "\t;;; Basic block executed " << (unsigned)w << " times.\n"; - } else { - OS << "\t;;; Never executed!\n"; - } - } - } - - virtual void emitBasicBlockEndAnnot(const BasicBlock *BB, - formatted_raw_ostream &OS) { - // Figure out how many times each successor executed. - std::vector > SuccCounts; - - const TerminatorInst *TI = BB->getTerminator(); - for (unsigned s = 0, e = TI->getNumSuccessors(); s != e; ++s) { - BasicBlock* Succ = TI->getSuccessor(s); - double w = ignoreMissing(PI.getEdgeWeight(std::make_pair(BB, Succ))); - if (w != 0) - SuccCounts.push_back(std::make_pair(std::make_pair(BB, Succ), w)); - } - if (!SuccCounts.empty()) { - OS << "\t;;; Out-edge counts:"; - for (unsigned i = 0, e = SuccCounts.size(); i != e; ++i) - OS << " [" << (SuccCounts[i]).second << " -> " - << (SuccCounts[i]).first.second->getName() << "]"; - OS << "\n"; - } - } - }; -} - -namespace { - /// ProfileInfoPrinterPass - Helper pass to dump the profile information for - /// a module. - // - // FIXME: This should move elsewhere. - class ProfileInfoPrinterPass : public ModulePass { - ProfileInfoLoader &PIL; - public: - static char ID; // Class identification, replacement for typeinfo. - explicit ProfileInfoPrinterPass(ProfileInfoLoader &_PIL) - : ModulePass(ID), PIL(_PIL) {} - - virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.setPreservesAll(); - AU.addRequired(); - } - - bool runOnModule(Module &M); - }; -} - -char ProfileInfoPrinterPass::ID = 0; - -bool ProfileInfoPrinterPass::runOnModule(Module &M) { - ProfileInfo &PI = getAnalysis(); - - // Output a report. Eventually, there will be multiple reports selectable on - // the command line, for now, just keep things simple. - - // Emit the most frequent function table... - std::vector > FunctionCounts; - std::vector > Counts; - for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) { - if (FI->isDeclaration()) continue; - double w = ignoreMissing(PI.getExecutionCount(FI)); - FunctionCounts.push_back(std::make_pair(FI, w)); - for (Function::iterator BB = FI->begin(), BBE = FI->end(); - BB != BBE; ++BB) { - double w = ignoreMissing(PI.getExecutionCount(BB)); - Counts.push_back(std::make_pair(BB, w)); - } - } - - // Sort by the frequency, backwards. - sort(FunctionCounts.begin(), FunctionCounts.end(), - PairSecondSortReverse()); - - double TotalExecutions = 0; - for (unsigned i = 0, e = FunctionCounts.size(); i != e; ++i) - TotalExecutions += FunctionCounts[i].second; - - outs() << "===" << std::string(73, '-') << "===\n" - << "LLVM profiling output for execution"; - if (PIL.getNumExecutions() != 1) outs() << "s"; - outs() << ":\n"; - - for (unsigned i = 0, e = PIL.getNumExecutions(); i != e; ++i) { - outs() << " "; - if (e != 1) outs() << i+1 << ". "; - outs() << PIL.getExecution(i) << "\n"; - } - - outs() << "\n===" << std::string(73, '-') << "===\n"; - outs() << "Function execution frequencies:\n\n"; - - // Print out the function frequencies... - outs() << " ## Frequency\n"; - for (unsigned i = 0, e = FunctionCounts.size(); i != e; ++i) { - if (FunctionCounts[i].second == 0) { - outs() << "\n NOTE: " << e-i << " function" - << (e-i-1 ? "s were" : " was") << " never executed!\n"; - break; - } - - outs() << format("%3d", i+1) << ". " - << format("%5.2g", FunctionCounts[i].second) << "/" - << format("%g", TotalExecutions) << " " - << FunctionCounts[i].first->getName() << "\n"; - } - - std::set FunctionsToPrint; - - TotalExecutions = 0; - for (unsigned i = 0, e = Counts.size(); i != e; ++i) - TotalExecutions += Counts[i].second; - - // Sort by the frequency, backwards. - sort(Counts.begin(), Counts.end(), - PairSecondSortReverse()); - - outs() << "\n===" << std::string(73, '-') << "===\n"; - outs() << "Top 20 most frequently executed basic blocks:\n\n"; - - // Print out the function frequencies... - outs() <<" ## %% \tFrequency\n"; - unsigned BlocksToPrint = Counts.size(); - if (BlocksToPrint > 20) BlocksToPrint = 20; - for (unsigned i = 0; i != BlocksToPrint; ++i) { - if (Counts[i].second == 0) break; - Function *F = Counts[i].first->getParent(); - outs() << format("%3d", i+1) << ". " - << format("%5g", Counts[i].second/(double)TotalExecutions*100)<<"% " - << format("%5.0f", Counts[i].second) << "/" - << format("%g", TotalExecutions) << "\t" - << F->getName() << "() - " - << Counts[i].first->getName() << "\n"; - FunctionsToPrint.insert(F); - } - - if (PrintAnnotatedLLVM || PrintAllCode) { - outs() << "\n===" << std::string(73, '-') << "===\n"; - outs() << "Annotated LLVM code for the module:\n\n"; - - ProfileAnnotator PA(PI); - - if (FunctionsToPrint.empty() || PrintAllCode) - M.print(outs(), &PA); - else - // Print just a subset of the functions. - for (std::set::iterator I = FunctionsToPrint.begin(), - E = FunctionsToPrint.end(); I != E; ++I) - (*I)->print(outs(), &PA); - } - - return false; -} - -int main(int argc, char **argv) { - // Print a stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(); - PrettyStackTraceProgram X(argc, argv); - - LLVMContext &Context = getGlobalContext(); - llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - - cl::ParseCommandLineOptions(argc, argv, "llvm profile dump decoder\n"); - - // Read in the bitcode file... - std::string ErrorMessage; - OwningPtr Buffer; - error_code ec; - Module *M = 0; - if (!(ec = MemoryBuffer::getFileOrSTDIN(BitcodeFile, Buffer))) { - M = ParseBitcodeFile(Buffer.get(), Context, &ErrorMessage); - } else - ErrorMessage = ec.message(); - if (M == 0) { - errs() << argv[0] << ": " << BitcodeFile << ": " - << ErrorMessage << "\n"; - return 1; - } - - // Read the profiling information. This is redundant since we load it again - // using the standard profile info provider pass, but for now this gives us - // access to additional information not exposed via the ProfileInfo - // interface. - ProfileInfoLoader PIL(argv[0], ProfileDataFile); - - // Run the printer pass. - PassManager PassMgr; - PassMgr.add(createProfileLoaderPass(ProfileDataFile)); - PassMgr.add(new ProfileInfoPrinterPass(PIL)); - PassMgr.run(*M); - - return 0; -} -- cgit v1.1 From 0ab5c6c16b1b09d76c3ba2d70443b10bcc26169c Mon Sep 17 00:00:00 2001 From: Andrew Kaylor Date: Wed, 2 Oct 2013 17:12:36 +0000 Subject: Adding out-of-process execution support to lli. At this time only Unix-based systems are supported. Windows has stubs and should re-route to the simulated mode. Thanks to Sriram Murali for contributions to this patch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191843 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/CMakeLists.txt | 3 + tools/lli/ChildTarget/CMakeLists.txt | 3 + tools/lli/ChildTarget/ChildTarget.cpp | 241 ++++++++++++++++++++++++++ tools/lli/ChildTarget/Makefile | 17 ++ tools/lli/ChildTarget/Unix/ChildTarget.inc | 141 +++++++++++++++ tools/lli/ChildTarget/Windows/ChildTarget.inc | 41 +++++ tools/lli/Makefile | 2 + tools/lli/RemoteTarget.cpp | 31 ++++ tools/lli/RemoteTarget.h | 27 ++- tools/lli/RemoteTargetExternal.cpp | 162 +++++++++++++++++ tools/lli/RemoteTargetExternal.h | 118 +++++++++++++ tools/lli/RemoteTargetMessage.h | 45 +++++ tools/lli/Unix/RemoteTargetExternal.inc | 91 ++++++++++ tools/lli/Windows/RemoteTargetExternal.inc | 32 ++++ tools/lli/lli.cpp | 49 +++++- 15 files changed, 987 insertions(+), 16 deletions(-) create mode 100644 tools/lli/ChildTarget/CMakeLists.txt create mode 100644 tools/lli/ChildTarget/ChildTarget.cpp create mode 100644 tools/lli/ChildTarget/Makefile create mode 100644 tools/lli/ChildTarget/Unix/ChildTarget.inc create mode 100644 tools/lli/ChildTarget/Windows/ChildTarget.inc create mode 100644 tools/lli/RemoteTargetExternal.cpp create mode 100644 tools/lli/RemoteTargetExternal.h create mode 100644 tools/lli/RemoteTargetMessage.h create mode 100644 tools/lli/Unix/RemoteTargetExternal.inc create mode 100644 tools/lli/Windows/RemoteTargetExternal.inc (limited to 'tools') diff --git a/tools/lli/CMakeLists.txt b/tools/lli/CMakeLists.txt index 98f411d..578c414 100644 --- a/tools/lli/CMakeLists.txt +++ b/tools/lli/CMakeLists.txt @@ -1,6 +1,8 @@ set(LLVM_LINK_COMPONENTS mcjit jit interpreter nativecodegen bitreader asmparser irreader selectiondag native instrumentation) +add_subdirectory(ChildTarget) + if( LLVM_USE_OPROFILE ) set(LLVM_LINK_COMPONENTS ${LLVM_LINK_COMPONENTS} @@ -21,4 +23,5 @@ add_llvm_tool(lli lli.cpp RecordingMemoryManager.cpp RemoteTarget.cpp + RemoteTargetExternal.cpp ) diff --git a/tools/lli/ChildTarget/CMakeLists.txt b/tools/lli/ChildTarget/CMakeLists.txt new file mode 100644 index 0000000..fd1ac24 --- /dev/null +++ b/tools/lli/ChildTarget/CMakeLists.txt @@ -0,0 +1,3 @@ +add_llvm_tool(lli-child-target + ChildTarget.cpp + ) diff --git a/tools/lli/ChildTarget/ChildTarget.cpp b/tools/lli/ChildTarget/ChildTarget.cpp new file mode 100644 index 0000000..a59209a --- /dev/null +++ b/tools/lli/ChildTarget/ChildTarget.cpp @@ -0,0 +1,241 @@ +#include "llvm/Config/config.h" + +#include "../RemoteTargetMessage.h" +#include +#include +#include +#include +#include + +using namespace llvm; + +class LLIChildTarget { +public: + void initialize(); + LLIMessageType waitForIncomingMessage(); + void handleMessage(LLIMessageType messageType); + +private: + // Incoming message handlers + void handleAllocateSpace(); + void handleLoadSection(bool IsCode); + void handleExecute(); + void handleTerminate(); + + // Outgoing message handlers + void sendChildActive(); + void sendAllocationResult(uint64_t Addr); + void sendLoadComplete(); + void sendExecutionComplete(uint64_t Result); + + // OS-specific functions + void initializeConnection(); + int WriteBytes(const void *Data, size_t Size); + int ReadBytes(void *Data, size_t Size); + uint64_t allocate(uint32_t Alignment, uint32_t Size); + void makeSectionExecutable(uint64_t Addr, uint32_t Size); + void InvalidateInstructionCache(const void *Addr, size_t Len); + void releaseMemory(uint64_t Addr, uint32_t Size); + + // Store a map of allocated buffers to sizes. + typedef std::map AllocMapType; + AllocMapType m_AllocatedBufferMap; + + // Communication handles (OS-specific) + void *ConnectionData; +}; + +int main() { + LLIChildTarget ThisChild; + ThisChild.initialize(); + LLIMessageType MsgType; + do { + MsgType = ThisChild.waitForIncomingMessage(); + ThisChild.handleMessage(MsgType); + } while (MsgType != LLI_Terminate && + MsgType != LLI_Error); + return 0; +} + +// Public methods +void LLIChildTarget::initialize() { + initializeConnection(); + sendChildActive(); +} + +LLIMessageType LLIChildTarget::waitForIncomingMessage() { + int32_t MsgType = -1; + if (ReadBytes(&MsgType, 4) > 0) + return (LLIMessageType)MsgType; + return LLI_Error; +} + +void LLIChildTarget::handleMessage(LLIMessageType messageType) { + switch (messageType) { + case LLI_AllocateSpace: + handleAllocateSpace(); + break; + case LLI_LoadCodeSection: + handleLoadSection(true); + break; + case LLI_LoadDataSection: + handleLoadSection(false); + break; + case LLI_Execute: + handleExecute(); + break; + case LLI_Terminate: + handleTerminate(); + break; + default: + // FIXME: Handle error! + break; + } +} + +// Incoming message handlers +void LLIChildTarget::handleAllocateSpace() { + // Read and verify the message data size. + uint32_t DataSize; + int rc = ReadBytes(&DataSize, 4); + assert(rc == 4); + assert(DataSize == 8); + + // Read the message arguments. + uint32_t Alignment; + uint32_t AllocSize; + rc = ReadBytes(&Alignment, 4); + assert(rc == 4); + rc = ReadBytes(&AllocSize, 4); + assert(rc == 4); + + // Allocate the memory. + uint64_t Addr = allocate(Alignment, AllocSize); + + // Send AllocationResult message. + sendAllocationResult(Addr); +} + +void LLIChildTarget::handleLoadSection(bool IsCode) { + // Read the message data size. + uint32_t DataSize; + int rc = ReadBytes(&DataSize, 4); + assert(rc == 4); + + // Read the target load address. + uint64_t Addr; + rc = ReadBytes(&Addr, 8); + assert(rc == 8); + + size_t BufferSize = DataSize - 8; + + // FIXME: Verify that this is in allocated space + + // Read section data into previously allocated buffer + rc = ReadBytes((void*)Addr, DataSize - 8); + assert(rc == (int)(BufferSize)); + + // If IsCode, mark memory executable + if (IsCode) + makeSectionExecutable(Addr, BufferSize); + + // Send MarkLoadComplete message. + sendLoadComplete(); +} + +void LLIChildTarget::handleExecute() { + // Read the message data size. + uint32_t DataSize; + int rc = ReadBytes(&DataSize, 4); + assert(rc == 4); + assert(DataSize == 8); + + // Read the target address. + uint64_t Addr; + rc = ReadBytes(&Addr, 8); + assert(rc == 8); + + // Call function + int Result; + int (*fn)(void) = (int(*)(void))Addr; + Result = fn(); + + // Send ExecutionResult message. + sendExecutionComplete((int64_t)Result); +} + +void LLIChildTarget::handleTerminate() { + // Release all allocated memory + AllocMapType::iterator Begin = m_AllocatedBufferMap.begin(); + AllocMapType::iterator End = m_AllocatedBufferMap.end(); + for (AllocMapType::iterator It = Begin; It != End; ++It) { + releaseMemory(It->first, It->second); + } + m_AllocatedBufferMap.clear(); +} + +// Outgoing message handlers +void LLIChildTarget::sendChildActive() { + // Write the message type. + uint32_t MsgType = (uint32_t)LLI_ChildActive; + int rc = WriteBytes(&MsgType, 4); + assert(rc == 4); + + // Write the data size. + uint32_t DataSize = 0; + rc = WriteBytes(&DataSize, 4); + assert(rc == 4); +} + +void LLIChildTarget::sendAllocationResult(uint64_t Addr) { + // Write the message type. + uint32_t MsgType = (uint32_t)LLI_AllocationResult; + int rc = WriteBytes(&MsgType, 4); + assert(rc == 4); + + // Write the data size. + uint32_t DataSize = 8; + rc = WriteBytes(&DataSize, 4); + assert(rc == 4); + + // Write the allocated address. + rc = WriteBytes(&Addr, 8); + assert(rc == 8); +} + +void LLIChildTarget::sendLoadComplete() { + // Write the message type. + uint32_t MsgType = (uint32_t)LLI_LoadComplete; + int rc = WriteBytes(&MsgType, 4); + assert(rc == 4); + + // Write the data size. + uint32_t DataSize = 0; + rc = WriteBytes(&DataSize, 4); + assert(rc == 4); +} + +void LLIChildTarget::sendExecutionComplete(uint64_t Result) { + // Write the message type. + uint32_t MsgType = (uint32_t)LLI_ExecutionResult; + int rc = WriteBytes(&MsgType, 4); + assert(rc == 4); + + + // Write the data size. + uint32_t DataSize = 8; + rc = WriteBytes(&DataSize, 4); + assert(rc == 4); + + // Write the result. + rc = WriteBytes(&Result, 8); + assert(rc == 8); +} + +#ifdef LLVM_ON_UNIX +#include "Unix/ChildTarget.inc" +#endif + +#ifdef LLVM_ON_WIN32 +#include "Windows/ChildTarget.inc" +#endif diff --git a/tools/lli/ChildTarget/Makefile b/tools/lli/ChildTarget/Makefile new file mode 100644 index 0000000..f77b144 --- /dev/null +++ b/tools/lli/ChildTarget/Makefile @@ -0,0 +1,17 @@ +##===- tools/lli/Makefile ------------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL := ../../.. +TOOLNAME := lli-child-target + +include $(LEVEL)/Makefile.config + +LINK_COMPONENTS := + +include $(LLVM_SRC_ROOT)/Makefile.rules diff --git a/tools/lli/ChildTarget/Unix/ChildTarget.inc b/tools/lli/ChildTarget/Unix/ChildTarget.inc new file mode 100644 index 0000000..9550e50 --- /dev/null +++ b/tools/lli/ChildTarget/Unix/ChildTarget.inc @@ -0,0 +1,141 @@ +//===- ChildTarget.inc - Child process for external JIT execution for Unix -==// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Implementation of the Unix-specific parts of the ChildTarget class +// which executes JITed code in a separate process from where it was built. +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include + +namespace { + +struct ConnectionData_t { + int InputPipe; + int OutputPipe; + + ConnectionData_t(int in, int out) : InputPipe(in), OutputPipe(out) {} +}; + +} // namespace + +// OS-specific methods +void LLIChildTarget::initializeConnection() { + // Store the parent ends of the pipes + ConnectionData = (void*)new ConnectionData_t(STDIN_FILENO, STDOUT_FILENO); +} + +int LLIChildTarget::WriteBytes(const void *Data, size_t Size) { + return write(((ConnectionData_t*)ConnectionData)->OutputPipe, Data, Size); +} + +int LLIChildTarget::ReadBytes(void *Data, size_t Size) { + return read(((ConnectionData_t*)ConnectionData)->InputPipe, Data, Size); +} + +// The functions below duplicate functionality that is implemented in +// Support/Memory.cpp with the goal of avoiding a dependency on any +// llvm libraries. + +uint64_t LLIChildTarget::allocate(uint32_t Alignment, uint32_t Size) { + if (!Alignment) + Alignment = 16; + + static const size_t PageSize = getpagesize(); + const size_t NumPages = (Size+PageSize-1)/PageSize; + Size = NumPages*PageSize; + + int fd = -1; +#ifdef NEED_DEV_ZERO_FOR_MMAP + static int zero_fd = open("/dev/zero", O_RDWR); + if (zero_fd == -1) + return 0; + fd = zero_fd; +#endif + + int MMFlags = MAP_PRIVATE | +#ifdef HAVE_MMAP_ANONYMOUS + MAP_ANONYMOUS +#else + MAP_ANON +#endif + ; // Ends statement above + + uint64_t Addr = (uint64_t)::mmap(0, Size, PROT_READ | PROT_WRITE, MMFlags, fd, 0); + if (Addr == (uint64_t)MAP_FAILED) + return 0; + + // Align the address. + Addr = (Addr + Alignment - 1) & ~(uintptr_t)(Alignment - 1); + + m_AllocatedBufferMap[Addr] = Size; + + // Return aligned address + return Addr; +} + +void LLIChildTarget::makeSectionExecutable(uint64_t Addr, uint32_t Size) { + // FIXME: We have to mark the memory as RWX because multiple code chunks may + // be on the same page. The RemoteTarget interface should be changed to + // work around that. + int Result = ::mprotect((void*)Addr, Size, PROT_READ | PROT_WRITE | PROT_EXEC); + if (Result != 0) + InvalidateInstructionCache((const void *)Addr, Size); +} + +/// InvalidateInstructionCache - Before the JIT can run a block of code +/// that has been emitted it must invalidate the instruction cache on some +/// platforms. +void LLIChildTarget::InvalidateInstructionCache(const void *Addr, + size_t Len) { + +// icache invalidation for PPC and ARM. +#if defined(__APPLE__) + +# if (defined(__POWERPC__) || defined (__ppc__) || \ + defined(_POWER) || defined(_ARCH_PPC)) || defined(__arm__) + sys_icache_invalidate(const_cast(Addr), Len); +# endif + +#else + +# if (defined(__POWERPC__) || defined (__ppc__) || \ + defined(_POWER) || defined(_ARCH_PPC)) && defined(__GNUC__) + const size_t LineSize = 32; + + const intptr_t Mask = ~(LineSize - 1); + const intptr_t StartLine = ((intptr_t) Addr) & Mask; + const intptr_t EndLine = ((intptr_t) Addr + Len + LineSize - 1) & Mask; + + for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize) + asm volatile("dcbf 0, %0" : : "r"(Line)); + asm volatile("sync"); + + for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize) + asm volatile("icbi 0, %0" : : "r"(Line)); + asm volatile("isync"); +# elif defined(__arm__) && defined(__GNUC__) + // FIXME: Can we safely always call this for __GNUC__ everywhere? + const char *Start = static_cast(Addr); + const char *End = Start + Len; + __clear_cache(const_cast(Start), const_cast(End)); +# elif defined(__mips__) + const char *Start = static_cast(Addr); + cacheflush(const_cast(Start), Len, BCACHE); +# endif + +#endif // end apple +} + +void LLIChildTarget::releaseMemory(uint64_t Addr, uint32_t Size) { + ::munmap((void*)Addr, Size); +} diff --git a/tools/lli/ChildTarget/Windows/ChildTarget.inc b/tools/lli/ChildTarget/Windows/ChildTarget.inc new file mode 100644 index 0000000..bb95aff --- /dev/null +++ b/tools/lli/ChildTarget/Windows/ChildTarget.inc @@ -0,0 +1,41 @@ +//=- ChildTarget.inc - Child process for external JIT execution for Windows -=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Non-implementation of the Windows-specific parts of the ChildTarget class +// which executes JITed code in a separate process from where it was built. +// +//===----------------------------------------------------------------------===// + +// The RemoteTargetExternal implementation should prevent us from ever getting +// here on Windows, but nothing prevents a user from running this directly. +void LLIChildTarget::initializeConnection() { + assert(0 && "lli-child-target is not implemented for Windows"); +} + +int LLIChildTarget::WriteBytes(const void *Data, size_t Size) { + return 0; +} + +int LLIChildTarget::ReadBytes(void *Data, size_t Size) { + return 0; +} + +uint64_t LLIChildTarget::allocate(uint32_t Alignment, uint32_t Size) { + return 0; +} + +void LLIChildTarget::makeSectionExecutable(uint64_t Addr, uint32_t Size) { +} + +void LLIChildTarget::InvalidateInstructionCache(const void *Addr, + size_t Len) { +} + +void LLIChildTarget::releaseMemory(uint64_t Addr, uint32_t Size) { +} diff --git a/tools/lli/Makefile b/tools/lli/Makefile index 7a40427..eca5d83 100644 --- a/tools/lli/Makefile +++ b/tools/lli/Makefile @@ -10,6 +10,8 @@ LEVEL := ../.. TOOLNAME := lli +PARALLEL_DIRS := ChildTarget + include $(LEVEL)/Makefile.config LINK_COMPONENTS := mcjit jit instrumentation interpreter nativecodegen bitreader asmparser irreader selectiondag native diff --git a/tools/lli/RemoteTarget.cpp b/tools/lli/RemoteTarget.cpp index 212bdfd..5c74e6e 100644 --- a/tools/lli/RemoteTarget.cpp +++ b/tools/lli/RemoteTarget.cpp @@ -13,13 +13,44 @@ //===----------------------------------------------------------------------===// #include "RemoteTarget.h" +#include "RemoteTargetExternal.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/Memory.h" #include #include + using namespace llvm; +// Static methods +RemoteTarget *RemoteTarget::createRemoteTarget() { + return new RemoteTarget; +} + +RemoteTarget *RemoteTarget::createExternalRemoteTarget(std::string &ChildName) { +#ifdef LLVM_ON_UNIX + return new RemoteTargetExternal(ChildName); +#else + return 0; +#endif +} + +bool RemoteTarget::hostSupportsExternalRemoteTarget() { +#ifdef LLVM_ON_UNIX + return true; +#else + return false; +#endif +} + + +//////////////////////////////////////////////////////////////////////////////// +// Simulated remote execution +// +// This implementation will simply move generated code and data to a new memory +// location in the current executable and let it run from there. +//////////////////////////////////////////////////////////////////////////////// + bool RemoteTarget::allocateSpace(size_t Size, unsigned Alignment, uint64_t &Address) { sys::MemoryBlock *Prev = Allocations.size() ? &Allocations.back() : NULL; diff --git a/tools/lli/RemoteTarget.h b/tools/lli/RemoteTarget.h index b2a6d0e..c95fbd1 100644 --- a/tools/lli/RemoteTarget.h +++ b/tools/lli/RemoteTarget.h @@ -41,7 +41,9 @@ public: /// /// @returns False on success. On failure, ErrorMsg is updated with /// descriptive text of the encountered error. - bool allocateSpace(size_t Size, unsigned Alignment, uint64_t &Address); + virtual bool allocateSpace(size_t Size, + unsigned Alignment, + uint64_t &Address); /// Load data into the target address space. /// @@ -51,7 +53,9 @@ public: /// /// @returns False on success. On failure, ErrorMsg is updated with /// descriptive text of the encountered error. - bool loadData(uint64_t Address, const void *Data, size_t Size); + virtual bool loadData(uint64_t Address, + const void *Data, + size_t Size); /// Load code into the target address space and prepare it for execution. /// @@ -61,7 +65,9 @@ public: /// /// @returns False on success. On failure, ErrorMsg is updated with /// descriptive text of the encountered error. - bool loadCode(uint64_t Address, const void *Data, size_t Size); + virtual bool loadCode(uint64_t Address, + const void *Data, + size_t Size); /// Execute code in the target process. The called function is required /// to be of signature int "(*)(void)". @@ -72,24 +78,29 @@ public: /// /// @returns False on success. On failure, ErrorMsg is updated with /// descriptive text of the encountered error. - bool executeCode(uint64_t Address, int &RetVal); + virtual bool executeCode(uint64_t Address, + int &RetVal); /// Minimum alignment for memory permissions. Used to seperate code and /// data regions to make sure data doesn't get marked as code or vice /// versa. /// /// @returns Page alignment return value. Default of 4k. - unsigned getPageAlignment() { return 4096; } + virtual unsigned getPageAlignment() { return 4096; } /// Start the remote process. - void create(); + virtual void create(); /// Terminate the remote process. - void stop(); + virtual void stop(); RemoteTarget() : ErrorMsg(""), IsRunning(false) {} - ~RemoteTarget() { if (IsRunning) stop(); } + virtual ~RemoteTarget() { if (IsRunning) stop(); } + // Create an instance of the system-specific remote target class. + static RemoteTarget *createRemoteTarget(); + static RemoteTarget *createExternalRemoteTarget(std::string &ChildName); + static bool hostSupportsExternalRemoteTarget(); private: // Main processing function for the remote target process. Command messages // are received on file descriptor CmdFD and responses come back on OutFD. diff --git a/tools/lli/RemoteTargetExternal.cpp b/tools/lli/RemoteTargetExternal.cpp new file mode 100644 index 0000000..59ad2d3 --- /dev/null +++ b/tools/lli/RemoteTargetExternal.cpp @@ -0,0 +1,162 @@ +//===---- RemoteTargetExternal.cpp - LLVM out-of-process JIT execution ----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Implementation of the RemoteTargetExternal class which executes JITed code +// in a separate process from where it was built. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Config/config.h" + +#include "RemoteTarget.h" +#include "RemoteTargetExternal.h" + +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/Memory.h" +#include "llvm/Support/Program.h" +#include "llvm/Support/raw_ostream.h" +#include + +using namespace llvm; + +bool RemoteTargetExternal::allocateSpace(size_t Size, unsigned Alignment, + uint64_t &Address) { + SendAllocateSpace(Alignment, Size); + Receive(LLI_AllocationResult, Address); + return false; +} + +bool RemoteTargetExternal::loadData(uint64_t Address, const void *Data, size_t Size) { + SendLoadSection(Address, Data, (uint32_t)Size, false); + Receive(LLI_LoadComplete); + return false; +} + +bool RemoteTargetExternal::loadCode(uint64_t Address, const void *Data, size_t Size) { + SendLoadSection(Address, Data, (uint32_t)Size, true); + Receive(LLI_LoadComplete); + return false; +} + +bool RemoteTargetExternal::executeCode(uint64_t Address, int &RetVal) { + SendExecute(Address); + + Receive(LLI_ExecutionResult, RetVal); + return false; +} + +void RemoteTargetExternal::stop() { + SendTerminate(); + Wait(); +} + +void RemoteTargetExternal::SendAllocateSpace(uint32_t Alignment, uint32_t Size) { + int rc; + uint32_t MsgType = (uint32_t)LLI_AllocateSpace; + rc = WriteBytes(&MsgType, 4); + assert(rc == 4 && "Error writing message type."); + + uint32_t DataSize = 8; + rc = WriteBytes(&DataSize, 4); + assert(rc == 4 && "Error writing data size."); + + rc = WriteBytes(&Alignment, 4); + assert(rc == 4 && "Error writing alignment data."); + + rc = WriteBytes(&Size, 4); + assert(rc == 4 && "Error writing size data."); +} + +void RemoteTargetExternal::SendLoadSection(uint64_t Addr, + const void *Data, + uint32_t Size, + bool IsCode) { + int rc; + uint32_t MsgType = IsCode ? LLI_LoadCodeSection : LLI_LoadDataSection; + rc = WriteBytes(&MsgType, 4); + assert(rc == 4 && "Error writing message type."); + + uint32_t DataSize = Size + 8; + rc = WriteBytes(&DataSize, 4); + assert(rc == 4 && "Error writing data size."); + + rc = WriteBytes(&Addr, 8); + assert(rc == 8 && "Error writing data."); + + rc = WriteBytes(Data, Size); + assert(rc == (int)Size && "Error writing data."); +} + +void RemoteTargetExternal::SendExecute(uint64_t Addr) { + int rc; + uint32_t MsgType = (uint32_t)LLI_Execute; + rc = WriteBytes(&MsgType, 4); + assert(rc == 4 && "Error writing message type."); + + uint32_t DataSize = 8; + rc = WriteBytes(&DataSize, 4); + assert(rc == 4 && "Error writing data size."); + + rc = WriteBytes(&Addr, 8); + assert(rc == 8 && "Error writing data."); +} + +void RemoteTargetExternal::SendTerminate() { + int rc; + uint32_t MsgType = (uint32_t)LLI_Terminate; + rc = WriteBytes(&MsgType, 4); + assert(rc == 4 && "Error writing message type."); + + // No data or data size is sent with Terminate +} + + +void RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType) { + int rc; + uint32_t MsgType; + rc = ReadBytes(&MsgType, 4); + assert(rc == 4 && "Error reading message type."); + assert(MsgType == ExpectedMsgType && "Error: received unexpected message type."); + + uint32_t DataSize; + rc = ReadBytes(&DataSize, 4); + assert(rc == 4 && "Error reading data size."); + assert(DataSize == 0 && "Error: unexpected data size."); +} + +void RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType, int &Data) { + uint64_t Temp; + Receive(ExpectedMsgType, Temp); + Data = (int)(int64_t)Temp; +} + +void RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType, uint64_t &Data) { + int rc; + uint32_t MsgType; + rc = ReadBytes(&MsgType, 4); + assert(rc == 4 && "Error reading message type."); + assert(MsgType == ExpectedMsgType && "Error: received unexpected message type."); + + uint32_t DataSize; + rc = ReadBytes(&DataSize, 4); + assert(rc == 4 && "Error reading data size."); + assert(DataSize == 8 && "Error: unexpected data size."); + + rc = ReadBytes(&Data, 8); + assert(DataSize == 8 && "Error: unexpected data."); +} + +#ifdef LLVM_ON_UNIX +#include "Unix/RemoteTargetExternal.inc" +#endif + +#ifdef LLVM_ON_WIN32 +#include "Windows/RemoteTargetExternal.inc" +#endif diff --git a/tools/lli/RemoteTargetExternal.h b/tools/lli/RemoteTargetExternal.h new file mode 100644 index 0000000..9a3644a --- /dev/null +++ b/tools/lli/RemoteTargetExternal.h @@ -0,0 +1,118 @@ +//===----- RemoteTargetExternal.h - LLVM out-of-process JIT execution -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Definition of the RemoteTargetExternal class which executes JITed code in a +// separate process from where it was built. +// +//===----------------------------------------------------------------------===// + +#ifndef LLI_REMOTETARGETEXTERNAL_H +#define LLI_REMOTETARGETEXTERNAL_H + +#include "llvm/Config/config.h" + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/DataTypes.h" +#include "llvm/Support/Memory.h" +#include +#include + +#include "RemoteTarget.h" +#include "RemoteTargetMessage.h" + +namespace llvm { + +class RemoteTargetExternal : public RemoteTarget { +public: + /// Allocate space in the remote target address space. + /// + /// @param Size Amount of space, in bytes, to allocate. + /// @param Alignment Required minimum alignment for allocated space. + /// @param[out] Address Remote address of the allocated memory. + /// + /// @returns False on success. On failure, ErrorMsg is updated with + /// descriptive text of the encountered error. + virtual bool allocateSpace(size_t Size, + unsigned Alignment, + uint64_t &Address); + + /// Load data into the target address space. + /// + /// @param Address Destination address in the target process. + /// @param Data Source address in the host process. + /// @param Size Number of bytes to copy. + /// + /// @returns False on success. On failure, ErrorMsg is updated with + /// descriptive text of the encountered error. + virtual bool loadData(uint64_t Address, const void *Data, size_t Size); + + /// Load code into the target address space and prepare it for execution. + /// + /// @param Address Destination address in the target process. + /// @param Data Source address in the host process. + /// @param Size Number of bytes to copy. + /// + /// @returns False on success. On failure, ErrorMsg is updated with + /// descriptive text of the encountered error. + virtual bool loadCode(uint64_t Address, const void *Data, size_t Size); + + /// Execute code in the target process. The called function is required + /// to be of signature int "(*)(void)". + /// + /// @param Address Address of the loaded function in the target + /// process. + /// @param[out] RetVal The integer return value of the called function. + /// + /// @returns False on success. On failure, ErrorMsg is updated with + /// descriptive text of the encountered error. + virtual bool executeCode(uint64_t Address, int &RetVal); + + /// Minimum alignment for memory permissions. Used to seperate code and + /// data regions to make sure data doesn't get marked as code or vice + /// versa. + /// + /// @returns Page alignment return value. Default of 4k. + virtual unsigned getPageAlignment() { return 4096; } + + /// Start the remote process. + virtual void create(); + + /// Terminate the remote process. + virtual void stop(); + + RemoteTargetExternal(std::string &Name) : RemoteTarget(), ChildName(Name) {} + virtual ~RemoteTargetExternal() {} + +private: + std::string ChildName; + + // This will get filled in as a point to an OS-specific structure. + void *ConnectionData; + + void SendAllocateSpace(uint32_t Alignment, uint32_t Size); + void SendLoadSection(uint64_t Addr, + const void *Data, + uint32_t Size, + bool IsCode); + void SendExecute(uint64_t Addr); + void SendTerminate(); + + void Receive(LLIMessageType Msg); + void Receive(LLIMessageType Msg, int &Data); + void Receive(LLIMessageType Msg, uint64_t &Data); + + int WriteBytes(const void *Data, size_t Size); + int ReadBytes(void *Data, size_t Size); + void Wait(); +}; + +} // end namespace llvm + +#endif // LLI_REMOTETARGETEXTERNAL_H diff --git a/tools/lli/RemoteTargetMessage.h b/tools/lli/RemoteTargetMessage.h new file mode 100644 index 0000000..12cfa9a --- /dev/null +++ b/tools/lli/RemoteTargetMessage.h @@ -0,0 +1,45 @@ +//===---- RemoteTargetMessage.h - LLI out-of-process message protocol -----===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Definition of the LLIMessageType enum which is used for communication with a +// child process for remote execution. +// +//===----------------------------------------------------------------------===// + +#ifndef LLI_REMOTETARGETMESSAGE_H +#define LLI_REMOTETARGETMESSAGE_H + +namespace llvm { + +// LLI messages from parent-to-child or vice versa follow an exceedingly simple +// protocol where the first four bytes represent the message type, the next +// four bytes represent the size of data for the command and following bytes +// represent the actual data. +// +// The protocol is not intended to be robust, secure or fault-tolerant. It is +// only here for testing purposes and is therefore intended to be the simplest +// implementation that will work. It is assumed that the parent and child +// share characteristics like endianness. + +enum LLIMessageType { + LLI_Error = -1, + LLI_ChildActive = 0, // Data = not used + LLI_AllocateSpace, // Data = struct { uint_32t Align, uint_32t Size } + LLI_AllocationResult, // Data = uint64_t AllocAddress (in Child memory space) + LLI_LoadCodeSection, // Data = uint32_t Addr, followed by section contests + LLI_LoadDataSection, // Data = uint32_t Addr, followed by section contents + LLI_LoadComplete, // Data = not used + LLI_Execute, // Data = Address of function to execute + LLI_ExecutionResult, // Data = uint64_t Result + LLI_Terminate // Data = not used +}; + +} // end namespace llvm + +#endif diff --git a/tools/lli/Unix/RemoteTargetExternal.inc b/tools/lli/Unix/RemoteTargetExternal.inc new file mode 100644 index 0000000..fd6c16b --- /dev/null +++ b/tools/lli/Unix/RemoteTargetExternal.inc @@ -0,0 +1,91 @@ +//=- RemoteTargetExternal.inc - LLVM out-of-process JIT execution for Unix --=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Implementation of the Unix-specific parts of the RemoteTargetExternal class +// which executes JITed code in a separate process from where it was built. +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include + +namespace { + +struct ConnectionData_t { + int InputPipe; + int OutputPipe; + + ConnectionData_t(int in, int out) : InputPipe(in), OutputPipe(out) {} +}; + +} // namespace + +namespace llvm { + +void RemoteTargetExternal::create() { + int PipeFD[2][2]; + pid_t ChildPID; + + pipe(PipeFD[0]); + pipe(PipeFD[1]); + + ChildPID = fork(); + + if (ChildPID == 0) { + // In the child... + + // Close the parent ends of the pipes + close(PipeFD[0][1]); + close(PipeFD[1][0]); + + // Use our pipes as stdin and stdout + if (PipeFD[0][0] != STDIN_FILENO) { + dup2(PipeFD[0][0], STDIN_FILENO); + close(PipeFD[0][0]); + } + if (PipeFD[1][1] != STDOUT_FILENO) { + dup2(PipeFD[1][1], STDOUT_FILENO); + close(PipeFD[1][1]); + } + + // Execute the child process. + char *args[1] = { NULL }; + int rc = execv(ChildName.c_str(), args); + if (rc != 0) + perror("Error executing child process: "); + } + else { + // In the parent... + + // Close the child ends of the pipes + close(PipeFD[0][0]); + close(PipeFD[1][1]); + + // Store the parent ends of the pipes + ConnectionData = (void*)new ConnectionData_t(PipeFD[1][0], PipeFD[0][1]); + + Receive(LLI_ChildActive); + } +} + +int RemoteTargetExternal::WriteBytes(const void *Data, size_t Size) { + return write(((ConnectionData_t*)ConnectionData)->OutputPipe, Data, Size); +} + +int RemoteTargetExternal::ReadBytes(void *Data, size_t Size) { + return read(((ConnectionData_t*)ConnectionData)->InputPipe, Data, Size); +} + +void RemoteTargetExternal::Wait() { + wait(NULL); +} + +} // namespace llvm \ No newline at end of file diff --git a/tools/lli/Windows/RemoteTargetExternal.inc b/tools/lli/Windows/RemoteTargetExternal.inc new file mode 100644 index 0000000..6536d99 --- /dev/null +++ b/tools/lli/Windows/RemoteTargetExternal.inc @@ -0,0 +1,32 @@ +//= RemoteTargetExternal.inc - LLVM out-of-process JIT execution for Windows =// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Definition of the Windows-specific parts of the RemoteTargetExternal class +// which is meant to execute JITed code in a separate process from where it was +// built. To support this functionality on Windows, implement these functions. +// +//===----------------------------------------------------------------------===// + +namespace llvm { + +void RemoteTargetExternal::create() { +} + +int RemoteTargetExternal::WriteBytes(const void *Data, size_t Size) { + return 0; +} + +int RemoteTargetExternal::ReadBytes(void *Data, size_t Size) { + return 0; +} + +void RemoteTargetExternal::Wait() { +} + +} // namespace llvm diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index ba9cb99..17b8ea7 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -41,6 +41,7 @@ #include "llvm/Support/PluginLoader.h" #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Process.h" +#include "llvm/Support/Program.h" #include "llvm/Support/Signals.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetSelect.h" @@ -83,6 +84,18 @@ namespace { cl::desc("Execute MCJIT'ed code in a separate process."), cl::init(false)); + // Manually specify the child process for remote execution. This overrides + // the simulated remote execution that allocates address space for child + // execution. The child process resides in the disk and communicates with lli + // via stdin/stdout pipes. + cl::opt + MCJITRemoteProcess("mcjit-remote-process", + cl::desc("Specify the filename of the process to launch " + "for remote MCJIT execution. If none is specified," + "\n\tremote execution will be simulated in-process."), + cl::value_desc("filename"), + cl::init("")); + // Determine optimization level. cl::opt OptLevel("O", @@ -481,30 +494,50 @@ int main(int argc, char **argv, char * const *envp) { // Everything is prepared now, so lay out our program for the target // address space, assign the section addresses to resolve any relocations, // and send it to the target. - RemoteTarget Target; - Target.create(); + + OwningPtr Target; + if (!MCJITRemoteProcess.empty()) { // Remote execution on a child process + if (!RemoteTarget::hostSupportsExternalRemoteTarget()) { + errs() << "Warning: host does not support external remote targets.\n" + << " Defaulting to simulated remote execution\n"; + Target.reset(RemoteTarget::createRemoteTarget()); + } else { + std::string ChildEXE = sys::FindProgramByName(MCJITRemoteProcess); + if (ChildEXE == "") { + errs() << "Unable to find child target: '\''" << MCJITRemoteProcess << "\'\n"; + return -1; + } + Target.reset(RemoteTarget::createExternalRemoteTarget(MCJITRemoteProcess)); + } + } else { + // No child process name provided, use simulated remote execution. + Target.reset(RemoteTarget::createRemoteTarget()); + } + + // Create the remote target + Target->create(); // Trigger compilation. EE->generateCodeForModule(Mod); // Layout the target memory. - layoutRemoteTargetMemory(&Target, MM); + layoutRemoteTargetMemory(Target.get(), MM); // Since we're executing in a (at least simulated) remote address space, // we can't use the ExecutionEngine::runFunctionAsMain(). We have to // grab the function address directly here and tell the remote target // to execute the function. // FIXME: argv and envp handling. - uint64_t Entry = (uint64_t)EE->getPointerToFunction(EntryFn); + uint64_t Entry = EE->getFunctionAddress(EntryFn->getName().str()); DEBUG(dbgs() << "Executing '" << EntryFn->getName() << "' at 0x" << format("%llx", Entry) << "\n"); - if (Target.executeCode(Entry, Result)) - errs() << "ERROR: " << Target.getErrorMsg() << "\n"; + if (Target->executeCode(Entry, Result)) + errs() << "ERROR: " << Target->getErrorMsg() << "\n"; - Target.stop(); - } else { + Target->stop(); + } else { // !RemoteMCJIT // Trigger compilation separately so code regions that need to be // invalidated will be known. (void)EE->getPointerToFunction(EntryFn); -- cgit v1.1 From 56849e7a9daaf1de00ab2b24c0a62a93add7eb4d Mon Sep 17 00:00:00 2001 From: Andrew Kaylor Date: Wed, 2 Oct 2013 18:00:34 +0000 Subject: Fixing compile warnings git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191844 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/RemoteTargetExternal.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/lli/RemoteTargetExternal.cpp b/tools/lli/RemoteTargetExternal.cpp index 59ad2d3..742a948 100644 --- a/tools/lli/RemoteTargetExternal.cpp +++ b/tools/lli/RemoteTargetExternal.cpp @@ -123,7 +123,7 @@ void RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType) { uint32_t MsgType; rc = ReadBytes(&MsgType, 4); assert(rc == 4 && "Error reading message type."); - assert(MsgType == ExpectedMsgType && "Error: received unexpected message type."); + assert(MsgType == (uint32_t)ExpectedMsgType && "Error: received unexpected message type."); uint32_t DataSize; rc = ReadBytes(&DataSize, 4); @@ -142,7 +142,7 @@ void RemoteTargetExternal::Receive(LLIMessageType ExpectedMsgType, uint64_t &Dat uint32_t MsgType; rc = ReadBytes(&MsgType, 4); assert(rc == 4 && "Error reading message type."); - assert(MsgType == ExpectedMsgType && "Error: received unexpected message type."); + assert(MsgType == (uint32_t)ExpectedMsgType && "Error: received unexpected message type."); uint32_t DataSize; rc = ReadBytes(&DataSize, 4); -- cgit v1.1 From f18815607a93f2b9d498aad4c8e13d1265e204ef Mon Sep 17 00:00:00 2001 From: Andrew Kaylor Date: Wed, 2 Oct 2013 18:04:40 +0000 Subject: Clean up lli execution code git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191845 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/lli.cpp | 80 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 41 insertions(+), 39 deletions(-) (limited to 'tools') diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index 17b8ea7..05bf4ec 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -467,12 +467,10 @@ int main(int argc, char **argv, char * const *envp) { // Reset errno to zero on entry to main. errno = 0; - // Remote target MCJIT doesn't (yet) support static constructors. No reason - // it couldn't. This is a limitation of the LLI implemantation, not the - // MCJIT itself. FIXME. - // - // Run static constructors. + int Result; + if (!RemoteMCJIT) { + // Run static constructors. if (UseMCJIT && !ForceInterpreter) { // Give MCJIT a chance to apply relocations and set page permissions. EE->finalizeObject(); @@ -486,10 +484,41 @@ int main(int argc, char **argv, char * const *envp) { EE->getPointerToFunction(Fn); } } - } - int Result; - if (RemoteMCJIT) { + // Trigger compilation separately so code regions that need to be + // invalidated will be known. + (void)EE->getPointerToFunction(EntryFn); + // Clear instruction cache before code will be executed. + if (RTDyldMM) + static_cast(RTDyldMM)->invalidateInstructionCache(); + + // Run main. + Result = EE->runFunctionAsMain(EntryFn, InputArgv, envp); + + // Run static destructors. + EE->runStaticConstructorsDestructors(true); + + // If the program didn't call exit explicitly, we should call it now. + // This ensures that any atexit handlers get called correctly. + if (Function *ExitF = dyn_cast(Exit)) { + std::vector Args; + GenericValue ResultGV; + ResultGV.IntVal = APInt(32, Result); + Args.push_back(ResultGV); + EE->runFunction(ExitF, Args); + errs() << "ERROR: exit(" << Result << ") returned!\n"; + abort(); + } else { + errs() << "ERROR: exit defined with wrong prototype!\n"; + abort(); + } + } else { + // else == "if (RemoteMCJIT)" + + // Remote target MCJIT doesn't (yet) support static constructors. No reason + // it couldn't. This is a limitation of the LLI implemantation, not the + // MCJIT itself. FIXME. + // RecordingMemoryManager *MM = static_cast(RTDyldMM); // Everything is prepared now, so lay out our program for the target // address space, assign the section addresses to resolve any relocations, @@ -536,39 +565,12 @@ int main(int argc, char **argv, char * const *envp) { if (Target->executeCode(Entry, Result)) errs() << "ERROR: " << Target->getErrorMsg() << "\n"; - Target->stop(); - } else { // !RemoteMCJIT - // Trigger compilation separately so code regions that need to be - // invalidated will be known. - (void)EE->getPointerToFunction(EntryFn); - // Clear instruction cache before code will be executed. - if (RTDyldMM) - static_cast(RTDyldMM)->invalidateInstructionCache(); + // Like static constructors, the remote target MCJIT support doesn't handle + // this yet. It could. FIXME. - // Run main. - Result = EE->runFunctionAsMain(EntryFn, InputArgv, envp); + // Stop the remote target + Target->stop(); } - // Like static constructors, the remote target MCJIT support doesn't handle - // this yet. It could. FIXME. - if (!RemoteMCJIT) { - // Run static destructors. - EE->runStaticConstructorsDestructors(true); - - // If the program didn't call exit explicitly, we should call it now. - // This ensures that any atexit handlers get called correctly. - if (Function *ExitF = dyn_cast(Exit)) { - std::vector Args; - GenericValue ResultGV; - ResultGV.IntVal = APInt(32, Result); - Args.push_back(ResultGV); - EE->runFunction(ExitF, Args); - errs() << "ERROR: exit(" << Result << ") returned!\n"; - abort(); - } else { - errs() << "ERROR: exit defined with wrong prototype!\n"; - abort(); - } - } return Result; } -- cgit v1.1 From b47c0108b3053e36599aec5b3313ea89608ae90a Mon Sep 17 00:00:00 2001 From: Andrew Kaylor Date: Wed, 2 Oct 2013 19:26:16 +0000 Subject: Fix build problems with remote lli implementation git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191848 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/ChildTarget/Unix/ChildTarget.inc | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'tools') diff --git a/tools/lli/ChildTarget/Unix/ChildTarget.inc b/tools/lli/ChildTarget/Unix/ChildTarget.inc index 9550e50..cd42f34 100644 --- a/tools/lli/ChildTarget/Unix/ChildTarget.inc +++ b/tools/lli/ChildTarget/Unix/ChildTarget.inc @@ -15,7 +15,28 @@ #include #include #include + +#ifdef HAVE_SYS_MMAN_H #include +#endif + +#ifdef __APPLE__ +#include +#endif + +#if defined(__mips__) +# if defined(__OpenBSD__) +# include +# else +# include +# endif +#endif + +#ifdef __APPLE__ +extern "C" void sys_icache_invalidate(const void *Addr, size_t len); +#else +extern "C" void __clear_cache(void *, void*); +#endif namespace { -- cgit v1.1 From d34a4d60f04f60352c1f388a129d8108584177d0 Mon Sep 17 00:00:00 2001 From: Richard Smith Date: Wed, 2 Oct 2013 21:33:12 +0000 Subject: Pass the resolved lli-child-target executable name to execv, rather than searching $PATH for it then blindly executing it from $PWD anyway. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191856 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/lli.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index 05bf4ec..1cdd91b 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -536,7 +536,7 @@ int main(int argc, char **argv, char * const *envp) { errs() << "Unable to find child target: '\''" << MCJITRemoteProcess << "\'\n"; return -1; } - Target.reset(RemoteTarget::createExternalRemoteTarget(MCJITRemoteProcess)); + Target.reset(RemoteTarget::createExternalRemoteTarget(ChildEXE)); } } else { // No child process name provided, use simulated remote execution. -- cgit v1.1 From 18b222a87264145979de8216e7243b0ac8921c9d Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Wed, 2 Oct 2013 21:58:02 +0000 Subject: Add newline at eof. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191857 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/Unix/RemoteTargetExternal.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lli/Unix/RemoteTargetExternal.inc b/tools/lli/Unix/RemoteTargetExternal.inc index fd6c16b..f1c3bad 100644 --- a/tools/lli/Unix/RemoteTargetExternal.inc +++ b/tools/lli/Unix/RemoteTargetExternal.inc @@ -88,4 +88,4 @@ void RemoteTargetExternal::Wait() { wait(NULL); } -} // namespace llvm \ No newline at end of file +} // namespace llvm -- cgit v1.1 From 62faf2f9d06392f6a619a0f95900bb7246f93573 Mon Sep 17 00:00:00 2001 From: Andrew Kaylor Date: Wed, 2 Oct 2013 22:27:23 +0000 Subject: Fixing lli-child-target build git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191861 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/ChildTarget/LLVMBuild.txt | 21 +++++++++++++++++++++ tools/lli/LLVMBuild.txt | 3 +++ 2 files changed, 24 insertions(+) create mode 100644 tools/lli/ChildTarget/LLVMBuild.txt (limited to 'tools') diff --git a/tools/lli/ChildTarget/LLVMBuild.txt b/tools/lli/ChildTarget/LLVMBuild.txt new file mode 100644 index 0000000..daf6df1 --- /dev/null +++ b/tools/lli/ChildTarget/LLVMBuild.txt @@ -0,0 +1,21 @@ +;===- ./tools/lli/ChildTarget/LLVMBuild.txt --------------------*- Conf -*--===; +; +; The LLVM Compiler Infrastructure +; +; This file is distributed under the University of Illinois Open Source +; License. See LICENSE.TXT for details. +; +;===------------------------------------------------------------------------===; +; +; This is an LLVMBuild description file for the components in this subdirectory. +; +; For more information on the LLVMBuild system, please see: +; +; http://llvm.org/docs/LLVMBuild.html +; +;===------------------------------------------------------------------------===; + +[component_0] +type = Tool +name = lli-child-target +parent = lli diff --git a/tools/lli/LLVMBuild.txt b/tools/lli/LLVMBuild.txt index c96a9e8..aab2a20 100644 --- a/tools/lli/LLVMBuild.txt +++ b/tools/lli/LLVMBuild.txt @@ -15,6 +15,9 @@ ; ;===------------------------------------------------------------------------===; +[common] +subdirectories = ChildTarget + [component_0] type = Tool name = lli -- cgit v1.1 From 75a641c910adb9df1de015de41cbf02570677bf8 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 3 Oct 2013 00:07:30 +0000 Subject: Dispose the codegen even when just writing the bitcode file. This makes it possible to add timers to the code generator and still use them with -plugin-opt=emit-llvm. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191866 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/gold/gold-plugin.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp index 7771709..bd11d1b 100644 --- a/tools/gold/gold-plugin.cpp +++ b/tools/gold/gold-plugin.cpp @@ -417,8 +417,10 @@ static ld_plugin_status all_symbols_read_hook(void) { bool err = lto_codegen_write_merged_modules(code_gen, path.c_str()); if (err) (*message)(LDPL_FATAL, "Failed to write the output file."); - if (options::generate_bc_file == options::BC_ONLY) + if (options::generate_bc_file == options::BC_ONLY) { + lto_codegen_dispose(code_gen); exit(0); + } } const char *objPath; if (lto_codegen_compile_to_file(code_gen, &objPath)) { -- cgit v1.1 From 438900938c3ac9d7fac2dd5d2c85ca4b9b2e35f7 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 3 Oct 2013 18:29:09 +0000 Subject: Optimize linkonce_odr unnamed_addr functions during LTO. Generalize the API so we can distinguish symbols that are needed just for a DSO symbol table from those that are used from some native .o. The symbols that are only wanted for the dso symbol table can be dropped if llvm can prove every other dso has a copy (linkonce_odr) and the address is not important (unnamed_addr). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191922 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/gold/gold-plugin.cpp | 7 ++++++- tools/llvm-lto/llvm-lto.cpp | 8 ++++++++ tools/lto/lto.cpp | 4 ++++ 3 files changed, 18 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp index bd11d1b..119631c 100644 --- a/tools/gold/gold-plugin.cpp +++ b/tools/gold/gold-plugin.cpp @@ -197,7 +197,7 @@ ld_plugin_status onload(ld_plugin_tv *tv) { case LDPT_ADD_SYMBOLS: add_symbols = tv->tv_u.tv_add_symbols; break; - case LDPT_GET_SYMBOLS: + case LDPT_GET_SYMBOLS_V2: get_symbols = tv->tv_u.tv_get_symbols; break; case LDPT_ADD_INPUT_FILE: @@ -386,6 +386,11 @@ static ld_plugin_status all_symbols_read_hook(void) { if (options::generate_api_file) api_file << I->syms[i].name << "\n"; + } else if (I->syms[i].resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) { + lto_codegen_add_dso_symbol(code_gen, I->syms[i].name); + + if (options::generate_api_file) + api_file << I->syms[i].name << " dso only\n"; } } } diff --git a/tools/llvm-lto/llvm-lto.cpp b/tools/llvm-lto/llvm-lto.cpp index 3ecd13f..1d03fa6 100644 --- a/tools/llvm-lto/llvm-lto.cpp +++ b/tools/llvm-lto/llvm-lto.cpp @@ -50,6 +50,10 @@ ExportedSymbols("exported-symbol", cl::desc("Symbol to export from the resulting object file"), cl::ZeroOrMore); +static cl::list +DSOSymbols("dso-symbol", + cl::desc("Symbol to put in the symtab in the resulting dso"), + cl::ZeroOrMore); int main(int argc, char **argv) { // Print a stack trace if we signal out. @@ -117,6 +121,10 @@ int main(int argc, char **argv) { for (unsigned i = 0; i < ExportedSymbols.size(); ++i) CodeGen.addMustPreserveSymbol(ExportedSymbols[i].c_str()); + // Add all the dso symbols to the table of symbols to expose. + for (unsigned i = 0; i < DSOSymbols.size(); ++i) + CodeGen.addDSOSymbol(DSOSymbols[i].c_str()); + if (!OutputFilename.empty()) { size_t len = 0; std::string ErrorInfo; diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index 7bfddcd..a3acd4c 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -260,6 +260,10 @@ void lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, cg->addMustPreserveSymbol(symbol); } +void lto_codegen_add_dso_symbol(lto_code_gen_t cg, const char *symbol) { + cg->addDSOSymbol(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). -- cgit v1.1 From b868e9101c138016aad5bd910b67f40a3213d6fc Mon Sep 17 00:00:00 2001 From: Andrew Kaylor Date: Fri, 4 Oct 2013 00:49:38 +0000 Subject: Adding support and tests for multiple module handling in lli git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191938 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/CMakeLists.txt | 2 +- tools/lli/RecordingMemoryManager.cpp | 126 ------------------- tools/lli/RecordingMemoryManager.h | 83 ------------- tools/lli/RemoteMemoryManager.cpp | 230 +++++++++++++++++++++++++++++++++++ tools/lli/RemoteMemoryManager.h | 105 ++++++++++++++++ tools/lli/lli.cpp | 115 +++++------------- 6 files changed, 369 insertions(+), 292 deletions(-) delete mode 100644 tools/lli/RecordingMemoryManager.cpp delete mode 100644 tools/lli/RecordingMemoryManager.h create mode 100644 tools/lli/RemoteMemoryManager.cpp create mode 100644 tools/lli/RemoteMemoryManager.h (limited to 'tools') diff --git a/tools/lli/CMakeLists.txt b/tools/lli/CMakeLists.txt index 578c414..5f8c7c9 100644 --- a/tools/lli/CMakeLists.txt +++ b/tools/lli/CMakeLists.txt @@ -21,7 +21,7 @@ endif( LLVM_USE_INTEL_JITEVENTS ) add_llvm_tool(lli lli.cpp - RecordingMemoryManager.cpp + RemoteMemoryManager.cpp RemoteTarget.cpp RemoteTargetExternal.cpp ) diff --git a/tools/lli/RecordingMemoryManager.cpp b/tools/lli/RecordingMemoryManager.cpp deleted file mode 100644 index d54b8e4..0000000 --- a/tools/lli/RecordingMemoryManager.cpp +++ /dev/null @@ -1,126 +0,0 @@ -//===- RecordingMemoryManager.cpp - Recording memory manager --------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This memory manager allocates local storage and keeps a record of each -// allocation. Iterators are provided for all data and code allocations. -// -//===----------------------------------------------------------------------===// - -#include "RecordingMemoryManager.h" -using namespace llvm; - -RecordingMemoryManager::~RecordingMemoryManager() { - for (SmallVectorImpl::iterator - I = AllocatedCodeMem.begin(), E = AllocatedCodeMem.end(); - I != E; ++I) - sys::Memory::releaseMappedMemory(I->first); - for (SmallVectorImpl::iterator - I = AllocatedDataMem.begin(), E = AllocatedDataMem.end(); - I != E; ++I) - sys::Memory::releaseMappedMemory(I->first); -} - -uint8_t *RecordingMemoryManager:: -allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, - StringRef SectionName) { - // The recording memory manager is just a local copy of the remote target. - // The alignment requirement is just stored here for later use. Regular - // heap storage is sufficient here, but we're using mapped memory to work - // around a bug in MCJIT. - sys::MemoryBlock Block = allocateSection(Size); - AllocatedCodeMem.push_back(Allocation(Block, Alignment)); - return (uint8_t*)Block.base(); -} - -uint8_t *RecordingMemoryManager:: -allocateDataSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID, StringRef SectionName, - bool IsReadOnly) { - // The recording memory manager is just a local copy of the remote target. - // The alignment requirement is just stored here for later use. Regular - // heap storage is sufficient here, but we're using mapped memory to work - // around a bug in MCJIT. - sys::MemoryBlock Block = allocateSection(Size); - AllocatedDataMem.push_back(Allocation(Block, Alignment)); - return (uint8_t*)Block.base(); -} - -sys::MemoryBlock RecordingMemoryManager::allocateSection(uintptr_t Size) { - error_code ec; - sys::MemoryBlock MB = sys::Memory::allocateMappedMemory(Size, - &Near, - sys::Memory::MF_READ | - sys::Memory::MF_WRITE, - ec); - assert(!ec && MB.base()); - - // FIXME: This is part of a work around to keep sections near one another - // when MCJIT performs relocations after code emission but before - // the generated code is moved to the remote target. - // Save this address as the basis for our next request - Near = MB; - return MB; -} - -void RecordingMemoryManager::setMemoryWritable() { llvm_unreachable("Unexpected!"); } -void RecordingMemoryManager::setMemoryExecutable() { llvm_unreachable("Unexpected!"); } -void RecordingMemoryManager::setPoisonMemory(bool poison) { llvm_unreachable("Unexpected!"); } -void RecordingMemoryManager::AllocateGOT() { llvm_unreachable("Unexpected!"); } -uint8_t *RecordingMemoryManager::getGOTBase() const { - llvm_unreachable("Unexpected!"); - return 0; -} -uint8_t *RecordingMemoryManager::startFunctionBody(const Function *F, uintptr_t &ActualSize){ - llvm_unreachable("Unexpected!"); - return 0; -} -uint8_t *RecordingMemoryManager::allocateStub(const GlobalValue* F, unsigned StubSize, - unsigned Alignment) { - llvm_unreachable("Unexpected!"); - return 0; -} -void RecordingMemoryManager::endFunctionBody(const Function *F, uint8_t *FunctionStart, - uint8_t *FunctionEnd) { - llvm_unreachable("Unexpected!"); -} -uint8_t *RecordingMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment) { - llvm_unreachable("Unexpected!"); - return 0; -} -uint8_t *RecordingMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment) { - llvm_unreachable("Unexpected!"); - return 0; -} -void RecordingMemoryManager::deallocateFunctionBody(void *Body) { - llvm_unreachable("Unexpected!"); -} - -static int jit_noop() { - return 0; -} - -void *RecordingMemoryManager::getPointerToNamedFunction(const std::string &Name, - bool AbortOnFailure) { - // We should not invoke parent's ctors/dtors from generated main()! - // On Mingw and Cygwin, the symbol __main is resolved to - // callee's(eg. tools/lli) one, to invoke wrong duplicated ctors - // (and register wrong callee's dtors with atexit(3)). - // We expect ExecutionEngine::runStaticConstructorsDestructors() - // is called before ExecutionEngine::runFunctionAsMain() is called. - if (Name == "__main") return (void*)(intptr_t)&jit_noop; - - // FIXME: Would it be responsible to provide GOT? - if (AbortOnFailure) { - if (Name == "_GLOBAL_OFFSET_TABLE_") - report_fatal_error("Program used external function '" + Name + - "' which could not be resolved!"); - } - - return NULL; -} diff --git a/tools/lli/RecordingMemoryManager.h b/tools/lli/RecordingMemoryManager.h deleted file mode 100644 index 05f4807..0000000 --- a/tools/lli/RecordingMemoryManager.h +++ /dev/null @@ -1,83 +0,0 @@ -//===- RecordingMemoryManager.h - LLI MCJIT recording memory manager ------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This memory manager allocates local storage and keeps a record of each -// allocation. Iterators are provided for all data and code allocations. -// -//===----------------------------------------------------------------------===// - -#ifndef RECORDINGMEMORYMANAGER_H -#define RECORDINGMEMORYMANAGER_H - -#include "llvm/ADT/SmallVector.h" -#include "llvm/ExecutionEngine/JITMemoryManager.h" -#include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/Memory.h" -#include - -namespace llvm { - -class RecordingMemoryManager : public JITMemoryManager { -public: - typedef std::pair Allocation; - -private: - SmallVector AllocatedDataMem; - SmallVector AllocatedCodeMem; - - // FIXME: This is part of a work around to keep sections near one another - // when MCJIT performs relocations after code emission but before - // the generated code is moved to the remote target. - sys::MemoryBlock Near; - sys::MemoryBlock allocateSection(uintptr_t Size); - -public: - RecordingMemoryManager() {} - virtual ~RecordingMemoryManager(); - - typedef SmallVectorImpl::const_iterator const_data_iterator; - typedef SmallVectorImpl::const_iterator const_code_iterator; - - const_data_iterator data_begin() const { return AllocatedDataMem.begin(); } - const_data_iterator data_end() const { return AllocatedDataMem.end(); } - const_code_iterator code_begin() const { return AllocatedCodeMem.begin(); } - const_code_iterator code_end() const { return AllocatedCodeMem.end(); } - - uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID, StringRef SectionName); - - uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, - unsigned SectionID, StringRef SectionName, - bool IsReadOnly); - - void *getPointerToNamedFunction(const std::string &Name, - bool AbortOnFailure = true); - - bool finalizeMemory(std::string *ErrMsg) { return false; } - - // The following obsolete JITMemoryManager calls are stubbed out for - // this model. - void setMemoryWritable(); - void setMemoryExecutable(); - void setPoisonMemory(bool poison); - void AllocateGOT(); - uint8_t *getGOTBase() const; - uint8_t *startFunctionBody(const Function *F, uintptr_t &ActualSize); - uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize, - unsigned Alignment); - void endFunctionBody(const Function *F, uint8_t *FunctionStart, - uint8_t *FunctionEnd); - uint8_t *allocateSpace(intptr_t Size, unsigned Alignment); - uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment); - void deallocateFunctionBody(void *Body); -}; - -} // end namespace llvm - -#endif diff --git a/tools/lli/RemoteMemoryManager.cpp b/tools/lli/RemoteMemoryManager.cpp new file mode 100644 index 0000000..1f86066 --- /dev/null +++ b/tools/lli/RemoteMemoryManager.cpp @@ -0,0 +1,230 @@ +//===---- RemoteMemoryManager.cpp - Recording memory manager --------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This memory manager allocates local storage and keeps a record of each +// allocation. Iterators are provided for all data and code allocations. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "lli" +#include "RemoteMemoryManager.h" +#include "llvm/ExecutionEngine/ExecutionEngine.h" +#include "llvm/ExecutionEngine/ObjectImage.h" +#include "llvm/Support/Debug.h" +#include "llvm/Support/Format.h" + +using namespace llvm; + +RemoteMemoryManager::~RemoteMemoryManager() { + for (SmallVector::iterator + I = AllocatedSections.begin(), E = AllocatedSections.end(); + I != E; ++I) + sys::Memory::releaseMappedMemory(I->MB); +} + +uint8_t *RemoteMemoryManager:: +allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, + StringRef SectionName) { + // The recording memory manager is just a local copy of the remote target. + // The alignment requirement is just stored here for later use. Regular + // heap storage is sufficient here, but we're using mapped memory to work + // around a bug in MCJIT. + sys::MemoryBlock Block = allocateSection(Size); + AllocatedSections.push_back( Allocation(Block, Alignment, true) ); + UnmappedSections.push_back( &AllocatedSections.back() ); + return (uint8_t*)Block.base(); +} + +uint8_t *RemoteMemoryManager:: +allocateDataSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, StringRef SectionName, + bool IsReadOnly) { + // The recording memory manager is just a local copy of the remote target. + // The alignment requirement is just stored here for later use. Regular + // heap storage is sufficient here, but we're using mapped memory to work + // around a bug in MCJIT. + sys::MemoryBlock Block = allocateSection(Size); + AllocatedSections.push_back( Allocation(Block, Alignment, false) ); + UnmappedSections.push_back( &AllocatedSections.back() ); + return (uint8_t*)Block.base(); +} + +sys::MemoryBlock RemoteMemoryManager::allocateSection(uintptr_t Size) { + error_code ec; + sys::MemoryBlock MB = sys::Memory::allocateMappedMemory(Size, + &Near, + sys::Memory::MF_READ | + sys::Memory::MF_WRITE, + ec); + assert(!ec && MB.base()); + + // FIXME: This is part of a work around to keep sections near one another + // when MCJIT performs relocations after code emission but before + // the generated code is moved to the remote target. + // Save this address as the basis for our next request + Near = MB; + return MB; +} + +void RemoteMemoryManager::notifyObjectLoaded(ExecutionEngine *EE, + const ObjectImage *Obj) { + // The client should have called setRemoteTarget() before triggering any + // code generation. + assert(Target); + if (!Target) + return; + + // FIXME: Make this function thread safe. + + // Lay out our sections in order, with all the code sections first, then + // all the data sections. + uint64_t CurOffset = 0; + unsigned MaxAlign = Target->getPageAlignment(); + SmallVector, 16> Offsets; + unsigned NumSections = UnmappedSections.size(); + // We're going to go through the list twice to separate code and data, but + // it's a very small list, so that's OK. + for (size_t i = 0, e = NumSections; i != e; ++i) { + const Allocation *Section = UnmappedSections[i]; + assert(Section); + if (Section->IsCode) { + unsigned Size = Section->MB.size(); + unsigned Align = Section->Alignment; + DEBUG(dbgs() << "code region: size " << Size + << ", alignment " << Align << "\n"); + // Align the current offset up to whatever is needed for the next + // section. + CurOffset = (CurOffset + Align - 1) / Align * Align; + // Save off the address of the new section and allocate its space. + Offsets.push_back(std::pair(Section, + CurOffset)); + CurOffset += Size; + } + } + // Adjust to keep code and data aligned on seperate pages. + CurOffset = (CurOffset + MaxAlign - 1) / MaxAlign * MaxAlign; + for (size_t i = 0, e = NumSections; i != e; ++i) { + const Allocation *Section = UnmappedSections[i]; + assert(Section); + if (!Section->IsCode) { + unsigned Size = Section->MB.size(); + unsigned Align = Section->Alignment; + DEBUG(dbgs() << "data region: size " << Size + << ", alignment " << Align << "\n"); + // Align the current offset up to whatever is needed for the next + // section. + CurOffset = (CurOffset + Align - 1) / Align * Align; + // Save off the address of the new section and allocate its space. + Offsets.push_back(std::pair(Section, + CurOffset)); + CurOffset += Size; + } + } + + // Allocate space in the remote target. + uint64_t RemoteAddr; + if (Target->allocateSpace(CurOffset, MaxAlign, RemoteAddr)) + report_fatal_error(Target->getErrorMsg()); + + // Map the section addresses so relocations will get updated in the local + // copies of the sections. + for (unsigned i = 0, e = Offsets.size(); i != e; ++i) { + uint64_t Addr = RemoteAddr + Offsets[i].second; + EE->mapSectionAddress(const_cast(Offsets[i].first->MB.base()), Addr); + + DEBUG(dbgs() << " Mapping local: " << Offsets[i].first->MB.base() + << " to remote: 0x" << format("%llx", Addr) << "\n"); + + MappedSections[Addr] = Offsets[i].first; + } + + UnmappedSections.clear(); +} + +bool RemoteMemoryManager::finalizeMemory(std::string *ErrMsg) { + // FIXME: Make this function thread safe. + for (DenseMap::iterator + I = MappedSections.begin(), E = MappedSections.end(); + I != E; ++I) { + uint64_t RemoteAddr = I->first; + const Allocation *Section = I->second; + if (Section->IsCode) { + Target->loadCode(RemoteAddr, Section->MB.base(), Section->MB.size()); + + DEBUG(dbgs() << " loading code: " << Section->MB.base() + << " to remote: 0x" << format("%llx", RemoteAddr) << "\n"); + } else { + Target->loadData(RemoteAddr, Section->MB.base(), Section->MB.size()); + + DEBUG(dbgs() << " loading data: " << Section->MB.base() + << " to remote: 0x" << format("%llx", RemoteAddr) << "\n"); + } + } + + MappedSections.clear(); + + return false; +} + +void RemoteMemoryManager::setMemoryWritable() { llvm_unreachable("Unexpected!"); } +void RemoteMemoryManager::setMemoryExecutable() { llvm_unreachable("Unexpected!"); } +void RemoteMemoryManager::setPoisonMemory(bool poison) { llvm_unreachable("Unexpected!"); } +void RemoteMemoryManager::AllocateGOT() { llvm_unreachable("Unexpected!"); } +uint8_t *RemoteMemoryManager::getGOTBase() const { + llvm_unreachable("Unexpected!"); + return 0; +} +uint8_t *RemoteMemoryManager::startFunctionBody(const Function *F, uintptr_t &ActualSize){ + llvm_unreachable("Unexpected!"); + return 0; +} +uint8_t *RemoteMemoryManager::allocateStub(const GlobalValue* F, unsigned StubSize, + unsigned Alignment) { + llvm_unreachable("Unexpected!"); + return 0; +} +void RemoteMemoryManager::endFunctionBody(const Function *F, uint8_t *FunctionStart, + uint8_t *FunctionEnd) { + llvm_unreachable("Unexpected!"); +} +uint8_t *RemoteMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment) { + llvm_unreachable("Unexpected!"); + return 0; +} +uint8_t *RemoteMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment) { + llvm_unreachable("Unexpected!"); + return 0; +} +void RemoteMemoryManager::deallocateFunctionBody(void *Body) { + llvm_unreachable("Unexpected!"); +} + +static int jit_noop() { + return 0; +} + +void *RemoteMemoryManager::getPointerToNamedFunction(const std::string &Name, + bool AbortOnFailure) { + // We should not invoke parent's ctors/dtors from generated main()! + // On Mingw and Cygwin, the symbol __main is resolved to + // callee's(eg. tools/lli) one, to invoke wrong duplicated ctors + // (and register wrong callee's dtors with atexit(3)). + // We expect ExecutionEngine::runStaticConstructorsDestructors() + // is called before ExecutionEngine::runFunctionAsMain() is called. + if (Name == "__main") return (void*)(intptr_t)&jit_noop; + + // FIXME: Would it be responsible to provide GOT? + if (AbortOnFailure) { + if (Name == "_GLOBAL_OFFSET_TABLE_") + report_fatal_error("Program used external function '" + Name + + "' which could not be resolved!"); + } + + return NULL; +} diff --git a/tools/lli/RemoteMemoryManager.h b/tools/lli/RemoteMemoryManager.h new file mode 100644 index 0000000..dc74666 --- /dev/null +++ b/tools/lli/RemoteMemoryManager.h @@ -0,0 +1,105 @@ +//===- RemoteMemoryManager.h - LLI MCJIT recording memory manager ------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This memory manager allocates local storage and keeps a record of each +// allocation. Iterators are provided for all data and code allocations. +// +//===----------------------------------------------------------------------===// + +#ifndef REMOTEMEMORYMANAGER_H +#define REMOTEMEMORYMANAGER_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ExecutionEngine/JITMemoryManager.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/Memory.h" +#include + +#include "RemoteTarget.h" + +namespace llvm { + +class RemoteMemoryManager : public JITMemoryManager { +public: + // Notice that this structure takes ownership of the memory allocated. + struct Allocation { + Allocation(sys::MemoryBlock mb, unsigned a, bool code) + : MB(mb), Alignment(a), IsCode(code) {} + + sys::MemoryBlock MB; + unsigned Alignment; + bool IsCode; + }; + +private: + // This vector contains Allocation objects for all sections which we have + // allocated. This vector effectively owns the memory associated with the + // allocations. + SmallVector AllocatedSections; + + // This vector contains pointers to Allocation objects for any sections we + // have allocated locally but have not yet remapped for the remote target. + // When we receive notification of a completed module load, we will map + // these sections into the remote target. + SmallVector UnmappedSections; + + // This map tracks the sections we have remapped for the remote target + // but have not yet copied to the target. + DenseMap MappedSections; + + // FIXME: This is part of a work around to keep sections near one another + // when MCJIT performs relocations after code emission but before + // the generated code is moved to the remote target. + sys::MemoryBlock Near; + sys::MemoryBlock allocateSection(uintptr_t Size); + + RemoteTarget *Target; + +public: + RemoteMemoryManager() : Target(NULL) {} + virtual ~RemoteMemoryManager(); + + uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, StringRef SectionName); + + uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, StringRef SectionName, + bool IsReadOnly); + + void *getPointerToNamedFunction(const std::string &Name, + bool AbortOnFailure = true); + + void notifyObjectLoaded(ExecutionEngine *EE, const ObjectImage *Obj); + + bool finalizeMemory(std::string *ErrMsg); + + // This is a non-interface function used by lli + void setRemoteTarget(RemoteTarget *T) { Target = T; } + + // The following obsolete JITMemoryManager calls are stubbed out for + // this model. + void setMemoryWritable(); + void setMemoryExecutable(); + void setPoisonMemory(bool poison); + void AllocateGOT(); + uint8_t *getGOTBase() const; + uint8_t *startFunctionBody(const Function *F, uintptr_t &ActualSize); + uint8_t *allocateStub(const GlobalValue* F, unsigned StubSize, + unsigned Alignment); + void endFunctionBody(const Function *F, uint8_t *FunctionStart, + uint8_t *FunctionEnd); + uint8_t *allocateSpace(intptr_t Size, unsigned Alignment); + uint8_t *allocateGlobal(uintptr_t Size, unsigned Alignment); + void deallocateFunctionBody(void *Body); +}; + +} // end namespace llvm + +#endif diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index 1cdd91b..ac0d219 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -15,7 +15,7 @@ #define DEBUG_TYPE "lli" #include "llvm/IR/LLVMContext.h" -#include "RecordingMemoryManager.h" +#include "RemoteMemoryManager.h" #include "RemoteTarget.h" #include "llvm/ADT/Triple.h" #include "llvm/Bitcode/ReaderWriter.h" @@ -131,6 +131,12 @@ namespace { cl::value_desc("function"), cl::init("main")); + cl::list + ExtraModules("extra-modules", + cl::CommaSeparated, + cl::desc("Extra modules to be loaded"), + cl::value_desc(",,...")); + cl::opt FakeArgv0("fake-argv0", cl::desc("Override the 'argv[0]' value passed into the executing" @@ -222,82 +228,6 @@ static void do_shutdown() { #endif } -void layoutRemoteTargetMemory(RemoteTarget *T, RecordingMemoryManager *JMM) { - // Lay out our sections in order, with all the code sections first, then - // all the data sections. - uint64_t CurOffset = 0; - unsigned MaxAlign = T->getPageAlignment(); - SmallVector, 16> Offsets; - SmallVector Sizes; - for (RecordingMemoryManager::const_code_iterator I = JMM->code_begin(), - E = JMM->code_end(); - I != E; ++I) { - DEBUG(dbgs() << "code region: size " << I->first.size() - << ", alignment " << I->second << "\n"); - // Align the current offset up to whatever is needed for the next - // section. - unsigned Align = I->second; - CurOffset = (CurOffset + Align - 1) / Align * Align; - // Save off the address of the new section and allocate its space. - Offsets.push_back(std::pair(I->first.base(), CurOffset)); - Sizes.push_back(I->first.size()); - CurOffset += I->first.size(); - } - // Adjust to keep code and data aligned on seperate pages. - CurOffset = (CurOffset + MaxAlign - 1) / MaxAlign * MaxAlign; - unsigned FirstDataIndex = Offsets.size(); - for (RecordingMemoryManager::const_data_iterator I = JMM->data_begin(), - E = JMM->data_end(); - I != E; ++I) { - DEBUG(dbgs() << "data region: size " << I->first.size() - << ", alignment " << I->second << "\n"); - // Align the current offset up to whatever is needed for the next - // section. - unsigned Align = I->second; - CurOffset = (CurOffset + Align - 1) / Align * Align; - // Save off the address of the new section and allocate its space. - Offsets.push_back(std::pair(I->first.base(), CurOffset)); - Sizes.push_back(I->first.size()); - CurOffset += I->first.size(); - } - - // Allocate space in the remote target. - uint64_t RemoteAddr; - if (T->allocateSpace(CurOffset, MaxAlign, RemoteAddr)) - report_fatal_error(T->getErrorMsg()); - // Map the section addresses so relocations will get updated in the local - // copies of the sections. - for (unsigned i = 0, e = Offsets.size(); i != e; ++i) { - uint64_t Addr = RemoteAddr + Offsets[i].second; - EE->mapSectionAddress(const_cast(Offsets[i].first), Addr); - - DEBUG(dbgs() << " Mapping local: " << Offsets[i].first - << " to remote: 0x" << format("%llx", Addr) << "\n"); - - } - - // Trigger application of relocations - EE->finalizeObject(); - - // Now load it all to the target. - for (unsigned i = 0, e = Offsets.size(); i != e; ++i) { - uint64_t Addr = RemoteAddr + Offsets[i].second; - - if (i < FirstDataIndex) { - T->loadCode(Addr, Offsets[i].first, Sizes[i]); - - DEBUG(dbgs() << " loading code: " << Offsets[i].first - << " to remote: 0x" << format("%llx", Addr) << "\n"); - } else { - T->loadData(Addr, Offsets[i].first, Sizes[i]); - - DEBUG(dbgs() << " loading data: " << Offsets[i].first - << " to remote: 0x" << format("%llx", Addr) << "\n"); - } - - } -} - //===----------------------------------------------------------------------===// // main Driver function // @@ -370,7 +300,7 @@ int main(int argc, char **argv, char * const *envp) { if (UseMCJIT && !ForceInterpreter) { builder.setUseMCJIT(true); if (RemoteMCJIT) - RTDyldMM = new RecordingMemoryManager(); + RTDyldMM = new RemoteMemoryManager(); else RTDyldMM = new SectionMemoryManager(); builder.setMCJITMemoryManager(RTDyldMM); @@ -420,6 +350,16 @@ int main(int argc, char **argv, char * const *envp) { exit(1); } + // Load any additional modules specified on the command line. + for (unsigned i = 0, e = ExtraModules.size(); i != e; ++i) { + Module *XMod = ParseIRFile(ExtraModules[i], Err, Context); + if (!XMod) { + Err.print(argv[0], errs()); + return 1; + } + EE->addModule(XMod); + } + // The following functions have no effect if their respective profiling // support wasn't enabled in the build configuration. EE->RegisterJITEventListener( @@ -519,7 +459,7 @@ int main(int argc, char **argv, char * const *envp) { // it couldn't. This is a limitation of the LLI implemantation, not the // MCJIT itself. FIXME. // - RecordingMemoryManager *MM = static_cast(RTDyldMM); + RemoteMemoryManager *MM = static_cast(RTDyldMM); // Everything is prepared now, so lay out our program for the target // address space, assign the section addresses to resolve any relocations, // and send it to the target. @@ -543,19 +483,30 @@ int main(int argc, char **argv, char * const *envp) { Target.reset(RemoteTarget::createRemoteTarget()); } - // Create the remote target + // Give the memory manager a pointer to our remote target interface object. + MM->setRemoteTarget(Target.get()); + + // Create the remote target. Target->create(); +// FIXME: Don't commit like this. I don't think these calls are necessary. +#if 0 // Trigger compilation. EE->generateCodeForModule(Mod); - // Layout the target memory. - layoutRemoteTargetMemory(Target.get(), MM); + // Get everything ready to execute. + EE->finalizeModule(Mod); +#endif // Since we're executing in a (at least simulated) remote address space, // we can't use the ExecutionEngine::runFunctionAsMain(). We have to // grab the function address directly here and tell the remote target // to execute the function. + // + // Our memory manager will map generated code into the remote address + // space as it is loaded and copy the bits over during the finalizeMemory + // operation. + // // FIXME: argv and envp handling. uint64_t Entry = EE->getFunctionAddress(EntryFn->getName().str()); -- cgit v1.1 From ef522b4c9c4d9357c355edf99edd766af3429faf Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 4 Oct 2013 17:30:14 +0000 Subject: Add lto_codegen_add_dso_symbol to the export list. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191970 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/lto.exports | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/lto/lto.exports b/tools/lto/lto.exports index 46d0d74..c0e220b 100644 --- a/tools/lto/lto.exports +++ b/tools/lto/lto.exports @@ -15,6 +15,7 @@ lto_module_is_object_file_for_target lto_module_is_object_file_in_memory lto_module_is_object_file_in_memory_for_target lto_module_dispose +lto_codegen_add_dso_symbol lto_codegen_add_module lto_codegen_add_must_preserve_symbol lto_codegen_compile -- cgit v1.1 From 33f362f549b50ac0697258948dbc98e0f43cf422 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Fri, 4 Oct 2013 19:10:03 +0000 Subject: lli: Check pipe creation for errors. This is unlikely to ever fail, but ubuntu GCC warns when the return value is unused. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191973 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/Unix/RemoteTargetExternal.inc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/lli/Unix/RemoteTargetExternal.inc b/tools/lli/Unix/RemoteTargetExternal.inc index f1c3bad..e245f7e 100644 --- a/tools/lli/Unix/RemoteTargetExternal.inc +++ b/tools/lli/Unix/RemoteTargetExternal.inc @@ -34,8 +34,9 @@ void RemoteTargetExternal::create() { int PipeFD[2][2]; pid_t ChildPID; - pipe(PipeFD[0]); - pipe(PipeFD[1]); + // Create two pipes. + if (pipe(PipeFD[0]) != 0 || pipe(PipeFD[1]) != 0) + perror("Error creating pipe: "); ChildPID = fork(); -- cgit v1.1 From e3fd646e178f92dbe2737a5230d73577090d9d0e Mon Sep 17 00:00:00 2001 From: Andrew Kaylor Date: Fri, 4 Oct 2013 20:09:36 +0000 Subject: Fixing container/pointer bug in remote-lli found by ASan git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191976 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/RemoteMemoryManager.cpp | 52 +++++++++++++++++++-------------------- tools/lli/RemoteMemoryManager.h | 5 ++-- 2 files changed, 29 insertions(+), 28 deletions(-) (limited to 'tools') diff --git a/tools/lli/RemoteMemoryManager.cpp b/tools/lli/RemoteMemoryManager.cpp index 1f86066..afc804d 100644 --- a/tools/lli/RemoteMemoryManager.cpp +++ b/tools/lli/RemoteMemoryManager.cpp @@ -36,8 +36,10 @@ allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, // heap storage is sufficient here, but we're using mapped memory to work // around a bug in MCJIT. sys::MemoryBlock Block = allocateSection(Size); + // AllocatedSections will own this memory. AllocatedSections.push_back( Allocation(Block, Alignment, true) ); - UnmappedSections.push_back( &AllocatedSections.back() ); + // UnmappedSections has the same information but does not own the memory. + UnmappedSections.push_back( Allocation(Block, Alignment, true) ); return (uint8_t*)Block.base(); } @@ -50,8 +52,10 @@ allocateDataSection(uintptr_t Size, unsigned Alignment, // heap storage is sufficient here, but we're using mapped memory to work // around a bug in MCJIT. sys::MemoryBlock Block = allocateSection(Size); + // AllocatedSections will own this memory. AllocatedSections.push_back( Allocation(Block, Alignment, false) ); - UnmappedSections.push_back( &AllocatedSections.back() ); + // UnmappedSections has the same information but does not own the memory. + UnmappedSections.push_back( Allocation(Block, Alignment, false) ); return (uint8_t*)Block.base(); } @@ -86,43 +90,39 @@ void RemoteMemoryManager::notifyObjectLoaded(ExecutionEngine *EE, // all the data sections. uint64_t CurOffset = 0; unsigned MaxAlign = Target->getPageAlignment(); - SmallVector, 16> Offsets; + SmallVector, 16> Offsets; unsigned NumSections = UnmappedSections.size(); // We're going to go through the list twice to separate code and data, but // it's a very small list, so that's OK. for (size_t i = 0, e = NumSections; i != e; ++i) { - const Allocation *Section = UnmappedSections[i]; - assert(Section); - if (Section->IsCode) { - unsigned Size = Section->MB.size(); - unsigned Align = Section->Alignment; + Allocation &Section = UnmappedSections[i]; + if (Section.IsCode) { + unsigned Size = Section.MB.size(); + unsigned Align = Section.Alignment; DEBUG(dbgs() << "code region: size " << Size << ", alignment " << Align << "\n"); // Align the current offset up to whatever is needed for the next // section. CurOffset = (CurOffset + Align - 1) / Align * Align; // Save off the address of the new section and allocate its space. - Offsets.push_back(std::pair(Section, - CurOffset)); + Offsets.push_back(std::pair(Section, CurOffset)); CurOffset += Size; } } // Adjust to keep code and data aligned on seperate pages. CurOffset = (CurOffset + MaxAlign - 1) / MaxAlign * MaxAlign; for (size_t i = 0, e = NumSections; i != e; ++i) { - const Allocation *Section = UnmappedSections[i]; - assert(Section); - if (!Section->IsCode) { - unsigned Size = Section->MB.size(); - unsigned Align = Section->Alignment; + Allocation &Section = UnmappedSections[i]; + if (!Section.IsCode) { + unsigned Size = Section.MB.size(); + unsigned Align = Section.Alignment; DEBUG(dbgs() << "data region: size " << Size << ", alignment " << Align << "\n"); // Align the current offset up to whatever is needed for the next // section. CurOffset = (CurOffset + Align - 1) / Align * Align; // Save off the address of the new section and allocate its space. - Offsets.push_back(std::pair(Section, - CurOffset)); + Offsets.push_back(std::pair(Section, CurOffset)); CurOffset += Size; } } @@ -136,9 +136,9 @@ void RemoteMemoryManager::notifyObjectLoaded(ExecutionEngine *EE, // copies of the sections. for (unsigned i = 0, e = Offsets.size(); i != e; ++i) { uint64_t Addr = RemoteAddr + Offsets[i].second; - EE->mapSectionAddress(const_cast(Offsets[i].first->MB.base()), Addr); + EE->mapSectionAddress(const_cast(Offsets[i].first.MB.base()), Addr); - DEBUG(dbgs() << " Mapping local: " << Offsets[i].first->MB.base() + DEBUG(dbgs() << " Mapping local: " << Offsets[i].first.MB.base() << " to remote: 0x" << format("%llx", Addr) << "\n"); MappedSections[Addr] = Offsets[i].first; @@ -149,20 +149,20 @@ void RemoteMemoryManager::notifyObjectLoaded(ExecutionEngine *EE, bool RemoteMemoryManager::finalizeMemory(std::string *ErrMsg) { // FIXME: Make this function thread safe. - for (DenseMap::iterator + for (DenseMap::iterator I = MappedSections.begin(), E = MappedSections.end(); I != E; ++I) { uint64_t RemoteAddr = I->first; - const Allocation *Section = I->second; - if (Section->IsCode) { - Target->loadCode(RemoteAddr, Section->MB.base(), Section->MB.size()); + const Allocation &Section = I->second; + if (Section.IsCode) { + Target->loadCode(RemoteAddr, Section.MB.base(), Section.MB.size()); - DEBUG(dbgs() << " loading code: " << Section->MB.base() + DEBUG(dbgs() << " loading code: " << Section.MB.base() << " to remote: 0x" << format("%llx", RemoteAddr) << "\n"); } else { - Target->loadData(RemoteAddr, Section->MB.base(), Section->MB.size()); + Target->loadData(RemoteAddr, Section.MB.base(), Section.MB.size()); - DEBUG(dbgs() << " loading data: " << Section->MB.base() + DEBUG(dbgs() << " loading data: " << Section.MB.base() << " to remote: 0x" << format("%llx", RemoteAddr) << "\n"); } } diff --git a/tools/lli/RemoteMemoryManager.h b/tools/lli/RemoteMemoryManager.h index dc74666..ca157a7 100644 --- a/tools/lli/RemoteMemoryManager.h +++ b/tools/lli/RemoteMemoryManager.h @@ -30,6 +30,7 @@ class RemoteMemoryManager : public JITMemoryManager { public: // Notice that this structure takes ownership of the memory allocated. struct Allocation { + Allocation() {} Allocation(sys::MemoryBlock mb, unsigned a, bool code) : MB(mb), Alignment(a), IsCode(code) {} @@ -48,11 +49,11 @@ private: // have allocated locally but have not yet remapped for the remote target. // When we receive notification of a completed module load, we will map // these sections into the remote target. - SmallVector UnmappedSections; + SmallVector UnmappedSections; // This map tracks the sections we have remapped for the remote target // but have not yet copied to the target. - DenseMap MappedSections; + DenseMap MappedSections; // FIXME: This is part of a work around to keep sections near one another // when MCJIT performs relocations after code emission but before -- cgit v1.1 From 36ea408903e4acafcb90650d94c9aa8e7484c1f5 Mon Sep 17 00:00:00 2001 From: Andrew Kaylor Date: Fri, 4 Oct 2013 20:53:49 +0000 Subject: Attempting to fix lli build error git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191979 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/RemoteMemoryManager.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/lli/RemoteMemoryManager.cpp b/tools/lli/RemoteMemoryManager.cpp index afc804d..8ccfde8 100644 --- a/tools/lli/RemoteMemoryManager.cpp +++ b/tools/lli/RemoteMemoryManager.cpp @@ -90,7 +90,7 @@ void RemoteMemoryManager::notifyObjectLoaded(ExecutionEngine *EE, // all the data sections. uint64_t CurOffset = 0; unsigned MaxAlign = Target->getPageAlignment(); - SmallVector, 16> Offsets; + SmallVector, 16> Offsets; unsigned NumSections = UnmappedSections.size(); // We're going to go through the list twice to separate code and data, but // it's a very small list, so that's OK. @@ -105,7 +105,7 @@ void RemoteMemoryManager::notifyObjectLoaded(ExecutionEngine *EE, // section. CurOffset = (CurOffset + Align - 1) / Align * Align; // Save off the address of the new section and allocate its space. - Offsets.push_back(std::pair(Section, CurOffset)); + Offsets.push_back(std::pair(Section, CurOffset)); CurOffset += Size; } } @@ -122,7 +122,7 @@ void RemoteMemoryManager::notifyObjectLoaded(ExecutionEngine *EE, // section. CurOffset = (CurOffset + Align - 1) / Align * Align; // Save off the address of the new section and allocate its space. - Offsets.push_back(std::pair(Section, CurOffset)); + Offsets.push_back(std::pair(Section, CurOffset)); CurOffset += Size; } } -- cgit v1.1 From ec2ac8985650a501b452b8fdb69d3124d7be5af9 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 4 Oct 2013 21:40:54 +0000 Subject: Fix object file writing in llvm-lto on Windows. We were writing in text mode. Patch by Greg Bedwell. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@191985 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-lto/llvm-lto.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/llvm-lto/llvm-lto.cpp b/tools/llvm-lto/llvm-lto.cpp index 1d03fa6..bce903f 100644 --- a/tools/llvm-lto/llvm-lto.cpp +++ b/tools/llvm-lto/llvm-lto.cpp @@ -136,7 +136,8 @@ int main(int argc, char **argv) { return 1; } - raw_fd_ostream FileStream(OutputFilename.c_str(), ErrorInfo); + raw_fd_ostream FileStream(OutputFilename.c_str(), ErrorInfo, + sys::fs::F_Binary); if (!ErrorInfo.empty()) { errs() << argv[0] << ": error opening the file '" << OutputFilename << "': " << ErrorInfo << "\n"; -- cgit v1.1 From 5ccfef6a1d9a5d3fcea56d8900dd35931c793484 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Sat, 5 Oct 2013 11:53:20 +0000 Subject: lli: Plug leaks in the remote target external implementation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192031 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/ChildTarget/ChildTarget.cpp | 1 + tools/lli/ChildTarget/Unix/ChildTarget.inc | 4 ++++ tools/lli/ChildTarget/Windows/ChildTarget.inc | 3 +++ tools/lli/RemoteTargetExternal.h | 2 +- tools/lli/Unix/RemoteTargetExternal.inc | 4 ++++ tools/lli/Windows/RemoteTargetExternal.inc | 3 +++ 6 files changed, 16 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lli/ChildTarget/ChildTarget.cpp b/tools/lli/ChildTarget/ChildTarget.cpp index a59209a..55fcae9 100644 --- a/tools/lli/ChildTarget/ChildTarget.cpp +++ b/tools/lli/ChildTarget/ChildTarget.cpp @@ -11,6 +11,7 @@ using namespace llvm; class LLIChildTarget { public: + ~LLIChildTarget(); // OS-specific destructor void initialize(); LLIMessageType waitForIncomingMessage(); void handleMessage(LLIMessageType messageType); diff --git a/tools/lli/ChildTarget/Unix/ChildTarget.inc b/tools/lli/ChildTarget/Unix/ChildTarget.inc index cd42f34..cc95810 100644 --- a/tools/lli/ChildTarget/Unix/ChildTarget.inc +++ b/tools/lli/ChildTarget/Unix/ChildTarget.inc @@ -49,6 +49,10 @@ struct ConnectionData_t { } // namespace +LLIChildTarget::~LLIChildTarget() { + delete static_cast(ConnectionData); +} + // OS-specific methods void LLIChildTarget::initializeConnection() { // Store the parent ends of the pipes diff --git a/tools/lli/ChildTarget/Windows/ChildTarget.inc b/tools/lli/ChildTarget/Windows/ChildTarget.inc index bb95aff..45db2b0 100644 --- a/tools/lli/ChildTarget/Windows/ChildTarget.inc +++ b/tools/lli/ChildTarget/Windows/ChildTarget.inc @@ -12,6 +12,9 @@ // //===----------------------------------------------------------------------===// +LLIChildTarget::~LLIChildTarget() { +} + // The RemoteTargetExternal implementation should prevent us from ever getting // here on Windows, but nothing prevents a user from running this directly. void LLIChildTarget::initializeConnection() { diff --git a/tools/lli/RemoteTargetExternal.h b/tools/lli/RemoteTargetExternal.h index 9a3644a..a4bfad2 100644 --- a/tools/lli/RemoteTargetExternal.h +++ b/tools/lli/RemoteTargetExternal.h @@ -88,7 +88,7 @@ public: virtual void stop(); RemoteTargetExternal(std::string &Name) : RemoteTarget(), ChildName(Name) {} - virtual ~RemoteTargetExternal() {} + virtual ~RemoteTargetExternal(); private: std::string ChildName; diff --git a/tools/lli/Unix/RemoteTargetExternal.inc b/tools/lli/Unix/RemoteTargetExternal.inc index e245f7e..9c1a4cc 100644 --- a/tools/lli/Unix/RemoteTargetExternal.inc +++ b/tools/lli/Unix/RemoteTargetExternal.inc @@ -89,4 +89,8 @@ void RemoteTargetExternal::Wait() { wait(NULL); } +RemoteTargetExternal::~RemoteTargetExternal() { + delete static_cast(ConnectionData); +} + } // namespace llvm diff --git a/tools/lli/Windows/RemoteTargetExternal.inc b/tools/lli/Windows/RemoteTargetExternal.inc index 6536d99..aef4627 100644 --- a/tools/lli/Windows/RemoteTargetExternal.inc +++ b/tools/lli/Windows/RemoteTargetExternal.inc @@ -29,4 +29,7 @@ int RemoteTargetExternal::ReadBytes(void *Data, size_t Size) { void RemoteTargetExternal::Wait() { } +RemoteTargetExternal::~RemoteTargetExternal() { +} + } // namespace llvm -- cgit v1.1 From c84c742eddc0c57c34271471f332c9857d79e672 Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Mon, 7 Oct 2013 08:58:27 +0000 Subject: [Mips] Teach llvm-readobj to print MIPS-specific ELF program headers. The patch reviewed by Michael Spencer. http://llvm-reviews.chandlerc.com/D1846 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192093 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/ELFDumper.cpp | 59 ++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 21 deletions(-) (limited to 'tools') diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index ffa0e01..f384824 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -391,26 +391,41 @@ static const EnumEntry ElfSectionFlags[] = { LLVM_READOBJ_ENUM_ENT(ELF, SHF_MIPS_NOSTRIP ) }; -static const EnumEntry ElfSegmentTypes[] = { - LLVM_READOBJ_ENUM_ENT(ELF, PT_NULL ), - LLVM_READOBJ_ENUM_ENT(ELF, PT_LOAD ), - LLVM_READOBJ_ENUM_ENT(ELF, PT_DYNAMIC), - LLVM_READOBJ_ENUM_ENT(ELF, PT_INTERP ), - LLVM_READOBJ_ENUM_ENT(ELF, PT_NOTE ), - LLVM_READOBJ_ENUM_ENT(ELF, PT_SHLIB ), - LLVM_READOBJ_ENUM_ENT(ELF, PT_PHDR ), - LLVM_READOBJ_ENUM_ENT(ELF, PT_TLS ), - - LLVM_READOBJ_ENUM_ENT(ELF, PT_GNU_EH_FRAME), - LLVM_READOBJ_ENUM_ENT(ELF, PT_SUNW_EH_FRAME), - LLVM_READOBJ_ENUM_ENT(ELF, PT_SUNW_UNWIND), - - LLVM_READOBJ_ENUM_ENT(ELF, PT_GNU_STACK), - LLVM_READOBJ_ENUM_ENT(ELF, PT_GNU_RELRO), - - LLVM_READOBJ_ENUM_ENT(ELF, PT_ARM_EXIDX), - LLVM_READOBJ_ENUM_ENT(ELF, PT_ARM_UNWIND) -}; +static const char *getElfSegmentType(unsigned Arch, unsigned Type) { + // Check potentially overlapped processor-specific + // program header type. + switch (Arch) { + case ELF::EM_ARM: + switch (Type) { + LLVM_READOBJ_ENUM_CASE(ELF, PT_ARM_EXIDX); + } + case ELF::EM_MIPS: + case ELF::EM_MIPS_RS3_LE: + switch (Type) { + LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_REGINFO); + LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_RTPROC); + LLVM_READOBJ_ENUM_CASE(ELF, PT_MIPS_OPTIONS); + } + } + + switch (Type) { + LLVM_READOBJ_ENUM_CASE(ELF, PT_NULL ); + LLVM_READOBJ_ENUM_CASE(ELF, PT_LOAD ); + LLVM_READOBJ_ENUM_CASE(ELF, PT_DYNAMIC); + LLVM_READOBJ_ENUM_CASE(ELF, PT_INTERP ); + LLVM_READOBJ_ENUM_CASE(ELF, PT_NOTE ); + LLVM_READOBJ_ENUM_CASE(ELF, PT_SHLIB ); + LLVM_READOBJ_ENUM_CASE(ELF, PT_PHDR ); + LLVM_READOBJ_ENUM_CASE(ELF, PT_TLS ); + + LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_EH_FRAME); + LLVM_READOBJ_ENUM_CASE(ELF, PT_SUNW_UNWIND); + + LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_STACK); + LLVM_READOBJ_ENUM_CASE(ELF, PT_GNU_RELRO); + default: return ""; + } +} static const EnumEntry ElfSegmentFlags[] = { LLVM_READOBJ_ENUM_ENT(ELF, PF_X), @@ -790,7 +805,9 @@ void ELFDumper::printProgramHeaders() { PE = Obj->end_program_headers(); PI != PE; ++PI) { DictScope P(W, "ProgramHeader"); - W.printEnum ("Type", PI->p_type, makeArrayRef(ElfSegmentTypes)); + W.printHex ("Type", + getElfSegmentType(Obj->getHeader()->e_machine, PI->p_type), + PI->p_type); W.printHex ("Offset", PI->p_offset); W.printHex ("VirtualAddress", PI->p_vaddr); W.printHex ("PhysicalAddress", PI->p_paddr); -- cgit v1.1 From 55a31a3aac9ef18e1251757fc13eb93015c63ec1 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 7 Oct 2013 15:42:22 +0000 Subject: Revert r191088, corresponding to r191823 to re-enable llvm-lto on cygming. r191088 is "llvm/tools/Makefile: Suppress building llvm-lto on cygming, for now, probably due to LTO.dll." git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192104 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/Makefile | 2 -- 1 file changed, 2 deletions(-) (limited to 'tools') diff --git a/tools/Makefile b/tools/Makefile index 11e417a..5fa5bf2 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -67,8 +67,6 @@ endif # On Win32, loadable modules can be built with ENABLE_SHARED. ifneq ($(ENABLE_SHARED),1) ifneq (,$(filter $(HOST_OS), Cygwin MingW)) - DIRS := $(filter-out llvm-lto, \ - $(DIRS)) PARALLEL_DIRS := $(filter-out bugpoint-passes, \ $(PARALLEL_DIRS)) endif -- cgit v1.1 From 5a0169f0a1434014e727b22240a45a1f329cc0be Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 8 Oct 2013 15:07:00 +0000 Subject: Only modify lto.exports.def when contents have changed. Patch by Greg Bedwell. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192182 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/CMakeLists.txt | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/lto/CMakeLists.txt b/tools/lto/CMakeLists.txt index 89160ee..957a9f0 100644 --- a/tools/lto/CMakeLists.txt +++ b/tools/lto/CMakeLists.txt @@ -15,10 +15,16 @@ if( NOT CYGWIN AND LLVM_ENABLE_PIC ) # 'EXPORTS'. The file "lto.exports" already contains the list, so we # massage it into the correct format here to create "lto.exports.def". set(LTO_EXPORTS_DEF ${CMAKE_CURRENT_BINARY_DIR}/lto.exports.def) + set(LTO_EXPORTS_DEF_TEMP ${LTO_EXPORTS_DEF}.txt) file(READ "lto.exports" exports_list) - file(WRITE ${LTO_EXPORTS_DEF} "LIBRARY LTO\n") - file(APPEND ${LTO_EXPORTS_DEF} "EXPORTS\n") - file(APPEND ${LTO_EXPORTS_DEF} ${exports_list}) + file(WRITE ${LTO_EXPORTS_DEF_TEMP} "LIBRARY LTO\n") + file(APPEND ${LTO_EXPORTS_DEF_TEMP} "EXPORTS\n") + file(APPEND ${LTO_EXPORTS_DEF_TEMP} ${exports_list}) + + # Copy the file only if it has changed. + execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${LTO_EXPORTS_DEF_TEMP} ${LTO_EXPORTS_DEF}) + set(SHARED_LIB_SOURCES ${SOURCES} ${LTO_EXPORTS_DEF}) else() set(SHARED_LIB_SOURCES ${SOURCES}) -- cgit v1.1 From eb59e4d5ac15604643540b3aa1e5628d2d440dfc Mon Sep 17 00:00:00 2001 From: Andrew Kaylor Date: Tue, 8 Oct 2013 17:15:11 +0000 Subject: Removing unintended code block from lli git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192205 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/lli.cpp | 9 --------- 1 file changed, 9 deletions(-) (limited to 'tools') diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index ac0d219..5578a1d 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -489,15 +489,6 @@ int main(int argc, char **argv, char * const *envp) { // Create the remote target. Target->create(); -// FIXME: Don't commit like this. I don't think these calls are necessary. -#if 0 - // Trigger compilation. - EE->generateCodeForModule(Mod); - - // Get everything ready to execute. - EE->finalizeModule(Mod); -#endif - // Since we're executing in a (at least simulated) remote address space, // we can't use the ExecutionEngine::runFunctionAsMain(). We have to // grab the function address directly here and tell the remote target -- cgit v1.1 From 0568ba6e3af7ae7eb3ad7871ad0581c926150c8d Mon Sep 17 00:00:00 2001 From: Greg Bedwell Date: Wed, 9 Oct 2013 08:55:27 +0000 Subject: Test commit. Remove whitespace from otherwise empty lines. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192284 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/opt/opt.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 71a9c02..0055bb0 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -417,7 +417,7 @@ struct BreakpointPrinter : public ModulePass { AU.setPreservesAll(); } }; - + } // anonymous namespace char BreakpointPrinter::ID = 0; @@ -460,7 +460,7 @@ static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, Builder.DisableUnitAtATime = !UnitAtATime; Builder.DisableUnrollLoops = (DisableLoopUnrolling.getNumOccurrences() > 0) ? DisableLoopUnrolling : OptLevel == 0; - + Builder.LoopVectorize = OptLevel > 1 && SizeLevel < 2; Builder.SLPVectorize = true; -- cgit v1.1 From 6a24c7d4e78ade068e60cbb95adb5021014ba0b7 Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 10 Oct 2013 17:31:54 +0000 Subject: Fix msbuild integration install script. We previously failed to check whether the SUCCESS variable was set, and would thus always exit with a failure if vs2012 didn't exist. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192370 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/msbuild/install.bat | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/msbuild/install.bat b/tools/msbuild/install.bat index 2b66a6c..fb00d27 100644 --- a/tools/msbuild/install.bat +++ b/tools/msbuild/install.bat @@ -18,8 +18,9 @@ IF EXIST %D% GOTO FOUND_V110 SET D="%ProgramFiles(x86)%\MSBuild\Microsoft.Cpp\v4.0\V110\Platforms\Win32\PlatformToolsets" IF EXIST %D% GOTO FOUND_V110 -IF NOT SUCCESS == 1 echo Failed to find MSBuild toolsets directory. -IF NOT SUCCESS == 1 goto FAILED +IF %SUCCESS% == 1 goto DONE +echo Failed to find MSBuild toolsets directory. +goto FAILED :FOUND_V100 @@ -45,6 +46,8 @@ copy Microsoft.Cpp.Win32.LLVM-vs2012_xp.props %D%\LLVM-vs2012_xp IF NOT %ERRORLEVEL% == 0 GOTO FAILED copy Microsoft.Cpp.Win32.LLVM-vs2012_xp.targets %D%\LLVM-vs2012_xp IF NOT %ERRORLEVEL% == 0 GOTO FAILED + +:DONE echo Done! goto END -- cgit v1.1 From a7d9a5d64a89ef8532fcf38cc8a57960d48e283e Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Thu, 10 Oct 2013 17:32:01 +0000 Subject: Provide msbuild integration for vs2013. Patch by Josh Samuel! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192371 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/msbuild/CMakeLists.txt | 9 +++++++++ tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in | 3 ++- tools/msbuild/install.bat | 22 ++++++++++++++++++++++ tools/msbuild/uninstall.bat | 16 ++++++++++++++++ 4 files changed, 49 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/msbuild/CMakeLists.txt b/tools/msbuild/CMakeLists.txt index 894645a..cc4f3d5 100644 --- a/tools/msbuild/CMakeLists.txt +++ b/tools/msbuild/CMakeLists.txt @@ -3,6 +3,8 @@ if (WIN32) set(prop_file_v100 "Microsoft.Cpp.Win32.LLVM-vs2010.props") set(prop_file_v110 "Microsoft.Cpp.Win32.LLVM-vs2012.props") set(prop_file_v110_xp "Microsoft.Cpp.Win32.LLVM-vs2012_xp.props") + set(prop_file_v120 "toolset-vs2013.props") + set(prop_file_v120_xp "toolset-vs2013_xp.props") # CPack will install a registry key in this format that we wish to reference. set(REG_KEY "${CMAKE_PROJECT_NAME} ${CPACK_PACKAGE_VERSION}") @@ -15,6 +17,11 @@ if (WIN32) configure_file(${prop_file_in} ${prop_file_v110}) set(VS_VERSION "v110_xp") configure_file(${prop_file_in} ${prop_file_v110_xp}) + set(VS_VSERSION "v120") + set(MSC_VERSION "1800") + configure_file(${prop_file_in} ${prop_file_v120}) + set(VS_VERSION "v120_xp") + configure_file(${prop_file_in} ${prop_file_v120_xp}) set(REG_KEY) set(VS_VERSION) @@ -22,6 +29,8 @@ if (WIN32) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${prop_file_v100}" DESTINATION tools/msbuild) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${prop_file_v110}" DESTINATION tools/msbuild) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${prop_file_v110_xp}" DESTINATION tools/msbuild) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${prop_file_v120}" DESTINATION tools/msbuild) + install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${prop_file_v120_xp}" DESTINATION tools/msbuild) install(DIRECTORY . DESTINATION tools/msbuild diff --git a/tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in b/tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in index fce6011..a6ef4ea 100644 --- a/tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in +++ b/tools/msbuild/Microsoft.Cpp.Win32.llvm.props.in @@ -1,5 +1,6 @@  - + + $(Registry:HKEY_LOCAL_MACHINE\SOFTWARE\LLVM\@REG_KEY@) diff --git a/tools/msbuild/install.bat b/tools/msbuild/install.bat index fb00d27..c4c61ac 100644 --- a/tools/msbuild/install.bat +++ b/tools/msbuild/install.bat @@ -18,6 +18,12 @@ IF EXIST %D% GOTO FOUND_V110 SET D="%ProgramFiles(x86)%\MSBuild\Microsoft.Cpp\v4.0\V110\Platforms\Win32\PlatformToolsets" IF EXIST %D% GOTO FOUND_V110 +:TRY_V120 +SET D="%ProgramFiles%\MSBuild\Microsoft.Cpp\v4.0\V120\Platforms\Win32\PlatformToolsets" +IF EXIST %D% GOTO FOUND_V120 +SET D="%ProgramFiles(x86)%\MSBuild\Microsoft.Cpp\v4.0\V120\Platforms\Win32\PlatformToolsets" +IF EXIST %D% GOTO FOUND_V120 + IF %SUCCESS% == 1 goto DONE echo Failed to find MSBuild toolsets directory. goto FAILED @@ -46,6 +52,22 @@ copy Microsoft.Cpp.Win32.LLVM-vs2012_xp.props %D%\LLVM-vs2012_xp IF NOT %ERRORLEVEL% == 0 GOTO FAILED copy Microsoft.Cpp.Win32.LLVM-vs2012_xp.targets %D%\LLVM-vs2012_xp IF NOT %ERRORLEVEL% == 0 GOTO FAILED +set SUCCESS=1 +GOTO TRY_V120 + +:FOUND_V120 +IF NOT EXIST %D%\LLVM-vs2013 mkdir %D%\LLVM-vs2013 +IF NOT %ERRORLEVEL% == 0 GOTO FAILED +copy toolset-vs2013.props %D%\LLVM-vs2013\toolset.props +IF NOT %ERRORLEVEL% == 0 GOTO FAILED +copy toolset-vs2013.targets %D%\LLVM-vs2013\toolset.targets +IF NOT %ERRORLEVEL% == 0 GOTO FAILED +IF NOT EXIST %D%\LLVM-vs2013_xp mkdir %D%\LLVM-vs2013_xp +IF NOT %ERRORLEVEL% == 0 GOTO FAILED +copy toolset-vs2013_xp.props %D%\LLVM-vs2013_xp\toolset.props +IF NOT %ERRORLEVEL% == 0 GOTO FAILED +copy toolset-vs2013_xp.targets %D%\LLVM-vs2013_xp\toolset.targets +IF NOT %ERRORLEVEL% == 0 GOTO FAILED :DONE echo Done! diff --git a/tools/msbuild/uninstall.bat b/tools/msbuild/uninstall.bat index f1f5619..7e94f87 100644 --- a/tools/msbuild/uninstall.bat +++ b/tools/msbuild/uninstall.bat @@ -31,4 +31,20 @@ IF EXIST %D%\LLVM-vs2012_xp del %D%\LLVM-vs2012_xp\Microsoft.Cpp.Win32.LLVM-vs20 IF EXIST %D%\LLVM-vs2012_xp del %D%\LLVM-vs2012_xp\Microsoft.Cpp.Win32.LLVM-vs2012_xp.targets IF EXIST %D%\LLVM-vs2012_xp rmdir %D%\LLVM-vs2012_xp +SET D="%ProgramFiles%\MSBuild\Microsoft.Cpp\v4.0\V120\Platforms\Win32\PlatformToolsets" +IF EXIST %D%\LLVM-vs2013 del %D%\LLVM-vs2013\toolset.props +IF EXIST %D%\LLVM-vs2013 del %D%\LLVM-vs2013\toolset.targets +IF EXIST %D%\LLVM-vs2013 rmdir %D%\LLVM-vs2013 +IF EXIST %D%\LLVM-vs2013_xp del %D%\LLVM-vs2013_xp\toolset.props +IF EXIST %D%\LLVM-vs2013_xp del %D%\LLVM-vs2013_xp\toolset.targets +IF EXIST %D%\LLVM-vs2013_xp rmdir %D%\LLVM-vs2013_xp + +SET D="%ProgramFiles(x86)%\MSBuild\Microsoft.Cpp\v4.0\V120\Platforms\Win32\PlatformToolsets" +IF EXIST %D%\LLVM-vs2013 del %D%\LLVM-vs2013\toolset.props +IF EXIST %D%\LLVM-vs2013 del %D%\LLVM-vs2013\toolset.targets +IF EXIST %D%\LLVM-vs2013 rmdir %D%\LLVM-vs2013 +IF EXIST %D%\LLVM-vs2013_xp del %D%\LLVM-vs2013_xp\toolset.props +IF EXIST %D%\LLVM-vs2013_xp del %D%\LLVM-vs2013_xp\toolset.targets +IF EXIST %D%\LLVM-vs2013_xp rmdir %D%\LLVM-vs2013_xp + echo Done! -- cgit v1.1 From b8e48a636e7ee6c13140382eb93d9695a65b0624 Mon Sep 17 00:00:00 2001 From: Manman Ren Date: Thu, 10 Oct 2013 18:40:01 +0000 Subject: Debug Info: In DIBuilder, the context field of subprogram is updated to use DIScopeRef. A paired commit at clang is required due to changes to DIBuilder. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192378 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/opt/opt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 0055bb0..8a8da01 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -404,7 +404,7 @@ struct BreakpointPrinter : public ModulePass { "A MDNode in llvm.dbg.sp should be null or a DISubprogram."); if (!SP) continue; - getContextName(SP.getContext(), Name); + getContextName(SP.getContext().resolve(TypeIdentifierMap), Name); Name = Name + SP.getDisplayName().str(); if (!Name.empty() && Processed.insert(Name)) { Out << Name << "\n"; -- cgit v1.1 From 528f6d787b1a847e61eb2f1114559f423fdeb68c Mon Sep 17 00:00:00 2001 From: Andrew Kaylor Date: Fri, 11 Oct 2013 21:25:48 +0000 Subject: Adding multiple object support to MCJIT EH frame handling git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192504 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/RemoteMemoryManager.cpp | 24 ------------------------ tools/lli/RemoteMemoryManager.h | 11 +++++++++-- 2 files changed, 9 insertions(+), 26 deletions(-) (limited to 'tools') diff --git a/tools/lli/RemoteMemoryManager.cpp b/tools/lli/RemoteMemoryManager.cpp index 8ccfde8..04fc40e 100644 --- a/tools/lli/RemoteMemoryManager.cpp +++ b/tools/lli/RemoteMemoryManager.cpp @@ -204,27 +204,3 @@ uint8_t *RemoteMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment) void RemoteMemoryManager::deallocateFunctionBody(void *Body) { llvm_unreachable("Unexpected!"); } - -static int jit_noop() { - return 0; -} - -void *RemoteMemoryManager::getPointerToNamedFunction(const std::string &Name, - bool AbortOnFailure) { - // We should not invoke parent's ctors/dtors from generated main()! - // On Mingw and Cygwin, the symbol __main is resolved to - // callee's(eg. tools/lli) one, to invoke wrong duplicated ctors - // (and register wrong callee's dtors with atexit(3)). - // We expect ExecutionEngine::runStaticConstructorsDestructors() - // is called before ExecutionEngine::runFunctionAsMain() is called. - if (Name == "__main") return (void*)(intptr_t)&jit_noop; - - // FIXME: Would it be responsible to provide GOT? - if (AbortOnFailure) { - if (Name == "_GLOBAL_OFFSET_TABLE_") - report_fatal_error("Program used external function '" + Name + - "' which could not be resolved!"); - } - - return NULL; -} diff --git a/tools/lli/RemoteMemoryManager.h b/tools/lli/RemoteMemoryManager.h index ca157a7..eabe042 100644 --- a/tools/lli/RemoteMemoryManager.h +++ b/tools/lli/RemoteMemoryManager.h @@ -74,13 +74,20 @@ public: unsigned SectionID, StringRef SectionName, bool IsReadOnly); - void *getPointerToNamedFunction(const std::string &Name, - bool AbortOnFailure = true); + // For now, remote symbol resolution is not support in lli. The MCJIT + // interface does support this, but clients must provide their own + // mechanism for finding remote symbol addresses. MCJIT will resolve + // symbols from Modules it contains. + uint64_t getSymbolAddress(const std::string &Name) {} void notifyObjectLoaded(ExecutionEngine *EE, const ObjectImage *Obj); bool finalizeMemory(std::string *ErrMsg); + // For now, remote EH frame registration isn't supported. Remote symbol + // resolution is a prerequisite to supporting remote EH frame registration. + void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) {} + // This is a non-interface function used by lli void setRemoteTarget(RemoteTarget *T) { Target = T; } -- cgit v1.1 From 4bad07fbec9d42769fdc5cea891f8cb7a3b284d5 Mon Sep 17 00:00:00 2001 From: Andrew Kaylor Date: Fri, 11 Oct 2013 22:47:10 +0000 Subject: Fixing problems in lli's RemoteMemoryManager. This fixes a problem from a previous check-in where a return value was omitted. Previously the remote/stubs-remote.ll and remote/stubs-sm-pic.ll tests were reporting passes, but they should have been failing. Those tests attempt to link against an external symbol and remote symbol resolution is not supported. The old RemoteMemoryManager implementation resulted in local symbols being used for resolution and the child process crashed but the test didn't notice. With this check-in remote symbol resolution fails, and so the test (correctly) fails. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192514 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/RemoteMemoryManager.h | 2 +- tools/lli/lli.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/lli/RemoteMemoryManager.h b/tools/lli/RemoteMemoryManager.h index eabe042..16d0a80 100644 --- a/tools/lli/RemoteMemoryManager.h +++ b/tools/lli/RemoteMemoryManager.h @@ -78,7 +78,7 @@ public: // interface does support this, but clients must provide their own // mechanism for finding remote symbol addresses. MCJIT will resolve // symbols from Modules it contains. - uint64_t getSymbolAddress(const std::string &Name) {} + uint64_t getSymbolAddress(const std::string &Name) { return 0; } void notifyObjectLoaded(ExecutionEngine *EE, const ObjectImage *Obj); diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index 5578a1d..7117707 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -398,18 +398,18 @@ int main(int argc, char **argv, char * const *envp) { return -1; } - // If the program doesn't explicitly call exit, we will need the Exit - // function later on to make an explicit call, so get the function now. - Constant *Exit = Mod->getOrInsertFunction("exit", Type::getVoidTy(Context), - Type::getInt32Ty(Context), - NULL); - // Reset errno to zero on entry to main. errno = 0; int Result; if (!RemoteMCJIT) { + // If the program doesn't explicitly call exit, we will need the Exit + // function later on to make an explicit call, so get the function now. + Constant *Exit = Mod->getOrInsertFunction("exit", Type::getVoidTy(Context), + Type::getInt32Ty(Context), + NULL); + // Run static constructors. if (UseMCJIT && !ForceInterpreter) { // Give MCJIT a chance to apply relocations and set page permissions. -- cgit v1.1 From e3ba15c794839abe076e3e2bdf6c626396a19d4d Mon Sep 17 00:00:00 2001 From: Will Dietz Date: Sat, 12 Oct 2013 00:55:57 +0000 Subject: Add missing #include's to cctype when using isdigit/alpha/etc. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192519 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp index 186eea9..da40da2 100644 --- a/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp +++ b/tools/llvm-bcanalyzer/llvm-bcanalyzer.cpp @@ -41,6 +41,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Support/system_error.h" #include +#include #include using namespace llvm; -- cgit v1.1 From 6dd7893e8c7234d65cdc47e3f3ce251fdfb35768 Mon Sep 17 00:00:00 2001 From: Will Dietz Date: Sat, 12 Oct 2013 21:29:16 +0000 Subject: yaml2coff/elf: Touchup for compatibility. * std::string::append(int, int) can be ambiguous. * std::vector<>::data() is a C++11 feature, use ArrayRef abstraction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192542 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/yaml2obj/yaml2coff.cpp | 2 +- tools/yaml2obj/yaml2elf.cpp | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) (limited to 'tools') diff --git a/tools/yaml2obj/yaml2coff.cpp b/tools/yaml2obj/yaml2coff.cpp index 11aae0e..c757eb6 100644 --- a/tools/yaml2obj/yaml2coff.cpp +++ b/tools/yaml2obj/yaml2coff.cpp @@ -32,7 +32,7 @@ struct COFFParser { COFFParser(COFFYAML::Object &Obj) : Obj(Obj) { // A COFF string table always starts with a 4 byte size field. Offsets into // it include this size, so allocate it now. - StringTable.append(4, 0); + StringTable.append(4, char(0)); } bool parseSections() { diff --git a/tools/yaml2obj/yaml2elf.cpp b/tools/yaml2obj/yaml2elf.cpp index d3b25ec..d46e154 100644 --- a/tools/yaml2obj/yaml2elf.cpp +++ b/tools/yaml2obj/yaml2elf.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "yaml2obj.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Object/ELFYAML.h" #include "llvm/Support/ELF.h" @@ -119,13 +120,13 @@ public: } // end anonymous namespace template -static size_t vectorDataSize(const std::vector &Vec) { - return Vec.size() * sizeof(T); +static size_t arrayDataSize(ArrayRef A) { + return A.size() * sizeof(T); } template -static void writeVectorData(raw_ostream &OS, const std::vector &Vec) { - OS.write((const char *)Vec.data(), vectorDataSize(Vec)); +static void writeArrayData(raw_ostream &OS, ArrayRef A) { + OS.write((const char *)A.data(), arrayDataSize(A)); } template @@ -235,8 +236,9 @@ handleSymtabSectionHeader(const ELFYAML::LocalGlobalWeakSymbols &Symbols, addSymbols(Symbols.Weak, State, Syms, ELF::STB_WEAK); ContiguousBlobAccumulator &CBA = State.getSectionContentAccum(); - writeVectorData(CBA.getOSAndAlignedOffset(SHeader.sh_offset), Syms); - SHeader.sh_size = vectorDataSize(Syms); + writeArrayData(CBA.getOSAndAlignedOffset(SHeader.sh_offset), + makeArrayRef(Syms)); + SHeader.sh_size = arrayDataSize(makeArrayRef(Syms)); } template @@ -359,7 +361,7 @@ static int writeELF(raw_ostream &OS, const ELFYAML::Object &Doc) { SHeaders.push_back(SHStrTabSHeader); OS.write((const char *)&Header, sizeof(Header)); - writeVectorData(OS, SHeaders); + writeArrayData(OS, makeArrayRef(SHeaders)); CBA.writeBlobToStream(OS); return 0; } -- cgit v1.1 From 95bf4c48ed490682485d040d856e02c0e2f6f9af Mon Sep 17 00:00:00 2001 From: Hans Wennborg Date: Mon, 14 Oct 2013 18:16:37 +0000 Subject: vs2013 msbuild integration: add missing .target files, fix typo in CMakeLists This should fix PR17568. Patch by Josh Samuel! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192610 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/msbuild/CMakeLists.txt | 2 +- tools/msbuild/toolset-vs2013.targets | 3 +++ tools/msbuild/toolset-vs2013_xp.targets | 21 +++++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) create mode 100644 tools/msbuild/toolset-vs2013.targets create mode 100644 tools/msbuild/toolset-vs2013_xp.targets (limited to 'tools') diff --git a/tools/msbuild/CMakeLists.txt b/tools/msbuild/CMakeLists.txt index cc4f3d5..c725ab7 100644 --- a/tools/msbuild/CMakeLists.txt +++ b/tools/msbuild/CMakeLists.txt @@ -17,7 +17,7 @@ if (WIN32) configure_file(${prop_file_in} ${prop_file_v110}) set(VS_VERSION "v110_xp") configure_file(${prop_file_in} ${prop_file_v110_xp}) - set(VS_VSERSION "v120") + set(VS_VERSION "v120") set(MSC_VERSION "1800") configure_file(${prop_file_in} ${prop_file_v120}) set(VS_VERSION "v120_xp") diff --git a/tools/msbuild/toolset-vs2013.targets b/tools/msbuild/toolset-vs2013.targets new file mode 100644 index 0000000..a6efac4 --- /dev/null +++ b/tools/msbuild/toolset-vs2013.targets @@ -0,0 +1,3 @@ + + + diff --git a/tools/msbuild/toolset-vs2013_xp.targets b/tools/msbuild/toolset-vs2013_xp.targets new file mode 100644 index 0000000..e719681 --- /dev/null +++ b/tools/msbuild/toolset-vs2013_xp.targets @@ -0,0 +1,21 @@ + + + + v4.0 + NoSupportCodeAnalysisXP;$(BeforeClCompileTargets) + + + + + + + + + + CheckWindowsSDK71A;$(PrepareForBuildDependsOn) + + + + + + -- cgit v1.1 From 43507d026bef31100cb0c35614bcf419029a265b Mon Sep 17 00:00:00 2001 From: Andrew Kaylor Date: Wed, 16 Oct 2013 00:14:21 +0000 Subject: Adding support for deregistering EH frames with MCJIT. Patch by Yaron Keren git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192753 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/RemoteMemoryManager.h | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/lli/RemoteMemoryManager.h b/tools/lli/RemoteMemoryManager.h index 16d0a80..5d0456f 100644 --- a/tools/lli/RemoteMemoryManager.h +++ b/tools/lli/RemoteMemoryManager.h @@ -87,6 +87,7 @@ public: // For now, remote EH frame registration isn't supported. Remote symbol // resolution is a prerequisite to supporting remote EH frame registration. void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) {} + void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) {} // This is a non-interface function used by lli void setRemoteTarget(RemoteTarget *T) { Target = T; } -- cgit v1.1 From d9729ae8c51707d52e437b4c61242a568324855b Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Wed, 16 Oct 2013 09:54:49 +0000 Subject: llvm-symbolizer: don't always run demangler on global object names git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192781 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-symbolizer/LLVMSymbolize.cpp | 8 +++++++- tools/llvm-symbolizer/LLVMSymbolize.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/llvm-symbolizer/LLVMSymbolize.cpp b/tools/llvm-symbolizer/LLVMSymbolize.cpp index 45c8664..320ab3f 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.cpp +++ b/tools/llvm-symbolizer/LLVMSymbolize.cpp @@ -196,7 +196,7 @@ std::string LLVMSymbolizer::symbolizeData(const std::string &ModuleName, if (Opts.UseSymbolTable) { if (ModuleInfo *Info = getOrCreateModuleInfo(ModuleName)) { if (Info->symbolizeData(ModuleOffset, Name, Start, Size) && Opts.Demangle) - Name = DemangleName(Name); + Name = DemangleGlobalName(Name); } } std::stringstream ss; @@ -436,5 +436,11 @@ std::string LLVMSymbolizer::DemangleName(const std::string &Name) { #endif } +std::string LLVMSymbolizer::DemangleGlobalName(const std::string &Name) { + // We can spoil names of globals with C linkage, so use an heuristic + // approach to check if the name should be demangled. + return (Name.substr(0, 2) == "_Z") ? DemangleName(Name) : Name; +} + } // namespace symbolize } // namespace llvm diff --git a/tools/llvm-symbolizer/LLVMSymbolize.h b/tools/llvm-symbolizer/LLVMSymbolize.h index 03c765c..eb2666a 100644 --- a/tools/llvm-symbolizer/LLVMSymbolize.h +++ b/tools/llvm-symbolizer/LLVMSymbolize.h @@ -71,6 +71,7 @@ private: ObjectFile *getObjectFileFromBinary(Binary *Bin, const std::string &ArchName); std::string printDILineInfo(DILineInfo LineInfo) const; + static std::string DemangleGlobalName(const std::string &Name); // Owns all the parsed binaries and object files. SmallVector ParsedBinariesAndObjects; -- cgit v1.1 From 648a2e6714885e9b3d2a4f380434fe44ef2c4b5b Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 16 Oct 2013 12:47:04 +0000 Subject: [pr17595] Fix a use after free. Destroying the codegen also frees the path of the created object. Copy the path to a std::string. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192787 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/gold/gold-plugin.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'tools') diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp index 119631c..8261739 100644 --- a/tools/gold/gold-plugin.cpp +++ b/tools/gold/gold-plugin.cpp @@ -427,9 +427,14 @@ static ld_plugin_status all_symbols_read_hook(void) { exit(0); } } - const char *objPath; - if (lto_codegen_compile_to_file(code_gen, &objPath)) { - (*message)(LDPL_ERROR, "Could not produce a combined object file\n"); + + std::string ObjPath; + { + const char *Temp; + if (lto_codegen_compile_to_file(code_gen, &Temp)) { + (*message)(LDPL_ERROR, "Could not produce a combined object file\n"); + } + ObjPath = Temp; } lto_codegen_dispose(code_gen); @@ -441,9 +446,9 @@ static ld_plugin_status all_symbols_read_hook(void) { } } - if ((*add_input_file)(objPath) != LDPS_OK) { + if ((*add_input_file)(ObjPath.c_str()) != LDPS_OK) { (*message)(LDPL_ERROR, "Unable to add .o file to the link."); - (*message)(LDPL_ERROR, "File left behind in: %s", objPath); + (*message)(LDPL_ERROR, "File left behind in: %s", ObjPath.c_str()); return LDPS_ERR; } @@ -454,7 +459,7 @@ static ld_plugin_status all_symbols_read_hook(void) { } if (options::obj_path.empty()) - Cleanup.push_back(objPath); + Cleanup.push_back(ObjPath); return LDPS_OK; } -- cgit v1.1 From 2d8a1d677c81c8e05d1dbc7832e1ced10cfc629a Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Fri, 18 Oct 2013 19:32:06 +0000 Subject: Check for errors when calling lto_codegen_add_module in the gold plugin. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks to Milan Lenčo for noticing it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@192996 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/gold/gold-plugin.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp index 8261739..360ec07 100644 --- a/tools/gold/gold-plugin.cpp +++ b/tools/gold/gold-plugin.cpp @@ -351,8 +351,13 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, } } - if (code_gen) - lto_codegen_add_module(code_gen, M); + if (code_gen) { + if (lto_codegen_add_module(code_gen, M)) { + (*message)(LDPL_ERROR, "Error linking module: %s", + lto_get_error_message()); + return LDPS_ERR; + } + } lto_module_dispose(M); -- cgit v1.1 From 32c69dd1abf419742d99c59e7d54812e315cbb2d Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Tue, 22 Oct 2013 00:09:03 +0000 Subject: Move the printing of llvm-cov information out from collectLineCounts(). collectLineCounts() should only organize the output data. This is done in anticipation of subsequent changes which will pass in GCNO and GCDA filenames into the print function where it is printed similar to the gcov output. Patch by Yuchen Wu! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193134 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-cov/llvm-cov.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/llvm-cov/llvm-cov.cpp b/tools/llvm-cov/llvm-cov.cpp index 7b21c5b..7404679 100644 --- a/tools/llvm-cov/llvm-cov.cpp +++ b/tools/llvm-cov/llvm-cov.cpp @@ -74,5 +74,6 @@ int main(int argc, char **argv) { FileInfo FI; GF.collectLineCounts(FI); + FI.print(); return 0; } -- cgit v1.1 From e877eebfe9d716ed1101aecf958af473836e70e1 Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Tue, 22 Oct 2013 05:09:41 +0000 Subject: Change llvm-cov output formatting to be more similar to gcov. - Replaced tabs with proper padding - print() takes two arguments, which are the GCNO and GCDA filenames - Files are listed at the top of output, appended by line 0 - Stripped strings of trailing \0s - Removed last two lines of whitespace in output Patch by Yuchen Wu! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193148 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-cov/llvm-cov.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/llvm-cov/llvm-cov.cpp b/tools/llvm-cov/llvm-cov.cpp index 7404679..26aec46 100644 --- a/tools/llvm-cov/llvm-cov.cpp +++ b/tools/llvm-cov/llvm-cov.cpp @@ -74,6 +74,6 @@ int main(int argc, char **argv) { FileInfo FI; GF.collectLineCounts(FI); - FI.print(); + FI.print(InputGCNO, InputGCDA); return 0; } -- cgit v1.1 From 2bef1a6b25d938210547cd0f5ba4a08abdad2583 Mon Sep 17 00:00:00 2001 From: Anders Waldenborg Date: Wed, 23 Oct 2013 08:10:20 +0000 Subject: Add llvm-c-test tool for testing llvm-c This provides rudimentary testing of the llvm-c api. The following commands are implemented: * --module-dump Read bytecode from stdin - print ir * --module-list-functions Read bytecode from stdin - list summary of functions * --module-list-globals Read bytecode from stdin - list summary of globals * --targets-list List available targets * --object-list-sections Read object file from stdin - list sections * --object-list-symbols Read object file from stdin - list symbols (like nm) * --disassemble Read lines of triple, hex ascii machine code from stdin - print disassembly * --calc Read lines of name, rpn from stdin - print generated module ir Differential-Revision: http://llvm-reviews.chandlerc.com/D1776 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193233 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/CMakeLists.txt | 6 ++ tools/Makefile | 2 +- tools/llvm-c-test/CMakeLists.txt | 16 +++++ tools/llvm-c-test/Makefile | 29 ++++++++ tools/llvm-c-test/calc.c | 143 +++++++++++++++++++++++++++++++++++++++ tools/llvm-c-test/disassemble.c | 85 +++++++++++++++++++++++ tools/llvm-c-test/helpers.c | 40 +++++++++++ tools/llvm-c-test/include-all.c | 33 +++++++++ tools/llvm-c-test/llvm-c-test.h | 37 ++++++++++ tools/llvm-c-test/main.c | 73 ++++++++++++++++++++ tools/llvm-c-test/module.c | 112 ++++++++++++++++++++++++++++++ tools/llvm-c-test/object.c | 85 +++++++++++++++++++++++ tools/llvm-c-test/targets.c | 29 ++++++++ 13 files changed, 689 insertions(+), 1 deletion(-) create mode 100644 tools/llvm-c-test/CMakeLists.txt create mode 100644 tools/llvm-c-test/Makefile create mode 100644 tools/llvm-c-test/calc.c create mode 100644 tools/llvm-c-test/disassemble.c create mode 100644 tools/llvm-c-test/helpers.c create mode 100644 tools/llvm-c-test/include-all.c create mode 100644 tools/llvm-c-test/llvm-c-test.h create mode 100644 tools/llvm-c-test/main.c create mode 100644 tools/llvm-c-test/module.c create mode 100644 tools/llvm-c-test/object.c create mode 100644 tools/llvm-c-test/targets.c (limited to 'tools') diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 69c4050..54f849c 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -39,6 +39,12 @@ add_llvm_tool_subdirectory(llvm-mcmarkup) add_llvm_tool_subdirectory(llvm-symbolizer) +if( NOT MSVC ) + add_llvm_tool_subdirectory(llvm-c-test) +else() + ignore_llvm_tool_subdirectory(llvm-c-test) +endif( NOT MSVC ) + add_llvm_tool_subdirectory(obj2yaml) add_llvm_tool_subdirectory(yaml2obj) diff --git a/tools/Makefile b/tools/Makefile index 5fa5bf2..be87254 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -31,7 +31,7 @@ PARALLEL_DIRS := opt llvm-as llvm-dis llc llvm-ar llvm-nm llvm-link \ lli llvm-extract llvm-mc bugpoint llvm-bcanalyzer llvm-diff \ macho-dump llvm-objdump llvm-readobj llvm-rtdyld \ llvm-dwarfdump llvm-cov llvm-size llvm-stress llvm-mcmarkup \ - llvm-symbolizer obj2yaml yaml2obj + llvm-symbolizer obj2yaml yaml2obj llvm-c-test # If Intel JIT Events support is configured, build an extra tool to test it. ifeq ($(USE_INTEL_JITEVENTS), 1) diff --git a/tools/llvm-c-test/CMakeLists.txt b/tools/llvm-c-test/CMakeLists.txt new file mode 100644 index 0000000..2926d9d --- /dev/null +++ b/tools/llvm-c-test/CMakeLists.txt @@ -0,0 +1,16 @@ +set(LLVM_LINK_COMPONENTS all) + +if (LLVM_COMPILER_IS_GCC_COMPATIBLE) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wstrict-prototypes") +endif () + +add_llvm_tool(llvm-c-test + calc.c + disassemble.c + helpers.c + include-all.c + main.c + module.c + object.c + targets.c + ) diff --git a/tools/llvm-c-test/Makefile b/tools/llvm-c-test/Makefile new file mode 100644 index 0000000..08be7c3 --- /dev/null +++ b/tools/llvm-c-test/Makefile @@ -0,0 +1,29 @@ +##===- tools/llvm-c-test -----------------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL = ../.. +TOOLNAME = llvm-c-test + +TOOL_NO_EXPORTS = 1 +NO_INSTALL = 1 + + +# If there is no shared lib, link all components... +ifneq ($(ENABLE_SHARED),1) +LINK_COMPONENTS = all +endif + +include $(LEVEL)/Makefile.common + +CFLAGS += -std=c99 -Wall -Wstrict-prototypes + +# ...but if it is built - use it +ifeq ($(ENABLE_SHARED),1) +LIBS = -lLLVM-$(LLVMVersion) +endif diff --git a/tools/llvm-c-test/calc.c b/tools/llvm-c-test/calc.c new file mode 100644 index 0000000..c34ff7b --- /dev/null +++ b/tools/llvm-c-test/calc.c @@ -0,0 +1,143 @@ +/*===-- calc.c - tool for testing libLLVM and llvm-c API ------------------===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This file implements the --calc command in llvm-c-test. --calc reads lines *| +|* from stdin, parses them as a name and an expression in reverse polish *| +|* notation and prints a module with a function with the expression. *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#include "llvm-c-test.h" +#include "llvm-c/Core.h" +#include +#include +#include +#include + +typedef LLVMValueRef (*binop_func_t)(LLVMBuilderRef, LLVMValueRef LHS, + LLVMValueRef RHS, const char *Name); + +static LLVMOpcode op_to_opcode(char op) { + switch (op) { + case '+': return LLVMAdd; + case '-': return LLVMSub; + case '*': return LLVMMul; + case '/': return LLVMSDiv; + case '&': return LLVMAnd; + case '|': return LLVMOr; + case '^': return LLVMXor; + } + assert(0 && "unknown operation"); + return 0; +} + +#define MAX_DEPTH 32 + +static LLVMValueRef build_from_tokens(char **tokens, int ntokens, + LLVMBuilderRef builder, + LLVMValueRef param) { + LLVMValueRef stack[MAX_DEPTH]; + int depth = 0; + + for (int i = 0; i < ntokens; i++) { + char tok = tokens[i][0]; + switch (tok) { + case '+': + case '-': + case '*': + case '/': + case '&': + case '|': + case '^': + if (depth < 2) { + printf("stack underflow\n"); + return NULL; + } + + stack[depth - 2] = LLVMBuildBinOp(builder, op_to_opcode(tok), + stack[depth - 1], stack[depth - 2], ""); + depth--; + + break; + + case '@': + if (depth < 1) { + printf("stack underflow\n"); + return NULL; + } + + LLVMValueRef off = LLVMBuildGEP(builder, param, &stack[depth - 1], 1, ""); + stack[depth - 1] = LLVMBuildLoad(builder, off, ""); + + break; + + default: { + char *end; + long val = strtol(tokens[i], &end, 0); + if (end[0] != '\0') { + printf("error parsing number\n"); + return NULL; + } + + if (depth >= MAX_DEPTH) { + printf("stack overflow\n"); + return NULL; + } + + stack[depth++] = LLVMConstInt(LLVMInt64Type(), val, 1); + break; + } + } + } + + if (depth < 1) { + printf("stack underflow at return\n"); + return NULL; + } + + LLVMBuildRet(builder, stack[depth - 1]); + + return stack[depth - 1]; +} + +static void handle_line(char **tokens, int ntokens) { + char *name = tokens[0]; + + LLVMModuleRef M = LLVMModuleCreateWithName(name); + + LLVMTypeRef I64ty = LLVMInt64Type(); + LLVMTypeRef I64Ptrty = LLVMPointerType(I64ty, 0); + LLVMTypeRef Fty = LLVMFunctionType(I64ty, &I64Ptrty, 1, 0); + + LLVMValueRef F = LLVMAddFunction(M, name, Fty); + LLVMBuilderRef builder = LLVMCreateBuilder(); + LLVMPositionBuilderAtEnd(builder, LLVMAppendBasicBlock(F, "entry")); + + LLVMValueRef param; + LLVMGetParams(F, ¶m); + LLVMSetValueName(param, "in"); + + LLVMValueRef res = build_from_tokens(tokens + 1, ntokens - 1, builder, param); + if (res) { + char *irstr = LLVMPrintModuleToString(M); + puts(irstr); + LLVMDisposeMessage(irstr); + } + + LLVMDisposeBuilder(builder); + + LLVMDisposeModule(M); +} + +int calc(void) { + + tokenize_stdin(handle_line); + + return 0; +} diff --git a/tools/llvm-c-test/disassemble.c b/tools/llvm-c-test/disassemble.c new file mode 100644 index 0000000..4b3d37b --- /dev/null +++ b/tools/llvm-c-test/disassemble.c @@ -0,0 +1,85 @@ +/*===-- disassemble.c - tool for testing libLLVM and llvm-c API -----------===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This file implements the --disassemble command in llvm-c-test. *| +|* --disassemble reads lines from stdin, parses them as a triple and hex *| +|* machine code, and prints disassembly of the machine code. *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#include "llvm-c-test.h" +#include "llvm-c/Disassembler.h" +#include "llvm-c/Target.h" +#include +#include + +static void pprint(int pos, unsigned char *buf, int len, const char *disasm) { + printf("%04x: ", pos); + for (int i = 0; i < 8; i++) { + if (i < len) { + printf("%02x ", buf[i]); + } else { + printf(" "); + } + } + + printf(" %s\n", disasm); +} + +static void do_disassemble(const char *triple, unsigned char *buf, int siz) { + LLVMDisasmContextRef D = LLVMCreateDisasm(triple, NULL, 0, NULL, NULL); + + if (!D) { + printf("ERROR: Couldn't create disassebler for triple %s\n", triple); + return; + } + + char outline[1024]; + int pos = 0; + while (pos < siz) { + size_t l = LLVMDisasmInstruction(D, buf + pos, siz - pos, 0, outline, + sizeof(outline)); + if (!l) { + pprint(pos, buf + pos, 1, "\t???"); + pos++; + } else { + pprint(pos, buf + pos, l, outline); + pos += l; + } + } + + LLVMDisasmDispose(D); +} + +static void handle_line(char **tokens, int ntokens) { + unsigned char disbuf[128]; + size_t disbuflen = 0; + char *triple = tokens[0]; + + printf("triple: %s\n", triple); + + for (int i = 1; i < ntokens; i++) { + disbuf[disbuflen++] = strtol(tokens[i], NULL, 16); + if (disbuflen >= sizeof(disbuf)) { + fprintf(stderr, "Warning: Too long line, truncating\n"); + break; + } + } + do_disassemble(triple, disbuf, disbuflen); +} + +int disassemble(void) { + LLVMInitializeAllTargetInfos(); + LLVMInitializeAllTargetMCs(); + LLVMInitializeAllDisassemblers(); + + tokenize_stdin(handle_line); + + return 0; +} diff --git a/tools/llvm-c-test/helpers.c b/tools/llvm-c-test/helpers.c new file mode 100644 index 0000000..1ea8a4f --- /dev/null +++ b/tools/llvm-c-test/helpers.c @@ -0,0 +1,40 @@ +/*===-- helpers.c - tool for testing libLLVM and llvm-c API ---------------===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* Helper functions *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#include "llvm-c-test.h" +#include +#include + +#define MAX_TOKENS 512 +#define MAX_LINE_LEN 1024 + +void tokenize_stdin(void (*cb)(char **tokens, int ntokens)) { + char line[MAX_LINE_LEN]; + char *tokbuf[MAX_TOKENS]; + + while (fgets(line, sizeof(line), stdin)) { + int c = 0; + + if (line[0] == ';' || line[0] == '\n') + continue; + + while (c < MAX_TOKENS) { + tokbuf[c] = strtok(c ? NULL : line, " \n"); + if (!tokbuf[c]) + break; + c++; + } + if (c) + cb(tokbuf, c); + } +} diff --git a/tools/llvm-c-test/include-all.c b/tools/llvm-c-test/include-all.c new file mode 100644 index 0000000..17b9917 --- /dev/null +++ b/tools/llvm-c-test/include-all.c @@ -0,0 +1,33 @@ +/*===-- include-all.c - tool for testing libLLVM and llvm-c API -----------===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This file doesn't have any actual code. It just make sure that all *| +|* the llvm-c include files are good and doesn't generate any warnings *| +|* *| +\*===----------------------------------------------------------------------===*/ + +// FIXME: Autogenerate this list + +#include "llvm-c/Analysis.h" +#include "llvm-c/BitReader.h" +#include "llvm-c/BitWriter.h" +#include "llvm-c/Core.h" +#include "llvm-c/Disassembler.h" +#include "llvm-c/ExecutionEngine.h" +#include "llvm-c/Initialization.h" +#include "llvm-c/LinkTimeOptimizer.h" +#include "llvm-c/Linker.h" +#include "llvm-c/Object.h" +#include "llvm-c/Target.h" +#include "llvm-c/TargetMachine.h" +#include "llvm-c/Transforms/IPO.h" +#include "llvm-c/Transforms/PassManagerBuilder.h" +#include "llvm-c/Transforms/Scalar.h" +#include "llvm-c/Transforms/Vectorize.h" +#include "llvm-c/lto.h" diff --git a/tools/llvm-c-test/llvm-c-test.h b/tools/llvm-c-test/llvm-c-test.h new file mode 100644 index 0000000..0a25aa6 --- /dev/null +++ b/tools/llvm-c-test/llvm-c-test.h @@ -0,0 +1,37 @@ +/*===-- llvm-c-test.h - tool for testing libLLVM and llvm-c API -----------===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* Header file for llvm-c-test *| +|* *| +\*===----------------------------------------------------------------------===*/ +#ifndef LLVM_C_TEST_H +#define LLVM_C_TEST_H + +// helpers.c +void tokenize_stdin(void (*cb)(char **tokens, int ntokens)); + +// module.c +int module_dump(void); +int module_list_functions(void); +int module_list_globals(void); + +// calc.c +int calc(void); + +// disassemble.c +int disassemble(void); + +// object.c +int object_list_sections(void); +int object_list_symbols(void); + +// targets.c +int targets_list(void); + +#endif diff --git a/tools/llvm-c-test/main.c b/tools/llvm-c-test/main.c new file mode 100644 index 0000000..72f8b04 --- /dev/null +++ b/tools/llvm-c-test/main.c @@ -0,0 +1,73 @@ +/*===-- main.c - tool for testing libLLVM and llvm-c API ------------------===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* Main file for llvm-c-tests. "Parses" arguments and dispatches. *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#include "llvm-c-test.h" +#include "llvm-c/BitReader.h" +#include "llvm-c/Core.h" +#include +#include +#include + +static void print_usage(void) { + fprintf(stderr, "llvm-c-test command\n\n"); + fprintf(stderr, " Commands:\n"); + fprintf(stderr, " * --module-dump\n"); + fprintf(stderr, " Read bytecode from stdin - print disassembly\n\n"); + fprintf(stderr, " * --module-list-functions\n"); + fprintf(stderr, + " Read bytecode from stdin - list summary of functions\n\n"); + fprintf(stderr, " * --module-list-globals\n"); + fprintf(stderr, " Read bytecode from stdin - list summary of globals\n\n"); + fprintf(stderr, " * --targets-list\n"); + fprintf(stderr, " List available targets\n\n"); + fprintf(stderr, " * --object-list-sections\n"); + fprintf(stderr, " Read object file form stdin - list sections\n\n"); + fprintf(stderr, " * --object-list-symbols\n"); + fprintf(stderr, + " Read object file form stdin - list symbols (like nm)\n\n"); + fprintf(stderr, " * --disassemble\n"); + fprintf(stderr, " Read lines of triple, hex ascii machine code from stdin " + "- print disassembly\n\n"); + fprintf(stderr, " * --calc\n"); + fprintf( + stderr, + " Read lines of name, rpn from stdin - print generated module\n\n"); +} + +int main(int argc, char **argv) { + LLVMPassRegistryRef pr = LLVMGetGlobalPassRegistry(); + + LLVMInitializeCore(pr); + + if (argc == 2 && !strcmp(argv[1], "--module-dump")) { + return module_dump(); + } else if (argc == 2 && !strcmp(argv[1], "--module-list-functions")) { + return module_list_functions(); + } else if (argc == 2 && !strcmp(argv[1], "--module-list-globals")) { + return module_list_globals(); + } else if (argc == 2 && !strcmp(argv[1], "--targets-list")) { + return targets_list(); + } else if (argc == 2 && !strcmp(argv[1], "--object-list-sections")) { + return object_list_sections(); + } else if (argc == 2 && !strcmp(argv[1], "--object-list-symbols")) { + return object_list_symbols(); + } else if (argc == 2 && !strcmp(argv[1], "--disassemble")) { + return disassemble(); + } else if (argc == 2 && !strcmp(argv[1], "--calc")) { + return calc(); + } else { + print_usage(); + } + + return 1; +} diff --git a/tools/llvm-c-test/module.c b/tools/llvm-c-test/module.c new file mode 100644 index 0000000..50e6e9c --- /dev/null +++ b/tools/llvm-c-test/module.c @@ -0,0 +1,112 @@ +/*===-- module.c - tool for testing libLLVM and llvm-c API ----------------===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This file implements the --module-dump, --module-list-functions and *| +|* --module-list-globals commands in llvm-c-test. *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#include "llvm-c-test.h" +#include "llvm-c/BitReader.h" +#include "llvm-c/Core.h" +#include +#include +#include + +static LLVMModuleRef load_module(void) { + LLVMMemoryBufferRef MB; + LLVMModuleRef M; + char *msg = NULL; + + if (LLVMCreateMemoryBufferWithSTDIN(&MB, &msg)) { + fprintf(stderr, "Error reading file: %s\n", msg); + exit(1); + } + + if (LLVMParseBitcode(MB, &M, &msg)) { + fprintf(stderr, "Error parsing bitcode: %s\n", msg); + exit(1); + } + + return M; +} + +int module_dump(void) { + LLVMModuleRef M = load_module(); + + char *irstr = LLVMPrintModuleToString(M); + puts(irstr); + LLVMDisposeMessage(irstr); + + LLVMDisposeModule(M); + + return 0; +} + +int module_list_functions(void) { + LLVMModuleRef M = load_module(); + LLVMValueRef f; + + f = LLVMGetFirstFunction(M); + while (f) { + if (LLVMIsDeclaration(f)) { + printf("FunctionDeclaration: %s\n", LLVMGetValueName(f)); + } else { + unsigned nisn = 0; + unsigned nbb = 0; + + printf("FunctionDefinition: %s [#bb=%u]\n", LLVMGetValueName(f), + LLVMCountBasicBlocks(f)); + + for (LLVMBasicBlockRef bb = LLVMGetFirstBasicBlock(f); bb; + bb = LLVMGetNextBasicBlock(bb)) { + nbb++; + for (LLVMValueRef isn = LLVMGetFirstInstruction(bb); isn; + isn = LLVMGetNextInstruction(isn)) { + nisn++; + if (LLVMIsACallInst(isn)) { + LLVMValueRef callee = + LLVMGetOperand(isn, LLVMGetNumOperands(isn) - 1); + printf(" calls: %s\n", LLVMGetValueName(callee)); + } + } + } + printf(" #isn: %u\n", nisn); + printf(" #bb: %u\n\n", nbb); + } + f = LLVMGetNextFunction(f); + } + + LLVMDisposeModule(M); + + return 0; +} + +int module_list_globals(void) { + LLVMModuleRef M = load_module(); + LLVMValueRef g; + + g = LLVMGetFirstGlobal(M); + while (g) { + LLVMTypeRef T = LLVMTypeOf(g); + char *s = LLVMPrintTypeToString(T); + + printf("Global%s: %s %s\n", + LLVMIsDeclaration(g) ? "Declaration" : "Definition", + LLVMGetValueName(g), s); + + LLVMDisposeMessage(s); + + g = LLVMGetNextGlobal(g); + } + + LLVMDisposeModule(M); + + return 0; +} diff --git a/tools/llvm-c-test/object.c b/tools/llvm-c-test/object.c new file mode 100644 index 0000000..c94e3af --- /dev/null +++ b/tools/llvm-c-test/object.c @@ -0,0 +1,85 @@ +/*===-- object.c - tool for testing libLLVM and llvm-c API ----------------===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This file implements the --object-list-sections and --object-list-symbols *| +|* commands in llvm-c-test. *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#include "llvm-c-test.h" +#include "llvm-c/Object.h" +#include +#include + +int object_list_sections(void) { + LLVMMemoryBufferRef MB; + LLVMObjectFileRef O; + char *msg = NULL; + + if (LLVMCreateMemoryBufferWithSTDIN(&MB, &msg)) { + fprintf(stderr, "Error reading file: %s\n", msg); + exit(1); + } + + O = LLVMCreateObjectFile(MB); + if (!O) { + fprintf(stderr, "Error reading object\n"); + exit(1); + } + + LLVMSectionIteratorRef sect = LLVMGetSections(O); + while (!LLVMIsSectionIteratorAtEnd(O, sect)) { + printf("'%s': @0x%08" PRIx64 " +%" PRIu64 "\n", LLVMGetSectionName(sect), + LLVMGetSectionAddress(sect), LLVMGetSectionSize(sect)); + + LLVMMoveToNextSection(sect); + } + + LLVMDisposeSectionIterator(sect); + + LLVMDisposeObjectFile(O); + + return 0; +} + +int object_list_symbols(void) { + LLVMMemoryBufferRef MB; + LLVMObjectFileRef O; + char *msg = NULL; + + if (LLVMCreateMemoryBufferWithSTDIN(&MB, &msg)) { + fprintf(stderr, "Error reading file: %s\n", msg); + exit(1); + } + + O = LLVMCreateObjectFile(MB); + if (!O) { + fprintf(stderr, "Error reading object\n"); + exit(1); + } + + LLVMSectionIteratorRef sect = LLVMGetSections(O); + LLVMSymbolIteratorRef sym = LLVMGetSymbols(O); + 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), + LLVMGetSectionName(sect)); + + LLVMMoveToNextSymbol(sym); + } + + LLVMDisposeSymbolIterator(sym); + + LLVMDisposeObjectFile(O); + + return 0; +} diff --git a/tools/llvm-c-test/targets.c b/tools/llvm-c-test/targets.c new file mode 100644 index 0000000..fccea09 --- /dev/null +++ b/tools/llvm-c-test/targets.c @@ -0,0 +1,29 @@ +/*===-- targets.c - tool for testing libLLVM and llvm-c API ---------------===*\ +|* *| +|* The LLVM Compiler Infrastructure *| +|* *| +|* This file is distributed under the University of Illinois Open Source *| +|* License. See LICENSE.TXT for details. *| +|* *| +|*===----------------------------------------------------------------------===*| +|* *| +|* This file implements the --targets command in llvm-c-test. *| +|* *| +\*===----------------------------------------------------------------------===*/ + +#include "llvm-c/TargetMachine.h" +#include + +int targets_list(void) { + LLVMInitializeAllTargetInfos(); + LLVMInitializeAllTargets(); + + for (LLVMTargetRef t = LLVMGetFirstTarget(); t; t = LLVMGetNextTarget(t)) { + printf("%s", LLVMGetTargetName(t)); + if (LLVMTargetHasJIT(t)) + printf(" (+jit)"); + printf("\n - %s\n", LLVMGetTargetDescription(t)); + } + + return 0; +} -- cgit v1.1 From 90fd79a222652126ee7d85f3afb2cd85aa51b2f9 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 23 Oct 2013 17:56:37 +0000 Subject: llvm-c-test: Make them C89-compliant. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193254 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-c-test/calc.c | 15 ++++++++++----- tools/llvm-c-test/disassemble.c | 11 +++++++---- tools/llvm-c-test/module.c | 6 ++++-- tools/llvm-c-test/object.c | 9 ++++++--- tools/llvm-c-test/targets.c | 3 ++- 5 files changed, 29 insertions(+), 15 deletions(-) (limited to 'tools') diff --git a/tools/llvm-c-test/calc.c b/tools/llvm-c-test/calc.c index c34ff7b..3119ccf 100644 --- a/tools/llvm-c-test/calc.c +++ b/tools/llvm-c-test/calc.c @@ -44,8 +44,9 @@ static LLVMValueRef build_from_tokens(char **tokens, int ntokens, LLVMValueRef param) { LLVMValueRef stack[MAX_DEPTH]; int depth = 0; + int i; - for (int i = 0; i < ntokens; i++) { + for (i = 0; i < ntokens; i++) { char tok = tokens[i][0]; switch (tok) { case '+': @@ -66,16 +67,19 @@ static LLVMValueRef build_from_tokens(char **tokens, int ntokens, break; - case '@': + case '@': { + LLVMValueRef off; + if (depth < 1) { printf("stack underflow\n"); return NULL; } - LLVMValueRef off = LLVMBuildGEP(builder, param, &stack[depth - 1], 1, ""); + off = LLVMBuildGEP(builder, param, &stack[depth - 1], 1, ""); stack[depth - 1] = LLVMBuildLoad(builder, off, ""); break; + } default: { char *end; @@ -108,6 +112,8 @@ static LLVMValueRef build_from_tokens(char **tokens, int ntokens, static void handle_line(char **tokens, int ntokens) { char *name = tokens[0]; + LLVMValueRef param; + LLVMValueRef res; LLVMModuleRef M = LLVMModuleCreateWithName(name); @@ -119,11 +125,10 @@ static void handle_line(char **tokens, int ntokens) { LLVMBuilderRef builder = LLVMCreateBuilder(); LLVMPositionBuilderAtEnd(builder, LLVMAppendBasicBlock(F, "entry")); - LLVMValueRef param; LLVMGetParams(F, ¶m); LLVMSetValueName(param, "in"); - LLVMValueRef res = build_from_tokens(tokens + 1, ntokens - 1, builder, param); + res = build_from_tokens(tokens + 1, ntokens - 1, builder, param); if (res) { char *irstr = LLVMPrintModuleToString(M); puts(irstr); diff --git a/tools/llvm-c-test/disassemble.c b/tools/llvm-c-test/disassemble.c index 4b3d37b..eb40bf3 100644 --- a/tools/llvm-c-test/disassemble.c +++ b/tools/llvm-c-test/disassemble.c @@ -20,8 +20,9 @@ #include static void pprint(int pos, unsigned char *buf, int len, const char *disasm) { + int i; printf("%04x: ", pos); - for (int i = 0; i < 8; i++) { + for (i = 0; i < 8; i++) { if (i < len) { printf("%02x ", buf[i]); } else { @@ -34,14 +35,15 @@ static void pprint(int pos, unsigned char *buf, int len, const char *disasm) { static void do_disassemble(const char *triple, unsigned char *buf, int siz) { LLVMDisasmContextRef D = LLVMCreateDisasm(triple, NULL, 0, NULL, NULL); + char outline[1024]; + int pos; if (!D) { printf("ERROR: Couldn't create disassebler for triple %s\n", triple); return; } - char outline[1024]; - int pos = 0; + pos = 0; while (pos < siz) { size_t l = LLVMDisasmInstruction(D, buf + pos, siz - pos, 0, outline, sizeof(outline)); @@ -61,10 +63,11 @@ static void handle_line(char **tokens, int ntokens) { unsigned char disbuf[128]; size_t disbuflen = 0; char *triple = tokens[0]; + int i; printf("triple: %s\n", triple); - for (int i = 1; i < ntokens; i++) { + for (i = 1; i < ntokens; i++) { disbuf[disbuflen++] = strtol(tokens[i], NULL, 16); if (disbuflen >= sizeof(disbuf)) { fprintf(stderr, "Warning: Too long line, truncating\n"); diff --git a/tools/llvm-c-test/module.c b/tools/llvm-c-test/module.c index 50e6e9c..1802386 100644 --- a/tools/llvm-c-test/module.c +++ b/tools/llvm-c-test/module.c @@ -58,16 +58,18 @@ int module_list_functions(void) { if (LLVMIsDeclaration(f)) { printf("FunctionDeclaration: %s\n", LLVMGetValueName(f)); } else { + LLVMBasicBlockRef bb; + LLVMValueRef isn; unsigned nisn = 0; unsigned nbb = 0; printf("FunctionDefinition: %s [#bb=%u]\n", LLVMGetValueName(f), LLVMCountBasicBlocks(f)); - for (LLVMBasicBlockRef bb = LLVMGetFirstBasicBlock(f); bb; + for (bb = LLVMGetFirstBasicBlock(f); bb; bb = LLVMGetNextBasicBlock(bb)) { nbb++; - for (LLVMValueRef isn = LLVMGetFirstInstruction(bb); isn; + for (isn = LLVMGetFirstInstruction(bb); isn; isn = LLVMGetNextInstruction(isn)) { nisn++; if (LLVMIsACallInst(isn)) { diff --git a/tools/llvm-c-test/object.c b/tools/llvm-c-test/object.c index c94e3af..2792928 100644 --- a/tools/llvm-c-test/object.c +++ b/tools/llvm-c-test/object.c @@ -20,6 +20,7 @@ int object_list_sections(void) { LLVMMemoryBufferRef MB; LLVMObjectFileRef O; + LLVMSectionIteratorRef sect; char *msg = NULL; if (LLVMCreateMemoryBufferWithSTDIN(&MB, &msg)) { @@ -33,7 +34,7 @@ int object_list_sections(void) { exit(1); } - LLVMSectionIteratorRef sect = LLVMGetSections(O); + sect = LLVMGetSections(O); while (!LLVMIsSectionIteratorAtEnd(O, sect)) { printf("'%s': @0x%08" PRIx64 " +%" PRIu64 "\n", LLVMGetSectionName(sect), LLVMGetSectionAddress(sect), LLVMGetSectionSize(sect)); @@ -51,6 +52,8 @@ int object_list_sections(void) { int object_list_symbols(void) { LLVMMemoryBufferRef MB; LLVMObjectFileRef O; + LLVMSectionIteratorRef sect; + LLVMSymbolIteratorRef sym; char *msg = NULL; if (LLVMCreateMemoryBufferWithSTDIN(&MB, &msg)) { @@ -64,8 +67,8 @@ int object_list_symbols(void) { exit(1); } - LLVMSectionIteratorRef sect = LLVMGetSections(O); - LLVMSymbolIteratorRef sym = LLVMGetSymbols(O); + sect = LLVMGetSections(O); + sym = LLVMGetSymbols(O); while (!LLVMIsSymbolIteratorAtEnd(O, sym)) { LLVMMoveToContainingSection(sect, sym); diff --git a/tools/llvm-c-test/targets.c b/tools/llvm-c-test/targets.c index fccea09..252c2e0 100644 --- a/tools/llvm-c-test/targets.c +++ b/tools/llvm-c-test/targets.c @@ -15,10 +15,11 @@ #include int targets_list(void) { + LLVMTargetRef t; LLVMInitializeAllTargetInfos(); LLVMInitializeAllTargets(); - for (LLVMTargetRef t = LLVMGetFirstTarget(); t; t = LLVMGetNextTarget(t)) { + for (t = LLVMGetFirstTarget(); t; t = LLVMGetNextTarget(t)) { printf("%s", LLVMGetTargetName(t)); if (LLVMTargetHasJIT(t)) printf(" (+jit)"); -- cgit v1.1 From 266acb9fee5bcb760d9dffe2afc10d62bb86b0e1 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 23 Oct 2013 17:56:46 +0000 Subject: llvm-c/lto.h: Avoid use of bool. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193255 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/lto.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index a3acd4c..ff3e308 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -90,26 +90,26 @@ const char* lto_get_error_message() { } /// lto_module_is_object_file - Validates if a file is a loadable object file. -bool lto_module_is_object_file(const char* path) { +int 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, +int 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) { +int 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 +int lto_module_is_object_file_in_memory_for_target(const void* mem, size_t length, const char* target_triplet_prefix) { @@ -216,21 +216,21 @@ void lto_codegen_dispose(lto_code_gen_t 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) { +int lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod) { return !cg->addModule(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) { +int lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model debug) { 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) { +int lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model model) { cg->setCodePICModel(model); return false; } @@ -267,7 +267,7 @@ void lto_codegen_add_dso_symbol(lto_code_gen_t cg, const char *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) { +int lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) { if (!parsedOptions) { cg->parseCodeGenDebugOptions(); parsedOptions = true; @@ -293,7 +293,7 @@ const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) { /// 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) { +int lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) { if (!parsedOptions) { cg->parseCodeGenDebugOptions(); parsedOptions = true; -- cgit v1.1 From 44c23939cf8d0f6bd77c1ee8cae5a1d13ad10f40 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 23 Oct 2013 17:56:59 +0000 Subject: llvm/tools/llvm-c-test should be built also on msvc. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193257 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/CMakeLists.txt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'tools') diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 54f849c..12e10fd 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -39,11 +39,7 @@ add_llvm_tool_subdirectory(llvm-mcmarkup) add_llvm_tool_subdirectory(llvm-symbolizer) -if( NOT MSVC ) - add_llvm_tool_subdirectory(llvm-c-test) -else() - ignore_llvm_tool_subdirectory(llvm-c-test) -endif( NOT MSVC ) +add_llvm_tool_subdirectory(llvm-c-test) add_llvm_tool_subdirectory(obj2yaml) add_llvm_tool_subdirectory(yaml2obj) -- cgit v1.1 From 07d5aef3057b2e403b20d683e7477c93fde67d99 Mon Sep 17 00:00:00 2001 From: Reid Kleckner Date: Thu, 24 Oct 2013 22:26:04 +0000 Subject: lto.h: Use lto_bool_t instead of int to restore the ABI This reverts commit r193255 and instead creates an lto_bool_t typedef that points to bool, _Bool, or unsigned char depending on what is available. Only recent versions of MSVC provide a stdbool.h header. Reviewers: rafael.espindola Differential Revision: http://llvm-reviews.chandlerc.com/D2019 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193377 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/lto.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'tools') diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index ff3e308..a3acd4c 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -90,26 +90,26 @@ const char* lto_get_error_message() { } /// lto_module_is_object_file - Validates if a file is a loadable object file. -int lto_module_is_object_file(const char* path) { +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. -int lto_module_is_object_file_for_target(const char* path, +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. -int lto_module_is_object_file_in_memory(const void* mem, size_t length) { +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. -int +bool lto_module_is_object_file_in_memory_for_target(const void* mem, size_t length, const char* target_triplet_prefix) { @@ -216,21 +216,21 @@ void lto_codegen_dispose(lto_code_gen_t 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). -int lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod) { +bool lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod) { return !cg->addModule(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). -int lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model debug) { +bool lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model debug) { 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). -int lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model model) { +bool lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model model) { cg->setCodePICModel(model); return false; } @@ -267,7 +267,7 @@ void lto_codegen_add_dso_symbol(lto_code_gen_t cg, const char *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). -int lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) { +bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) { if (!parsedOptions) { cg->parseCodeGenDebugOptions(); parsedOptions = true; @@ -293,7 +293,7 @@ const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) { /// 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. -int lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) { +bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) { if (!parsedOptions) { cg->parseCodeGenDebugOptions(); parsedOptions = true; -- cgit v1.1 From 50c5b4680d0a3d1341f0b0d441c7b5dd4e5cd732 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Fri, 25 Oct 2013 15:58:58 +0000 Subject: llvm-c-test: Don't leak memory buffers. Detected by valgrind. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193416 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-c-test/module.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'tools') diff --git a/tools/llvm-c-test/module.c b/tools/llvm-c-test/module.c index 1802386..2661fc8 100644 --- a/tools/llvm-c-test/module.c +++ b/tools/llvm-c-test/module.c @@ -31,9 +31,11 @@ static LLVMModuleRef load_module(void) { if (LLVMParseBitcode(MB, &M, &msg)) { fprintf(stderr, "Error parsing bitcode: %s\n", msg); + LLVMDisposeMemoryBuffer(MB); exit(1); } + LLVMDisposeMemoryBuffer(MB); return M; } -- cgit v1.1 From 69f4280b5451071285700eb5bb5c38beb4336048 Mon Sep 17 00:00:00 2001 From: Daniel Sanders Date: Fri, 25 Oct 2013 17:41:41 +0000 Subject: [bugpoint] Increase the default memory limit for subprocesses to 300MB. Summary: Currently shared library builds (BUILD_SHARED_LIBS=ON in cmake) fail three bugpoint tests (BugPoint/remove_arguments_test.ll, BugPoint/crash-narrowfunctiontest.ll, and BugPoint/metadata.ll). If I run the bugpoint commands that llvm-lit runs with without -silence-passes I see errors such as this: opt: error while loading shared libraries: libLLVMSystemZInfo.so: failed to map segment from shared object: Cannot allocate memory It seems that the increased size of the binaries in a shared library build is causing the subprocess to exceed the 100MB memory limit. This patch therefore increases the default limit to a level at which these tests pass. Reviewers: dsanders Reviewed By: dsanders CC: llvm-commits, rafael Differential Revision: http://llvm-reviews.chandlerc.com/D2013 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193420 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/bugpoint/bugpoint.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/bugpoint/bugpoint.cpp b/tools/bugpoint/bugpoint.cpp index 5e8fdd1..9bc592e 100644 --- a/tools/bugpoint/bugpoint.cpp +++ b/tools/bugpoint/bugpoint.cpp @@ -49,8 +49,8 @@ TimeoutValue("timeout", cl::init(300), cl::value_desc("seconds"), static cl::opt MemoryLimit("mlimit", cl::init(-1), cl::value_desc("MBytes"), - cl::desc("Maximum amount of memory to use. 0 disables check." - " Defaults to 100MB (800MB under valgrind).")); + cl::desc("Maximum amount of memory to use. 0 disables check." + " Defaults to 300MB (800MB under valgrind).")); static cl::opt UseValgrind("enable-valgrind", @@ -152,7 +152,7 @@ int main(int argc, char **argv) { if (sys::RunningOnValgrind() || UseValgrind) MemoryLimit = 800; else - MemoryLimit = 100; + MemoryLimit = 300; } BugDriver D(argv[0], FindBugs, TimeoutValue, MemoryLimit, -- cgit v1.1 From 2d60c0945102e6887fcdc752a7b714546afae354 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sat, 26 Oct 2013 13:52:31 +0000 Subject: lli/RemoteMemoryManager.cpp: Resurrect __main stuff removed in r192504 to unbreak mingw32. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193472 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/RemoteMemoryManager.cpp | 16 ++++++++++++++++ tools/lli/RemoteMemoryManager.h | 2 +- 2 files changed, 17 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lli/RemoteMemoryManager.cpp b/tools/lli/RemoteMemoryManager.cpp index 04fc40e..f730f09 100644 --- a/tools/lli/RemoteMemoryManager.cpp +++ b/tools/lli/RemoteMemoryManager.cpp @@ -204,3 +204,19 @@ uint8_t *RemoteMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment) void RemoteMemoryManager::deallocateFunctionBody(void *Body) { llvm_unreachable("Unexpected!"); } + +static int jit_noop() { + return 0; +} + +uint64_t RemoteMemoryManager::getSymbolAddress(const std::string &Name) { + // We should not invoke parent's ctors/dtors from generated main()! + // On Mingw and Cygwin, the symbol __main is resolved to + // callee's(eg. tools/lli) one, to invoke wrong duplicated ctors + // (and register wrong callee's dtors with atexit(3)). + // We expect ExecutionEngine::runStaticConstructorsDestructors() + // is called before ExecutionEngine::runFunctionAsMain() is called. + if (Name == "__main") return (uintptr_t)&jit_noop; + + return 0; +} diff --git a/tools/lli/RemoteMemoryManager.h b/tools/lli/RemoteMemoryManager.h index 5d0456f..3368b30 100644 --- a/tools/lli/RemoteMemoryManager.h +++ b/tools/lli/RemoteMemoryManager.h @@ -78,7 +78,7 @@ public: // interface does support this, but clients must provide their own // mechanism for finding remote symbol addresses. MCJIT will resolve // symbols from Modules it contains. - uint64_t getSymbolAddress(const std::string &Name) { return 0; } + uint64_t getSymbolAddress(const std::string &Name); void notifyObjectLoaded(ExecutionEngine *EE, const ObjectImage *Obj); -- cgit v1.1 From f61049b2d8aa19341c32b0dbe67c272b30e078d3 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sun, 27 Oct 2013 10:22:52 +0000 Subject: MCJIT-remote: __main should be resolved in child context. - Mark tests as XFAIL:cygming in test/ExecutionEngine/MCJIT/remote. Rather to suppress them, I'd like to leave them running as XFAIL. - Revert r193472. RecordMemoryManager no longer resolves __main on cygming. There are a couple of issues. - X86 Codegen emits "call __main" in @main for targeting cygming. It is useless in JIT. FYI, tests are passing when emitting __main is disabled. - Current remote JIT does not resolve any symbols in child context. FIXME: __main should be disabled, or remote JIT should resolve __main. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193498 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/RemoteMemoryManager.cpp | 16 ---------------- tools/lli/RemoteMemoryManager.h | 2 +- 2 files changed, 1 insertion(+), 17 deletions(-) (limited to 'tools') diff --git a/tools/lli/RemoteMemoryManager.cpp b/tools/lli/RemoteMemoryManager.cpp index f730f09..04fc40e 100644 --- a/tools/lli/RemoteMemoryManager.cpp +++ b/tools/lli/RemoteMemoryManager.cpp @@ -204,19 +204,3 @@ uint8_t *RemoteMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment) void RemoteMemoryManager::deallocateFunctionBody(void *Body) { llvm_unreachable("Unexpected!"); } - -static int jit_noop() { - return 0; -} - -uint64_t RemoteMemoryManager::getSymbolAddress(const std::string &Name) { - // We should not invoke parent's ctors/dtors from generated main()! - // On Mingw and Cygwin, the symbol __main is resolved to - // callee's(eg. tools/lli) one, to invoke wrong duplicated ctors - // (and register wrong callee's dtors with atexit(3)). - // We expect ExecutionEngine::runStaticConstructorsDestructors() - // is called before ExecutionEngine::runFunctionAsMain() is called. - if (Name == "__main") return (uintptr_t)&jit_noop; - - return 0; -} diff --git a/tools/lli/RemoteMemoryManager.h b/tools/lli/RemoteMemoryManager.h index 3368b30..5d0456f 100644 --- a/tools/lli/RemoteMemoryManager.h +++ b/tools/lli/RemoteMemoryManager.h @@ -78,7 +78,7 @@ public: // interface does support this, but clients must provide their own // mechanism for finding remote symbol addresses. MCJIT will resolve // symbols from Modules it contains. - uint64_t getSymbolAddress(const std::string &Name); + uint64_t getSymbolAddress(const std::string &Name) { return 0; } void notifyObjectLoaded(ExecutionEngine *EE, const ObjectImage *Obj); -- cgit v1.1 From 61abf1550f6b12b066c959512ab10ce0720df207 Mon Sep 17 00:00:00 2001 From: Andrew Kaylor Date: Mon, 28 Oct 2013 21:58:15 +0000 Subject: Standardizing lli's extra module command line option git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193544 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/lli.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index 7117707..6425142 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -132,8 +132,7 @@ namespace { cl::init("main")); cl::list - ExtraModules("extra-modules", - cl::CommaSeparated, + ExtraModules("extra-module", cl::desc("Extra modules to be loaded"), cl::value_desc(",,...")); -- cgit v1.1 From 730e3c69952d4f26a0c51b55902ac55c88238ee8 Mon Sep 17 00:00:00 2001 From: Alp Toker Date: Mon, 28 Oct 2013 22:51:25 +0000 Subject: Fix the lli --extra-module value_desc git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193552 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/lli.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index 6425142..9e0a78f 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -134,7 +134,7 @@ namespace { cl::list ExtraModules("extra-module", cl::desc("Extra modules to be loaded"), - cl::value_desc(",,...")); + cl::value_desc("input bitcode")); cl::opt FakeArgv0("fake-argv0", -- cgit v1.1 From 47b7fd54481d25aff90bfe772d54435bbea0908f Mon Sep 17 00:00:00 2001 From: Andrew Kaylor Date: Tue, 29 Oct 2013 01:29:56 +0000 Subject: Adding a workaround for __main linking with remote lli and Cygwin/MinGW git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193570 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/lli.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'tools') diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index 9e0a78f..808a95a 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -27,8 +27,10 @@ #include "llvm/ExecutionEngine/JITMemoryManager.h" #include "llvm/ExecutionEngine/MCJIT.h" #include "llvm/ExecutionEngine/SectionMemoryManager.h" +#include "llvm/IR/IRBuilder.h" #include "llvm/IR/Module.h" #include "llvm/IR/Type.h" +#include "llvm/IR/TypeBuilder.h" #include "llvm/IRReader/IRReader.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Debug.h" @@ -227,6 +229,46 @@ static void do_shutdown() { #endif } +// On Mingw and Cygwin, an external symbol named '__main' is called from the +// generated 'main' function to allow static intialization. To avoid linking +// problems with remote targets (because lli's remote target support does not +// currently handle external linking) we add a secondary module which defines +// an empty '__main' function. +static void addCygMingExtraModule(ExecutionEngine *EE, + LLVMContext &Context, + StringRef TargetTripleStr) { + IRBuilder<> Builder(Context); + Triple TargetTriple(TargetTripleStr); + + // Create a new module. + Module *M = new Module("CygMingHelper", Context); + M->setTargetTriple(TargetTripleStr); + + // Create an empty function named "__main". + Function *Result; + if (TargetTriple.isArch64Bit()) { + Result = Function::Create( + TypeBuilder::get(Context), + GlobalValue::ExternalLinkage, "__main", M); + } else { + Result = Function::Create( + TypeBuilder::get(Context), + GlobalValue::ExternalLinkage, "__main", M); + } + BasicBlock *BB = BasicBlock::Create(Context, "__main", Result); + Builder.SetInsertPoint(BB); + Value *ReturnVal; + if (TargetTriple.isArch64Bit()) + ReturnVal = ConstantInt::get(Context, APInt(64, 0)); + else + ReturnVal = ConstantInt::get(Context, APInt(32, 0)); + Builder.CreateRet(ReturnVal); + + // Add this new module to the ExecutionEngine. + EE->addModule(M); +} + + //===----------------------------------------------------------------------===// // main Driver function // @@ -359,6 +401,12 @@ int main(int argc, char **argv, char * const *envp) { EE->addModule(XMod); } + // If the target is Cygwin/MingW and we are generating remote code, we + // need an extra module to help out with linking. + if (RemoteMCJIT && Triple(Mod->getTargetTriple()).isOSCygMing()) { + addCygMingExtraModule(EE, Context, Mod->getTargetTriple()); + } + // The following functions have no effect if their respective profiling // support wasn't enabled in the build configuration. EE->RegisterJITEventListener( -- cgit v1.1 From 5f7a5773e679107565f9da79c26bb558d5e9c051 Mon Sep 17 00:00:00 2001 From: Andrew Kaylor Date: Tue, 29 Oct 2013 01:33:14 +0000 Subject: Cleaning up comments in lli git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193571 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lli/lli.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index 808a95a..f317566 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -88,8 +88,8 @@ namespace { // Manually specify the child process for remote execution. This overrides // the simulated remote execution that allocates address space for child - // execution. The child process resides in the disk and communicates with lli - // via stdin/stdout pipes. + // execution. The child process will be executed and will communicate with + // lli via stdin/stdout pipes. cl::opt MCJITRemoteProcess("mcjit-remote-process", cl::desc("Specify the filename of the process to launch " -- cgit v1.1 From 54818dc7466861623971ebc793d8afe48bd58e4f Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Tue, 29 Oct 2013 14:25:43 +0000 Subject: Support names like llvm-ar-3.4 and llvm-ranlib-3.4. They are used in some packages. For example: http://packages.ubuntu.com/saucy/i386/llvm-3.4/filelist This fixes pr17721. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193612 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-ar/llvm-ar.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp index e56e49ad..64ef3fa 100644 --- a/tools/llvm-ar/llvm-ar.cpp +++ b/tools/llvm-ar/llvm-ar.cpp @@ -877,9 +877,9 @@ int main(int argc, char **argv) { ); StringRef Stem = sys::path::stem(ToolName); - if (Stem.endswith("ar")) + if (Stem.find("ar") != StringRef::npos) return ar_main(argv); - if (Stem.endswith("ranlib")) + if (Stem.find("ranlib") != StringRef::npos) return ranlib_main(); fail("Not ranlib or ar!"); } -- cgit v1.1 From 93324a6793ca9bef558162a260160fd210a5e6e3 Mon Sep 17 00:00:00 2001 From: Yuchen Wu Date: Thu, 31 Oct 2013 02:01:24 +0000 Subject: Updated llvm-cov's OVERVIEW description git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193732 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-cov/llvm-cov.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/llvm-cov/llvm-cov.cpp b/tools/llvm-cov/llvm-cov.cpp index 26aec46..4a69c71 100644 --- a/tools/llvm-cov/llvm-cov.cpp +++ b/tools/llvm-cov/llvm-cov.cpp @@ -38,7 +38,7 @@ int main(int argc, char **argv) { PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - cl::ParseCommandLineOptions(argc, argv, "llvm cov\n"); + cl::ParseCommandLineOptions(argc, argv, "llvm coverage tool\n"); GCOVFile GF; if (InputGCNO.empty()) -- cgit v1.1 From 90f9b8a7bcd02b154a0c068c0589171b43ffba8d Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 31 Oct 2013 14:35:00 +0000 Subject: Rules adjustments in order to build on DragonFly BSD. Patch by Robin Hahling. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193750 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-shlib/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/llvm-shlib/Makefile b/tools/llvm-shlib/Makefile index 1d9053b..92f3132 100644 --- a/tools/llvm-shlib/Makefile +++ b/tools/llvm-shlib/Makefile @@ -62,13 +62,13 @@ ifeq ($(HOST_OS),Darwin) endif endif -ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux FreeBSD GNU/kFreeBSD OpenBSD GNU Bitrig)) +ifeq ($(HOST_OS), $(filter $(HOST_OS), DragonFly Linux FreeBSD GNU/kFreeBSD OpenBSD GNU Bitrig)) # Include everything from the .a's into the shared library. LLVMLibsOptions := -Wl,--whole-archive $(LLVMLibsOptions) \ -Wl,--no-whole-archive endif -ifeq ($(HOST_OS), $(filter $(HOST_OS), Linux FreeBSD GNU/kFreeBSD GNU)) +ifeq ($(HOST_OS), $(filter $(HOST_OS), DragonFly Linux FreeBSD GNU/kFreeBSD GNU)) # Add soname to the library. LLVMLibsOptions += -Wl,--soname,lib$(LIBRARYNAME)$(SHLIBEXT) endif -- cgit v1.1 From 7e667c56cf7e27ff521ceb86518beab32bfb630d Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Thu, 31 Oct 2013 20:51:58 +0000 Subject: Use LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN instead of the "dso list". There are two ways one could implement hiding of linkonce_odr symbols in LTO: * LLVM tells the linker which symbols can be hidden if not used from native files. * The linker tells LLVM which symbols are not used from other object files, but will be put in the dso symbol table if present. GOLD's API is the second option. It was implemented almost 1:1 in llvm by passing the list down to internalize. LLVM already had partial support for the first option. It is also very similar to how ld64 handles hiding these symbols when *not* doing LTO. This patch then * removes the APIs for the DSO list. * marks LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN all linkonce_odr unnamed_addr global values and other linkonce_odr whose address is not used. * makes the gold plugin responsible for handling the API mismatch. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193800 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/gold/gold-plugin.cpp | 21 +++++++++++++++------ tools/llvm-lto/llvm-lto.cpp | 28 ++++++++++++++++++++++++++-- tools/lto/lto.cpp | 4 ---- tools/lto/lto.exports | 1 - 4 files changed, 41 insertions(+), 13 deletions(-) (limited to 'tools') diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp index 360ec07..0e3bad2 100644 --- a/tools/gold/gold-plugin.cpp +++ b/tools/gold/gold-plugin.cpp @@ -15,6 +15,7 @@ #include "llvm/Config/config.h" // plugin-api.h requires HAVE_STDINT_H #include "plugin-api.h" #include "llvm-c/lto.h" +#include "llvm/ADT/StringSet.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Support/Errno.h" #include "llvm/Support/FileSystem.h" @@ -67,6 +68,7 @@ namespace { std::list Modules; std::vector Cleanup; lto_code_gen_t code_gen = NULL; + StringSet<> CannotBeHidden; } namespace options { @@ -297,6 +299,9 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, sym.version = NULL; int scope = attrs & LTO_SYMBOL_SCOPE_MASK; + bool CanBeHidden = scope == LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN; + if (!CanBeHidden) + CannotBeHidden.insert(sym.name); switch (scope) { case LTO_SYMBOL_SCOPE_HIDDEN: sym.visibility = LDPV_HIDDEN; @@ -306,6 +311,7 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, break; case 0: // extern case LTO_SYMBOL_SCOPE_DEFAULT: + case LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN: sym.visibility = LDPV_DEFAULT; break; default: @@ -364,6 +370,14 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, return LDPS_OK; } +static bool mustPreserve(const claimed_file &F, int i) { + if (F.syms[i].resolution == LDPR_PREVAILING_DEF) + return true; + if (F.syms[i].resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) + return CannotBeHidden.count(F.syms[i].name); + return false; +} + /// all_symbols_read_hook - gold informs us that all symbols have been read. /// At this point, we use get_symbols to see if any of our definitions have /// been overridden by a native object file. Then, perform optimization and @@ -386,16 +400,11 @@ static ld_plugin_status all_symbols_read_hook(void) { continue; (*get_symbols)(I->handle, I->syms.size(), &I->syms[0]); for (unsigned i = 0, e = I->syms.size(); i != e; i++) { - if (I->syms[i].resolution == LDPR_PREVAILING_DEF) { + if (mustPreserve(*I, i)) { lto_codegen_add_must_preserve_symbol(code_gen, I->syms[i].name); if (options::generate_api_file) api_file << I->syms[i].name << "\n"; - } else if (I->syms[i].resolution == LDPR_PREVAILING_DEF_IRONLY_EXP) { - lto_codegen_add_dso_symbol(code_gen, I->syms[i].name); - - if (options::generate_api_file) - api_file << I->syms[i].name << " dso only\n"; } } } diff --git a/tools/llvm-lto/llvm-lto.cpp b/tools/llvm-lto/llvm-lto.cpp index bce903f..0fc68ae 100644 --- a/tools/llvm-lto/llvm-lto.cpp +++ b/tools/llvm-lto/llvm-lto.cpp @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/StringSet.h" #include "llvm/CodeGen/CommandFlags.h" #include "llvm/LTO/LTOCodeGenerator.h" #include "llvm/LTO/LTOModule.h" @@ -55,6 +56,12 @@ DSOSymbols("dso-symbol", cl::desc("Symbol to put in the symtab in the resulting dso"), cl::ZeroOrMore); +namespace { +struct ModuleInfo { + std::vector CanBeHidden; +}; +} + int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); @@ -99,6 +106,12 @@ int main(int argc, char **argv) { CodeGen.setDebugInfo(LTO_DEBUG_MODEL_DWARF); CodeGen.setTargetOptions(Options); + llvm::StringSet DSOSymbolsSet; + for (unsigned i = 0; i < DSOSymbols.size(); ++i) + DSOSymbolsSet.insert(DSOSymbols[i]); + + std::vector KeptDSOSyms; + for (unsigned i = BaseArg; i < InputFilenames.size(); ++i) { std::string error; OwningPtr Module(LTOModule::makeLTOModule(InputFilenames[i].c_str(), @@ -115,6 +128,17 @@ int main(int argc, char **argv) { << "': " << error << "\n"; return 1; } + + unsigned NumSyms = Module->getSymbolCount(); + for (unsigned I = 0; I < NumSyms; ++I) { + StringRef Name = Module->getSymbolName(I); + if (!DSOSymbolsSet.count(Name)) + continue; + lto_symbol_attributes Attrs = Module->getSymbolAttributes(I); + unsigned Scope = Attrs & LTO_SYMBOL_SCOPE_MASK; + if (Scope != LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN) + KeptDSOSyms.push_back(Name); + } } // Add all the exported symbols to the table of symbols to preserve. @@ -122,8 +146,8 @@ int main(int argc, char **argv) { CodeGen.addMustPreserveSymbol(ExportedSymbols[i].c_str()); // Add all the dso symbols to the table of symbols to expose. - for (unsigned i = 0; i < DSOSymbols.size(); ++i) - CodeGen.addDSOSymbol(DSOSymbols[i].c_str()); + for (unsigned i = 0; i < KeptDSOSyms.size(); ++i) + CodeGen.addMustPreserveSymbol(KeptDSOSyms[i].c_str()); if (!OutputFilename.empty()) { size_t len = 0; diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index a3acd4c..7bfddcd 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -260,10 +260,6 @@ void lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, cg->addMustPreserveSymbol(symbol); } -void lto_codegen_add_dso_symbol(lto_code_gen_t cg, const char *symbol) { - cg->addDSOSymbol(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). diff --git a/tools/lto/lto.exports b/tools/lto/lto.exports index c0e220b..46d0d74 100644 --- a/tools/lto/lto.exports +++ b/tools/lto/lto.exports @@ -15,7 +15,6 @@ lto_module_is_object_file_for_target lto_module_is_object_file_in_memory lto_module_is_object_file_in_memory_for_target lto_module_dispose -lto_codegen_add_dso_symbol lto_codegen_add_module lto_codegen_add_must_preserve_symbol lto_codegen_compile -- cgit v1.1 From daaa8b720b026c83bf6d4307042057665348b222 Mon Sep 17 00:00:00 2001 From: Yuchen Wu Date: Sat, 2 Nov 2013 00:09:17 +0000 Subject: Added command-line option to output llvm-cov to file. Added -o option to llvm-cov. If no output file is specified, it defaults to STDOUT. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193899 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-cov/llvm-cov.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/llvm-cov/llvm-cov.cpp b/tools/llvm-cov/llvm-cov.cpp index 4a69c71..ad6c671 100644 --- a/tools/llvm-cov/llvm-cov.cpp +++ b/tools/llvm-cov/llvm-cov.cpp @@ -17,6 +17,7 @@ #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryObject.h" #include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Support/Signals.h" #include "llvm/Support/system_error.h" using namespace llvm; @@ -30,6 +31,9 @@ InputGCNO("gcno", cl::desc(""), cl::init("")); static cl::opt InputGCDA("gcda", cl::desc(""), cl::init("")); +static cl::opt +OutputFile("o", cl::desc(""), cl::init("-")); + //===----------------------------------------------------------------------===// int main(int argc, char **argv) { @@ -40,6 +44,11 @@ int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, "llvm coverage tool\n"); + std::string ErrorInfo; + raw_fd_ostream OS(OutputFile.c_str(), ErrorInfo); + if (!ErrorInfo.empty()) + errs() << ErrorInfo << "\n"; + GCOVFile GF; if (InputGCNO.empty()) errs() << " " << argv[0] << ": No gcov input file!\n"; @@ -74,6 +83,6 @@ int main(int argc, char **argv) { FileInfo FI; GF.collectLineCounts(FI); - FI.print(InputGCNO, InputGCDA); + FI.print(OS, InputGCNO, InputGCDA); return 0; } -- cgit v1.1 From bc884fd9f7bdb64d250be639edc8dc85a20a1975 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 2 Nov 2013 21:16:09 +0000 Subject: move getSymbolNMTypeChar to the one program that needs it: nm. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193933 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-nm/llvm-nm.cpp | 225 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 224 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index 01dd1c3..8449c29 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -20,6 +20,9 @@ #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/IR/Module.h" #include "llvm/Object/Archive.h" +#include "llvm/Object/COFF.h" +#include "llvm/Object/ELFObjectFile.h" +#include "llvm/Object/MachO.h" #include "llvm/Object/MachOUniversal.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/CommandLine.h" @@ -303,6 +306,226 @@ static void DumpSymbolNamesFromModule(Module *M) { SortAndPrintSymbolList(); } +template +error_code getSymbolNMTypeChar(ELFObjectFile &Obj, symbol_iterator I, + char &Result) { + typedef typename ELFObjectFile::Elf_Sym Elf_Sym; + typedef typename ELFObjectFile::Elf_Shdr Elf_Shdr; + + DataRefImpl Symb = I->getRawDataRefImpl(); + const Elf_Sym *ESym = Obj.getSymbol(Symb); + const ELFFile &EF = *Obj.getELFFile(); + const Elf_Shdr *ESec = EF.getSection(ESym); + + char ret = '?'; + + if (ESec) { + switch (ESec->sh_type) { + case ELF::SHT_PROGBITS: + case ELF::SHT_DYNAMIC: + switch (ESec->sh_flags) { + case(ELF::SHF_ALLOC | ELF::SHF_EXECINSTR) : + ret = 't'; + break; + case(ELF::SHF_ALLOC | ELF::SHF_WRITE) : + ret = 'd'; + break; + case ELF::SHF_ALLOC: + case(ELF::SHF_ALLOC | ELF::SHF_MERGE) : + case(ELF::SHF_ALLOC | ELF::SHF_MERGE | ELF::SHF_STRINGS) : + ret = 'r'; + break; + } + break; + case ELF::SHT_NOBITS: + ret = 'b'; + } + } + + switch (EF.getSymbolTableIndex(ESym)) { + case ELF::SHN_UNDEF: + if (ret == '?') + ret = 'U'; + break; + case ELF::SHN_ABS: + ret = 'a'; + break; + case ELF::SHN_COMMON: + ret = 'c'; + break; + } + + switch (ESym->getBinding()) { + case ELF::STB_GLOBAL: + ret = ::toupper(ret); + break; + case ELF::STB_WEAK: + if (EF.getSymbolTableIndex(ESym) == ELF::SHN_UNDEF) + ret = 'w'; + else if (ESym->getType() == ELF::STT_OBJECT) + ret = 'V'; + else + ret = 'W'; + } + + if (ret == '?' && ESym->getType() == ELF::STT_SECTION) { + StringRef Name; + error_code EC = I->getName(Name); + if (EC) + return EC; + Result = StringSwitch(Name) + .StartsWith(".debug", 'N') + .StartsWith(".note", 'n') + .Default('?'); + return object_error::success; + } + + Result = ret; + return object_error::success; +} + +static error_code getSymbolNMTypeChar(COFFObjectFile &Obj, symbol_iterator I, + char &Result) { + const coff_symbol *symb = Obj.getCOFFSymbol(I); + StringRef name; + if (error_code ec = I->getName(name)) + return ec; + char ret = StringSwitch(name) + .StartsWith(".debug", 'N') + .StartsWith(".sxdata", 'N') + .Default('?'); + + if (ret != '?') { + Result = ret; + return object_error::success; + } + + uint32_t Characteristics = 0; + if (symb->SectionNumber > 0) { + section_iterator SecI = Obj.end_sections(); + if (error_code ec = I->getSection(SecI)) + return ec; + const coff_section *Section = Obj.getCOFFSection(SecI); + Characteristics = Section->Characteristics; + } + + switch (symb->SectionNumber) { + case COFF::IMAGE_SYM_UNDEFINED: + // Check storage classes. + if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_WEAK_EXTERNAL) { + Result = 'w'; + return object_error::success; // Don't do ::toupper. + } else if (symb->Value != 0) // Check for common symbols. + ret = 'c'; + else + ret = 'u'; + break; + case COFF::IMAGE_SYM_ABSOLUTE: + ret = 'a'; + break; + case COFF::IMAGE_SYM_DEBUG: + ret = 'n'; + break; + default: + // Check section type. + if (Characteristics & COFF::IMAGE_SCN_CNT_CODE) + ret = 't'; + else if (Characteristics & COFF::IMAGE_SCN_MEM_READ && + ~Characteristics & COFF::IMAGE_SCN_MEM_WRITE) // Read only. + ret = 'r'; + else if (Characteristics & COFF::IMAGE_SCN_CNT_INITIALIZED_DATA) + ret = 'd'; + else if (Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA) + ret = 'b'; + else if (Characteristics & COFF::IMAGE_SCN_LNK_INFO) + ret = 'i'; + + // Check for section symbol. + else if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_STATIC && + symb->Value == 0) + ret = 's'; + } + + if (symb->StorageClass == COFF::IMAGE_SYM_CLASS_EXTERNAL) + ret = ::toupper(static_cast(ret)); + + Result = ret; + return object_error::success; +} + +static uint8_t getNType(MachOObjectFile &Obj, DataRefImpl Symb) { + if (Obj.is64Bit()) { + MachO::nlist_64 STE = Obj.getSymbol64TableEntry(Symb); + return STE.n_type; + } + MachO::nlist STE = Obj.getSymbolTableEntry(Symb); + return STE.n_type; +} + +static error_code getSymbolNMTypeChar(MachOObjectFile &Obj, symbol_iterator I, + char &Res) { + DataRefImpl Symb = I->getRawDataRefImpl(); + uint8_t NType = getNType(Obj, Symb); + + char Char; + switch (NType & MachO::N_TYPE) { + case MachO::N_UNDF: + Char = 'u'; + break; + case MachO::N_ABS: + Char = 's'; + break; + case MachO::N_SECT: { + section_iterator Sec = Obj.end_sections(); + Obj.getSymbolSection(Symb, Sec); + DataRefImpl Ref = Sec->getRawDataRefImpl(); + StringRef SectionName; + Obj.getSectionName(Ref, SectionName); + StringRef SegmentName = Obj.getSectionFinalSegmentName(Ref); + if (SegmentName == "__TEXT" && SectionName == "__text") + Char = 't'; + else + Char = 's'; + } break; + default: + Char = '?'; + break; + } + + if (NType & (MachO::N_EXT | MachO::N_PEXT)) + Char = toupper(static_cast(Char)); + Res = Char; + return object_error::success; +} + +static char getNMTypeChar(ObjectFile *Obj, symbol_iterator I) { + char Res = '?'; + if (COFFObjectFile *COFF = dyn_cast(Obj)) { + error(getSymbolNMTypeChar(*COFF, I, Res)); + return Res; + } + if (MachOObjectFile *MachO = dyn_cast(Obj)) { + error(getSymbolNMTypeChar(*MachO, I, Res)); + return Res; + } + + if (ELF32LEObjectFile *ELF = dyn_cast(Obj)) { + error(getSymbolNMTypeChar(*ELF, I, Res)); + return Res; + } + if (ELF64LEObjectFile *ELF = dyn_cast(Obj)) { + error(getSymbolNMTypeChar(*ELF, I, Res)); + return Res; + } + if (ELF32BEObjectFile *ELF = dyn_cast(Obj)) { + error(getSymbolNMTypeChar(*ELF, I, Res)); + return Res; + } + ELF64BEObjectFile *ELF = cast(Obj); + error(getSymbolNMTypeChar(*ELF, I, Res)); + return Res; +} + static void DumpSymbolNamesFromObject(ObjectFile *obj) { error_code ec; symbol_iterator ibegin = obj->begin_symbols(); @@ -325,7 +548,7 @@ static void DumpSymbolNamesFromObject(ObjectFile *obj) { } if (PrintAddress) if (error(i->getAddress(s.Address))) break; - if (error(i->getNMTypeChar(s.TypeChar))) break; + s.TypeChar = getNMTypeChar(obj, i); if (error(i->getName(s.Name))) break; SymbolList.push_back(s); } -- cgit v1.1 From 42f2a6b41ea62d4ccd10a6c469b27549881a7406 Mon Sep 17 00:00:00 2001 From: Jakub Staszak Date: Mon, 4 Nov 2013 19:22:50 +0000 Subject: Use startswith_lower() where possible. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194007 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/bugpoint/ToolRunner.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/bugpoint/ToolRunner.cpp b/tools/bugpoint/ToolRunner.cpp index 107d0db..254d997 100644 --- a/tools/bugpoint/ToolRunner.cpp +++ b/tools/bugpoint/ToolRunner.cpp @@ -662,7 +662,7 @@ static bool IsARMArchitecture(std::vector Args) { I = Args.begin(), E = Args.end(); I != E; ++I) { if (StringRef(*I).equals_lower("-arch")) { ++I; - if (I != E && StringRef(*I).substr(0, strlen("arm")).equals_lower("arm")) + if (I != E && StringRef(*I).startswith_lower("arm")) return true; } } -- cgit v1.1 From d8acf0078cf363252727acff00f85ae8074f95b3 Mon Sep 17 00:00:00 2001 From: Yuchen Wu Date: Tue, 5 Nov 2013 01:20:41 +0000 Subject: llvm-cov: Added command-line option to change dir. This will allow for much easier testing when the input files are in a different folder from the test script. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194034 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-cov/llvm-cov.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/llvm-cov/llvm-cov.cpp b/tools/llvm-cov/llvm-cov.cpp index ad6c671..1827773 100644 --- a/tools/llvm-cov/llvm-cov.cpp +++ b/tools/llvm-cov/llvm-cov.cpp @@ -20,6 +20,7 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Signals.h" #include "llvm/Support/system_error.h" +#include using namespace llvm; static cl::opt @@ -34,6 +35,9 @@ InputGCDA("gcda", cl::desc(""), cl::init("")); static cl::opt OutputFile("o", cl::desc(""), cl::init("-")); +static cl::opt +WorkingDir("C", cl::desc("change path of working directory"), + cl::init("")); //===----------------------------------------------------------------------===// int main(int argc, char **argv) { @@ -44,6 +48,13 @@ int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, "llvm coverage tool\n"); + if (!WorkingDir.empty()) { + if (chdir(WorkingDir.c_str()) == -1) { + errs() << "Cannot change to directory: " << WorkingDir << ".\n"; + return 1; + } + } + std::string ErrorInfo; raw_fd_ostream OS(OutputFile.c_str(), ErrorInfo); if (!ErrorInfo.empty()) @@ -77,7 +88,6 @@ int main(int argc, char **argv) { } } - if (DumpGCOV) GF.dump(); -- cgit v1.1 From f44533c65e351329306aec7bb9e3eeab26c009b6 Mon Sep 17 00:00:00 2001 From: Yuchen Wu Date: Tue, 5 Nov 2013 01:56:29 +0000 Subject: Revert "llvm-cov: Added command-line option to change dir." This reverts commit d8acf0078cf363252727acff00f85ae8074f95b3. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194040 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-cov/llvm-cov.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) (limited to 'tools') diff --git a/tools/llvm-cov/llvm-cov.cpp b/tools/llvm-cov/llvm-cov.cpp index 1827773..ad6c671 100644 --- a/tools/llvm-cov/llvm-cov.cpp +++ b/tools/llvm-cov/llvm-cov.cpp @@ -20,7 +20,6 @@ #include "llvm/Support/raw_ostream.h" #include "llvm/Support/Signals.h" #include "llvm/Support/system_error.h" -#include using namespace llvm; static cl::opt @@ -35,9 +34,6 @@ InputGCDA("gcda", cl::desc(""), cl::init("")); static cl::opt OutputFile("o", cl::desc(""), cl::init("-")); -static cl::opt -WorkingDir("C", cl::desc("change path of working directory"), - cl::init("")); //===----------------------------------------------------------------------===// int main(int argc, char **argv) { @@ -48,13 +44,6 @@ int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, "llvm coverage tool\n"); - if (!WorkingDir.empty()) { - if (chdir(WorkingDir.c_str()) == -1) { - errs() << "Cannot change to directory: " << WorkingDir << ".\n"; - return 1; - } - } - std::string ErrorInfo; raw_fd_ostream OS(OutputFile.c_str(), ErrorInfo); if (!ErrorInfo.empty()) @@ -88,6 +77,7 @@ int main(int argc, char **argv) { } } + if (DumpGCOV) GF.dump(); -- cgit v1.1 From 4d6b695c953462c3317e3a7eb57d0534db858ac2 Mon Sep 17 00:00:00 2001 From: Alp Toker Date: Tue, 5 Nov 2013 09:33:43 +0000 Subject: Suppress OS crash dialog in llvm-rtdyld All other tools have this -- it's needed to avoid hanging lit on Windows in case of a crash. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194060 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-rtdyld/llvm-rtdyld.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tools') diff --git a/tools/llvm-rtdyld/llvm-rtdyld.cpp b/tools/llvm-rtdyld/llvm-rtdyld.cpp index c5c2854..531595e 100644 --- a/tools/llvm-rtdyld/llvm-rtdyld.cpp +++ b/tools/llvm-rtdyld/llvm-rtdyld.cpp @@ -22,6 +22,8 @@ #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Memory.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" using namespace llvm; @@ -239,6 +241,9 @@ static int executeInput() { } int main(int argc, char **argv) { + sys::PrintStackTraceOnErrorSignal(); + PrettyStackTraceProgram X(argc, argv); + ProgramName = argv[0]; llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. -- cgit v1.1 From 6af8781854a15eadb9df6b45f27fa5cceda5eb16 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Fri, 8 Nov 2013 12:35:56 +0000 Subject: llvm-ar: Let opening a directory failed in llvm-ar. Linux cannot open directories with open(2), although cygwin and *bsd can. Motivation: The test, Object/directory.ll, had been failing with --target=cygwin on Linux. XFAIL was improper for host issues. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194257 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-ar/llvm-ar.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'tools') diff --git a/tools/llvm-ar/llvm-ar.cpp b/tools/llvm-ar/llvm-ar.cpp index 64ef3fa..d70db72 100644 --- a/tools/llvm-ar/llvm-ar.cpp +++ b/tools/llvm-ar/llvm-ar.cpp @@ -782,6 +782,13 @@ static void performWriteOperation(ArchiveOperation Operation, sys::fs::file_status Status; failIfError(sys::fs::status(FD, Status), FileName); + // Opening a directory doesn't make sense. Let it failed. + // Linux cannot open directories with open(2), although + // cygwin and *bsd can. + if (Status.type() == sys::fs::file_type::directory_file) + failIfError(error_code(errc::is_a_directory, posix_category()), + FileName); + OwningPtr File; failIfError(MemoryBuffer::getOpenFile(FD, FileName, File, Status.getSize(), false), -- cgit v1.1 From 2531651206a2d12d37ad93a6f9bc9f8762105b4e Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Mon, 11 Nov 2013 20:08:24 +0000 Subject: Change libLTO back to linking with @executable_path instead of @rpath. This partially reverts r187641 until ld64 adopts a change to link with an rpath setting. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194418 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/lto/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/lto/Makefile b/tools/lto/Makefile index 672fef4..cedbee1 100644 --- a/tools/lto/Makefile +++ b/tools/lto/Makefile @@ -46,7 +46,7 @@ ifeq ($(HOST_OS),Darwin) ifneq ($(DARWIN_VERS),8) LLVMLibsOptions := $(LLVMLibsOptions) \ -Wl,-install_name \ - -Wl,"@rpath/lib$(LIBRARYNAME)$(SHLIBEXT)" + -Wl,"@executable_path/../lib/lib$(LIBRARYNAME)$(SHLIBEXT)" endif # If we're doing an Apple-style build, add the LTO object path. -- cgit v1.1 From fe9ce427d076627beed834d5c322e61323dfd1fc Mon Sep 17 00:00:00 2001 From: Simon Atanasyan Date: Mon, 11 Nov 2013 20:51:48 +0000 Subject: Add support for DT_VERxxx and DT_MIPS_xxx .dynamic section entries to the llvm-readobj. The patch reviewed by Michael Spencer. http://llvm-reviews.chandlerc.com/D2113 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194421 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-readobj/ELFDumper.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'tools') diff --git a/tools/llvm-readobj/ELFDumper.cpp b/tools/llvm-readobj/ELFDumper.cpp index f384824..07a9083 100644 --- a/tools/llvm-readobj/ELFDumper.cpp +++ b/tools/llvm-readobj/ELFDumper.cpp @@ -683,6 +683,16 @@ static const char *getTypeString(uint64_t Type) { LLVM_READOBJ_TYPE_CASE(SYMENT); LLVM_READOBJ_TYPE_CASE(SYMTAB); LLVM_READOBJ_TYPE_CASE(TEXTREL); + LLVM_READOBJ_TYPE_CASE(VERNEED); + LLVM_READOBJ_TYPE_CASE(VERNEEDNUM); + LLVM_READOBJ_TYPE_CASE(VERSYM); + LLVM_READOBJ_TYPE_CASE(MIPS_RLD_VERSION); + LLVM_READOBJ_TYPE_CASE(MIPS_FLAGS); + LLVM_READOBJ_TYPE_CASE(MIPS_BASE_ADDRESS); + LLVM_READOBJ_TYPE_CASE(MIPS_LOCAL_GOTNO); + LLVM_READOBJ_TYPE_CASE(MIPS_SYMTABNO); + LLVM_READOBJ_TYPE_CASE(MIPS_UNREFEXTNO); + LLVM_READOBJ_TYPE_CASE(MIPS_GOTSYM); default: return "unknown"; } } @@ -715,9 +725,21 @@ static void printValue(const ELFFile *O, uint64_t Type, uint64_t Value, case DT_FINI_ARRAY: case DT_PREINIT_ARRAY: case DT_DEBUG: + case DT_VERNEED: + case DT_VERSYM: case DT_NULL: + case DT_MIPS_FLAGS: + case DT_MIPS_BASE_ADDRESS: + case DT_MIPS_GOTSYM: OS << format("0x%" PRIX64, Value); break; + case DT_VERNEEDNUM: + case DT_MIPS_RLD_VERSION: + case DT_MIPS_LOCAL_GOTNO: + case DT_MIPS_SYMTABNO: + case DT_MIPS_UNREFEXTNO: + OS << Value; + break; case DT_PLTRELSZ: case DT_RELASZ: case DT_RELAENT: -- cgit v1.1 From 05c837ec24ba0de81c2d4068b925996f3cadef53 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Thu, 14 Nov 2013 11:45:16 +0000 Subject: llvm-cov requires IR and Support as libraries. Instrumentation would be overkill. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194695 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-cov/CMakeLists.txt | 2 +- tools/llvm-cov/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/llvm-cov/CMakeLists.txt b/tools/llvm-cov/CMakeLists.txt index 7184b9e..67cea71 100644 --- a/tools/llvm-cov/CMakeLists.txt +++ b/tools/llvm-cov/CMakeLists.txt @@ -1,4 +1,4 @@ -set(LLVM_LINK_COMPONENTS instrumentation ) +set(LLVM_LINK_COMPONENTS core support ) add_llvm_tool(llvm-cov llvm-cov.cpp diff --git a/tools/llvm-cov/Makefile b/tools/llvm-cov/Makefile index 2d47ce4..efed6cc 100644 --- a/tools/llvm-cov/Makefile +++ b/tools/llvm-cov/Makefile @@ -9,7 +9,7 @@ LEVEL := ../.. TOOLNAME := llvm-cov -LINK_COMPONENTS := instrumentation +LINK_COMPONENTS := core support # This tool has no plugins, optimize startup time. TOOL_NO_EXPORTS := 1 -- cgit v1.1 From d881c1bdd1f63bbbdb8eec5f6ae7fd765103972f Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Fri, 15 Nov 2013 09:44:17 +0000 Subject: llvm-cov: Clean up memory leaks. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194799 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-cov/llvm-cov.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/llvm-cov/llvm-cov.cpp b/tools/llvm-cov/llvm-cov.cpp index ad6c671..5f6999e 100644 --- a/tools/llvm-cov/llvm-cov.cpp +++ b/tools/llvm-cov/llvm-cov.cpp @@ -58,7 +58,7 @@ int main(int argc, char **argv) { errs() << InputGCNO << ": " << ec.message() << "\n"; return 1; } - GCOVBuffer GCNO_GB(GCNO_Buff.take()); + GCOVBuffer GCNO_GB(GCNO_Buff.get()); if (!GF.read(GCNO_GB)) { errs() << "Invalid .gcno File!\n"; return 1; @@ -70,7 +70,7 @@ int main(int argc, char **argv) { errs() << InputGCDA << ": " << ec.message() << "\n"; return 1; } - GCOVBuffer GCDA_GB(GCDA_Buff.take()); + GCOVBuffer GCDA_GB(GCDA_Buff.get()); if (!GF.read(GCDA_GB)) { errs() << "Invalid .gcda File!\n"; return 1; -- cgit v1.1 From 5a364c5561ec04e33a6f5d52c14f1bac6f247ea0 Mon Sep 17 00:00:00 2001 From: Juergen Ributzka Date: Fri, 15 Nov 2013 22:34:48 +0000 Subject: [weak vtables] Remove a bunch of weak vtables This patch removes most of the trivial cases of weak vtables by pinning them to a single object file. Differential Revision: http://llvm-reviews.chandlerc.com/D2068 Reviewed by Andy git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194865 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-stress/llvm-stress.cpp | 40 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/llvm-stress/llvm-stress.cpp b/tools/llvm-stress/llvm-stress.cpp index 15f7abf..d262a69 100644 --- a/tools/llvm-stress/llvm-stress.cpp +++ b/tools/llvm-stress/llvm-stress.cpp @@ -128,7 +128,7 @@ public: BB(Block),PT(PT),Ran(R),Context(BB->getContext()) {} /// virtual D'tor to silence warnings. - virtual ~Modifier() {} + virtual ~Modifier(); /// Add a new instruction. virtual void Act() = 0; @@ -285,8 +285,11 @@ protected: LLVMContext &Context; }; +Modifier::~Modifier() {} + struct LoadModifier: public Modifier { LoadModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual ~LoadModifier(); virtual void Act() { // Try to use predefined pointers. If non exist, use undef pointer value; Value *Ptr = getRandomPointerValue(); @@ -295,8 +298,11 @@ struct LoadModifier: public Modifier { } }; +LoadModifier::~LoadModifier() {} + struct StoreModifier: public Modifier { StoreModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual ~StoreModifier(); virtual void Act() { // Try to use predefined pointers. If non exist, use undef pointer value; Value *Ptr = getRandomPointerValue(); @@ -313,8 +319,11 @@ struct StoreModifier: public Modifier { } }; +StoreModifier::~StoreModifier() {} + struct BinModifier: public Modifier { BinModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual ~BinModifier(); virtual void Act() { Value *Val0 = getRandomVal(); @@ -356,9 +365,13 @@ struct BinModifier: public Modifier { } }; +BinModifier::~BinModifier() {} + /// Generate constant values. struct ConstModifier: public Modifier { ConstModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual ~ConstModifier(); + virtual void Act() { Type *Ty = pickType(); @@ -403,8 +416,11 @@ struct ConstModifier: public Modifier { } }; +ConstModifier::~ConstModifier() {} + struct AllocaModifier: public Modifier { AllocaModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R){} + virtual ~AllocaModifier(); virtual void Act() { Type *Tp = pickType(); @@ -412,9 +428,12 @@ struct AllocaModifier: public Modifier { } }; +AllocaModifier::~AllocaModifier() {} + struct ExtractElementModifier: public Modifier { ExtractElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): Modifier(BB, PT, R) {} + virtual ~ExtractElementModifier(); virtual void Act() { Value *Val0 = getRandomVectorValue(); @@ -426,8 +445,12 @@ struct ExtractElementModifier: public Modifier { } }; +ExtractElementModifier::~ExtractElementModifier() {} + struct ShuffModifier: public Modifier { ShuffModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual ~ShuffModifier(); + virtual void Act() { Value *Val0 = getRandomVectorValue(); @@ -453,9 +476,12 @@ struct ShuffModifier: public Modifier { } }; +ShuffModifier::~ShuffModifier() {} + struct InsertElementModifier: public Modifier { InsertElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): Modifier(BB, PT, R) {} + virtual ~InsertElementModifier(); virtual void Act() { Value *Val0 = getRandomVectorValue(); @@ -470,8 +496,12 @@ struct InsertElementModifier: public Modifier { }; +InsertElementModifier::~InsertElementModifier() {} + struct CastModifier: public Modifier { CastModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual ~CastModifier(); + virtual void Act() { Value *V = getRandomVal(); @@ -555,9 +585,12 @@ struct CastModifier: public Modifier { }; +CastModifier::~CastModifier() {} + struct SelectModifier: public Modifier { SelectModifier(BasicBlock *BB, PieceTable *PT, Random *R): Modifier(BB, PT, R) {} + virtual ~SelectModifier(); virtual void Act() { // Try a bunch of different select configuration until a valid one is found. @@ -579,9 +612,12 @@ struct SelectModifier: public Modifier { } }; +SelectModifier::~SelectModifier() {} struct CmpModifier: public Modifier { CmpModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual ~CmpModifier(); + virtual void Act() { Value *Val0 = getRandomVal(); @@ -607,6 +643,8 @@ struct CmpModifier: public Modifier { } }; +CmpModifier::~CmpModifier() {} + void FillFunction(Function *F, Random &R) { // Create a legal entry block. BasicBlock *BB = BasicBlock::Create(F->getContext(), "BB", F); -- cgit v1.1 From b21ab43cfc3fa0dacf5c95f04e58b6d804b59a16 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Mon, 18 Nov 2013 09:31:53 +0000 Subject: Revert r194865 and r194874. This change is incorrect. If you delete virtual destructor of both a base class and a subclass, then the following code: Base *foo = new Child(); delete foo; will not cause the destructor for members of Child class. As a result, I observe plently of memory leaks. Notable examples I investigated are: ObjectBuffer and ObjectBufferStream, AttributeImpl and StringSAttributeImpl. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194997 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-stress/llvm-stress.cpp | 40 +-------------------------------------- 1 file changed, 1 insertion(+), 39 deletions(-) (limited to 'tools') diff --git a/tools/llvm-stress/llvm-stress.cpp b/tools/llvm-stress/llvm-stress.cpp index d262a69..15f7abf 100644 --- a/tools/llvm-stress/llvm-stress.cpp +++ b/tools/llvm-stress/llvm-stress.cpp @@ -128,7 +128,7 @@ public: BB(Block),PT(PT),Ran(R),Context(BB->getContext()) {} /// virtual D'tor to silence warnings. - virtual ~Modifier(); + virtual ~Modifier() {} /// Add a new instruction. virtual void Act() = 0; @@ -285,11 +285,8 @@ protected: LLVMContext &Context; }; -Modifier::~Modifier() {} - struct LoadModifier: public Modifier { LoadModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} - virtual ~LoadModifier(); virtual void Act() { // Try to use predefined pointers. If non exist, use undef pointer value; Value *Ptr = getRandomPointerValue(); @@ -298,11 +295,8 @@ struct LoadModifier: public Modifier { } }; -LoadModifier::~LoadModifier() {} - struct StoreModifier: public Modifier { StoreModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} - virtual ~StoreModifier(); virtual void Act() { // Try to use predefined pointers. If non exist, use undef pointer value; Value *Ptr = getRandomPointerValue(); @@ -319,11 +313,8 @@ struct StoreModifier: public Modifier { } }; -StoreModifier::~StoreModifier() {} - struct BinModifier: public Modifier { BinModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} - virtual ~BinModifier(); virtual void Act() { Value *Val0 = getRandomVal(); @@ -365,13 +356,9 @@ struct BinModifier: public Modifier { } }; -BinModifier::~BinModifier() {} - /// Generate constant values. struct ConstModifier: public Modifier { ConstModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} - virtual ~ConstModifier(); - virtual void Act() { Type *Ty = pickType(); @@ -416,11 +403,8 @@ struct ConstModifier: public Modifier { } }; -ConstModifier::~ConstModifier() {} - struct AllocaModifier: public Modifier { AllocaModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R){} - virtual ~AllocaModifier(); virtual void Act() { Type *Tp = pickType(); @@ -428,12 +412,9 @@ struct AllocaModifier: public Modifier { } }; -AllocaModifier::~AllocaModifier() {} - struct ExtractElementModifier: public Modifier { ExtractElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): Modifier(BB, PT, R) {} - virtual ~ExtractElementModifier(); virtual void Act() { Value *Val0 = getRandomVectorValue(); @@ -445,12 +426,8 @@ struct ExtractElementModifier: public Modifier { } }; -ExtractElementModifier::~ExtractElementModifier() {} - struct ShuffModifier: public Modifier { ShuffModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} - virtual ~ShuffModifier(); - virtual void Act() { Value *Val0 = getRandomVectorValue(); @@ -476,12 +453,9 @@ struct ShuffModifier: public Modifier { } }; -ShuffModifier::~ShuffModifier() {} - struct InsertElementModifier: public Modifier { InsertElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): Modifier(BB, PT, R) {} - virtual ~InsertElementModifier(); virtual void Act() { Value *Val0 = getRandomVectorValue(); @@ -496,12 +470,8 @@ struct InsertElementModifier: public Modifier { }; -InsertElementModifier::~InsertElementModifier() {} - struct CastModifier: public Modifier { CastModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} - virtual ~CastModifier(); - virtual void Act() { Value *V = getRandomVal(); @@ -585,12 +555,9 @@ struct CastModifier: public Modifier { }; -CastModifier::~CastModifier() {} - struct SelectModifier: public Modifier { SelectModifier(BasicBlock *BB, PieceTable *PT, Random *R): Modifier(BB, PT, R) {} - virtual ~SelectModifier(); virtual void Act() { // Try a bunch of different select configuration until a valid one is found. @@ -612,12 +579,9 @@ struct SelectModifier: public Modifier { } }; -SelectModifier::~SelectModifier() {} struct CmpModifier: public Modifier { CmpModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} - virtual ~CmpModifier(); - virtual void Act() { Value *Val0 = getRandomVal(); @@ -643,8 +607,6 @@ struct CmpModifier: public Modifier { } }; -CmpModifier::~CmpModifier() {} - void FillFunction(Function *F, Random &R) { // Create a legal entry block. BasicBlock *BB = BasicBlock::Create(F->getContext(), "BB", F); -- cgit v1.1 From 26efdc5621043d28dc0c78addc7b7a75d1591a10 Mon Sep 17 00:00:00 2001 From: David Blaikie Date: Tue, 19 Nov 2013 00:29:42 +0000 Subject: llvm-dwarfdump: support for emitting only the debug_types section using -debug-dump git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195063 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-dwarfdump/llvm-dwarfdump.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp index c46bd6b..413a50b 100644 --- a/tools/llvm-dwarfdump/llvm-dwarfdump.cpp +++ b/tools/llvm-dwarfdump/llvm-dwarfdump.cpp @@ -62,6 +62,7 @@ DumpType("debug-dump", cl::init(DIDT_All), clEnumValN(DIDT_Aranges, "aranges", ".debug_aranges"), clEnumValN(DIDT_Info, "info", ".debug_info"), clEnumValN(DIDT_InfoDwo, "info.dwo", ".debug_info.dwo"), + clEnumValN(DIDT_Types, "types", ".debug_types"), clEnumValN(DIDT_Line, "line", ".debug_line"), clEnumValN(DIDT_Loc, "loc", ".debug_loc"), clEnumValN(DIDT_Frames, "frames", ".debug_frame"), -- cgit v1.1 From 354362524a72b3fa43a6c09380b7ae3b2380cbba Mon Sep 17 00:00:00 2001 From: Juergen Ributzka Date: Tue, 19 Nov 2013 00:57:56 +0000 Subject: [weak vtables] Remove a bunch of weak vtables This patch removes most of the trivial cases of weak vtables by pinning them to a single object file. The memory leaks in this version have been fixed. Thanks Alexey for pointing them out. Differential Revision: http://llvm-reviews.chandlerc.com/D2068 Reviewed by Andy git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195064 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-stress/llvm-stress.cpp | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/llvm-stress/llvm-stress.cpp b/tools/llvm-stress/llvm-stress.cpp index 15f7abf..672e481 100644 --- a/tools/llvm-stress/llvm-stress.cpp +++ b/tools/llvm-stress/llvm-stress.cpp @@ -128,7 +128,7 @@ public: BB(Block),PT(PT),Ran(R),Context(BB->getContext()) {} /// virtual D'tor to silence warnings. - virtual ~Modifier() {} + virtual ~Modifier(); /// Add a new instruction. virtual void Act() = 0; @@ -287,6 +287,7 @@ protected: struct LoadModifier: public Modifier { LoadModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual ~LoadModifier(); virtual void Act() { // Try to use predefined pointers. If non exist, use undef pointer value; Value *Ptr = getRandomPointerValue(); @@ -297,6 +298,7 @@ struct LoadModifier: public Modifier { struct StoreModifier: public Modifier { StoreModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual ~StoreModifier(); virtual void Act() { // Try to use predefined pointers. If non exist, use undef pointer value; Value *Ptr = getRandomPointerValue(); @@ -315,6 +317,7 @@ struct StoreModifier: public Modifier { struct BinModifier: public Modifier { BinModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual ~BinModifier(); virtual void Act() { Value *Val0 = getRandomVal(); @@ -359,6 +362,8 @@ struct BinModifier: public Modifier { /// Generate constant values. struct ConstModifier: public Modifier { ConstModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual ~ConstModifier(); + virtual void Act() { Type *Ty = pickType(); @@ -405,6 +410,7 @@ struct ConstModifier: public Modifier { struct AllocaModifier: public Modifier { AllocaModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R){} + virtual ~AllocaModifier(); virtual void Act() { Type *Tp = pickType(); @@ -415,6 +421,7 @@ struct AllocaModifier: public Modifier { struct ExtractElementModifier: public Modifier { ExtractElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): Modifier(BB, PT, R) {} + virtual ~ExtractElementModifier(); virtual void Act() { Value *Val0 = getRandomVectorValue(); @@ -428,6 +435,8 @@ struct ExtractElementModifier: public Modifier { struct ShuffModifier: public Modifier { ShuffModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual ~ShuffModifier(); + virtual void Act() { Value *Val0 = getRandomVectorValue(); @@ -456,6 +465,7 @@ struct ShuffModifier: public Modifier { struct InsertElementModifier: public Modifier { InsertElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): Modifier(BB, PT, R) {} + virtual ~InsertElementModifier(); virtual void Act() { Value *Val0 = getRandomVectorValue(); @@ -472,6 +482,8 @@ struct InsertElementModifier: public Modifier { struct CastModifier: public Modifier { CastModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual ~CastModifier(); + virtual void Act() { Value *V = getRandomVal(); @@ -558,6 +570,7 @@ struct CastModifier: public Modifier { struct SelectModifier: public Modifier { SelectModifier(BasicBlock *BB, PieceTable *PT, Random *R): Modifier(BB, PT, R) {} + virtual ~SelectModifier(); virtual void Act() { // Try a bunch of different select configuration until a valid one is found. @@ -582,6 +595,8 @@ struct SelectModifier: public Modifier { struct CmpModifier: public Modifier { CmpModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} + virtual ~CmpModifier(); + virtual void Act() { Value *Val0 = getRandomVal(); @@ -607,6 +622,20 @@ struct CmpModifier: public Modifier { } }; +// Use out-of-line definitions to prevent weak vtables. +Modifier::~Modifier() {} +LoadModifier::~LoadModifier() {} +StoreModifier::~StoreModifier() {} +BinModifier::~BinModifier() {} +ConstModifier::~ConstModifier() {} +AllocaModifier::~AllocaModifier() {} +ExtractElementModifier::~ExtractElementModifier() {} +ShuffModifier::~ShuffModifier() {} +InsertElementModifier::~InsertElementModifier() {} +CastModifier::~CastModifier() {} +SelectModifier::~SelectModifier() {} +CmpModifier::~CmpModifier() {} + void FillFunction(Function *F, Random &R) { // Create a legal entry block. BasicBlock *BB = BasicBlock::Create(F->getContext(), "BB", F); -- cgit v1.1 From 9d7c776d32c8a4d64b37a91c2d627629cf1498ef Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 19 Nov 2013 06:35:35 +0000 Subject: Merging r195092: ------------------------------------------------------------------------ r195092 | ributzka | 2013-11-18 19:08:35 -0800 (Mon, 18 Nov 2013) | 5 lines [weak vtables] Place class definitions into anonymous namespaces to prevent weak vtables. This patch places class definitions in implementation files into anonymous namespaces to prevent weak vtables. This eliminates the need of providing an out-of-line definition to pin the vtable explicitly to the file. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_34@195111 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-stress/llvm-stress.cpp | 38 ++++++-------------------------------- 1 file changed, 6 insertions(+), 32 deletions(-) (limited to 'tools') diff --git a/tools/llvm-stress/llvm-stress.cpp b/tools/llvm-stress/llvm-stress.cpp index 672e481..fd10baf 100644 --- a/tools/llvm-stress/llvm-stress.cpp +++ b/tools/llvm-stress/llvm-stress.cpp @@ -52,6 +52,7 @@ static cl::opt GenPPCFP128("generate-ppc-fp128", static cl::opt GenX86MMX("generate-x86-mmx", cl::desc("Generate X86 MMX floating-point values"), cl::init(false)); +namespace { /// A utility class to provide a pseudo-random number generator which is /// the same across all platforms. This is somewhat close to the libc /// implementation. Note: This is not a cryptographically secure pseudorandom @@ -128,7 +129,7 @@ public: BB(Block),PT(PT),Ran(R),Context(BB->getContext()) {} /// virtual D'tor to silence warnings. - virtual ~Modifier(); + virtual ~Modifier() {} /// Add a new instruction. virtual void Act() = 0; @@ -287,7 +288,6 @@ protected: struct LoadModifier: public Modifier { LoadModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} - virtual ~LoadModifier(); virtual void Act() { // Try to use predefined pointers. If non exist, use undef pointer value; Value *Ptr = getRandomPointerValue(); @@ -298,7 +298,6 @@ struct LoadModifier: public Modifier { struct StoreModifier: public Modifier { StoreModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} - virtual ~StoreModifier(); virtual void Act() { // Try to use predefined pointers. If non exist, use undef pointer value; Value *Ptr = getRandomPointerValue(); @@ -317,7 +316,6 @@ struct StoreModifier: public Modifier { struct BinModifier: public Modifier { BinModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} - virtual ~BinModifier(); virtual void Act() { Value *Val0 = getRandomVal(); @@ -362,8 +360,6 @@ struct BinModifier: public Modifier { /// Generate constant values. struct ConstModifier: public Modifier { ConstModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} - virtual ~ConstModifier(); - virtual void Act() { Type *Ty = pickType(); @@ -410,7 +406,6 @@ struct ConstModifier: public Modifier { struct AllocaModifier: public Modifier { AllocaModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R){} - virtual ~AllocaModifier(); virtual void Act() { Type *Tp = pickType(); @@ -421,7 +416,6 @@ struct AllocaModifier: public Modifier { struct ExtractElementModifier: public Modifier { ExtractElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): Modifier(BB, PT, R) {} - virtual ~ExtractElementModifier(); virtual void Act() { Value *Val0 = getRandomVectorValue(); @@ -435,8 +429,6 @@ struct ExtractElementModifier: public Modifier { struct ShuffModifier: public Modifier { ShuffModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} - virtual ~ShuffModifier(); - virtual void Act() { Value *Val0 = getRandomVectorValue(); @@ -465,7 +457,6 @@ struct ShuffModifier: public Modifier { struct InsertElementModifier: public Modifier { InsertElementModifier(BasicBlock *BB, PieceTable *PT, Random *R): Modifier(BB, PT, R) {} - virtual ~InsertElementModifier(); virtual void Act() { Value *Val0 = getRandomVectorValue(); @@ -482,8 +473,6 @@ struct InsertElementModifier: public Modifier { struct CastModifier: public Modifier { CastModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} - virtual ~CastModifier(); - virtual void Act() { Value *V = getRandomVal(); @@ -570,7 +559,6 @@ struct CastModifier: public Modifier { struct SelectModifier: public Modifier { SelectModifier(BasicBlock *BB, PieceTable *PT, Random *R): Modifier(BB, PT, R) {} - virtual ~SelectModifier(); virtual void Act() { // Try a bunch of different select configuration until a valid one is found. @@ -595,8 +583,6 @@ struct SelectModifier: public Modifier { struct CmpModifier: public Modifier { CmpModifier(BasicBlock *BB, PieceTable *PT, Random *R):Modifier(BB, PT, R) {} - virtual ~CmpModifier(); - virtual void Act() { Value *Val0 = getRandomVal(); @@ -622,21 +608,9 @@ struct CmpModifier: public Modifier { } }; -// Use out-of-line definitions to prevent weak vtables. -Modifier::~Modifier() {} -LoadModifier::~LoadModifier() {} -StoreModifier::~StoreModifier() {} -BinModifier::~BinModifier() {} -ConstModifier::~ConstModifier() {} -AllocaModifier::~AllocaModifier() {} -ExtractElementModifier::~ExtractElementModifier() {} -ShuffModifier::~ShuffModifier() {} -InsertElementModifier::~InsertElementModifier() {} -CastModifier::~CastModifier() {} -SelectModifier::~SelectModifier() {} -CmpModifier::~CmpModifier() {} - -void FillFunction(Function *F, Random &R) { +} // end anonymous namespace + +static void FillFunction(Function *F, Random &R) { // Create a legal entry block. BasicBlock *BB = BasicBlock::Create(F->getContext(), "BB", F); ReturnInst::Create(F->getContext(), BB); @@ -683,7 +657,7 @@ void FillFunction(Function *F, Random &R) { SM->ActN(5); // Throw in a few stores. } -void IntroduceControlFlow(Function *F, Random &R) { +static void IntroduceControlFlow(Function *F, Random &R) { std::vector BoolInst; for (BasicBlock::iterator it = F->begin()->begin(), e = F->begin()->end(); it != e; ++it) { -- cgit v1.1 From 91e3564ee7cc478fc3006d6bae5387ba2d46f20c Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Mon, 25 Nov 2013 05:23:29 +0000 Subject: Merging r195479: ------------------------------------------------------------------------ r195479 | hans | 2013-11-22 10:25:43 -0800 (Fri, 22 Nov 2013) | 4 lines VS integration: use the correct registry key after r195379 I changed the registry key in that commit, but forgot to update the integration files. This change makes them use the same variable. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_34@195607 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/msbuild/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/msbuild/CMakeLists.txt b/tools/msbuild/CMakeLists.txt index c725ab7..08b8aee 100644 --- a/tools/msbuild/CMakeLists.txt +++ b/tools/msbuild/CMakeLists.txt @@ -7,7 +7,7 @@ if (WIN32) set(prop_file_v120_xp "toolset-vs2013_xp.props") # CPack will install a registry key in this format that we wish to reference. - set(REG_KEY "${CMAKE_PROJECT_NAME} ${CPACK_PACKAGE_VERSION}") + set(REG_KEY "${CPACK_PACKAGE_INSTALL_REGISTRY_KEY}") set(VS_VERSION "v100") set(MSC_VERSION "1600") -- cgit v1.1 From b70b8c3a931ad81256f193c81be6487f936357a8 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Mon, 2 Dec 2013 19:20:45 +0000 Subject: Merging r196100: ------------------------------------------------------------------------ r196100 | alp | 2013-12-02 06:17:47 -0800 (Mon, 02 Dec 2013) | 4 lines Cut the gold plugin README down to size This file hasn't been updated in years. Remove old information and point to the current documentation at GoldPlugin.rst. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_34@196135 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/gold/README.txt | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) (limited to 'tools') diff --git a/tools/gold/README.txt b/tools/gold/README.txt index a906a90..286d9af 100644 --- a/tools/gold/README.txt +++ b/tools/gold/README.txt @@ -1,21 +1,13 @@ +The LLVM Gold LTO Plugin +======================== + This directory contains a plugin that is designed to work with binutils gold linker. At present time, this is not the default linker in binutils, and the default build of gold does not support plugins. -Obtaining binutils: - - cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src login - {enter "anoncvs" as the password} - cvs -z 9 -d :pserver:anoncvs@sourceware.org:/cvs/src co binutils - -This will create a src/ directory. Make a build/ directory and from -there configure binutils with "../src/configure --enable-gold --enable-plugins". -Then build binutils with "make all-gold". +See docs/GoldPlugin.html for complete build and usage instructions. -To build the LLVMgold plugin, configure LLVM with the option ---with-binutils-include=/path/to/binutils/src/include/ --enable-pic. To use the -plugin, run "ld-new --plugin /path/to/LLVMgold.so". -Without PIC libLTO and LLVMgold are not being built (because they would fail -link on x86-64 with a relocation error: PIC and non-PIC can't be combined). +NOTE: libLTO and LLVMgold aren't built without PIC because they would fail +to link on x86-64 with a relocation error: PIC and non-PIC can't be combined. As an alternative to passing --enable-pic, you can use 'make ENABLE_PIC=1' in your entire LLVM build. -- cgit v1.1 From b84d18f57604b86ce2cae5a2447a5f879153bc0f Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Sat, 7 Dec 2013 09:31:26 +0000 Subject: Merging r196294: ------------------------------------------------------------------------ r196294 | arnolds | 2013-12-03 08:33:06 -0800 (Tue, 03 Dec 2013) | 7 lines opt: Mirror vectorization presets of clang clang enables vectorization at optimization levels > 1 and size level < 2. opt should behave similarily. Loop vectorization and SLP vectorization can be disabled with the flags -disable-(loop/slp)-vectorization. ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_34@196649 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/opt/opt.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 8a8da01..dba16f7 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -139,6 +139,16 @@ static cl::opt DisableLoopUnrolling("disable-loop-unrolling", cl::desc("Disable loop unrolling in all relevant passes"), cl::init(false)); +static cl::opt +DisableLoopVectorization("disable-loop-vectorization", + cl::desc("Disable the loop vectorization pass"), + cl::init(false)); + +static cl::opt +DisableSLPVectorization("disable-slp-vectorization", + cl::desc("Disable the slp vectorization pass"), + cl::init(false)); + static cl::opt DisableSimplifyLibCalls("disable-simplify-libcalls", @@ -461,8 +471,10 @@ static void AddOptimizationPasses(PassManagerBase &MPM,FunctionPassManager &FPM, Builder.DisableUnrollLoops = (DisableLoopUnrolling.getNumOccurrences() > 0) ? DisableLoopUnrolling : OptLevel == 0; - Builder.LoopVectorize = OptLevel > 1 && SizeLevel < 2; - Builder.SLPVectorize = true; + Builder.LoopVectorize = + DisableLoopVectorization ? false : OptLevel > 1 && SizeLevel < 2; + Builder.SLPVectorize = + DisableSLPVectorization ? false : OptLevel > 1 && SizeLevel < 2; Builder.populateFunctionPassManager(FPM); Builder.populateModulePassManager(MPM); -- cgit v1.1