================
@@ -0,0 +1,276 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM 
Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements shared functionality for linking static libraries
+// (archives) in offloading tools.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Frontend/Offloading/ArchiveLinker.h"
+#include "llvm/BinaryFormat/Magic.h"
+#include "llvm/Object/Archive.h"
+#include "llvm/Object/IRObjectFile.h"
+#include "llvm/Object/ObjectFile.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/Support/Path.h"
+#include <optional>
+#include <string>
+
+using namespace llvm;
+using namespace llvm::object;
+
+namespace llvm {
+namespace offloading {
+
+Expected<Symbol> Symbol::createFromObject(MemoryBufferRef File,
+                                          const SymbolRef &Sym) {
+  Symbol Result;
+  Result.File = File;
+
+  auto FlagsOrErr = Sym.getFlags();
+  if (!FlagsOrErr)
+    return FlagsOrErr.takeError();
+
+  if (*FlagsOrErr & SymbolRef::SF_Undefined)
+    Result.SymFlags |= Undefined;
+  if (*FlagsOrErr & SymbolRef::SF_Weak)
+    Result.SymFlags |= Weak;
+
+  return Result;
+}
+
+static std::optional<std::string> findFile(StringRef Dir, StringRef Root,
+                                           const Twine &Name) {
+  SmallString<128> Path;
+  if (Dir.starts_with("="))
+    sys::path::append(Path, Root, Dir.substr(1), Name);
+  else
+    sys::path::append(Path, Dir, Name);
+
+  if (sys::fs::exists(Path))
+    return static_cast<std::string>(Path);
+  return std::nullopt;
+}
+
+static std::optional<std::string>
+findFromSearchPaths(StringRef Name, StringRef Root,
+                    ArrayRef<StringRef> SearchPaths) {
+  for (StringRef Dir : SearchPaths)
+    if (std::optional<std::string> File = findFile(Dir, Root, Name))
+      return File;
+  return std::nullopt;
+}
+
+/// Search for static libraries in the linker's library path given input like
+/// `-lfoo` or `-l:libfoo.a`.
+static std::optional<std::string>
+searchLibrary(StringRef Input, StringRef Root,
+              ArrayRef<StringRef> SearchPaths) {
+  if (Input.starts_with(":"))
+    return findFromSearchPaths(Input.drop_front(), Root, SearchPaths);
+  SmallString<128> LibName;
+  ("lib" + Input + ".a").toVector(LibName);
+  return findFromSearchPaths(LibName, Root, SearchPaths);
+}
+
+static Expected<bool> getSymbolsFromBitcode(MemoryBufferRef Buffer,
+                                            StringMap<Symbol> &SymTab,
+                                            bool IsLazy) {
+  Expected<IRSymtabFile> IRSymtabOrErr = readIRSymtab(Buffer);
+  if (!IRSymtabOrErr)
+    return IRSymtabOrErr.takeError();
+  bool Extracted = !IsLazy;
+  StringMap<Symbol> PendingSymbols;
+  for (unsigned I = 0; I != IRSymtabOrErr->Mods.size(); ++I) {
+    for (const auto &IRSym : IRSymtabOrErr->TheReader.module_symbols(I)) {
+      if (IRSym.isFormatSpecific() || !IRSym.isGlobal())
+        continue;
+
+      StringMap<Symbol> &Target =
+          (IsLazy && !SymTab.count(IRSym.getName())) ? PendingSymbols : SymTab;
+      Symbol &OldSym = Target[IRSym.getName()];
+      Symbol Sym = Symbol(Buffer, IRSym);
+      if (OldSym.File.getBuffer().empty())
+        OldSym = Sym;
+
+      bool ResolvesReference =
+          !Sym.isUndefined() &&
+          (OldSym.isUndefined() || (OldSym.isWeak() && !Sym.isWeak())) &&
+          !(OldSym.isWeak() && OldSym.isUndefined() && IsLazy);
+      Extracted |= ResolvesReference;
+
+      Sym.UsedInRegularObj = OldSym.UsedInRegularObj;
+      if (ResolvesReference)
+        OldSym = Sym;
+    }
+  }
+  if (Extracted)
+    for (const auto &[Name, Symbol] : PendingSymbols)
+      SymTab[Name] = Symbol;
+  return Extracted;
+}
+
+static Expected<bool> getSymbolsFromObject(ObjectFile &ObjFile,
+                                           StringMap<Symbol> &SymTab,
+                                           bool IsLazy) {
+  bool Extracted = !IsLazy;
+  StringMap<Symbol> PendingSymbols;
+  for (SymbolRef ObjSym : ObjFile.symbols()) {
+    auto NameOrErr = ObjSym.getName();
+    if (!NameOrErr)
+      return NameOrErr.takeError();
+
+    StringMap<Symbol> &Target =
+        (IsLazy && !SymTab.count(*NameOrErr)) ? PendingSymbols : SymTab;
+    Symbol &OldSym = Target[*NameOrErr];
+
+    auto SymOrErr =
+        Symbol::createFromObject(ObjFile.getMemoryBufferRef(), ObjSym);
+    if (!SymOrErr)
+      return SymOrErr.takeError();
+    Symbol Sym = *SymOrErr;
+
+    if (OldSym.File.getBuffer().empty())
+      OldSym = Sym;
+
+    bool ResolvesReference = OldSym.isUndefined() && !Sym.isUndefined() &&
+                             (!OldSym.isWeak() || !IsLazy);
+    Extracted |= ResolvesReference;
+
+    if (ResolvesReference)
+      OldSym = Sym;
+    OldSym.UsedInRegularObj = true;
+  }
+  if (Extracted)
+    for (const auto &[Name, Symbol] : PendingSymbols)
+      SymTab[Name] = Symbol;
+  return Extracted;
+}
+
+static Expected<bool> getSymbols(MemoryBufferRef Buffer,
+                                 StringMap<Symbol> &SymTab, bool IsLazy) {
+  switch (identify_magic(Buffer.getBuffer())) {
+  case file_magic::bitcode: {
+    return getSymbolsFromBitcode(Buffer, SymTab, IsLazy);
+  }
+  case file_magic::elf_relocatable: {
+    Expected<std::unique_ptr<ObjectFile>> ObjFile =
+        ObjectFile::createObjectFile(Buffer);
+    if (!ObjFile)
+      return ObjFile.takeError();
+    return getSymbolsFromObject(**ObjFile, SymTab, IsLazy);
+  }
+  default:
+    return createStringError("Unsupported file type: '" +
+                             Buffer.getBufferIdentifier() + "'");
+  }
+}
+
+Expected<ResolvedInputs>
+resolveArchiveMembers(const Inputs &In,
+                      function_ref<bool(MemoryBufferRef)> IsFatBinary) {
----------------
bader wrote:

Please, check if 2ac9bed8e2d7 matches your thinking.

https://github.com/llvm/llvm-project/pull/201253
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to