[llvm] 28fefcc - [llvm][llvm-nm] add TextAPI/MachO support

Cyndy Ishida via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 11 19:00:32 PDT 2020


Author: Cyndy Ishida
Date: 2020-06-11T18:54:16-07:00
New Revision: 28fefcc83c52291fef817afbe469b4fd0a80ca20

URL: https://github.com/llvm/llvm-project/commit/28fefcc83c52291fef817afbe469b4fd0a80ca20
DIFF: https://github.com/llvm/llvm-project/commit/28fefcc83c52291fef817afbe469b4fd0a80ca20.diff

LOG: [llvm][llvm-nm] add TextAPI/MachO support

Summary:
This completes the needed glueing to support reading tbd files from nm.
This includes specifying which slice filtering with `--arch` and a new
option specifically for tbd files `--add-inlinedinfo` which will show
the reexported libraries that are appended in the tbd file.

Reviewers: ributzka, steven_wu, JDevlieghere, jhenderson

Reviewed By: JDevlieghere

Subscribers: hiraditya, MaskRay, dexonsmith, rupprecht, llvm-commits

Tags: #llvm

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

Added: 
    llvm/test/Object/Inputs/tapi-invalid-v1.tbd
    llvm/test/Object/Inputs/tapi-invalid-v2.tbd
    llvm/test/Object/Inputs/tapi-invalid-v3.tbd
    llvm/test/Object/Inputs/tapi-v1.tbd
    llvm/test/Object/Inputs/tapi-v2.tbd
    llvm/test/Object/Inputs/tapi-v3.tbd
    llvm/test/Object/Inputs/tapi-v4.tbd
    llvm/test/Object/nm-tapi-invalids.test
    llvm/test/Object/nm-tapi.test

Modified: 
    llvm/docs/CommandGuide/llvm-nm.rst
    llvm/include/llvm/Object/TapiFile.h
    llvm/include/llvm/Object/TapiUniversal.h
    llvm/include/llvm/TextAPI/MachO/Architecture.def
    llvm/include/llvm/TextAPI/MachO/Architecture.h
    llvm/lib/Object/TapiFile.cpp
    llvm/lib/Object/TapiUniversal.cpp
    llvm/lib/TextAPI/MachO/Architecture.cpp
    llvm/lib/TextAPI/MachO/TextStubCommon.cpp
    llvm/tools/llvm-nm/llvm-nm.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/docs/CommandGuide/llvm-nm.rst b/llvm/docs/CommandGuide/llvm-nm.rst
index 71efac7fa7af..c47be8034efc 100644
--- a/llvm/docs/CommandGuide/llvm-nm.rst
+++ b/llvm/docs/CommandGuide/llvm-nm.rst
@@ -246,6 +246,10 @@ MACH-O SPECIFIC OPTIONS
  Add symbols from the dyldinfo, if they are not already in the symbol table.
  This is the default.
 
+.. option:: --add-inlinedinfo
+
+ Add symbols from the inlined libraries, TBD file inputs only.
+
 .. option:: --arch=<arch1[,arch2,...]>
 
  Dump the symbols from the specified architecture(s).

diff  --git a/llvm/include/llvm/Object/TapiFile.h b/llvm/include/llvm/Object/TapiFile.h
index b20cd1a37aa0..ab99690ff2fa 100644
--- a/llvm/include/llvm/Object/TapiFile.h
+++ b/llvm/include/llvm/Object/TapiFile.h
@@ -41,6 +41,8 @@ class TapiFile : public SymbolicFile {
 
   static bool classof(const Binary *v) { return v->isTapiFile(); }
 
+  bool is64Bit() { return MachO::is64Bit(Arch); }
+
 private:
   struct Symbol {
     StringRef Prefix;
@@ -52,6 +54,7 @@ class TapiFile : public SymbolicFile {
   };
 
   std::vector<Symbol> Symbols;
+  MachO::Architecture Arch;
 };
 
 } // end namespace object.

