[llvm] r369600 - [Object] Add tapi files to object

Cyndy Ishida via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 21 16:30:53 PDT 2019


Author: cishida
Date: Wed Aug 21 16:30:53 2019
New Revision: 369600

URL: http://llvm.org/viewvc/llvm-project?rev=369600&view=rev
Log:
[Object] Add tapi files to object

Summary:
The intention for this is to allow reading and printing symbols out from
llvm-nm. Tapi file, and Tapi universal follow a similiar format to
their respective MachO Object format.

The tests are dependent on llvm-nm processing tbd files which is why its in D66160

Reviewers: ributzka, steven_wu, lhames

Reviewed By: ributzka, lhames

Subscribers: mgorny, hiraditya, dexonsmith, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D66159

Added:
    llvm/trunk/include/llvm/Object/TapiFile.h
    llvm/trunk/include/llvm/Object/TapiUniversal.h
    llvm/trunk/lib/Object/TapiFile.cpp
    llvm/trunk/lib/Object/TapiUniversal.cpp
Modified:
    llvm/trunk/include/llvm/Object/Binary.h
    llvm/trunk/lib/Object/Binary.cpp
    llvm/trunk/lib/Object/CMakeLists.txt
    llvm/trunk/lib/Object/LLVMBuild.txt

Modified: llvm/trunk/include/llvm/Object/Binary.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/Binary.h?rev=369600&r1=369599&r2=369600&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Object/Binary.h (original)
+++ llvm/trunk/include/llvm/Object/Binary.h Wed Aug 21 16:30:53 2019
@@ -42,7 +42,9 @@ protected:
     ID_Archive,
     ID_MachOUniversalBinary,
     ID_COFFImportFile,
-    ID_IR, // LLVM IR
+    ID_IR,            // LLVM IR
+    ID_TapiUniversal, // Text-based Dynamic Library Stub file.
+    ID_TapiFile,      // Text-based Dynamic Library Stub file.
 
     ID_Minidump,
 
@@ -101,16 +103,18 @@ public:
     return TypeID > ID_StartObjects && TypeID < ID_EndObjects;
   }
 
