Home | History | Annotate | Line # | Download | only in Object
      1 //===- COFFImportFile.h - COFF short import file implementation -*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 //
      9 // COFF short import file is a special kind of file which contains
     10 // only symbol names for DLL-exported symbols. This class implements
     11 // exporting of Symbols to create libraries and a SymbolicFile
     12 // interface for the file type.
     13 //
     14 //===----------------------------------------------------------------------===//
     15 
     16 #ifndef LLVM_OBJECT_COFFIMPORTFILE_H
     17 #define LLVM_OBJECT_COFFIMPORTFILE_H
     18 
     19 #include "llvm/ADT/ArrayRef.h"
     20 #include "llvm/Object/COFF.h"
     21 #include "llvm/Object/IRObjectFile.h"
     22 #include "llvm/Object/ObjectFile.h"
     23 #include "llvm/Object/SymbolicFile.h"
     24 #include "llvm/Support/MemoryBuffer.h"
     25 #include "llvm/Support/raw_ostream.h"
     26 
     27 namespace llvm {
     28 namespace object {
     29 
     30 class COFFImportFile : public SymbolicFile {
     31 public:
     32   COFFImportFile(MemoryBufferRef Source)
     33       : SymbolicFile(ID_COFFImportFile, Source) {}
     34 
     35   static bool classof(Binary const *V) { return V->isCOFFImportFile(); }
     36 
     37   void moveSymbolNext(DataRefImpl &Symb) const override { ++Symb.p; }
     38 
     39   Error printSymbolName(raw_ostream &OS, DataRefImpl Symb) const override {
     40     if (Symb.p == 0)
     41       OS << "__imp_";
     42     OS << StringRef(Data.getBufferStart() + sizeof(coff_import_header));
     43     return Error::success();
     44   }
     45 
     46   Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override {
     47     return SymbolRef::SF_Global;
     48   }
     49 
     50   basic_symbol_iterator symbol_begin() const override {
     51     return BasicSymbolRef(DataRefImpl(), this);
     52   }
     53 
     54   basic_symbol_iterator symbol_end() const override {
     55     DataRefImpl Symb;
     56     Symb.p = isData() ? 1 : 2;
     57     return BasicSymbolRef(Symb, this);
     58   }
     59 
     60   const coff_import_header *getCOFFImportHeader() const {
     61     return reinterpret_cast<const object::coff_import_header *>(
     62         Data.getBufferStart());
     63   }
     64 
     65 private:
     66   bool isData() const {
     67     return getCOFFImportHeader()->getType() == COFF::IMPORT_DATA;
     68   }
     69 };
     70 
     71 struct COFFShortExport {
     72   /// The name of the export as specified in the .def file or on the command
     73   /// line, i.e. "foo" in "/EXPORT:foo", and "bar" in "/EXPORT:foo=bar". This
     74   /// may lack mangling, such as underscore prefixing and stdcall suffixing.
     75   std::string Name;
     76 
     77   /// The external, exported name. Only non-empty when export renaming is in
     78   /// effect, i.e. "foo" in "/EXPORT:foo=bar".
     79   std::string ExtName;
     80 
     81   /// The real, mangled symbol name from the object file. Given
     82   /// "/export:foo=bar", this could be "_bar@8" if bar is stdcall.
     83   std::string SymbolName;
     84 
     85   /// Creates a weak alias. This is the name of the weak aliasee. In a .def
     86   /// file, this is "baz" in "EXPORTS\nfoo = bar == baz".
     87   std::string AliasTarget;
     88 
     89   uint16_t Ordinal = 0;
     90   bool Noname = false;
     91   bool Data = false;
     92   bool Private = false;
     93   bool Constant = false;
     94 
     95   friend bool operator==(const COFFShortExport &L, const COFFShortExport &R) {
     96     return L.Name == R.Name && L.ExtName == R.ExtName &&
     97             L.Ordinal == R.Ordinal && L.Noname == R.Noname &&
     98             L.Data == R.Data && L.Private == R.Private;
     99   }
    100 
    101   friend bool operator!=(const COFFShortExport &L, const COFFShortExport &R) {
    102     return !(L == R);
    103   }
    104 };
    105 
    106 Error writeImportLibrary(StringRef ImportName, StringRef Path,
    107                          ArrayRef<COFFShortExport> Exports,
    108                          COFF::MachineTypes Machine, bool MinGW);
    109 
    110 } // namespace object
    111 } // namespace llvm
    112 
    113 #endif
    114