diff  --git a/llvm/include/llvm/Object/TapiUniversal.h b/llvm/include/llvm/Object/TapiUniversal.h
index 923a9a26975c..0f494fcfac42 100644
--- a/llvm/include/llvm/Object/TapiUniversal.h
+++ b/llvm/include/llvm/Object/TapiUniversal.h
@@ -41,18 +41,26 @@ class TapiUniversal : public Binary {
 
     uint32_t getCPUType() const {
       auto Result =
-          MachO::getCPUTypeFromArchitecture(Parent->Architectures[Index]);
+          MachO::getCPUTypeFromArchitecture(Parent->Libraries[Index].Arch);
       return Result.first;
     }
 
     uint32_t getCPUSubType() const {
       auto Result =
-          MachO::getCPUTypeFromArchitecture(Parent->Architectures[Index]);
+          MachO::getCPUTypeFromArchitecture(Parent->Libraries[Index].Arch);
       return Result.second;
     }
 
     StringRef getArchFlagName() const {
-      return MachO::getArchitectureName(Parent->Architectures[Index]);
+      return MachO::getArchitectureName(Parent->Libraries[Index].Arch);
+    }
+
+    std::string getInstallName() const {
+      return std::string(Parent->Libraries[Index].InstallName);
+    }
+
+    bool isTopLevelLib() const {
+      return Parent->ParsedFile->getInstallName() == getInstallName();
     }
 
     Expected<std::unique_ptr<TapiFile>> getAsObjectFile() const;
@@ -86,21 +94,25 @@ class TapiUniversal : public Binary {
 
   object_iterator begin_objects() const { return ObjectForArch(this, 0); }
   object_iterator end_objects() const {
-    return ObjectForArch(this, Architectures.size());
+    return ObjectForArch(this, Libraries.size());
   }
 
   iterator_range<object_iterator> objects() const {
     return make_range(begin_objects(), end_objects());
   }
 
-  uint32_t getNumberOfObjects() const { return Architectures.size(); }
+  uint32_t getNumberOfObjects() const { return Libraries.size(); }
 
-  // Cast methods.
   static bool classof(const Binary *v) { return v->isTapiUniversal(); }
 
 private:
+  struct Library {
+    StringRef InstallName;
+    MachO::Architecture Arch;
+  };
+
   std::unique_ptr<MachO::InterfaceFile> ParsedFile;
-  std::vector<MachO::Architecture> Architectures;
+  std::vector<Library> Libraries;
 };
 
 } // end namespace object.

diff  --git a/llvm/include/llvm/TextAPI/MachO/Architecture.def b/llvm/include/llvm/TextAPI/MachO/Architecture.def
index be31382147bc..2fcae3b28d44 100644
--- a/llvm/include/llvm/TextAPI/MachO/Architecture.def
+++ b/llvm/include/llvm/TextAPI/MachO/Architecture.def
@@ -13,27 +13,27 @@
 ///
 /// X86 architectures sorted by cpu type and sub type id.
 ///
-ARCHINFO(i386, MachO::CPU_TYPE_I386, MachO::CPU_SUBTYPE_I386_ALL)
-ARCHINFO(x86_64, MachO::CPU_TYPE_X86_64, MachO::CPU_SUBTYPE_X86_64_ALL)
-ARCHINFO(x86_64h, MachO::CPU_TYPE_X86_64, MachO::CPU_SUBTYPE_X86_64_H)
+ARCHINFO(i386, MachO::CPU_TYPE_I386, MachO::CPU_SUBTYPE_I386_ALL, 32)
+ARCHINFO(x86_64, MachO::CPU_TYPE_X86_64, MachO::CPU_SUBTYPE_X86_64_ALL, 64)
+ARCHINFO(x86_64h, MachO::CPU_TYPE_X86_64, MachO::CPU_SUBTYPE_X86_64_H, 64)
 
 
 ///
 /// ARM architectures sorted by cpu sub type id.
 ///
-ARCHINFO(armv4t, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V4T)
-ARCHINFO(armv6, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V6)
-ARCHINFO(armv5, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V5TEJ)
-ARCHINFO(armv7, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7)
-ARCHINFO(armv7s, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7S)
-ARCHINFO(armv7k, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7K)
-ARCHINFO(armv6m, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V6M)
-ARCHINFO(armv7m, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7M)
-ARCHINFO(armv7em, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7EM)
+ARCHINFO(armv4t, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V4T, 32)
+ARCHINFO(armv6, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V6, 32)
+ARCHINFO(armv5, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V5TEJ, 32)
+ARCHINFO(armv7, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7, 32)
+ARCHINFO(armv7s, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7S, 32)
+ARCHINFO(armv7k, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7K, 32)
+ARCHINFO(armv6m, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V6M, 32)
+ARCHINFO(armv7m, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7M, 32)
+ARCHINFO(armv7em, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7EM, 32)
 
 
 ///
 /// ARM64 architectures sorted by cpu sub type id.
 ///