-  bool isSymbolic() const { return isIR() || isObject() || isCOFFImportFile(); }
-
-  bool isArchive() const {
-    return TypeID == ID_Archive;
+  bool isSymbolic() const {
+    return isIR() || isObject() || isCOFFImportFile() || isTapiFile();
   }
 
+  bool isArchive() const { return TypeID == ID_Archive; }
+
   bool isMachOUniversalBinary() const {
     return TypeID == ID_MachOUniversalBinary;
   }
 
+  bool isTapiUniversal() const { return TypeID == ID_TapiUniversal; }
+
   bool isELF() const {
     return TypeID >= ID_ELF32L && TypeID <= ID_ELF64B;
   }
@@ -137,6 +141,8 @@ public:
 
   bool isMinidump() const { return TypeID == ID_Minidump; }
 
+  bool isTapiFile() const { return TypeID == ID_TapiFile; }
+
   bool isLittleEndian() const {
     return !(TypeID == ID_ELF32B || TypeID == ID_ELF64B ||
              TypeID == ID_MachO32B || TypeID == ID_MachO64B);

Added: llvm/trunk/include/llvm/Object/TapiFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/TapiFile.h?rev=369600&view=auto
==============================================================================
--- llvm/trunk/include/llvm/Object/TapiFile.h (added)
+++ llvm/trunk/include/llvm/Object/TapiFile.h Wed Aug 21 16:30:53 2019
@@ -0,0 +1,60 @@
+//===- TapiFile.h - Text-based Dynamic Library Stub -------------*- C++ -*-===//
+//
+// 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 declares the TapiFile interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_TAPI_FILE_H
+#define LLVM_OBJECT_TAPI_FILE_H
+
+#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/iterator_range.h"
+#include "llvm/Object/SymbolicFile.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/TextAPI/MachO/InterfaceFile.h"
+
+namespace llvm {
+namespace object {
+
+class TapiFile : public SymbolicFile {
+public:
+  TapiFile(MemoryBufferRef Source, const MachO::InterfaceFile &interface,
+           MachO::Architecture Arch);
+  ~TapiFile() override;
+
+  void moveSymbolNext(DataRefImpl &DRI) const override;
+
+  Error printSymbolName(raw_ostream &OS, DataRefImpl DRI) const override;
+
+  uint32_t getSymbolFlags(DataRefImpl DRI) const override;
+
+  basic_symbol_iterator symbol_begin() const override;
+
+  basic_symbol_iterator symbol_end() const override;
+
+  static bool classof(const Binary *v) { return v->isTapiFile(); }
+
+private:
+  struct Symbol {
+    StringRef Prefix;
+    StringRef Name;
+    uint32_t Flags;
+
+    constexpr Symbol(StringRef Prefix, StringRef Name, uint32_t Flags)
+        : Prefix(Prefix), Name(Name), Flags(Flags) {}
+  };
+
+  std::vector<Symbol> Symbols;
+};
+
+} // end namespace object.
+} // end namespace llvm.
+
+#endif // LLVM_OBJECT_TAPI_FILE_H

Added: llvm/trunk/include/llvm/Object/TapiUniversal.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Object/TapiUniversal.h?rev=369600&view=auto
==============================================================================
--- llvm/trunk/include/llvm/Object/TapiUniversal.h (added)
+++ llvm/trunk/include/llvm/Object/TapiUniversal.h Wed Aug 21 16:30:53 2019
@@ -0,0 +1,109 @@
+//===-- TapiUniversal.h - Text-based Dynamic Library Stub -------*- C++ -*-===//
+//
+// 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 declares the TapiUniversal interface.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_OBJECT_TAPI_UNIVERSAL_H
+#define LLVM_OBJECT_TAPI_UNIVERSAL_H
+
+#include "llvm/Object/Binary.h"
+#include "llvm/Object/TapiFile.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/TextAPI/MachO/Architecture.h"
+#include "llvm/TextAPI/MachO/InterfaceFile.h"
+
+namespace llvm {
+namespace object {
+
+class TapiUniversal : public Binary {
+public:
+  class ObjectForArch {
+    const TapiUniversal *Parent;
+    int Index;
+
+  public:
+    ObjectForArch(const TapiUniversal *Parent, int Index)
+        : Parent(Parent), Index(Index) {}
+
+    ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
+
+    bool operator==(const ObjectForArch &Other) const {
+      return (Parent == Other.Parent) && (Index == Other.Index);
+    }
+
+    uint32_t getCPUType() const {
+      auto Result =
+          MachO::getCPUTypeFromArchitecture(Parent->Architectures[Index]);
+      return Result.first;
+    }
+
+    uint32_t getCPUSubType() const {
+      auto Result =
+          MachO::getCPUTypeFromArchitecture(Parent->Architectures[Index]);
+      return Result.second;
+    }
+
+    std::string getArchFlagName() const {
+      return MachO::getArchitectureName(Parent->Architectures[Index]);
+    }
+
+    Expected<std::unique_ptr<TapiFile>> getAsObjectFile() const;
+  };
+
+  class object_iterator {
+    ObjectForArch Obj;
+
+  public:
+    object_iterator(const ObjectForArch &Obj) : Obj(Obj) {}
+    const ObjectForArch *operator->() const { return &Obj; }
+    const ObjectForArch &operator*() const { return Obj; }
+
+    bool operator==(const object_iterator &Other) const {
+      return Obj == Other.Obj;
+    }
+    bool operator!=(const object_iterator &Other) const {
+      return !(*this == Other);
+    }
+
+    object_iterator &operator++() { // Preincrement
+      Obj = Obj.getNext();
+      return *this;
+    }
+  };
+
+  TapiUniversal(MemoryBufferRef Source, Error &Err);
+  static Expected<std::unique_ptr<TapiUniversal>>
+  create(MemoryBufferRef Source);
+  ~TapiUniversal() override;
+
+  object_iterator begin_objects() const { return ObjectForArch(this, 0); }
+  object_iterator end_objects() const {
+    return ObjectForArch(this, Architectures.size());
+  }
+
+  iterator_range<object_iterator> objects() const {
+    return make_range(begin_objects(), end_objects());
+  }
+
+  uint32_t getNumberOfObjects() const { return Architectures.size(); }
+
+  // Cast methods.
+  static bool classof(const Binary *v) { return v->isTapiUniversal(); }
+
+private:
+  std::unique_ptr<MachO::InterfaceFile> ParsedFile;
+  std::vector<MachO::Architecture> Architectures;
+};
+
+} // end namespace object.
+} // end namespace llvm.
+
+#endif // LLVM_OBJECT_TAPI_UNIVERSAL_H

Modified: llvm/trunk/lib/Object/Binary.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/Binary.cpp?rev=369600&r1=369599&r2=369600&view=diff
==============================================================================
--- llvm/trunk/lib/Object/Binary.cpp (original)
+++ llvm/trunk/lib/Object/Binary.cpp Wed Aug 21 16:30:53 2019
@@ -18,6 +18,7 @@
 #include "llvm/Object/MachOUniversal.h"
 #include "llvm/Object/Minidump.h"
 #include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/TapiUniversal.h"
 #include "llvm/Object/WindowsResource.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/ErrorHandling.h"
@@ -87,8 +88,7 @@ Expected<std::unique_ptr<Binary>> object
   case file_magic::minidump:
     return MinidumpFile::create(Buffer);
   case file_magic::tapi_file:
-    // Placeholder until TAPI is supported for lib/Object
-    return errorCodeToError(object_error::invalid_file_type);
+    return TapiUniversal::create(Buffer);
   }
   llvm_unreachable("Unexpected Binary File Type");
 }

