diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Object/COFFImportFile.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/Object/COFFImportFile.cpp | 114 | 
1 files changed, 87 insertions, 27 deletions
diff --git a/contrib/llvm-project/llvm/lib/Object/COFFImportFile.cpp b/contrib/llvm-project/llvm/lib/Object/COFFImportFile.cpp index 60556c149bf7..d3b5cf2d9f7b 100644 --- a/contrib/llvm-project/llvm/lib/Object/COFFImportFile.cpp +++ b/contrib/llvm-project/llvm/lib/Object/COFFImportFile.cpp @@ -52,6 +52,38 @@ StringRef COFFImportFile::getFileFormatName() const {    }  } +StringRef COFFImportFile::getExportName() const { +  const coff_import_header *hdr = getCOFFImportHeader(); +  StringRef name = Data.getBuffer().substr(sizeof(*hdr)).split('\0').first; + +  auto ltrim1 = [](StringRef s, StringRef chars) { +    return !s.empty() && chars.contains(s[0]) ? s.substr(1) : s; +  }; + +  switch (hdr->getNameType()) { +  case IMPORT_ORDINAL: +    name = ""; +    break; +  case IMPORT_NAME_NOPREFIX: +    name = ltrim1(name, "?@_"); +    break; +  case IMPORT_NAME_UNDECORATE: +    name = ltrim1(name, "?@_"); +    name = name.substr(0, name.find('@')); +    break; +  case IMPORT_NAME_EXPORTAS: { +    // Skip DLL name +    name = Data.getBuffer().substr(sizeof(*hdr) + name.size() + 1); +    name = name.split('\0').second.split('\0').first; +    break; +  } +  default: +    break; +  } + +  return name; +} +  static uint16_t getImgRelRelocation(MachineTypes Machine) {    switch (Machine) {    default: @@ -76,7 +108,7 @@ template <class T> static void append(std::vector<uint8_t> &B, const T &Data) {  }  static void writeStringTable(std::vector<uint8_t> &B, -                             ArrayRef<const std::string> Strings) { +                             ArrayRef<const std::string_view> Strings) {    // The COFF string table consists of a 4-byte value which is the size of the    // table, including the length field itself.  This value is followed by the    // string content itself, which is an array of null-terminated C-style @@ -139,9 +171,6 @@ static Expected<std::string> replace(StringRef S, StringRef From,    return (Twine(S.substr(0, Pos)) + To + S.substr(Pos + From.size())).str();  } -static const std::string NullImportDescriptorSymbolName = -    "__NULL_IMPORT_DESCRIPTOR"; -  namespace {  // This class constructs various small object files necessary to support linking  // symbols imported from a DLL.  The contents are pretty strictly defined and @@ -160,8 +189,9 @@ class ObjectFactory {  public:    ObjectFactory(StringRef S, MachineTypes M)        : NativeMachine(M), ImportName(S), Library(llvm::sys::path::stem(S)), -        ImportDescriptorSymbolName(("__IMPORT_DESCRIPTOR_" + Library).str()), -        NullThunkSymbolName(("\x7f" + Library + "_NULL_THUNK_DATA").str()) {} +        ImportDescriptorSymbolName((ImportDescriptorPrefix + Library).str()), +        NullThunkSymbolName( +            (NullThunkDataPrefix + Library + NullThunkDataSuffix).str()) {}    // Creates an Import Descriptor.  This is a small object file which contains a    // reference to the terminators and contains the library name (entry) for the @@ -183,6 +213,7 @@ public:    // Library Format.    NewArchiveMember createShortImport(StringRef Sym, uint16_t Ordinal,                                       ImportType Type, ImportNameType NameType, +                                     StringRef ExportName,                                       MachineTypes Machine);    // Create a weak external file which is described in PE/COFF Aux Format 3. @@ -474,12 +505,13 @@ NewArchiveMember ObjectFactory::createNullThunk(std::vector<uint8_t> &Buffer) {    return {MemoryBufferRef{F, ImportName}};  } -NewArchiveMember ObjectFactory::createShortImport(StringRef Sym, -                                                  uint16_t Ordinal, -                                                  ImportType ImportType, -                                                  ImportNameType NameType, -                                                  MachineTypes Machine) { +NewArchiveMember +ObjectFactory::createShortImport(StringRef Sym, uint16_t Ordinal, +                                 ImportType ImportType, ImportNameType NameType, +                                 StringRef ExportName, MachineTypes Machine) {    size_t ImpSize = ImportName.size() + Sym.size() + 2; // +2 for NULs +  if (!ExportName.empty()) +    ImpSize += ExportName.size() + 1;    size_t Size = sizeof(coff_import_header) + ImpSize;    char *Buf = Alloc.Allocate<char>(Size);    memset(Buf, 0, Size); @@ -499,6 +531,10 @@ NewArchiveMember ObjectFactory::createShortImport(StringRef Sym,    memcpy(P, Sym.data(), Sym.size());    P += Sym.size() + 1;    memcpy(P, ImportName.data(), ImportName.size()); +  if (!ExportName.empty()) { +    P += ImportName.size() + 1; +    memcpy(P, ExportName.data(), ExportName.size()); +  }    return {MemoryBufferRef(StringRef(Buf, Size), ImportName)};  } @@ -615,27 +651,51 @@ Error writeImportLibrary(StringRef ImportName, StringRef Path,        ImportType = IMPORT_CONST;      StringRef SymbolName = E.SymbolName.empty() ? E.Name : E.SymbolName; -    ImportNameType NameType = E.Noname -                                  ? IMPORT_ORDINAL -                                  : getNameType(SymbolName, E.Name, -                                                Machine, MinGW); -    Expected<std::string> Name = E.ExtName.empty() -                                     ? std::string(SymbolName) -                                     : replace(SymbolName, E.Name, E.ExtName); - -    if (!Name) -      return Name.takeError(); - -    if (!E.AliasTarget.empty() && *Name != E.AliasTarget) { +    std::string Name; + +    if (E.ExtName.empty()) { +      Name = std::string(SymbolName); +    } else { +      Expected<std::string> ReplacedName = +          replace(SymbolName, E.Name, E.ExtName); +      if (!ReplacedName) +        return ReplacedName.takeError(); +      Name.swap(*ReplacedName); +    } + +    if (!E.AliasTarget.empty() && Name != E.AliasTarget) {        Members.push_back( -          OF.createWeakExternal(E.AliasTarget, *Name, false, Machine)); +          OF.createWeakExternal(E.AliasTarget, Name, false, Machine));        Members.push_back( -          OF.createWeakExternal(E.AliasTarget, *Name, true, Machine)); +          OF.createWeakExternal(E.AliasTarget, Name, true, Machine));        continue;      } -    Members.push_back( -        OF.createShortImport(*Name, E.Ordinal, ImportType, NameType, Machine)); +    ImportNameType NameType; +    std::string ExportName; +    if (E.Noname) { +      NameType = IMPORT_ORDINAL; +    } else { +      NameType = getNameType(SymbolName, E.Name, Machine, MinGW); +    } + +    // On ARM64EC, use EXPORTAS to import demangled name for mangled symbols. +    if (ImportType == IMPORT_CODE && isArm64EC(Machine)) { +      if (std::optional<std::string> MangledName = +              getArm64ECMangledFunctionName(Name)) { +        if (ExportName.empty()) { +          NameType = IMPORT_NAME_EXPORTAS; +          ExportName.swap(Name); +        } +        Name = std::move(*MangledName); +      } else if (ExportName.empty()) { +        NameType = IMPORT_NAME_EXPORTAS; +        ExportName = std::move(*getArm64ECDemangledFunctionName(Name)); +      } +    } + +    Members.push_back(OF.createShortImport(Name, E.Ordinal, ImportType, +                                           NameType, ExportName, Machine));    }    return writeArchive(Path, Members, SymtabWritingMode::NormalSymtab,  | 
