From 14963a696b8c4dc89409889288e85f531bd59534 Mon Sep 17 00:00:00 2001 From: Kevin Enderby Date: Wed, 14 May 2014 21:18:50 +0000 Subject: [PATCH] Teach llvm-nm to know about fat archives (aka MachOUniversal files containing archives). First step as other tools will be updated next. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@208812 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/MachOUniversal.h | 3 +++ lib/Object/MachOUniversal.cpp | 20 +++++++++++++++ .../macho-universal-archive.x86_64.i386 | Bin 0 -> 1656 bytes test/Object/nm-universal-binary.test | 23 ++++++++++++++---- tools/llvm-nm/llvm-nm.cpp | 14 +++++++++++ 5 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 test/Object/Inputs/macho-universal-archive.x86_64.i386 diff --git a/include/llvm/Object/MachOUniversal.h b/include/llvm/Object/MachOUniversal.h index da1445fd70a..d27c824a87a 100644 --- a/include/llvm/Object/MachOUniversal.h +++ b/include/llvm/Object/MachOUniversal.h @@ -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 &Result) const; + + error_code getAsArchive(std::unique_ptr &Result) const; }; class object_iterator { diff --git a/lib/Object/MachOUniversal.cpp b/lib/Object/MachOUniversal.cpp index 3f3731f22d8..5085efde5ec 100644 --- a/lib/Object/MachOUniversal.cpp +++ b/lib/Object/MachOUniversal.cpp @@ -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 &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 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 diff --git a/test/Object/Inputs/macho-universal-archive.x86_64.i386 b/test/Object/Inputs/macho-universal-archive.x86_64.i386 new file mode 100644 index 0000000000000000000000000000000000000000..1660714c68ea8e4a638889b1a061153393b376a2 GIT binary patch literal 1656 zcmbVM&1(};5TDf8me`LRJSZrxDCj}cY+9QHMOsW`!HT6#p&rU>Y*SNclM+)J1fft6 z_aOKuc=YH|J%~`D#e@1sSm;5aM-i$1e*50brrL@+FgxEfZ|BXMce}4%i%45UqyzL2 zFewu4qz-6w(G0{P$Ze;u6l*i(tFbd~Un=Q@;Pz*;m(rbNNz3L4Z&x&zr}9eoO0Co^bI zH61IL78a_BD$~k`Z(nxtGZFqE{x$f~9Wo9Oa2)uE@&WM7=;Q1Pz{+e8F-j#ssd}kV z*SwYs`N={kTkf)9n2)h9K!em#S+zc-O3mD>*XApCjZ&$-`D~tUW4~d}XGERT3ZTeW zU0f>8)YWojWxg`2)JV{O>*5*4F?167*t1Pg)1EyQlq!|gT&=iR(gDAouWa%R8QL)U zj3`G$tV^I`@?*e{U=D*iD1HGHeliLq(8nTs_lIkv`@S&Y`CH!FXUBWYDzcIPPU1iK z>iNq%oXJE+}*GBV{j%oJqpp>;V27<8dV+w7h+#W{dS=Xi_RSTo?}JPOyv}K@M9tv}%re v&dI3pDTDI7t#3(thVRMB|3WAHt*LbcAiZ#Idr_F@quiXq;O>H34Cd!2$5XhC literal 0 HcmV?d00001 diff --git a/test/Object/nm-universal-binary.test b/test/Object/nm-universal-binary.test index 07a97f7aff9..faf4812e537 100644 --- a/test/Object/nm-universal-binary.test +++ b/test/Object/nm-universal-binary.test @@ -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 diff --git a/tools/llvm-nm/llvm-nm.cpp b/tools/llvm-nm/llvm-nm.cpp index 0a1491b8467..57e9d55c866 100644 --- a/tools/llvm-nm/llvm-nm.cpp +++ b/tools/llvm-nm/llvm-nm.cpp @@ -595,10 +595,24 @@ static void dumpSymbolNamesFromFile(std::string &Filename) { E = UB->end_objects(); I != E; ++I) { std::unique_ptr Obj; + std::unique_ptr 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 Child; + if (AI->getAsBinary(Child, &Context)) + continue; + if (SymbolicFile *O = dyn_cast(Child.get())) { + outs() << A->getFileName() << ":"; + outs() << O->getFileName() << ":\n"; + dumpSymbolNamesFromObject(O); + } + } + } } return; } -- 2.34.1