Modified: llvm/trunk/lib/Object/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/CMakeLists.txt?rev=369600&r1=369599&r2=369600&view=diff
==============================================================================
--- llvm/trunk/lib/Object/CMakeLists.txt (original)
+++ llvm/trunk/lib/Object/CMakeLists.txt Wed Aug 21 16:30:53 2019
@@ -21,6 +21,8 @@ add_llvm_library(LLVMObject
   RelocationResolver.cpp
   SymbolicFile.cpp
   SymbolSize.cpp
+  TapiFile.cpp
+  TapiUniversal.cpp
   WasmObjectFile.cpp
   WindowsMachineFlag.cpp
   WindowsResource.cpp

Modified: llvm/trunk/lib/Object/LLVMBuild.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/LLVMBuild.txt?rev=369600&r1=369599&r2=369600&view=diff
==============================================================================
--- llvm/trunk/lib/Object/LLVMBuild.txt (original)
+++ llvm/trunk/lib/Object/LLVMBuild.txt Wed Aug 21 16:30:53 2019
@@ -18,4 +18,4 @@
 type = Library
 name = Object
 parent = Libraries
-required_libraries = BitReader Core MC BinaryFormat MCParser Support
+required_libraries = BitReader Core MC BinaryFormat MCParser Support TextAPI

Added: llvm/trunk/lib/Object/TapiFile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/TapiFile.cpp?rev=369600&view=auto
==============================================================================
--- llvm/trunk/lib/Object/TapiFile.cpp (added)
+++ llvm/trunk/lib/Object/TapiFile.cpp Wed Aug 21 16:30:53 2019
@@ -0,0 +1,104 @@
+//===- TapiFile.cpp -------------------------------------------------------===//
+//
+// 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 defines the Text-based Dynamcic Library Stub format.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Object/TapiFile.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+
+using namespace llvm;
+using namespace MachO;
+using namespace object;
+
+static constexpr StringLiteral ObjC1ClassNamePrefix = ".objc_class_name_";
+static constexpr StringLiteral ObjC2ClassNamePrefix = "_OBJC_CLASS_$_";
+static constexpr StringLiteral ObjC2MetaClassNamePrefix = "_OBJC_METACLASS_$_";
+static constexpr StringLiteral ObjC2EHTypePrefix = "_OBJC_EHTYPE_$_";
+static constexpr StringLiteral ObjC2IVarPrefix = "_OBJC_IVAR_$_";
+
+static uint32_t getFlags(const Symbol *Sym) {
+  uint32_t Flags = BasicSymbolRef::SF_Global;
+  if (Sym->isUndefined())
+    Flags |= BasicSymbolRef::SF_Undefined;
+  else
+    Flags |= BasicSymbolRef::SF_Exported;
+
+  if (Sym->isWeakDefined() || Sym->isWeakReferenced())
+    Flags |= BasicSymbolRef::SF_Weak;
+
+  return Flags;
+}
+
+TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &interface,
+                   Architecture Arch)
+    : SymbolicFile(ID_TapiFile, Source) {
+  for (const auto *Symbol : interface.symbols()) {
+    if (!Symbol->getArchitectures().has(Arch))
+      continue;
+
+    auto PlatformKind = interface.getPlatform();
+    switch (Symbol->getKind()) {
+    case SymbolKind::GlobalSymbol:
+      Symbols.emplace_back(StringRef(), Symbol->getName(), getFlags(Symbol));
+      break;
+    case SymbolKind::ObjectiveCClass:
+      if (PlatformKind == PlatformKind::macOS && Arch == AK_i386) {
+        Symbols.emplace_back(ObjC1ClassNamePrefix, Symbol->getName(),
+                             getFlags(Symbol));
+      } else {
+        Symbols.emplace_back(ObjC2ClassNamePrefix, Symbol->getName(),
+                             getFlags(Symbol));
+        Symbols.emplace_back(ObjC2MetaClassNamePrefix, Symbol->getName(),
+                             getFlags(Symbol));
+      }
+      break;
+    case SymbolKind::ObjectiveCClassEHType:
+      Symbols.emplace_back(ObjC2EHTypePrefix, Symbol->getName(),
+                           getFlags(Symbol));
+      break;
+    case SymbolKind::ObjectiveCInstanceVariable:
+      Symbols.emplace_back(ObjC2IVarPrefix, Symbol->getName(),
+                           getFlags(Symbol));
+      break;
+    }
+  }
+}
+
+TapiFile::~TapiFile() = default;
+
+void TapiFile::moveSymbolNext(DataRefImpl &DRI) const {
+  const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p);
+  DRI.p = reinterpret_cast<uintptr_t>(++Sym);
+}
+
+Error TapiFile::printSymbolName(raw_ostream &OS, DataRefImpl DRI) const {
+  const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p);
+  OS << Sym->Prefix << Sym->Name;
+  return Error::success();
+}
+
+uint32_t TapiFile::getSymbolFlags(DataRefImpl DRI) const {
+  const auto *Sym = reinterpret_cast<const Symbol *>(DRI.p);
+  return Sym->Flags;
+}
+
+basic_symbol_iterator TapiFile::symbol_begin() const {
+  DataRefImpl DRI;
+  DRI.p = reinterpret_cast<uintptr_t>(&*Symbols.begin());
+  return BasicSymbolRef{DRI, this};
+}
+
+basic_symbol_iterator TapiFile::symbol_end() const {
+  DataRefImpl DRI;
+  DRI.p = reinterpret_cast<uintptr_t>(&*Symbols.end());
+  return BasicSymbolRef{DRI, this};
+}

