mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-07 00:23:43 +00:00
Teach llvm-nm to know about fat archives (aka MachOUniversal files
containing archives). First step as other tools will be updated next. llvm-svn: 208812
This commit is contained in:
parent
a0653a3e6c
commit
e858a65323
@ -17,6 +17,7 @@
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/Object/Binary.h"
|
||||
#include "llvm/Object/Archive.h"
|
||||
#include "llvm/Support/ErrorOr.h"
|
||||
#include "llvm/Support/MachO.h"
|
||||
|
||||
@ -53,6 +54,8 @@ public:
|
||||
uint32_t getCPUType() const { return Header.cputype; }
|
||||
|
||||
error_code getAsObjectFile(std::unique_ptr<ObjectFile> &Result) const;
|
||||
|
||||
error_code getAsArchive(std::unique_ptr<Archive> &Result) const;
|
||||
};
|
||||
|
||||
class object_iterator {
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "llvm/Object/MachOUniversal.h"
|
||||
#include "llvm/Object/MachO.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
#include "llvm/Object/Archive.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/Host.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
@ -90,6 +91,25 @@ error_code MachOUniversalBinary::ObjectForArch::getAsObjectFile(
|
||||
return object_error::parse_failed;
|
||||
}
|
||||
|
||||
error_code MachOUniversalBinary::ObjectForArch::getAsArchive(
|
||||
std::unique_ptr<Archive> &Result) const {
|
||||
if (Parent) {
|
||||
StringRef ParentData = Parent->getData();
|
||||
StringRef ObjectData = ParentData.substr(Header.offset, Header.size);
|
||||
std::string ObjectName =
|
||||
Parent->getFileName().str() + ":" +
|
||||
Triple::getArchTypeName(MachOObjectFile::getArch(Header.cputype));
|
||||
MemoryBuffer *ObjBuffer = MemoryBuffer::getMemBuffer(
|
||||
ObjectData, ObjectName, false);
|
||||
ErrorOr<Archive *> Obj = Archive::create(ObjBuffer);
|
||||
if (error_code EC = Obj.getError())
|
||||
return EC;
|
||||
Result.reset(Obj.get());
|
||||
return object_error::success;
|
||||
}
|
||||
return object_error::parse_failed;
|
||||
}
|
||||
|
||||
void MachOUniversalBinary::anchor() { }
|
||||
|
||||
ErrorOr<MachOUniversalBinary *>
|
||||
|
BIN
llvm/test/Object/Inputs/macho-universal-archive.x86_64.i386
Normal file
BIN
llvm/test/Object/Inputs/macho-universal-archive.x86_64.i386
Normal file
Binary file not shown.
@ -1,6 +1,19 @@
|
||||
RUN: llvm-nm %p/Inputs/macho-universal.x86_64.i386 | FileCheck %s
|
||||
RUN: llvm-nm %p/Inputs/macho-universal.x86_64.i386 \
|
||||
RUN: | FileCheck %s -check-prefix CHECK-OBJ
|
||||
RUN: llvm-nm %p/Inputs/macho-universal-archive.x86_64.i386 \
|
||||
RUN: | FileCheck %s -check-prefix CHECK-AR
|
||||
|
||||
CHECK: macho-universal.x86_64.i386:x86_64
|
||||
CHECK: 0000000100000f60 T _main
|
||||
CHECK: macho-universal.x86_64.i386:i386
|
||||
CHECK: 00001fa0 T _main
|
||||
CHECK-OBJ: macho-universal.x86_64.i386:x86_64
|
||||
CHECK-OBJ: 0000000100000f60 T _main
|
||||
CHECK-OBJ: macho-universal.x86_64.i386:i386
|
||||
CHECK-OBJ: 00001fa0 T _main
|
||||
|
||||
CHECK-AR: macho-universal-archive.x86_64.i386:x86_64:hello.o:
|
||||
CHECK-AR: 0000000000000068 s EH_frame0
|
||||
CHECK-AR: 000000000000003b s L_.str
|
||||
CHECK-AR: 0000000000000000 T _main
|
||||
CHECK-AR: 0000000000000080 S _main.eh
|
||||
CHECK-AR: 0000000000000000 U _printf
|
||||
CHECK-AR: macho-universal-archive.x86_64.i386:i386:foo.o:
|
||||
CHECK-AR: 00000008 S _bar
|
||||
CHECK-AR: 00000000 T _foo
|
||||
|
@ -595,10 +595,24 @@ static void dumpSymbolNamesFromFile(std::string &Filename) {
|
||||
E = UB->end_objects();
|
||||
I != E; ++I) {
|
||||
std::unique_ptr<ObjectFile> Obj;
|
||||
std::unique_ptr<Archive> A;
|
||||
if (!I->getAsObjectFile(Obj)) {
|
||||
outs() << Obj->getFileName() << ":\n";
|
||||
dumpSymbolNamesFromObject(Obj.get());
|
||||
}
|
||||
else if (!I->getAsArchive(A)) {
|
||||
for (Archive::child_iterator AI = A->child_begin(), AE = A->child_end();
|
||||
AI != AE; ++AI) {
|
||||
std::unique_ptr<Binary> Child;
|
||||
if (AI->getAsBinary(Child, &Context))
|
||||
continue;
|
||||
if (SymbolicFile *O = dyn_cast<SymbolicFile>(Child.get())) {
|
||||
outs() << A->getFileName() << ":";
|
||||
outs() << O->getFileName() << ":\n";
|
||||
dumpSymbolNamesFromObject(O);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user