mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-15 04:29:42 +00:00
[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
This commit is contained in:
parent
519b019a0a
commit
28fefcc83c
@ -246,6 +246,10 @@ MACH-O SPECIFIC OPTIONS
|
|||||||
Add symbols from the dyldinfo, if they are not already in the symbol table.
|
Add symbols from the dyldinfo, if they are not already in the symbol table.
|
||||||
This is the default.
|
This is the default.
|
||||||
|
|
||||||
|
.. option:: --add-inlinedinfo
|
||||||
|
|
||||||
|
Add symbols from the inlined libraries, TBD file inputs only.
|
||||||
|
|
||||||
.. option:: --arch=<arch1[,arch2,...]>
|
.. option:: --arch=<arch1[,arch2,...]>
|
||||||
|
|
||||||
Dump the symbols from the specified architecture(s).
|
Dump the symbols from the specified architecture(s).
|
||||||
|
@ -41,6 +41,8 @@ public:
|
|||||||
|
|
||||||
static bool classof(const Binary *v) { return v->isTapiFile(); }
|
static bool classof(const Binary *v) { return v->isTapiFile(); }
|
||||||
|
|
||||||
|
bool is64Bit() { return MachO::is64Bit(Arch); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Symbol {
|
struct Symbol {
|
||||||
StringRef Prefix;
|
StringRef Prefix;
|
||||||
@ -52,6 +54,7 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Symbol> Symbols;
|
std::vector<Symbol> Symbols;
|
||||||
|
MachO::Architecture Arch;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace object.
|
} // end namespace object.
|
||||||
|
@ -41,18 +41,26 @@ public:
|
|||||||
|
|
||||||
uint32_t getCPUType() const {
|
uint32_t getCPUType() const {
|
||||||
auto Result =
|
auto Result =
|
||||||
MachO::getCPUTypeFromArchitecture(Parent->Architectures[Index]);
|
MachO::getCPUTypeFromArchitecture(Parent->Libraries[Index].Arch);
|
||||||
return Result.first;
|
return Result.first;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t getCPUSubType() const {
|
uint32_t getCPUSubType() const {
|
||||||
auto Result =
|
auto Result =
|
||||||
MachO::getCPUTypeFromArchitecture(Parent->Architectures[Index]);
|
MachO::getCPUTypeFromArchitecture(Parent->Libraries[Index].Arch);
|
||||||
return Result.second;
|
return Result.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringRef getArchFlagName() const {
|
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;
|
Expected<std::unique_ptr<TapiFile>> getAsObjectFile() const;
|
||||||
@ -86,21 +94,25 @@ public:
|
|||||||
|
|
||||||
object_iterator begin_objects() const { return ObjectForArch(this, 0); }
|
object_iterator begin_objects() const { return ObjectForArch(this, 0); }
|
||||||
object_iterator end_objects() const {
|
object_iterator end_objects() const {
|
||||||
return ObjectForArch(this, Architectures.size());
|
return ObjectForArch(this, Libraries.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator_range<object_iterator> objects() const {
|
iterator_range<object_iterator> objects() const {
|
||||||
return make_range(begin_objects(), end_objects());
|
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(); }
|
static bool classof(const Binary *v) { return v->isTapiUniversal(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
struct Library {
|
||||||
|
StringRef InstallName;
|
||||||
|
MachO::Architecture Arch;
|
||||||
|
};
|
||||||
|
|
||||||
std::unique_ptr<MachO::InterfaceFile> ParsedFile;
|
std::unique_ptr<MachO::InterfaceFile> ParsedFile;
|
||||||
std::vector<MachO::Architecture> Architectures;
|
std::vector<Library> Libraries;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end namespace object.
|
} // end namespace object.
|
||||||
|
@ -13,27 +13,27 @@
|
|||||||
///
|
///
|
||||||
/// X86 architectures sorted by cpu type and sub type id.
|
/// X86 architectures sorted by cpu type and sub type id.
|
||||||
///
|
///
|
||||||
ARCHINFO(i386, MachO::CPU_TYPE_I386, MachO::CPU_SUBTYPE_I386_ALL)
|
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)
|
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)
|
ARCHINFO(x86_64h, MachO::CPU_TYPE_X86_64, MachO::CPU_SUBTYPE_X86_64_H, 64)
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// ARM architectures sorted by cpu sub type id.
|
/// ARM architectures sorted by cpu sub type id.
|
||||||
///
|
///
|
||||||
ARCHINFO(armv4t, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V4T)
|
ARCHINFO(armv4t, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V4T, 32)
|
||||||
ARCHINFO(armv6, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V6)
|
ARCHINFO(armv6, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V6, 32)
|
||||||
ARCHINFO(armv5, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V5TEJ)
|
ARCHINFO(armv5, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V5TEJ, 32)
|
||||||
ARCHINFO(armv7, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7)
|
ARCHINFO(armv7, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7, 32)
|
||||||
ARCHINFO(armv7s, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7S)
|
ARCHINFO(armv7s, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7S, 32)
|
||||||
ARCHINFO(armv7k, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7K)
|
ARCHINFO(armv7k, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7K, 32)
|
||||||
ARCHINFO(armv6m, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V6M)
|
ARCHINFO(armv6m, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V6M, 32)
|
||||||
ARCHINFO(armv7m, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7M)
|
ARCHINFO(armv7m, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7M, 32)
|
||||||
ARCHINFO(armv7em, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7EM)
|
ARCHINFO(armv7em, MachO::CPU_TYPE_ARM, MachO::CPU_SUBTYPE_ARM_V7EM, 32)
|
||||||
|
|
||||||
|
|
||||||
///
|
///
|
||||||
/// ARM64 architectures sorted by cpu sub type id.
|
/// ARM64 architectures sorted by cpu sub type id.
|
||||||
///
|
///
|
||||||
ARCHINFO(arm64, MachO::CPU_TYPE_ARM64, MachO::CPU_SUBTYPE_ARM64_ALL)
|
ARCHINFO(arm64, MachO::CPU_TYPE_ARM64, MachO::CPU_SUBTYPE_ARM64_ALL, 64)
|
||||||
ARCHINFO(arm64e, MachO::CPU_TYPE_ARM64, MachO::CPU_SUBTYPE_ARM64E)
|
ARCHINFO(arm64e, MachO::CPU_TYPE_ARM64, MachO::CPU_SUBTYPE_ARM64E, 64)
|
||||||
|
@ -25,7 +25,7 @@ namespace MachO {
|
|||||||
|
|
||||||
/// Defines the architecture slices that are supported by Text-based Stub files.
|
/// Defines the architecture slices that are supported by Text-based Stub files.
|
||||||
enum Architecture : uint8_t {
|
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"
|
#include "llvm/TextAPI/MachO/Architecture.def"
|
||||||
#undef ARCHINFO
|
#undef ARCHINFO
|
||||||
AK_unknown, // this has to go last.
|
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.
|
/// Convert a target to an architecture slice.
|
||||||
Architecture mapToArchitecture(const llvm::Triple &Target);
|
Architecture mapToArchitecture(const llvm::Triple &Target);
|
||||||
|
|
||||||
|
/// Check if architecture is 64 bit.
|
||||||
|
bool is64Bit(Architecture);
|
||||||
|
|
||||||
raw_ostream &operator<<(raw_ostream &OS, Architecture Arch);
|
raw_ostream &operator<<(raw_ostream &OS, Architecture Arch);
|
||||||
|
|
||||||
} // end namespace MachO.
|
} // end namespace MachO.
|
||||||
|
@ -40,7 +40,7 @@ static uint32_t getFlags(const Symbol *Sym) {
|
|||||||
|
|
||||||
TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &interface,
|
TapiFile::TapiFile(MemoryBufferRef Source, const InterfaceFile &interface,
|
||||||
Architecture Arch)
|
Architecture Arch)
|
||||||
: SymbolicFile(ID_TapiFile, Source) {
|
: SymbolicFile(ID_TapiFile, Source), Arch(Arch) {
|
||||||
for (const auto *Symbol : interface.symbols()) {
|
for (const auto *Symbol : interface.symbols()) {
|
||||||
if (!Symbol->getArchitectures().has(Arch))
|
if (!Symbol->getArchitectures().has(Arch))
|
||||||
continue;
|
continue;
|
||||||
|
@ -22,7 +22,7 @@ using namespace object;
|
|||||||
|
|
||||||
TapiUniversal::TapiUniversal(MemoryBufferRef Source, Error &Err)
|
TapiUniversal::TapiUniversal(MemoryBufferRef Source, Error &Err)
|
||||||
: Binary(ID_TapiUniversal, Source) {
|
: Binary(ID_TapiUniversal, Source) {
|
||||||
auto Result = TextAPIReader::get(Source);
|
Expected<std::unique_ptr<InterfaceFile>> Result = TextAPIReader::get(Source);
|
||||||
ErrorAsOutParameter ErrAsOuParam(&Err);
|
ErrorAsOutParameter ErrAsOuParam(&Err);
|
||||||
if (!Result) {
|
if (!Result) {
|
||||||
Err = Result.takeError();
|
Err = Result.takeError();
|
||||||
@ -30,9 +30,16 @@ TapiUniversal::TapiUniversal(MemoryBufferRef Source, Error &Err)
|
|||||||
}
|
}
|
||||||
ParsedFile = std::move(Result.get());
|
ParsedFile = std::move(Result.get());
|
||||||
|
|
||||||
auto Archs = ParsedFile->getArchitectures();
|
auto FlattenObjectInfo = [this](const auto &File) {
|
||||||
for (auto Arch : Archs)
|
StringRef Name = File->getInstallName();
|
||||||
Architectures.emplace_back(Arch);
|
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;
|
TapiUniversal::~TapiUniversal() = default;
|
||||||
@ -41,7 +48,7 @@ Expected<std::unique_ptr<TapiFile>>
|
|||||||
TapiUniversal::ObjectForArch::getAsObjectFile() const {
|
TapiUniversal::ObjectForArch::getAsObjectFile() const {
|
||||||
return std::unique_ptr<TapiFile>(new TapiFile(Parent->getMemoryBufferRef(),
|
return std::unique_ptr<TapiFile>(new TapiFile(Parent->getMemoryBufferRef(),
|
||||||
*Parent->ParsedFile.get(),
|
*Parent->ParsedFile.get(),
|
||||||
Parent->Architectures[Index]));
|
Parent->Libraries[Index].Arch));
|
||||||
}
|
}
|
||||||
|
|
||||||
Expected<std::unique_ptr<TapiUniversal>>
|
Expected<std::unique_ptr<TapiUniversal>>
|
||||||
|
@ -15,12 +15,13 @@
|
|||||||
#include "llvm/ADT/Triple.h"
|
#include "llvm/ADT/Triple.h"
|
||||||
#include "llvm/BinaryFormat/MachO.h"
|
#include "llvm/BinaryFormat/MachO.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
#include "llvm/TextAPI/MachO/ArchitectureSet.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
namespace MachO {
|
namespace MachO {
|
||||||
|
|
||||||
Architecture getArchitectureFromCpuType(uint32_t CPUType, uint32_t CPUSubType) {
|
Architecture getArchitectureFromCpuType(uint32_t CPUType, uint32_t CPUSubType) {
|
||||||
#define ARCHINFO(Arch, Type, Subtype) \
|
#define ARCHINFO(Arch, Type, Subtype, NumBits) \
|
||||||
if (CPUType == (Type) && \
|
if (CPUType == (Type) && \
|
||||||
(CPUSubType & ~MachO::CPU_SUBTYPE_MASK) == (Subtype)) \
|
(CPUSubType & ~MachO::CPU_SUBTYPE_MASK) == (Subtype)) \
|
||||||
return AK_##Arch;
|
return AK_##Arch;
|
||||||
@ -32,7 +33,7 @@ Architecture getArchitectureFromCpuType(uint32_t CPUType, uint32_t CPUSubType) {
|
|||||||
|
|
||||||
Architecture getArchitectureFromName(StringRef Name) {
|
Architecture getArchitectureFromName(StringRef Name) {
|
||||||
return StringSwitch<Architecture>(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"
|
#include "llvm/TextAPI/MachO/Architecture.def"
|
||||||
#undef ARCHINFO
|
#undef ARCHINFO
|
||||||
.Default(AK_unknown);
|
.Default(AK_unknown);
|
||||||
@ -40,7 +41,7 @@ Architecture getArchitectureFromName(StringRef Name) {
|
|||||||
|
|
||||||
StringRef getArchitectureName(Architecture Arch) {
|
StringRef getArchitectureName(Architecture Arch) {
|
||||||
switch (Arch) {
|
switch (Arch) {
|
||||||
#define ARCHINFO(Arch, Type, Subtype) \
|
#define ARCHINFO(Arch, Type, Subtype, NumBits) \
|
||||||
case AK_##Arch: \
|
case AK_##Arch: \
|
||||||
return #Arch;
|
return #Arch;
|
||||||
#include "llvm/TextAPI/MachO/Architecture.def"
|
#include "llvm/TextAPI/MachO/Architecture.def"
|
||||||
@ -56,7 +57,7 @@ StringRef getArchitectureName(Architecture Arch) {
|
|||||||
|
|
||||||
std::pair<uint32_t, uint32_t> getCPUTypeFromArchitecture(Architecture Arch) {
|
std::pair<uint32_t, uint32_t> getCPUTypeFromArchitecture(Architecture Arch) {
|
||||||
switch (Arch) {
|
switch (Arch) {
|
||||||
#define ARCHINFO(Arch, Type, Subtype) \
|
#define ARCHINFO(Arch, Type, Subtype, NumBits) \
|
||||||
case AK_##Arch: \
|
case AK_##Arch: \
|
||||||
return std::make_pair(Type, Subtype);
|
return std::make_pair(Type, Subtype);
|
||||||
#include "llvm/TextAPI/MachO/Architecture.def"
|
#include "llvm/TextAPI/MachO/Architecture.def"
|
||||||
@ -74,6 +75,20 @@ Architecture mapToArchitecture(const Triple &Target) {
|
|||||||
return getArchitectureFromName(Target.getArchName());
|
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) {
|
raw_ostream &operator<<(raw_ostream &OS, Architecture Arch) {
|
||||||
OS << getArchitectureName(Arch);
|
OS << getArchitectureName(Arch);
|
||||||
return OS;
|
return OS;
|
||||||
|
@ -129,7 +129,7 @@ QuotingType ScalarTraits<PlatformSet>::mustQuote(StringRef) {
|
|||||||
|
|
||||||
void ScalarBitSetTraits<ArchitectureSet>::bitset(IO &IO,
|
void ScalarBitSetTraits<ArchitectureSet>::bitset(IO &IO,
|
||||||
ArchitectureSet &Archs) {
|
ArchitectureSet &Archs) {
|
||||||
#define ARCHINFO(arch, type, subtype) \
|
#define ARCHINFO(arch, type, subtype, numbits) \
|
||||||
IO.bitSetCase(Archs, #arch, 1U << static_cast<int>(AK_##arch));
|
IO.bitSetCase(Archs, #arch, 1U << static_cast<int>(AK_##arch));
|
||||||
#include "llvm/TextAPI/MachO/Architecture.def"
|
#include "llvm/TextAPI/MachO/Architecture.def"
|
||||||
#undef ARCHINFO
|
#undef ARCHINFO
|
||||||
|
15
llvm/test/Object/Inputs/tapi-invalid-v1.tbd
Normal file
15
llvm/test/Object/Inputs/tapi-invalid-v1.tbd
Normal file
@ -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
llvm/test/Object/Inputs/tapi-invalid-v2.tbd
Normal file
21
llvm/test/Object/Inputs/tapi-invalid-v2.tbd
Normal file
@ -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
llvm/test/Object/Inputs/tapi-invalid-v3.tbd
Normal file
23
llvm/test/Object/Inputs/tapi-invalid-v3.tbd
Normal file
@ -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
llvm/test/Object/Inputs/tapi-v1.tbd
Normal file
15
llvm/test/Object/Inputs/tapi-v1.tbd
Normal file
@ -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
llvm/test/Object/Inputs/tapi-v2.tbd
Normal file
21
llvm/test/Object/Inputs/tapi-v2.tbd
Normal file
@ -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
llvm/test/Object/Inputs/tapi-v3.tbd
Normal file
24
llvm/test/Object/Inputs/tapi-v3.tbd
Normal file
@ -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 ]
|
||||||
|
...
|
38
llvm/test/Object/Inputs/tapi-v4.tbd
Normal file
38
llvm/test/Object/Inputs/tapi-v4.tbd
Normal file
@ -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' ]
|
||||||
|
...
|
20
llvm/test/Object/nm-tapi-invalids.test
Normal file
20
llvm/test/Object/nm-tapi-invalids.test
Normal file
@ -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'
|
58
llvm/test/Object/nm-tapi.test
Normal file
58
llvm/test/Object/nm-tapi.test
Normal file
@ -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
|
@ -28,6 +28,8 @@
|
|||||||
#include "llvm/Object/MachO.h"
|
#include "llvm/Object/MachO.h"
|
||||||
#include "llvm/Object/MachOUniversal.h"
|
#include "llvm/Object/MachOUniversal.h"
|
||||||
#include "llvm/Object/ObjectFile.h"
|
#include "llvm/Object/ObjectFile.h"
|
||||||
|
#include "llvm/Object/TapiFile.h"
|
||||||
|
#include "llvm/Object/TapiUniversal.h"
|
||||||
#include "llvm/Object/Wasm.h"
|
#include "llvm/Object/Wasm.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Support/FileSystem.h"
|
#include "llvm/Support/FileSystem.h"
|
||||||
@ -210,6 +212,11 @@ cl::opt<bool> NoLLVMBitcode("no-llvm-bc",
|
|||||||
cl::desc("Disable LLVM bitcode reader"),
|
cl::desc("Disable LLVM bitcode reader"),
|
||||||
cl::cat(NMCat));
|
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");
|
cl::extrahelp HelpResponse("\nPass @FILE as argument to read options from FILE.\n");
|
||||||
|
|
||||||
bool PrintAddress = true;
|
bool PrintAddress = true;
|
||||||
@ -340,6 +347,8 @@ static char isSymbolList64Bit(SymbolicFile &Obj) {
|
|||||||
return false;
|
return false;
|
||||||
if (isa<WasmObjectFile>(Obj))
|
if (isa<WasmObjectFile>(Obj))
|
||||||
return false;
|
return false;
|
||||||
|
if (TapiFile *Tapi = dyn_cast<TapiFile>(&Obj))
|
||||||
|
return Tapi->is64Bit();
|
||||||
if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj))
|
if (MachOObjectFile *MachO = dyn_cast<MachOObjectFile>(&Obj))
|
||||||
return MachO->is64Bit();
|
return MachO->is64Bit();
|
||||||
return cast<ELFObjectFileBase>(Obj).getBytesInAddress() == 8;
|
return cast<ELFObjectFileBase>(Obj).getBytesInAddress() == 8;
|
||||||
@ -1046,6 +1055,10 @@ static char getSymbolNMTypeChar(MachOObjectFile &Obj, basic_symbol_iterator I) {
|
|||||||
return '?';
|
return '?';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char getSymbolNMTypeChar(TapiFile &Obj, basic_symbol_iterator I) {
|
||||||
|
return 's';
|
||||||
|
}
|
||||||
|
|
||||||
static char getSymbolNMTypeChar(WasmObjectFile &Obj, basic_symbol_iterator I) {
|
static char getSymbolNMTypeChar(WasmObjectFile &Obj, basic_symbol_iterator I) {
|
||||||
uint32_t Flags = cantFail(I->getFlags());
|
uint32_t Flags = cantFail(I->getFlags());
|
||||||
if (Flags & SymbolRef::SF_Executable)
|
if (Flags & SymbolRef::SF_Executable)
|
||||||
@ -1139,6 +1152,8 @@ static char getNMSectionTagAndName(SymbolicFile &Obj, basic_symbol_iterator I,
|
|||||||
Ret = getSymbolNMTypeChar(*MachO, I);
|
Ret = getSymbolNMTypeChar(*MachO, I);
|
||||||
else if (WasmObjectFile *Wasm = dyn_cast<WasmObjectFile>(&Obj))
|
else if (WasmObjectFile *Wasm = dyn_cast<WasmObjectFile>(&Obj))
|
||||||
Ret = getSymbolNMTypeChar(*Wasm, I);
|
Ret = getSymbolNMTypeChar(*Wasm, I);
|
||||||
|
else if (TapiFile *Tapi = dyn_cast<TapiFile>(&Obj))
|
||||||
|
Ret = getSymbolNMTypeChar(*Tapi, I);
|
||||||
else if (ELFObjectFileBase *ELF = dyn_cast<ELFObjectFileBase>(&Obj)) {
|
else if (ELFObjectFileBase *ELF = dyn_cast<ELFObjectFileBase>(&Obj)) {
|
||||||
if (ELFSymbolRef(*I).getELFType() == ELF::STT_GNU_IFUNC)
|
if (ELFSymbolRef(*I).getELFType() == ELF::STT_GNU_IFUNC)
|
||||||
return 'i';
|
return 'i';
|
||||||
@ -2081,6 +2096,31 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
|
|||||||
}
|
}
|
||||||
return;
|
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 (SymbolicFile *O = dyn_cast<SymbolicFile>(&Bin)) {
|
||||||
if (!MachOPrintSizeWarning && PrintSize && isa<MachOObjectFile>(O)) {
|
if (!MachOPrintSizeWarning && PrintSize && isa<MachOObjectFile>(O)) {
|
||||||
WithColor::warning(errs(), ToolName)
|
WithColor::warning(errs(), ToolName)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user