-ARCHINFO(arm64, MachO::CPU_TYPE_ARM64, MachO::CPU_SUBTYPE_ARM64_ALL)
-ARCHINFO(arm64e, MachO::CPU_TYPE_ARM64, MachO::CPU_SUBTYPE_ARM64E)
+ARCHINFO(arm64, MachO::CPU_TYPE_ARM64, MachO::CPU_SUBTYPE_ARM64_ALL, 64)
+ARCHINFO(arm64e, MachO::CPU_TYPE_ARM64, MachO::CPU_SUBTYPE_ARM64E, 64)

diff  --git a/llvm/include/llvm/TextAPI/MachO/Architecture.h b/llvm/include/llvm/TextAPI/MachO/Architecture.h
index c7ffea78962d..7a9f951d0316 100644
--- a/llvm/include/llvm/TextAPI/MachO/Architecture.h
+++ b/llvm/include/llvm/TextAPI/MachO/Architecture.h
@@ -25,7 +25,7 @@ namespace MachO {
 
 /// Defines the architecture slices that are supported by Text-based Stub files.
 enum Architecture : uint8_t {
-#define ARCHINFO(Arch, Type, SubType) AK_##Arch,
+#define ARCHINFO(Arch, Type, SubType, NumBits) AK_##Arch,
 #include "llvm/TextAPI/MachO/Architecture.def"
 #undef ARCHINFO
   AK_unknown, // this has to go last.
@@ -46,6 +46,9 @@ std::pair<uint32_t, uint32_t> getCPUTypeFromArchitecture(Architecture Arch);
 /// Convert a target to an architecture slice.
 Architecture mapToArchitecture(const llvm::Triple &Target);
 
+/// Check if architecture is 64 bit.
+bool is64Bit(Architecture);
+
 raw_ostream &operator<<(raw_ostream &OS, Architecture Arch);
 
 } // end namespace MachO.

diff  --git a/llvm/lib/Object/TapiFile.cpp b/llvm/lib/Object/TapiFile.cpp
index bbc341295db7..c732a8edbe73 100644
--- a/llvm/lib/Object/TapiFile.cpp
+++ b/llvm/lib/Object/TapiFile.cpp
@@ -40,7 +40,7 @@ static uint32_t getFlags(const Symbol *Sym) {
 
 TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &interface,
                    Architecture Arch)
-    : SymbolicFile(ID_TapiFile, Source) {
+    : SymbolicFile(ID_TapiFile, Source), Arch(Arch) {
   for (const auto *Symbol : interface.symbols()) {
     if (!Symbol->getArchitectures().has(Arch))
       continue;

diff  --git a/llvm/lib/Object/TapiUniversal.cpp b/llvm/lib/Object/TapiUniversal.cpp
index b3273e345a61..48cb949cb6f4 100644
--- a/llvm/lib/Object/TapiUniversal.cpp
+++ b/llvm/lib/Object/TapiUniversal.cpp
@@ -22,7 +22,7 @@ using namespace object;
 
 TapiUniversal::TapiUniversal(MemoryBufferRef Source, Error &Err)
     : Binary(ID_TapiUniversal, Source) {
-  auto Result = TextAPIReader::get(Source);
+  Expected<std::unique_ptr<InterfaceFile>> Result = TextAPIReader::get(Source);
   ErrorAsOutParameter ErrAsOuParam(&Err);
   if (!Result) {
     Err = Result.takeError();
@@ -30,9 +30,16 @@ TapiUniversal::TapiUniversal(MemoryBufferRef Source, Error &Err)
   }
   ParsedFile = std::move(Result.get());
 
-  auto Archs = ParsedFile->getArchitectures();
-  for (auto Arch : Archs)
-    Architectures.emplace_back(Arch);
+  auto FlattenObjectInfo = [this](const auto &File) {
+    StringRef Name = File->getInstallName();
+    for (const Architecture Arch : File->getArchitectures())
+      Libraries.emplace_back(Library({Name, Arch}));
+  };
+
+  FlattenObjectInfo(ParsedFile);
+  // Get inlined documents from tapi file.
+  for (const std::shared_ptr<InterfaceFile> &File : ParsedFile->documents())
+    FlattenObjectInfo(File);
 }
 
 TapiUniversal::~TapiUniversal() = default;
@@ -41,7 +48,7 @@ Expected<std::unique_ptr<TapiFile>>
 TapiUniversal::ObjectForArch::getAsObjectFile() const {
   return std::unique_ptr<TapiFile>(new TapiFile(Parent->getMemoryBufferRef(),
                                                 *Parent->ParsedFile.get(),
-                                                Parent->Architectures[Index]));
+                                                Parent->Libraries[Index].Arch));
 }
 
 Expected<std::unique_ptr<TapiUniversal>>

diff  --git a/llvm/lib/TextAPI/MachO/Architecture.cpp b/llvm/lib/TextAPI/MachO/Architecture.cpp
index e1c2d42927ec..0c5988030336 100644
--- a/llvm/lib/TextAPI/MachO/Architecture.cpp
+++ b/llvm/lib/TextAPI/MachO/Architecture.cpp
@@ -15,12 +15,13 @@
 #include "llvm/ADT/Triple.h"
 #include "llvm/BinaryFormat/MachO.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/TextAPI/MachO/ArchitectureSet.h"
 
 namespace llvm {
 namespace MachO {
 
 Architecture getArchitectureFromCpuType(uint32_t CPUType, uint32_t CPUSubType) {
-#define ARCHINFO(Arch, Type, Subtype)                                          \
+#define ARCHINFO(Arch, Type, Subtype, NumBits)                                 \
   if (CPUType == (Type) &&                                                     \
       (CPUSubType & ~MachO::CPU_SUBTYPE_MASK) == (Subtype))                    \
     return AK_##Arch;
@@ -32,7 +33,7 @@ Architecture getArchitectureFromCpuType(uint32_t CPUType, uint32_t CPUSubType) {
 
 Architecture getArchitectureFromName(StringRef Name) {
   return StringSwitch<Architecture>(Name)
-#define ARCHINFO(Arch, Type, Subtype) .Case(#Arch, AK_##Arch)
+#define ARCHINFO(Arch, Type, Subtype, NumBits) .Case(#Arch, AK_##Arch)
 #include "llvm/TextAPI/MachO/Architecture.def"
 #undef ARCHINFO
       .Default(AK_unknown);
@@ -40,7 +41,7 @@ Architecture getArchitectureFromName(StringRef Name) {
 
 StringRef getArchitectureName(Architecture Arch) {
   switch (Arch) {
-#define ARCHINFO(Arch, Type, Subtype)                                          \
+#define ARCHINFO(Arch, Type, Subtype, NumBits)                                 \
   case AK_##Arch:                                                              \
     return #Arch;
 #include "llvm/TextAPI/MachO/Architecture.def"
@@ -56,7 +57,7 @@ StringRef getArchitectureName(Architecture Arch) {
 
 std::pair<uint32_t, uint32_t> getCPUTypeFromArchitecture(Architecture Arch) {
   switch (Arch) {
-#define ARCHINFO(Arch, Type, Subtype)                                          \
+#define ARCHINFO(Arch, Type, Subtype, NumBits)                                 \
   case AK_##Arch:                                                              \
     return std::make_pair(Type, Subtype);
 #include "llvm/TextAPI/MachO/Architecture.def"
@@ -74,6 +75,20 @@ Architecture mapToArchitecture(const Triple &Target) {
   return getArchitectureFromName(Target.getArchName());
 }
 
+bool is64Bit(Architecture Arch) {
+  switch (Arch) {
+#define ARCHINFO(Arch, Type, Subtype, NumBits)                                 \
+  case AK_##Arch:                                                              \
+    return NumBits == 64;
+#include "llvm/TextAPI/MachO/Architecture.def"
+#undef ARCHINFO
+  case AK_unknown:
+    return false;
+  }
+
+  llvm_unreachable("Fully handled switch case above.");
+}
+
 raw_ostream &operator<<(raw_ostream &OS, Architecture Arch) {
   OS << getArchitectureName(Arch);
   return OS;

diff  --git a/llvm/lib/TextAPI/MachO/TextStubCommon.cpp b/llvm/lib/TextAPI/MachO/TextStubCommon.cpp
index 2da0b11da831..4a82df6beac1 100644
--- a/llvm/lib/TextAPI/MachO/TextStubCommon.cpp
+++ b/llvm/lib/TextAPI/MachO/TextStubCommon.cpp
@@ -129,7 +129,7 @@ QuotingType ScalarTraits<PlatformSet>::mustQuote(StringRef) {
 
 void ScalarBitSetTraits<ArchitectureSet>::bitset(IO &IO,
                                                  ArchitectureSet &Archs) {
-#define ARCHINFO(arch, type, subtype)                                          \
+#define ARCHINFO(arch, type, subtype, numbits)                                 \
   IO.bitSetCase(Archs, #arch, 1U << static_cast<int>(AK_##arch));
 #include "llvm/TextAPI/MachO/Architecture.def"
 #undef ARCHINFO

diff  --git a/llvm/test/Object/Inputs/tapi-invalid-v1.tbd b/llvm/test/Object/Inputs/tapi-invalid-v1.tbd
new file mode 100644
index 000000000000..ab382378a22f
--- /dev/null
+++ b/llvm/test/Object/Inputs/tapi-invalid-v1.tbd
@@ -0,0 +1,15 @@
+--- !tapi-tbd-v1
+
+archs: [ armv7, armv7s, arm64 ]
+
+platform: ios
+install-name: /u/l/libfoo.dylib
+current-version: 1.2.3
+compatibility-version: 1.0
+swift-version: 0
+objc-constraint: none
+expors:
+ - archs: [ arm64, armv7 ]
+   allowed-clients: [ client ]
+   symbols: [ _sym, _test, _a, _b, ]
+...

diff  --git a/llvm/test/Object/Inputs/tapi-invalid-v2.tbd b/llvm/test/Object/Inputs/tapi-invalid-v2.tbd
new file mode 100644
index 000000000000..653381e645f3
--- /dev/null
+++ b/llvm/test/Object/Inputs/tapi-invalid-v2.tbd
@@ -0,0 +1,21 @@
+--- !tapi-tbd-v2
+uuids: [ "armv7: 00000000-0000-0000-0000-000000000000",
+         "armv7s: 11111111-1111-1111-1111-111111111111",
+         "arm64: 22222222-2222-2222-2222-222222222222" ]
+platform: ios
+flags: [ installapi ]
+install-name: /u/l/libfoo.dylib
+current-version: 1.2.3
+compatibility-version: 1.0
+swift-version: 0
+objc-constraint: retain_release
+parent-umbrella: Umbrella.dylib
+exports:
+  - archs: [ armv7, armv7s, arm64 ]
+    allowable-clients: [ client ]
+    re-exports: [ ]
+    symbols: [ _sym1, _sym2, _sym3 ]
+undefineds:
+  - archs: [ arm64 ]
+    symbols: [ _sym ]
+...

diff  --git a/llvm/test/Object/Inputs/tapi-invalid-v3.tbd b/llvm/test/Object/Inputs/tapi-invalid-v3.tbd
new file mode 100644
index 000000000000..d932216c9964
--- /dev/null
+++ b/llvm/test/Object/Inputs/tapi-invalid-v3.tbd
@@ -0,0 +1,23 @@
+--- !tapi-tbd-v3
+archs: [ i386, armv7, armv7s ]
+platform: ios
+install-name: /usr/lib/libfoo.dylib
+swift-abi-version: 3
+exports:
+  - archs: [ i386, armv7, armv7s ]
+    re-exports: [ /usr/lib/external/liba.dylib ]
+    symbols: [ _sym1, _sym2 ]
+    objc-classes: [ NSString, NSBlockPredicate ]
+    objc-eh-types: [ NSString ]
+    objc-ivars: [ NSBlockPredicate._block ]
+  - archs: [ i386 ]
+    symbols: [ _sym3 ]
+--- !tapi-tbd-v3
+archs: [ armv7, armv7s ]
+platform: ios
+install-name: /usr/lib/liba.dylib
+swift-version: 3
+exports:
+  - archs: [ armv7, armv7s ]
+    symbols: [ _sym10, _sym11 ]
+...

diff  --git a/llvm/test/Object/Inputs/tapi-v1.tbd b/llvm/test/Object/Inputs/tapi-v1.tbd
new file mode 100644
index 000000000000..80e1efd944e3
--- /dev/null
+++ b/llvm/test/Object/Inputs/tapi-v1.tbd
@@ -0,0 +1,15 @@
+--- !tapi-tbd-v1
+
+archs: [ armv7, armv7s ]
+
+platform: ios
+install-name: /u/l/libfoo.dylib
+current-version: 1.2.3
+compatibility-version: 1.0
+swift-version: 0
+objc-constraint: none
+exports:
+ - archs: [ armv7, armv7s ]
+   allowed-clients: [ client ]
+   symbols: [ _sym, ]
+...

diff  --git a/llvm/test/Object/Inputs/tapi-v2.tbd b/llvm/test/Object/Inputs/tapi-v2.tbd
new file mode 100644
index 000000000000..228f98332ef9
--- /dev/null
+++ b/llvm/test/Object/Inputs/tapi-v2.tbd
@@ -0,0 +1,21 @@
+--- !tapi-tbd-v2
+archs: [ armv7, armv7s, arm64 ]
+uuids: [ "armv7: 00000000-0000-0000-0000-000000000000",
+         "armv7s: 11111111-1111-1111-1111-111111111111",
+         "arm64: 22222222-2222-2222-2222-222222222222" ]
+platform: ios
+flags: [ installapi, flat_namespace ]
+install-name: /u/l/libfoo.dylib
+current-version: 1.2.3
+compatibility-version: 1.0
+swift-version: 0
+objc-constraint: retain_release
+parent-umbrella: Umbrella.dylib
+exports:
+  - archs: [ armv7, armv7s, arm64 ]
+    symbols: [ _sym1, _sym2, _sym3 ]
+
+undefineds:
+  - archs: [ arm64 ]
+    symbols: [ _sym ]
+...

diff  --git a/llvm/test/Object/Inputs/tapi-v3.tbd b/llvm/test/Object/Inputs/tapi-v3.tbd
new file mode 100644
index 000000000000..d00d61c7a7a9
--- /dev/null
+++ b/llvm/test/Object/Inputs/tapi-v3.tbd
@@ -0,0 +1,24 @@
+--- !tapi-tbd-v3
+archs: [ i386, x86_64 ]
+platform: ios
+install-name: /usr/lib/libfoo.dylib
+swift-abi-version: 3
+exports:
+  - archs: [ i386, x86_64 ]
+    re-exports: [ /usr/lib/external/liba.dylib ]
+    symbols: [ _sym1, _sym2 ]
+    objc-classes: [ NSString, NSBlockPredicate ]
+    objc-eh-types: [ NSString ]
+    objc-ivars: [ NSBlockPredicate._block ]
+  - archs: [ i386 ]
+    symbols: [ _sym3 ]
+--- !tapi-tbd-v3
+archs: [ x86_64 ]
+platform: ios
+install-name: /usr/lib/liba.dylib
+swift-abi-version: 3
+parent-umbrella: foo
+exports:
+  - archs: [ x86_64 ]
+    symbols: [ _sym10, _sym11 ]
+...

diff  --git a/llvm/test/Object/Inputs/tapi-v4.tbd b/llvm/test/Object/Inputs/tapi-v4.tbd
new file mode 100644
index 000000000000..33f656071d5f
--- /dev/null
+++ b/llvm/test/Object/Inputs/tapi-v4.tbd
@@ -0,0 +1,38 @@
+--- !tapi-tbd
+tbd-version:     4
+targets:         [ i386-ios-simulator, x86_64-ios-simulator ]
+uuids:
+  - target:          i386-ios-simulator
+    value:           00000000-0000-0000-0000-000000000000
+  - target:          x86_64-ios-simulator
+    value:           12FF0E69-DD5A-3356-BB9E-24A133D816F0
+install-name:    '/u/l/libFoo.dylib'
+current-version: 1288
+reexported-libraries:
+  - targets:              [ i386-ios-simulator, x86_64-ios-simulator ]
+    libraries:            [  '/u/l/s/libPrivate.dylib', '/u/l/libPublic.dylib' ]
+exports:
+  - targets:              [ i386-ios-simulator ]
+    symbols:              [ '_sym1' ]
+    weak-symbols:         [ '_sym2' ]
+  - targets:              [ x86_64-ios-simulator, i386-ios-simulator ]
+    symbols:              [ '_sym3', '_sym4' ]
+--- !tapi-tbd
+tbd-version:     4
+targets:         [ i386-ios-simulator, x86_64-ios-simulator ]
+uuids:
+  - target:          i386-ios-simulator
+    value:           2E88EC2B-F951-3D76-B114-F6CC635EFE8C
+  - target:          x86_64-ios-simulator
+    value:           42CD91A1-9824-3FC3-81B2-5355D95C99C7
+install-name:    '/u/l/s/libPrivate.dylib'
+current-version: 60177
+parent-umbrella:
+  - targets:         [ i386-ios-simulator, x86_64-ios-simulator ]
+    umbrella:        Foo 
+exports:
+  - targets:         [ x86_64-ios-simulator ]
+    symbols:         [ '_sym1', '_sym2' ]
+  - targets:         [ x86_64-ios-simulator, i386-ios-simulator ]
+    symbols:         [  '_sym3', '_sym4' ]
+...

diff  --git a/llvm/test/Object/nm-tapi-invalids.test b/llvm/test/Object/nm-tapi-invalids.test
new file mode 100644
index 000000000000..95ed521c918b
--- /dev/null
+++ b/llvm/test/Object/nm-tapi-invalids.test
@@ -0,0 +1,20 @@
+RUN: not llvm-nm %p/Inputs/tapi-invalid-v1.tbd 2>&1\
+RUN:          | FileCheck %s -check-prefix V1 
+
+RUN: not llvm-nm %p/Inputs/tapi-invalid-v2.tbd 2>&1\
+RUN:          | FileCheck %s -check-prefix V2
+
+RUN: not llvm-nm %p/Inputs/tapi-invalid-v3.tbd 2>&1\
+RUN:          | FileCheck %s -check-prefix V3
+
+# Typo Check
+V1: tapi-invalid-v1.tbd malformed file
+V1-NEXT: tapi-invalid-v1.tbd:12:2: error: unknown key 'expors'
+
+# Missing required key
+V2: tapi-invalid-v2.tbd malformed file
+V2-NEXT: tapi-invalid-v2.tbd:2:1: error: missing required key 'archs'
+
+# v2 key in v3 specified file
+V3: tapi-invalid-v3.tbd malformed file
+V3-NEXT: tapi-invalid-v3.tbd:19:16: error: unknown key 'swift-version'

diff  --git a/llvm/test/Object/nm-tapi.test b/llvm/test/Object/nm-tapi.test
new file mode 100644
index 000000000000..8f49daedd6bc
--- /dev/null
+++ b/llvm/test/Object/nm-tapi.test
@@ -0,0 +1,58 @@
+RUN: llvm-nm %p/Inputs/tapi-v1.tbd 2>&1\
+RUN:          | FileCheck %s -check-prefix V1
+
+RUN: llvm-nm %p/Inputs/tapi-v2.tbd \
+RUN:          | FileCheck %s -check-prefix V2
+
+RUN: llvm-nm --add-inlinedinfo --arch=x86_64 %p/Inputs/tapi-v3.tbd \
+RUN:          | FileCheck %s -check-prefix V3
+
+RUN: llvm-nm %p/Inputs/tapi-v4.tbd \
+RUN:          | FileCheck %s -check-prefix V4
+
+V1: /u/l/libfoo.dylib (for architecture armv7):
+V1-NEXT: 00000000 S _sym
+V1: /u/l/libfoo.dylib (for architecture armv7s):
+V1-NEXT: 00000000 S _sym
+
+V2: /u/l/libfoo.dylib (for architecture armv7):
+V2-NEXT: 00000000 S _sym1
+V2-NEXT: 00000000 S _sym2
+V2-NEXT: 00000000 S _sym3
+V2: /u/l/libfoo.dylib (for architecture armv7s):
+V2-NEXT: 00000000 S _sym1
+V2-NEXT: 00000000 S _sym2
+V2-NEXT: 00000000 S _sym3
+V2: /u/l/libfoo.dylib (for architecture arm64):
+V2-NEXT:          U _sym
+V2-NEXT: 0000000000000000 S _sym1
+V2-NEXT: 0000000000000000 S _sym2
+V2-NEXT: 0000000000000000 S _sym3
+
+V3: /usr/lib/libfoo.dylib (for architecture x86_64):
+V3-NEXT: 0000000000000000 S _OBJC_CLASS_$_NSBlockPredicate
+V3-NEXT: 0000000000000000 S _OBJC_CLASS_$_NSString
+V3-NEXT: 0000000000000000 S _OBJC_EHTYPE_$_NSString
+V3-NEXT: 0000000000000000 S _OBJC_IVAR_$_NSBlockPredicate._block
+V3-NEXT: 0000000000000000 S _OBJC_METACLASS_$_NSBlockPredicate
+V3-NEXT: 0000000000000000 S _OBJC_METACLASS_$_NSString
+V3-NEXT: 0000000000000000 S _sym1
+V3-NEXT: 0000000000000000 S _sym2
+V3: /usr/lib/liba.dylib (for architecture x86_64):
+V3-NEXT: 0000000000000000 S _OBJC_CLASS_$_NSBlockPredicate
+V3-NEXT: 0000000000000000 S _OBJC_CLASS_$_NSString
+V3-NEXT: 0000000000000000 S _OBJC_EHTYPE_$_NSString
+V3-NEXT: 0000000000000000 S _OBJC_IVAR_$_NSBlockPredicate._block
+V3-NEXT: 0000000000000000 S _OBJC_METACLASS_$_NSBlockPredicate
+V3-NEXT: 0000000000000000 S _OBJC_METACLASS_$_NSString
+V3-NEXT: 0000000000000000 S _sym1
+V3-NEXT: 0000000000000000 S _sym2
+
+V4: /u/l/libFoo.dylib (for architecture i386):
+V4-NEXT: 00000000 S _sym1
+V4-NEXT: 00000000 W _sym2
+V4-NEXT: 00000000 S _sym3
+V4-NEXT: 00000000 S _sym4
+V4: /u/l/libFoo.dylib (for architecture x86_64):
+V4-NEXT: 0000000000000000 S _sym3
+V4-NEXT: 0000000000000000 S _sym4

diff  --git a/llvm/tools/llvm-nm/llvm-nm.cpp b/llvm/tools/llvm-nm/llvm-nm.cpp
index 496ad3ce4be5..4385e2aaa287 100644
--- a/llvm/tools/llvm-nm/llvm-nm.cpp
+++ b/llvm/tools/llvm-nm/llvm-nm.cpp
@@ -28,6 +28,8 @@
 #include "llvm/Object/MachO.h"
 #include "llvm/Object/MachOUniversal.h"
 #include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/TapiFile.h"
+#include "llvm/Object/TapiUniversal.h"
 #include "llvm/Object/Wasm.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/FileSystem.h"
@@ -210,6 +212,11 @@ cl::opt<bool> NoLLVMBitcode("no-llvm-bc",
                             cl::desc("Disable LLVM bitcode reader"),
                             cl::cat(NMCat));
 
+cl::opt<bool> AddInlinedInfo("add-inlinedinfo",
+                             cl::desc("Add symbols from the inlined libraries, "
+                                      "TBD(Mach-O) only"),
+                             cl::cat(NMCat));
+
 cl::extrahelp HelpResponse("\nPass @FILE as argument to read options from FILE.\n");
 
 bool PrintAddress = true;
@@ -340,6 +347,8 @@ static char isSymbolList64Bit(SymbolicFile &Obj) {
     return false;
   if (isa<WasmObjectFile>(Obj))
     return false;
+  if (TapiFile *Tapi = dyn_cast<TapiFile>(&Obj))
+    return Tapi->is64Bit();
   if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj))
     return MachO->is64Bit();
   return cast<ELFObjectFileBase>(Obj).getBytesInAddress() == 8;
@@ -1046,6 +1055,10 @@ static char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) {
   return '?';
 }
 
+static char getSymbolNMTypeChar(TapiFile &Obj, basic_symbol_iterator I) {
+  return 's';
+}
+
 static char getSymbolNMTypeChar(WasmObjectFile &Obj, basic_symbol_iterator I) {
   uint32_t Flags = cantFail(I->getFlags());
   if (Flags & SymbolRef::SF_Executable)
@@ -1139,6 +1152,8 @@ static char getNMSectionTagAndName(SymbolicFile &Obj, basic_symbol_iterator I,
     Ret = getSymbolNMTypeChar(*MachO, I);
   else if (WasmObjectFile *Wasm = dyn_cast<WasmObjectFile>(&Obj))
     Ret = getSymbolNMTypeChar(*Wasm, I);
+  else if (TapiFile *Tapi = dyn_cast<TapiFile>(&Obj))
+    Ret = getSymbolNMTypeChar(*Tapi, I);
   else if (ELFObjectFileBase *ELF = dyn_cast<ELFObjectFileBase>(&Obj)) {
     if (ELFSymbolRef(*I).getELFType() == ELF::STT_GNU_IFUNC)
       return 'i';
@@ -2081,6 +2096,31 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
     }
     return;
   }
+
+  if (TapiUniversal *TU = dyn_cast<TapiUniversal>(&Bin)) {
+    for (const TapiUniversal::ObjectForArch &I : TU->objects()) {
+      StringRef ArchName = I.getArchFlagName();
+      const bool ShowArch =
+          ArchFlags.empty() ||
+          any_of(ArchFlags, [&](StringRef Name) { return Name == ArchName; });
+      if (!ShowArch)
+        continue;
+      if (!AddInlinedInfo && !I.isTopLevelLib())
+        continue;
+      if (auto ObjOrErr = I.getAsObjectFile()) {
+        outs() << "\n"
+               << I.getInstallName() << " (for architecture " << ArchName << ")"
+               << ":\n";
+        dumpSymbolNamesFromObject(*ObjOrErr.get(), false, {}, ArchName);
+      } else if (Error E =
+                     isNotObjectErrorInvalidFileType(ObjOrErr.takeError())) {
+        error(std::move(E), Filename, ArchName);
+      }
+    }
+
+    return;
+  }
+
   if (SymbolicFile *O = dyn_cast<SymbolicFile>(&Bin)) {
     if (!MachOPrintSizeWarning && PrintSize &&  isa<MachOObjectFile>(O)) {
       WithColor::warning(errs(), ToolName)


        


More information about the llvm-commits mailing list