Skip to content

Commit

Permalink
[llvm][llvm-nm] add TextAPI/MachO support
Browse files Browse the repository at this point in the history
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
  • Loading branch information
cyndyishida committed Jun 12, 2020
1 parent 519b019 commit 28fefcc
Show file tree
Hide file tree
Showing 19 changed files with 352 additions and 33 deletions.
4 changes: 4 additions & 0 deletions llvm/docs/CommandGuide/llvm-nm.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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).
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/Object/TapiFile.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -52,6 +54,7 @@ class TapiFile : public SymbolicFile {
};

std::vector<Symbol> Symbols;
MachO::Architecture Arch;
};

} // end namespace object.
Expand Down
26 changes: 19 additions & 7 deletions llvm/include/llvm/Object/TapiUniversal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down
28 changes: 14 additions & 14 deletions llvm/include/llvm/TextAPI/MachO/Architecture.def
Original file line number Diff line number Diff line change
Expand Up @@ -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)
5 changes: 4 additions & 1 deletion llvm/include/llvm/TextAPI/MachO/Architecture.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Object/TapiFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
17 changes: 12 additions & 5 deletions llvm/lib/Object/TapiUniversal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,24 @@ 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();
return;
}
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;
Expand All @@ -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>>
Expand Down
23 changes: 19 additions & 4 deletions llvm/lib/TextAPI/MachO/Architecture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -32,15 +33,15 @@ 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);
}

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"
Expand All @@ -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"
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/TextAPI/MachO/TextStubCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
15 changes: 15 additions & 0 deletions llvm/test/Object/Inputs/tapi-invalid-v1.tbd
Original file line number Diff line number Diff line change
@@ -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, ]
...
21 changes: 21 additions & 0 deletions llvm/test/Object/Inputs/tapi-invalid-v2.tbd
Original file line number Diff line number Diff line change
@@ -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 ]
...
23 changes: 23 additions & 0 deletions llvm/test/Object/Inputs/tapi-invalid-v3.tbd
Original file line number Diff line number Diff line change
@@ -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 ]
...
15 changes: 15 additions & 0 deletions llvm/test/Object/Inputs/tapi-v1.tbd
Original file line number Diff line number Diff line change
@@ -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, ]
...
21 changes: 21 additions & 0 deletions llvm/test/Object/Inputs/tapi-v2.tbd
Original file line number Diff line number Diff line change
@@ -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 ]
...
24 changes: 24 additions & 0 deletions llvm/test/Object/Inputs/tapi-v3.tbd
Original file line number Diff line number Diff line change
@@ -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 ]
...
Loading

0 comments on commit 28fefcc

Please sign in to comment.