[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