Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:17

0001 //===- COFFImportFile.h - COFF short import file implementation -*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // COFF short import file is a special kind of file which contains
0010 // only symbol names for DLL-exported symbols. This class implements
0011 // exporting of Symbols to create libraries and a SymbolicFile
0012 // interface for the file type.
0013 //
0014 //===----------------------------------------------------------------------===//
0015 
0016 #ifndef LLVM_OBJECT_COFFIMPORTFILE_H
0017 #define LLVM_OBJECT_COFFIMPORTFILE_H
0018 
0019 #include "llvm/ADT/ArrayRef.h"
0020 #include "llvm/IR/Mangler.h"
0021 #include "llvm/Object/COFF.h"
0022 #include "llvm/Object/ObjectFile.h"
0023 #include "llvm/Object/SymbolicFile.h"
0024 #include "llvm/Support/MemoryBufferRef.h"
0025 #include "llvm/Support/raw_ostream.h"
0026 
0027 namespace llvm {
0028 namespace object {
0029 
0030 constexpr std::string_view ImportDescriptorPrefix = "__IMPORT_DESCRIPTOR_";
0031 constexpr std::string_view NullImportDescriptorSymbolName =
0032     "__NULL_IMPORT_DESCRIPTOR";
0033 constexpr std::string_view NullThunkDataPrefix = "\x7f";
0034 constexpr std::string_view NullThunkDataSuffix = "_NULL_THUNK_DATA";
0035 
0036 class COFFImportFile : public SymbolicFile {
0037 private:
0038   enum SymbolIndex { ImpSymbol, ThunkSymbol, ECAuxSymbol, ECThunkSymbol };
0039 
0040 public:
0041   COFFImportFile(MemoryBufferRef Source)
0042       : SymbolicFile(ID_COFFImportFile, Source) {}
0043 
0044   static bool classof(Binary const *V) { return V->isCOFFImportFile(); }
0045 
0046   void moveSymbolNext(DataRefImpl &Symb) const override { ++Symb.p; }
0047 
0048   Error printSymbolName(raw_ostream &OS, DataRefImpl Symb) const override;
0049 
0050   Expected<uint32_t> getSymbolFlags(DataRefImpl Symb) const override {
0051     return SymbolRef::SF_Global;
0052   }
0053 
0054   basic_symbol_iterator symbol_begin() const override {
0055     return BasicSymbolRef(DataRefImpl(), this);
0056   }
0057 
0058   basic_symbol_iterator symbol_end() const override {
0059     DataRefImpl Symb;
0060     if (isData())
0061       Symb.p = ImpSymbol + 1;
0062     else if (COFF::isArm64EC(getMachine()))
0063       Symb.p = ECThunkSymbol + 1;
0064     else
0065       Symb.p = ThunkSymbol + 1;
0066     return BasicSymbolRef(Symb, this);
0067   }
0068 
0069   bool is64Bit() const override { return false; }
0070 
0071   const coff_import_header *getCOFFImportHeader() const {
0072     return reinterpret_cast<const object::coff_import_header *>(
0073         Data.getBufferStart());
0074   }
0075 
0076   uint16_t getMachine() const { return getCOFFImportHeader()->Machine; }
0077 
0078   StringRef getFileFormatName() const;
0079   StringRef getExportName() const;
0080 
0081 private:
0082   bool isData() const {
0083     return getCOFFImportHeader()->getType() == COFF::IMPORT_DATA;
0084   }
0085 };
0086 
0087 struct COFFShortExport {
0088   /// The name of the export as specified in the .def file or on the command
0089   /// line, i.e. "foo" in "/EXPORT:foo", and "bar" in "/EXPORT:foo=bar". This
0090   /// may lack mangling, such as underscore prefixing and stdcall suffixing.
0091   std::string Name;
0092 
0093   /// The external, exported name. Only non-empty when export renaming is in
0094   /// effect, i.e. "foo" in "/EXPORT:foo=bar".
0095   std::string ExtName;
0096 
0097   /// The real, mangled symbol name from the object file. Given
0098   /// "/export:foo=bar", this could be "_bar@8" if bar is stdcall.
0099   std::string SymbolName;
0100 
0101   /// Creates an import library entry that imports from a DLL export with a
0102   /// different name. This is the name of the DLL export that should be
0103   /// referenced when linking against this import library entry. In a .def
0104   /// file, this is "baz" in "EXPORTS\nfoo = bar == baz".
0105   std::string ImportName;
0106 
0107   /// Specifies EXPORTAS name. In a .def file, this is "bar" in
0108   /// "EXPORTS\nfoo EXPORTAS bar".
0109   std::string ExportAs;
0110 
0111   uint16_t Ordinal = 0;
0112   bool Noname = false;
0113   bool Data = false;
0114   bool Private = false;
0115   bool Constant = false;
0116 
0117   friend bool operator==(const COFFShortExport &L, const COFFShortExport &R) {
0118     return L.Name == R.Name && L.ExtName == R.ExtName &&
0119             L.Ordinal == R.Ordinal && L.Noname == R.Noname &&
0120             L.Data == R.Data && L.Private == R.Private;
0121   }
0122 
0123   friend bool operator!=(const COFFShortExport &L, const COFFShortExport &R) {
0124     return !(L == R);
0125   }
0126 };
0127 
0128 /// Writes a COFF import library containing entries described by the Exports
0129 /// array.
0130 ///
0131 /// For hybrid targets such as ARM64EC, additional native entry points can be
0132 /// exposed using the NativeExports parameter. When NativeExports is used, the
0133 /// output import library will expose these native ARM64 imports alongside the
0134 /// entries described in the Exports array. Such a library can be used for
0135 /// linking both ARM64EC and pure ARM64 objects, and the linker will pick only
0136 /// the exports relevant to the target platform. For non-hybrid targets,
0137 /// the NativeExports parameter should not be used.
0138 Error writeImportLibrary(StringRef ImportName, StringRef Path,
0139                          ArrayRef<COFFShortExport> Exports,
0140                          COFF::MachineTypes Machine, bool MinGW,
0141                          ArrayRef<COFFShortExport> NativeExports = {});
0142 
0143 } // namespace object
0144 } // namespace llvm
0145 
0146 #endif