Added: llvm/trunk/lib/Object/TapiUniversal.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Object/TapiUniversal.cpp?rev=369600&view=auto
==============================================================================
--- llvm/trunk/lib/Object/TapiUniversal.cpp (added)
+++ llvm/trunk/lib/Object/TapiUniversal.cpp Wed Aug 21 16:30:53 2019
@@ -0,0 +1,54 @@
+//===- TapiUniversal.cpp --------------------------------------------------===//
+//
+// 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 defines the Text-based Dynamic Library Stub format.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Object/TapiUniversal.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Object/Error.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include "llvm/TextAPI/MachO/TextAPIReader.h"
+
+using namespace llvm;
+using namespace MachO;
+using namespace object;
+
+TapiUniversal::TapiUniversal(MemoryBufferRef Source, Error &Err)
+    : Binary(ID_TapiUniversal, Source) {
+  auto Result = TextAPIReader::get(Source);
+  ErrorAsOutParameter ErrAsOuParam(&Err);
+  if (!Result) {
+    Err = Result.takeError();
+    return;
+  }
+  ParsedFile = std::move(Result.get());
+
+  auto Archs = ParsedFile->getArchitectures();
+  for (auto Arch : Archs)
+    Architectures.emplace_back(Arch);
+}
+
+TapiUniversal::~TapiUniversal() = default;
+
+Expected<std::unique_ptr<TapiFile>>
+TapiUniversal::ObjectForArch::getAsObjectFile() const {
+  return std::unique_ptr<TapiFile>(new TapiFile(Parent->getMemoryBufferRef(),
+                                                *Parent->ParsedFile.get(),
+                                                Parent->Architectures[Index]));
+}
+
+Expected<std::unique_ptr<TapiUniversal>>
+TapiUniversal::create(MemoryBufferRef Source) {
+  Error Err = Error::success();
+  std::unique_ptr<TapiUniversal> Ret(new TapiUniversal(Source, Err));
+  if (Err)
+    return std::move(Err);
+  return std::move(Ret);
+}




More information about the llvm-commits mailing list