]>
git.saurik.com Git - apple/ld64.git/blob - src/ObjDump.cpp
2 * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
23 #include <sys/types.h>
28 #include <mach-o/loader.h>
29 #include <mach-o/fat.h>
30 #include <mach-o/stab.h>
33 #include "ObjectFile.h"
34 #include "ObjectFileMachO-all.h"
36 __attribute__((noreturn
))
37 void throwf(const char* format
, ...)
41 va_start(list
, format
);
42 vasprintf(&p
, format
, list
);
49 static void dumpStabs(std::vector
<ObjectFile::StabsInfo
>* stabs
)
52 const int stabCount
= stabs
->size();
53 printf("stabs: (%u)\n", stabCount
);
54 for (int i
=0; i
< stabCount
; ++i
) {
55 ObjectFile::StabsInfo
& stab
= (*stabs
)[i
];
56 const char* code
= "?????";
140 printf(" %08X %02X %04X %s %s\n", (uint32_t)stab
.atomOffset
, stab
.other
, stab
.desc
, code
, stab
.string
);
145 static void dumpAtom(ObjectFile::Atom
* atom
)
147 //printf("atom: %p\n", atom);
150 printf("name: %s\n", atom
->getDisplayName());
153 switch ( atom
->getScope() ) {
154 case ObjectFile::Atom::scopeTranslationUnit
:
155 printf("scope: translation unit\n");
157 case ObjectFile::Atom::scopeLinkageUnit
:
158 printf("scope: linkage unit\n");
160 case ObjectFile::Atom::scopeGlobal
:
161 printf("scope: global\n");
164 printf("scope: unknown\n");
167 // segment and section
168 printf("section: %s,%s\n", atom
->getSegment().getName(), atom
->getSectionName());
172 if ( atom
->isWeakDefinition() )
174 if ( atom
->isCoalesableByName() )
175 printf("coalesce-by-name ");
176 if ( atom
->isCoalesableByValue() )
177 printf("coalesce-by-value ");
178 if ( atom
->dontDeadStrip() )
179 printf("dont-dead-strip ");
180 if ( atom
->isZeroFill() )
181 printf("zero-fill ");
185 printf("size: 0x%012llX\n", atom
->getSize());
188 printf("align: %d\n", atom
->getAlignment());
191 uint64_t size
= atom
->getSize();
193 uint8_t content
[size
];
194 atom
->copyRawContent(content
);
196 if ( strcmp(atom
->getSectionName(), "__cstring") == 0 ) {
197 printf("\"%s\"", content
);
200 for (unsigned int i
=0; i
< size
; ++i
)
201 printf("%02X ", content
[i
]);
207 std::vector
<ObjectFile::Reference
*>& references
= atom
->getReferences();
208 const int refCount
= references
.size();
209 printf("references: (%u)\n", refCount
);
210 for (int i
=0; i
< refCount
; ++i
) {
211 ObjectFile::Reference
* ref
= references
[i
];
212 printf(" %s\n", ref
->getDescription());
216 std::vector
<ObjectFile::StabsInfo
>* stabs
= atom
->getStabsDebugInfo();
222 static void dumpFile(ObjectFile::Reader
* reader
)
226 std::vector
<ObjectFile::StabsInfo
>* stabs
= reader
->getStabsDebugInfo();
231 std::vector
<ObjectFile::Atom
*> atoms
= reader
->getAtoms();
232 const int atomCount
= atoms
.size();
233 for(int i
=0; i
< atomCount
; ++i
) {
240 static ObjectFile::Reader
* createReader(const char* path
, const ObjectFile::ReaderOptions
& options
)
242 struct stat stat_buf
;
244 int fd
= ::open(path
, O_RDONLY
, 0);
246 throw "cannot open file";
247 ::fstat(fd
, &stat_buf
);
248 char* p
= (char*)::mmap(NULL
, stat_buf
.st_size
, PROT_READ
, MAP_FILE
, fd
, 0);
250 const mach_header
* mh
= (mach_header
*)p
;
251 if ( mh
->magic
== OSSwapBigToHostInt32(FAT_MAGIC
) ) {
252 const struct fat_header
* fh
= (struct fat_header
*)p
;
253 const struct fat_arch
* archs
= (struct fat_arch
*)(p
+ sizeof(struct fat_header
));
254 for (unsigned long i
=0; i
< fh
->nfat_arch
; ++i
) {
255 if ( archs
[i
].cputype
== CPU_TYPE_POWERPC64
) {
256 p
= p
+ archs
[i
].offset
;
257 mh
= (struct mach_header
*)p
;
261 if ( mh
->magic
== MH_MAGIC
) {
262 if ( mh
->filetype
== MH_OBJECT
) {
263 switch ( mh
->cputype
) {
265 return i386::ObjectFileMachO::MakeReader((class i386::macho_header
*)mh
, path
, options
);
266 case CPU_TYPE_POWERPC
:
267 return ppc::ObjectFileMachO::MakeReader((class ppc::macho_header
*)mh
, path
, options
);
268 case CPU_TYPE_POWERPC64
:
269 return ppc64::ObjectFileMachO::MakeReader((class ppc64::macho_header
*)mh
, path
, options
);
271 throw "unknown mach-o cpu type";
274 if ( mh
->filetype
== MH_DYLIB
)
275 return ppc::ObjectFileDylibMachO::MakeReader((class ppc::macho_header
*)mh
, path
, options
);
276 throw "unknown mach-o file type";
278 else if ( mh
->magic
== MH_MAGIC_64
) {
279 if ( mh
->filetype
== MH_OBJECT
)
280 return ppc64::ObjectFileMachO::MakeReader((class ppc64::macho_header
*)mh
, path
, options
);
281 if ( mh
->filetype
== MH_DYLIB
)
282 return ppc64::ObjectFileDylibMachO::MakeReader((class ppc64::macho_header
*)mh
, path
, options
);
283 throw "unknown mach-o file type";
285 else if ( mh
->magic
== OSSwapInt32(MH_MAGIC
) ) {
286 if ( mh
->filetype
== OSSwapInt32(MH_OBJECT
) ) {
287 switch ( OSSwapInt32(mh
->cputype
) ) {
289 return i386::ObjectFileMachO::MakeReader((class i386::macho_header
*)mh
, path
, options
);
290 case CPU_TYPE_POWERPC
:
291 return ppc::ObjectFileMachO::MakeReader((class ppc::macho_header
*)mh
, path
, options
);
292 case CPU_TYPE_POWERPC64
:
293 return ppc64::ObjectFileMachO::MakeReader((class ppc64::macho_header
*)mh
, path
, options
);
295 throw "unknown mach-o cpu type";
298 if ( mh
->filetype
== OSSwapInt32(MH_DYLIB
) )
299 return ppc::ObjectFileDylibMachO::MakeReader((class ppc::macho_header
*)mh
, path
, options
);
300 throw "unknown mach-o file type";
302 else if ( mh
->magic
== OSSwapInt32(MH_MAGIC_64
) ) {
303 if ( mh
->filetype
== OSSwapInt32(MH_OBJECT
) )
304 return ppc64::ObjectFileMachO::MakeReader((class ppc64::macho_header
*)mh
, path
, options
);
305 if ( mh
->filetype
== OSSwapInt32(MH_DYLIB
) )
306 return ppc64::ObjectFileDylibMachO::MakeReader((class ppc64::macho_header
*)mh
, path
, options
);
307 throw "unknown mach-o file type";
309 throw "unknown file type";
313 int main(int argc
, const char* argv
[])
315 ObjectFile::ReaderOptions options
;
316 //const char* path = argv[1];
317 //ObjectFile::Reader* reader = ObjectFile::Reader::createReader(path);
319 ObjectFile::Reader
* reader
= createReader("/tmp/gcov-1.o", options
);
323 catch (const char* msg
) {
324 fprintf(stderr
, "ObjDump failed: %s\n", msg
);