[PATCH] D29892: ar: add llvm-dlltool support
Rafael Avila de Espindola via llvm-commits
llvm-commits at lists.llvm.org
Mon May 15 08:22:25 PDT 2017
Martell Malone via Phabricator <reviews at reviews.llvm.org> writes:
> martell updated this revision to Diff 98637.
> martell added a comment.
> Herald added a subscriber: inglorion.
>
> light update to take https://reviews.llvm.org/D32689 into account.
>
> note:
> also seems `llvm-readobj` can't read weak externals
> will have to add support on top of the short import libs support I done previously.
>
>
> Repository:
> rL LLVM
>
> https://reviews.llvm.org/D29892
>
> Files:
> include/llvm/DlltoolDriver/DlltoolDriver.h
> include/llvm/Object/COFFImportFile.h
> include/llvm/Object/COFFModuleDefinition.h
> lib/CMakeLists.txt
> lib/DlltoolDriver/CMakeLists.txt
> lib/DlltoolDriver/DlltoolDriver.cpp
> lib/DlltoolDriver/LLVMBuild.txt
> lib/DlltoolDriver/Options.td
> lib/Object/ArchiveWriter.cpp
> lib/Object/COFFImportFile.cpp
> lib/Object/COFFModuleDefinition.cpp
> test/DllTool/coff-exports.def
> test/DllTool/lit.local.cfg
> tools/llvm-ar/CMakeLists.txt
> tools/llvm-ar/llvm-ar.cpp
>
> Index: tools/llvm-ar/llvm-ar.cpp
> ===================================================================
> --- tools/llvm-ar/llvm-ar.cpp
> +++ tools/llvm-ar/llvm-ar.cpp
> @@ -16,6 +16,7 @@
> #include "llvm/ADT/Triple.h"
> #include "llvm/IR/LLVMContext.h"
> #include "llvm/IR/Module.h"
> +#include "llvm/DlltoolDriver/DlltoolDriver.h"
> #include "llvm/LibDriver/LibDriver.h"
> #include "llvm/Object/Archive.h"
> #include "llvm/Object/ArchiveWriter.h"
> @@ -859,6 +860,9 @@
> llvm::InitializeAllAsmParsers();
>
> StringRef Stem = sys::path::stem(ToolName);
> + if (Stem.find("dlltool") != StringRef::npos)
> + return dlltoolDriverMain(makeArrayRef(argv, argc));
> +
> if (Stem.find("ranlib") == StringRef::npos &&
> Stem.find("lib") != StringRef::npos)
> return libDriverMain(makeArrayRef(argv, argc));
> @@ -874,5 +878,5 @@
> return ranlib_main();
> if (Stem.find("ar") != StringRef::npos)
> return ar_main();
> - fail("Not ranlib, ar or lib!");
> + fail("Not ranlib, ar, lib or dlltool!");
> }
> Index: tools/llvm-ar/CMakeLists.txt
> ===================================================================
> --- tools/llvm-ar/CMakeLists.txt
> +++ tools/llvm-ar/CMakeLists.txt
> @@ -1,6 +1,7 @@
> set(LLVM_LINK_COMPONENTS
> ${LLVM_TARGETS_TO_BUILD}
> Core
> + DlltoolDriver
> LibDriver
> Object
> Support
> @@ -15,3 +16,4 @@
>
> add_llvm_tool_symlink(llvm-ranlib llvm-ar)
> add_llvm_tool_symlink(llvm-lib llvm-ar)
> +add_llvm_tool_symlink(llvm-dlltool llvm-ar)
> Index: test/DllTool/lit.local.cfg
> ===================================================================
> --- /dev/null
> +++ test/DllTool/lit.local.cfg
> @@ -0,0 +1 @@
> +config.suffixes = ['.def']
> Index: test/DllTool/coff-exports.def
> ===================================================================
> --- /dev/null
> +++ test/DllTool/coff-exports.def
> @@ -0,0 +1,13 @@
> +; RUN: llvm-dlltool -a x86_64 %s %t.a
> +; RUN: llvm-readobj -coff-exports %t.a | FileCheck %s
> +
> +LIBRARY test.dll
> +EXPORTS
> +TestFunction
> +
> +; CHECK: File: test.dll
> +; CHECK: Format: COFF-import-file
> +; CHECK: Type: code
> +; CHECK: Name type: name
> +; CHECK: Symbol: __imp_TestFunction
> +; CHECK: Symbol: TestFunction
> Index: lib/Object/COFFModuleDefinition.cpp
> ===================================================================
> --- lib/Object/COFFModuleDefinition.cpp
> +++ lib/Object/COFFModuleDefinition.cpp
> @@ -55,8 +55,10 @@
> StringRef Value;
> };
>
> -static bool isDecorated(StringRef Sym) {
> - return Sym.startswith("_") || Sym.startswith("@") || Sym.startswith("?");
> +static bool isDecorated(StringRef Sym, bool MingwDef) {
> + // Disable Sym.startswith("_") for mingw-w64
> + return (!MingwDef && Sym.startswith("_")) ||
> + Sym.startswith("@") || Sym.startswith("?");
> }
>
> static Error createError(const Twine &Err) {
> @@ -82,6 +84,10 @@
> return lex();
> }
> case '=':
> + // This lets us handle "==" which is a dlltool ism
> + if (Buf[1] == '=')
> + Buf = Buf.drop_front();
> +
> Buf = Buf.drop_front();
> return Token(Equal, "=");
> case ',':
> @@ -120,7 +126,8 @@
>
> class Parser {
> public:
> - explicit Parser(StringRef S, MachineTypes M) : Lex(S), Machine(M) {}
> + explicit Parser(StringRef S, MachineTypes M,
> + bool B) : Lex(S), Machine(M), MingwDef(B) {}
>
> Expected<COFFModuleDefinition> parse() {
> do {
> @@ -213,9 +220,9 @@
> }
>
> if (Machine == IMAGE_FILE_MACHINE_I386) {
> - if (!isDecorated(E.Name))
> + if (!isDecorated(E.Name, MingwDef))
> E.Name = (std::string("_").append(E.Name));
> - if (!E.ExtName.empty() && !isDecorated(E.ExtName))
> + if (!E.ExtName.empty() && !isDecorated(E.ExtName, MingwDef))
> E.ExtName = (std::string("_").append(E.ExtName));
> }
>
> @@ -244,6 +251,12 @@
> continue;
> }
> unget();
> +
> + if (E.isWeak())
> + E.SymbolName = E.ExtName;
> + else
> + E.SymbolName = E.Name;
> +
> Info.Exports.push_back(E);
> return Error::success();
> }
> @@ -308,11 +321,13 @@
> std::vector<Token> Stack;
> MachineTypes Machine;
> COFFModuleDefinition Info;
> + bool MingwDef;
> };
>
> Expected<COFFModuleDefinition> parseCOFFModuleDefinition(MemoryBufferRef MB,
> - MachineTypes Machine) {
> - return Parser(MB.getBuffer(), Machine).parse();
> + MachineTypes Machine,
> + bool MingwDef) {
> + return Parser(MB.getBuffer(), Machine, MingwDef).parse();
> }
>
> } // namespace object
> Index: lib/Object/COFFImportFile.cpp
> ===================================================================
> --- lib/Object/COFFImportFile.cpp
> +++ lib/Object/COFFImportFile.cpp
> @@ -162,6 +162,10 @@
> // Library Format.
> NewArchiveMember createShortImport(StringRef Sym, uint16_t Ordinal,
> ImportType Type, ImportNameType NameType);
> +
> + // Create a weak external file which is described in PE/COFF Aux Format 3.
> + NewArchiveMember createWeakExternal(std::vector<uint8_t> &Buffer,
> + StringRef Sym, StringRef Weak, bool imp);
> };
> } // namespace
>
> @@ -476,6 +480,89 @@
> return {MemoryBufferRef(StringRef(Buf, Size), DLLName)};
> }
>
> +NewArchiveMember ObjectFactory::createWeakExternal(std::vector<uint8_t> &Buffer,
> + StringRef Sym, StringRef Weak, bool imp) {
> + static const uint32_t NumberOfSections = 1;
> + static const uint32_t NumberOfSymbols = 5;
> +
> + // COFF Header
> + coff_file_header Header{
> + u16(0), u16(NumberOfSections), u32(0),
> + u32(sizeof(Header) + (NumberOfSections * sizeof(coff_section))),
> + u32(NumberOfSymbols), u16(0),
> + u16(0),
> + };
> + append(Buffer, Header);
> +
> + // Section Header Table
> + static const coff_section SectionTable[NumberOfSections] = {
> + {{'.', 'd', 'r', 'e', 'c', 't', 'v', 'e'},
> + u32(0),
> + u32(0),
> + u32(0),
> + u32(0),
> + u32(0),
> + u32(0),
> + u16(0),
> + u16(0),
> + u32(IMAGE_SCN_LNK_INFO | IMAGE_SCN_LNK_REMOVE)}
> + };
> + append(Buffer, SectionTable);
> +
> + // Symbol Table
> + coff_symbol16 SymbolTable[NumberOfSymbols] = {
> + {{{'@', 'c', 'o', 'm', 'p', '.', 'i', 'd'}},
> + u32(0),
> + u16(0xFFFF),
> + u16(0),
> + IMAGE_SYM_CLASS_STATIC,
> + 0},
> + {{{'@', 'f', 'e', 'a', 't', '.', '0', '0'}},
> + u32(0),
> + u16(0xFFFF),
> + u16(0),
> + IMAGE_SYM_CLASS_STATIC,
> + 0},
> + {{{0, 0, 0, 0, 0, 0, 0, 0}},
> + u32(0),
> + u16(0),
> + u16(0),
> + IMAGE_SYM_CLASS_EXTERNAL,
> + 0},
> + {{{0, 0, 0, 0, 0, 0, 0, 0}},
> + u32(0),
> + u16(0),
> + u16(0),
> + IMAGE_SYM_CLASS_WEAK_EXTERNAL,
> + 1},
> + {{{2, 0, 0, 0, 3, 0, 0, 0}},
> + u32(0),
> + u16(0),
> + u16(0),
> + uint8_t(0),
> + 0},
> + };
> + reinterpret_cast<StringTableOffset &>(SymbolTable[2].Name).Offset =
> + sizeof(uint32_t);
> +
> + //__imp_ String Table
> + if(imp) {
> + reinterpret_cast<StringTableOffset &>(SymbolTable[3].Name).Offset =
> + sizeof(uint32_t) + Sym.size() + 1 + 6;
> + writeStringTable(Buffer, {std::string("__imp_").append(Sym),
> + std::string("__imp_").append(Weak)});
> + } else {
> + reinterpret_cast<StringTableOffset &>(SymbolTable[3].Name).Offset =
> + sizeof(uint32_t) + Sym.size() + 1;
> + writeStringTable(Buffer, {Sym, Weak});
> + }
> + append(Buffer, SymbolTable);
> +
> + StringRef F{reinterpret_cast<const char *>(Buffer.data()), Buffer.size()};
> + return {MemoryBufferRef{F, DLLName}};
> +
> +}
> +
> std::error_code writeImportLibrary(StringRef DLLName, StringRef Path,
> ArrayRef<COFFShortExport> Exports,
> MachineTypes Machine) {
> @@ -496,6 +583,14 @@
> if (E.Private)
> continue;
>
> + if (E.isWeak()) {
> + std::vector<uint8_t> *WeakBuffer1 = new std::vector<uint8_t>();
> + std::vector<uint8_t> *WeakBuffer2 = new std::vector<uint8_t>();
> + Members.push_back(OF.createWeakExternal(*WeakBuffer1, E.Name, E.ExtName, false));
> + Members.push_back(OF.createWeakExternal(*WeakBuffer2, E.Name, E.ExtName, true));
> + continue;
> + }
> +
> ImportType ImportType = IMPORT_CODE;
> if (E.Data)
> ImportType = IMPORT_DATA;
> Index: lib/Object/ArchiveWriter.cpp
> ===================================================================
> --- lib/Object/ArchiveWriter.cpp
> +++ lib/Object/ArchiveWriter.cpp
> @@ -314,7 +314,8 @@
> continue;
> if (!(Symflags & object::SymbolRef::SF_Global))
> continue;
> - if (Symflags & object::SymbolRef::SF_Undefined)
> + if (Symflags & object::SymbolRef::SF_Undefined &&
> + !(Symflags & object::SymbolRef::SF_Weak))
> continue;
This does look wrong for ELF. In any case, I will just check in a
testcase for ELF that will show the issue.
Cheers,
Rafael
More information about the llvm-commits
mailing list