diff --git a/llvm/docs/CommandGuide/llvm-nm.rst b/llvm/docs/CommandGuide/llvm-nm.rst --- a/llvm/docs/CommandGuide/llvm-nm.rst +++ b/llvm/docs/CommandGuide/llvm-nm.rst @@ -246,6 +246,10 @@ 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= Dump the symbols from the specified architecture(s). diff --git a/llvm/include/llvm/Object/TapiFile.h b/llvm/include/llvm/Object/TapiFile.h --- a/llvm/include/llvm/Object/TapiFile.h +++ b/llvm/include/llvm/Object/TapiFile.h @@ -41,6 +41,8 @@ static bool classof(const Binary *v) { return v->isTapiFile(); } + bool is64Bit() { return MachO::is64Bit(Arch); } + private: struct Symbol { StringRef Prefix; @@ -52,6 +54,7 @@ }; std::vector Symbols; + MachO::Architecture Arch; }; } // end namespace object. diff --git a/llvm/include/llvm/Object/TapiUniversal.h b/llvm/include/llvm/Object/TapiUniversal.h --- a/llvm/include/llvm/Object/TapiUniversal.h +++ b/llvm/include/llvm/Object/TapiUniversal.h @@ -41,18 +41,26 @@ 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> getAsObjectFile() const; @@ -86,21 +94,25 @@ 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 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 ParsedFile; - std::vector Architectures; + std::vector Libraries; }; } // end namespace object. diff --git a/llvm/include/llvm/TextAPI/MachO/Architecture.h b/llvm/include/llvm/TextAPI/MachO/Architecture.h --- a/llvm/include/llvm/TextAPI/MachO/Architecture.h +++ b/llvm/include/llvm/TextAPI/MachO/Architecture.h @@ -25,7 +25,7 @@ /// 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 @@ /// 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/include/llvm/TextAPI/MachO/Architecture.def b/llvm/include/llvm/TextAPI/MachO/Architecture.def --- 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/lib/Object/TapiFile.cpp b/llvm/lib/Object/TapiFile.cpp --- a/llvm/lib/Object/TapiFile.cpp +++ b/llvm/lib/Object/TapiFile.cpp @@ -40,7 +40,7 @@ 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 --- a/llvm/lib/Object/TapiUniversal.cpp +++ b/llvm/lib/Object/TapiUniversal.cpp @@ -22,7 +22,7 @@ TapiUniversal::TapiUniversal(MemoryBufferRef Source, Error &Err) : Binary(ID_TapiUniversal, Source) { - auto Result = TextAPIReader::get(Source); + Expected> Result = TextAPIReader::get(Source); ErrorAsOutParameter ErrAsOuParam(&Err); if (!Result) { Err = Result.takeError(); @@ -30,9 +30,16 @@ } 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 &File : ParsedFile->documents()) + FlattenObjectInfo(File); } TapiUniversal::~TapiUniversal() = default; @@ -41,7 +48,7 @@ TapiUniversal::ObjectForArch::getAsObjectFile() const { return std::unique_ptr(new TapiFile(Parent->getMemoryBufferRef(), *Parent->ParsedFile.get(), - Parent->Architectures[Index])); + Parent->Libraries[Index].Arch)); } Expected> diff --git a/llvm/lib/TextAPI/MachO/Architecture.cpp b/llvm/lib/TextAPI/MachO/Architecture.cpp --- 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 getArchitectureFromName(StringRef Name) { return StringSwitch(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 @@ 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 @@ std::pair 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 @@ 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 --- a/llvm/lib/TextAPI/MachO/TextStubCommon.cpp +++ b/llvm/lib/TextAPI/MachO/TextStubCommon.cpp @@ -129,7 +129,7 @@ void ScalarBitSetTraits::bitset(IO &IO, ArchitectureSet &Archs) { -#define ARCHINFO(arch, type, subtype) \ +#define ARCHINFO(arch, type, subtype, numbits) \ IO.bitSetCase(Archs, #arch, 1U << static_cast(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 --- /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 --- /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 --- /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 --- /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 --- /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 --- /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 --- /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 --- /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 --- /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 --- 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::desc("Disable LLVM bitcode reader"), cl::cat(NMCat)); +cl::opt 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 @@ return false; if (isa(Obj)) return false; + if (TapiFile *Tapi = dyn_cast(&Obj)) + return Tapi->is64Bit(); if (MachOObjectFile *MachO = dyn_cast(&Obj)) return MachO->is64Bit(); return cast(Obj).getBytesInAddress() == 8; @@ -1046,6 +1055,10 @@ 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 @@ Ret = getSymbolNMTypeChar(*MachO, I); else if (WasmObjectFile *Wasm = dyn_cast(&Obj)) Ret = getSymbolNMTypeChar(*Wasm, I); + else if (TapiFile *Tapi = dyn_cast(&Obj)) + Ret = getSymbolNMTypeChar(*Tapi, I); else if (ELFObjectFileBase *ELF = dyn_cast(&Obj)) { if (ELFSymbolRef(*I).getELFType() == ELF::STT_GNU_IFUNC) return 'i'; @@ -2081,6 +2096,31 @@ } return; } + + if (TapiUniversal *TU = dyn_cast(&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(&Bin)) { if (!MachOPrintSizeWarning && PrintSize && isa(O)) { WithColor::warning(errs(), ToolName)