X-Git-Url: https://git.saurik.com/apple/ld64.git/blobdiff_plain/9d2e0767a8f401be0067937f63a08b1c4f79297d..55e3d2f687f4ed9653982dbda92c6a055b0a8350:/src/ObjectDump.cpp diff --git a/src/ObjectDump.cpp b/src/ObjectDump.cpp deleted file mode 100755 index e46cd3d..0000000 --- a/src/ObjectDump.cpp +++ /dev/null @@ -1,497 +0,0 @@ -/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- - * - * Copyright (c) 2005-2006 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#include -#include -#include -#include -#include - -#include "MachOReaderRelocatable.hpp" - -#define LTO_SUPPORT 1 - -#if LTO_SUPPORT - #include "LTOReader.hpp" -#endif - -static bool sDumpContent= true; -static bool sDumpStabs = false; -static bool sSort = true; -static bool sNMmode = false; -static cpu_type_t sPreferredArch = CPU_TYPE_POWERPC64; -static const char* sMatchName; -static int sPrintRestrict; -static int sPrintAlign; -static int sPrintName; - - - __attribute__((noreturn)) -void throwf(const char* format, ...) -{ - va_list list; - char* p; - va_start(list, format); - vasprintf(&p, format, list); - va_end(list); - - const char* t = p; - throw t; -} - -void warning(const char* format, ...) -{ - va_list list; - fprintf(stderr, "warning: "); - va_start(list, format); - vfprintf(stderr, format, list); - va_end(list); - fprintf(stderr, "\n"); -} - -static void dumpStabs(std::vector* stabs) -{ - // debug info - printf("stabs: (%lu)\n", stabs->size()); - for (std::vector::iterator it = stabs->begin(); it != stabs->end(); ++it ) { - ObjectFile::Reader::Stab& stab = *it; - const char* code = "?????"; - switch (stab.type) { - case N_GSYM: - code = " GSYM"; - break; - case N_FNAME: - code = "FNAME"; - break; - case N_FUN: - code = " FUN"; - break; - case N_STSYM: - code = "STSYM"; - break; - case N_LCSYM: - code = "LCSYM"; - break; - case N_BNSYM: - code = "BNSYM"; - break; - case N_OPT: - code = " OPT"; - break; - case N_RSYM: - code = " RSYM"; - break; - case N_SLINE: - code = "SLINE"; - break; - case N_ENSYM: - code = "ENSYM"; - break; - case N_SSYM: - code = " SSYM"; - break; - case N_SO: - code = " SO"; - break; - case N_OSO: - code = " OSO"; - break; - case N_LSYM: - code = " LSYM"; - break; - case N_BINCL: - code = "BINCL"; - break; - case N_SOL: - code = " SOL"; - break; - case N_PARAMS: - code = "PARMS"; - break; - case N_VERSION: - code = " VERS"; - break; - case N_OLEVEL: - code = "OLEVL"; - break; - case N_PSYM: - code = " PSYM"; - break; - case N_EINCL: - code = "EINCL"; - break; - case N_ENTRY: - code = "ENTRY"; - break; - case N_LBRAC: - code = "LBRAC"; - break; - case N_EXCL: - code = " EXCL"; - break; - case N_RBRAC: - code = "RBRAC"; - break; - case N_BCOMM: - code = "BCOMM"; - break; - case N_ECOMM: - code = "ECOMM"; - break; - case N_LENG: - code = "LENG"; - break; - } - printf(" [atom=%20s] %02X %04X %s %s\n", ((stab.atom != NULL) ? stab.atom->getDisplayName() : ""), stab.other, stab.desc, code, stab.string); - } -} - - -static void dumpAtomLikeNM(ObjectFile::Atom* atom) -{ - uint32_t size = atom->getSize(); - - const char* visibility; - switch ( atom->getScope() ) { - case ObjectFile::Atom::scopeTranslationUnit: - visibility = "internal"; - break; - case ObjectFile::Atom::scopeLinkageUnit: - visibility = "hidden "; - break; - case ObjectFile::Atom::scopeGlobal: - visibility = "global "; - break; - default: - visibility = " "; - break; - } - - const char* kind; - switch ( atom->getDefinitionKind() ) { - case ObjectFile::Atom::kRegularDefinition: - kind = "regular "; - break; - case ObjectFile::Atom::kTentativeDefinition: - kind = "tentative"; - break; - case ObjectFile::Atom::kWeakDefinition: - kind = "weak "; - break; - case ObjectFile::Atom::kAbsoluteSymbol: - kind = "absolute "; - break; - default: - kind = " "; - break; - } - - printf("0x%08X %s %s %s\n", size, visibility, kind, atom->getDisplayName()); -} - - -static void dumpAtom(ObjectFile::Atom* atom) -{ - if(sMatchName && strcmp(sMatchName, atom->getDisplayName())) - return; - - //printf("atom: %p\n", atom); - - // name - if(!sPrintRestrict || sPrintName) - printf("name: %s\n", atom->getDisplayName()); - - // scope - if(!sPrintRestrict) - switch ( atom->getScope() ) { - case ObjectFile::Atom::scopeTranslationUnit: - printf("scope: translation unit\n"); - break; - case ObjectFile::Atom::scopeLinkageUnit: - printf("scope: linkage unit\n"); - break; - case ObjectFile::Atom::scopeGlobal: - printf("scope: global\n"); - break; - default: - printf("scope: unknown\n"); - } - - // kind - if(!sPrintRestrict) - switch ( atom->getDefinitionKind() ) { - case ObjectFile::Atom::kRegularDefinition: - printf("kind: regular\n"); - break; - case ObjectFile::Atom::kWeakDefinition: - printf("kind: weak\n"); - break; - case ObjectFile::Atom::kTentativeDefinition: - printf("kind: tentative\n"); - break; - case ObjectFile::Atom::kExternalDefinition: - printf("kind: import\n"); - break; - case ObjectFile::Atom::kExternalWeakDefinition: - printf("kind: weak import\n"); - break; - case ObjectFile::Atom::kAbsoluteSymbol: - printf("kind: absolute symbol\n"); - break; - default: - printf("kind: unknown\n"); - } - - // segment and section - if(!sPrintRestrict && (atom->getSectionName() != NULL) ) - printf("section: %s,%s\n", atom->getSegment().getName(), atom->getSectionName()); - - // attributes - if(!sPrintRestrict) { - printf("attrs: "); - if ( atom->dontDeadStrip() ) - printf("dont-dead-strip "); - if ( atom->isZeroFill() ) - printf("zero-fill "); - if ( atom->isThumb() ) - printf("thumb "); - printf("\n"); - } - - // size - if(!sPrintRestrict) - printf("size: 0x%012llX\n", atom->getSize()); - - // alignment - if(!sPrintRestrict || sPrintAlign) - printf("align: %u mod %u\n", atom->getAlignment().modulus, (1 << atom->getAlignment().powerOf2) ); - - // content - if (!sPrintRestrict && sDumpContent ) { - uint64_t size = atom->getSize(); - if ( size < 4096 ) { - uint8_t content[size]; - atom->copyRawContent(content); - printf("content: "); - if ( strcmp(atom->getSectionName(), "__cstring") == 0 ) { - printf("\""); - for (unsigned int i=0; i < size; ++i) { - if(content[i]<'!' || content[i]>=127) - printf("\\%o", content[i]); - else - printf("%c", content[i]); - } - printf("\""); - } - else { - for (unsigned int i=0; i < size; ++i) - printf("%02X ", content[i]); - } - } - printf("\n"); - } - - // references - if(!sPrintRestrict) { - std::vector& references = atom->getReferences(); - const int refCount = references.size(); - printf("references: (%u)\n", refCount); - for (int i=0; i < refCount; ++i) { - ObjectFile::Reference* ref = references[i]; - printf(" %s\n", ref->getDescription()); - } - } - - // line info - if(!sPrintRestrict) { - std::vector* lineInfo = atom->getLineInfo(); - if ( (lineInfo != NULL) && (lineInfo->size() > 0) ) { - printf("line info: (%lu)\n", lineInfo->size()); - for (std::vector::iterator it = lineInfo->begin(); it != lineInfo->end(); ++it) { - printf(" offset 0x%04X, line %d, file %s\n", it->atomOffset, it->lineNumber, it->fileName); - } - } - } - - if(!sPrintRestrict) - printf("\n"); -} - -struct AtomSorter -{ - bool operator()(const ObjectFile::Atom* left, const ObjectFile::Atom* right) - { - if ( left == right ) - return false; - return (strcmp(left->getDisplayName(), right->getDisplayName()) < 0); - } -}; - - -static void dumpFile(ObjectFile::Reader* reader) -{ - // stabs debug info - if ( sDumpStabs && (reader->getDebugInfoKind() == ObjectFile::Reader::kDebugInfoStabs) ) { - std::vector* stabs = reader->getStabs(); - if ( stabs != NULL ) - dumpStabs(stabs); - } - - // get all atoms - std::vector atoms = reader->getAtoms(); - - // make copy of vector and sort (so output is canonical) - std::vector sortedAtoms(atoms); - if ( sSort ) - std::sort(sortedAtoms.begin(), sortedAtoms.end(), AtomSorter()); - - for(std::vector::iterator it=sortedAtoms.begin(); it != sortedAtoms.end(); ++it) { - if ( sNMmode ) - dumpAtomLikeNM(*it); - else - dumpAtom(*it); - } -} - - -static ObjectFile::Reader* createReader(const char* path, const ObjectFile::ReaderOptions& options) -{ - struct stat stat_buf; - - int fd = ::open(path, O_RDONLY, 0); - if ( fd == -1 ) - throwf("cannot open file: %s", path); - ::fstat(fd, &stat_buf); - uint8_t* p = (uint8_t*)::mmap(NULL, stat_buf.st_size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0); - ::close(fd); - const mach_header* mh = (mach_header*)p; - if ( mh->magic == OSSwapBigToHostInt32(FAT_MAGIC) ) { - const struct fat_header* fh = (struct fat_header*)p; - const struct fat_arch* archs = (struct fat_arch*)(p + sizeof(struct fat_header)); - for (unsigned long i=0; i < OSSwapBigToHostInt32(fh->nfat_arch); ++i) { - if ( OSSwapBigToHostInt32(archs[i].cputype) == (uint32_t)sPreferredArch ) { - p = p + OSSwapBigToHostInt32(archs[i].offset); - mh = (struct mach_header*)p; - } - } - } - if ( mach_o::relocatable::Reader::validFile(p) ) - return new mach_o::relocatable::Reader::Reader(p, path, 0, options, 0); - else if ( mach_o::relocatable::Reader::validFile(p) ) - return new mach_o::relocatable::Reader::Reader(p, path, 0, options, 0); - else if ( mach_o::relocatable::Reader::validFile(p) ) - return new mach_o::relocatable::Reader::Reader(p, path, 0, options, 0); - else if ( mach_o::relocatable::Reader::validFile(p) ) - return new mach_o::relocatable::Reader::Reader(p, path, 0, options, 0); - else if ( mach_o::relocatable::Reader::validFile(p) ) - return new mach_o::relocatable::Reader::Reader(p, path, 0, options, 0); -#if LTO_SUPPORT - if ( lto::Reader::validFile(p, stat_buf.st_size, 0) ) { - return new lto::Reader(p, stat_buf.st_size, path, 0, options, 0); - } -#endif - - throwf("not a mach-o object file: %s", path); -} - -static -void -usage() -{ - fprintf(stderr, "ObjectDump options:\n" - "\t-no_content\tdon't dump contents\n" - "\t-stabs\t\tdump stabs\n" - "\t-arch aaa\tonly dump info about arch aaa\n" - "\t-only sym\tonly dump info about sym\n" - "\t-align\t\tonly print alignment info\n" - "\t-name\t\tonly print symbol names\n" - ); -} - -int main(int argc, const char* argv[]) -{ - if(argc<2) { - usage(); - return 0; - } - - ObjectFile::ReaderOptions options; - try { - for(int i=1; i < argc; ++i) { - const char* arg = argv[i]; - if ( arg[0] == '-' ) { - if ( strcmp(arg, "-no_content") == 0 ) { - sDumpContent = false; - } - else if ( strcmp(arg, "-nm") == 0 ) { - sNMmode = true; - } - else if ( strcmp(arg, "-stabs") == 0 ) { - sDumpStabs = true; - } - else if ( strcmp(arg, "-no_sort") == 0 ) { - sSort = false; - } - else if ( strcmp(arg, "-arch") == 0 ) { - const char* arch = ++i