[PATCH] D29892: ar: add llvm-dlltool support

Martell Malone via llvm-commits llvm-commits at lists.llvm.org
Mon May 15 08:32:51 PDT 2017


>
> > 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.

Great, Thanks Rafael.
This should help a lot to ensure we don't break any existing functionality.

Suggestions are welcome on how best to make this happen for COFF only.
Passing magic boolean flags might not be the correct way.

Best,
Martell

On Mon, May 15, 2017 at 4:22 PM, Rafael Avila de Espindola <
rafael.espindola at gmail.com> wrote:

> 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
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170515/6468d8d2/attachment.html>


More information about the llvm-commits mailing list