1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-  
   3  * Copyright (c) 2005-2010 Apple Inc. All rights reserved. 
   5  * @APPLE_LICENSE_HEADER_START@ 
   7  * This file contains Original Code and/or Modifications of Original Code 
   8  * as defined in and that are subject to the Apple Public Source License 
   9  * Version 2.0 (the 'License'). You may not use this file except in 
  10  * compliance with the License. Please obtain a copy of the License at 
  11  * http://www.opensource.apple.com/apsl/ and read it before using this 
  14  * The Original Code and all software distributed under the License are 
  15  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  16  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  17  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  18  * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  19  * Please see the License for the specific language governing rights and 
  20  * limitations under the License. 
  22  * @APPLE_LICENSE_HEADER_END@ 
  25 #include <sys/types.h> 
  29 #include <mach-o/nlist.h> 
  30 #include <mach-o/stab.h> 
  31 #include <mach-o/fat.h> 
  32 #include <mach-o/loader.h> 
  34 #include "MachOFileAbstraction.hpp" 
  35 #include "parsers/macho_relocatable_file.h" 
  36 #include "parsers/lto_file.h" 
  38 static bool                     sDumpContent
= true; 
  39 static bool                     sDumpStabs      
= false; 
  40 static bool                     sSort           
= true; 
  41 static bool                     sNMmode         
= false; 
  42 static bool                     sShowSection                    
= true; 
  43 static bool                     sShowDefinitionKind             
= true; 
  44 static bool                     sShowCombineKind                
= true; 
  45 static bool                     sShowLineInfo                   
= true; 
  47 static cpu_type_t               sPreferredArch 
= 0xFFFFFFFF; 
  48 static cpu_subtype_t    sPreferredSubArch 
= 0xFFFFFFFF; 
  49 static const char* sMatchName 
= NULL
; 
  50 static int sPrintRestrict
; 
  51 static int sPrintAlign
; 
  52 static int sPrintName
; 
  54  __attribute__((noreturn
)) 
  55 void throwf(const char* format
, ...)  
  59         va_start(list
, format
); 
  60         vasprintf(&p
, format
, list
); 
  67 void warning(const char* format
, ...) 
  70         fprintf(stderr
, "warning: "); 
  71         va_start(list
, format
); 
  72         vfprintf(stderr
, format
, list
); 
  74         fprintf(stderr
, "\n"); 
  77 static void dumpStabs(const std::vector
<ld::relocatable::File::Stab
>* stabs
) 
  80         printf("stabs: (%lu)\n", stabs
->size()); 
  81         for (std::vector
<ld::relocatable::File::Stab
>::const_iterator it 
= stabs
->begin(); it 
!= stabs
->end(); ++it 
) { 
  82                 const ld::relocatable::File::Stab
& stab 
= *it
; 
  83                 const char* code 
= "?????"; 
 170                 printf("  [atom=%20s] %02X %04X %s %s\n", ((stab
.atom 
!= NULL
) ? stab
.atom
->name() : ""), stab
.other
, stab
.desc
, code
, stab
.string
); 
 175 static void dumpAtomLikeNM(ld::Atom
* atom
) 
 177         uint32_t size 
= atom
->size(); 
 179         const char* visibility
; 
 180         switch ( atom
->scope() ) { 
 181                 case ld::Atom::scopeTranslationUnit
: 
 182                         visibility 
= "internal"; 
 184                 case ld::Atom::scopeLinkageUnit
: 
 185                         visibility 
= "hidden  "; 
 187                 case ld::Atom::scopeGlobal
: 
 188                         visibility 
= "global  "; 
 196         switch ( atom
->definitionKind() ) { 
 197                 case ld::Atom::kRegularDefinition
: 
 200                 case ld::Atom::kTentativeDefinition
: 
 203                 case ld::Atom::kWeakDefinition
: 
 206                 case ld::Atom::kAbsoluteSymbol
: 
 214         printf("0x%08X %s %s %s\n", size
, visibility
, kind
, atom
->name()); 
 218 static void dumpAtom(ld::Atom
* atom
) 
 220         if(sMatchName 
&& strcmp(sMatchName
, atom
->name())) 
 223         //printf("atom:    %p\n", atom); 
 226         if(!sPrintRestrict 
|| sPrintName
) 
 227                 printf("name:    %s\n",  atom
->name()); 
 231                 switch ( atom
->scope() ) { 
 232                 case ld::Atom::scopeTranslationUnit
: 
 233                         printf("scope:   translation unit\n"); 
 235                 case ld::Atom::scopeLinkageUnit
: 
 236                         printf("scope:   linkage unit\n"); 
 238                 case ld::Atom::scopeGlobal
: 
 239                         printf("scope:   global\n"); 
 242                         printf("scope:   unknown\n"); 
 247                 switch ( atom
->definitionKind() ) { 
 248                 case ld::Atom::kRegularDefinition
: 
 249                         printf("kind:     regular\n"); 
 251                 case ld::Atom::kWeakDefinition
: 
 252                         printf("kind:     weak\n"); 
 254                 case ld::Atom::kTentativeDefinition
: 
 255                         printf("kind:     tentative\n"); 
 257                 case ld::Atom::kExternalDefinition
: 
 258                         printf("kind:     import\n"); 
 260                 case ld::Atom::kExternalWeakDefinition
: 
 261                         printf("kind:     weak import\n"); 
 263                 case ld::Atom::kAbsoluteSymbol
: 
 264                         printf("kind:     absolute symbol\n"); 
 267                         printf("kind:   unknown\n"); 
 270         // segment and section 
 271         if(!sPrintRestrict 
&& (atom
->section().sectionName() != NULL
) ) 
 272                 printf("section: %s,%s\n", atom
->section().segmentName(), atom
->section().sectionName()); 
 275         if(!sPrintRestrict
) { 
 277                 if ( atom
->dontDeadStrip() ) 
 278                         printf("dont-dead-strip "); 
 279                 if ( atom
->isThumb() ) 
 286                 printf("size:    0x%012llX\n", atom
->size()); 
 289         if(!sPrintRestrict 
|| sPrintAlign
) 
 290                 printf("align:    %u mod %u\n", atom
->alignment().modulus
, (1 << atom
->alignment().powerOf2
) ); 
 293         if (!sPrintRestrict 
&& sDumpContent 
) {  
 294                 uint64_t size 
= atom
->size(); 
 296                         uint8_t content
[size
]; 
 297                         atom
->copyRawContent(content
); 
 299                         if ( atom
->contentType() == ld::Atom::typeCString 
) { 
 301                                 for (unsigned int i
=0; i 
< size
; ++i
) { 
 302                                         if(content
[i
]<'!' || content
[i
]>=127) 
 303                                                 printf("\\%o", content
[i
]); 
 305                                                 printf("%c", content
[i
]); 
 310                                 for (unsigned int i
=0; i 
< size
; ++i
) 
 311                                         printf("%02X ", content
[i
]); 
 318         if(!sPrintRestrict
) { 
 319                 if ( atom
->beginUnwind() != atom
->endUnwind() ) { 
 320                         printf("unwind encodings:\n"); 
 321                         for (ld::Atom::UnwindInfo::iterator it 
= atom
->beginUnwind(); it 
!= atom
->endUnwind(); ++it
) { 
 322                                 printf("\t 0x%04X  0x%08X\n", it
->startOffset
, it
->unwindInfo
); 
 328         if(!sPrintRestrict
) { 
 329                 std::vector
<ObjectFile::Reference
*>&  references 
= atom
->getReferences(); 
 330                 const int refCount 
= references
.size(); 
 331                 printf("references: (%u)\n", refCount
); 
 332                 for (int i
=0; i 
< refCount
; ++i
) { 
 333                         ObjectFile::Reference
* ref 
= references
[i
]; 
 334                         printf("   %s\n", ref
->getDescription()); 
 339         if(!sPrintRestrict
) { 
 340                 if ( atom
->beginLineInfo() != atom
->endLineInfo() ) { 
 341                         printf("line info:\n"); 
 342                         for (ld::Atom::LineInfo::iterator it 
= atom
->beginLineInfo(); it 
!= atom
->endLineInfo(); ++it
) { 
 343                                 printf("   offset 0x%04X, line %d, file %s\n", it
->atomOffset
, it
->lineNumber
, it
->fileName
); 
 354      bool operator()(const ld::Atom
* left
, const ld::Atom
* right
) 
 358                 // first sort by segment name 
 359                 int diff 
= strcmp(left
->section().segmentName(), right
->section().segmentName()); 
 363                 // then sort by section name 
 364                 diff 
= strcmp(left
->section().sectionName(), right
->section().sectionName()); 
 368                 // then sort by atom name 
 369                 diff 
= strcmp(left
->name(), right
->name()); 
 373                 // if cstring, sort by content 
 374                 if ( left
->contentType() == ld::Atom::typeCString 
) { 
 375                         diff 
= strcmp((char*)left
->rawContentPointer(), (char*)right
->rawContentPointer()); 
 379                 else if ( left
->section().type() == ld::Section::typeCStringPointer 
) { 
 380                         // if pointer to c-string sort by name 
 381                         const char* leftString 
= NULL
; 
 382                         assert(left
->fixupsBegin() != left
->fixupsEnd()); 
 383                         for (ld::Fixup::iterator fit 
= left
->fixupsBegin(); fit 
!= left
->fixupsEnd(); ++fit
) { 
 384                                 if ( fit
->binding 
== ld::Fixup::bindingByContentBound 
) { 
 385                                         const ld::Atom
* cstringAtom 
= fit
->u
.target
; 
 386                                         assert(cstringAtom
->contentType() == ld::Atom::typeCString
); 
 387                                         leftString 
= (char*)cstringAtom
->rawContentPointer(); 
 390                         const char* rightString 
= NULL
; 
 391                         assert(right
->fixupsBegin() != right
->fixupsEnd()); 
 392                         for (ld::Fixup::iterator fit 
= right
->fixupsBegin(); fit 
!= right
->fixupsEnd(); ++fit
) { 
 393                                 if ( fit
->binding 
== ld::Fixup::bindingByContentBound 
) { 
 394                                         const ld::Atom
* cstringAtom 
= fit
->u
.target
; 
 395                                         assert(cstringAtom
->contentType() == ld::Atom::typeCString
); 
 396                                         rightString 
= (char*)cstringAtom
->rawContentPointer(); 
 399                         assert(leftString 
!= NULL
); 
 400                         assert(rightString 
!= NULL
); 
 401                         diff 
= strcmp(leftString
, rightString
); 
 405                 else if ( left
->section().type() == ld::Section::typeLiteral4 
) { 
 406                         // if literal sort by content 
 407                         uint32_t leftValue  
= *(uint32_t*)left
->rawContentPointer(); 
 408                         uint32_t rightValue 
= *(uint32_t*)right
->rawContentPointer(); 
 409                         diff 
= (leftValue 
- rightValue
); 
 413                 else if ( left
->section().type() == ld::Section::typeCFI 
) { 
 414                         // if __he_frame sort by address 
 415                         diff 
= (left
->objectAddress() - right
->objectAddress()); 
 419                 else if ( left
->section().type() == ld::Section::typeNonLazyPointer 
) { 
 420                         // if non-lazy-pointer sort by name 
 421                         const char* leftString 
= NULL
; 
 422                         assert(left
->fixupsBegin() != left
->fixupsEnd()); 
 423                         for (ld::Fixup::iterator fit 
= left
->fixupsBegin(); fit 
!= left
->fixupsEnd(); ++fit
) { 
 424                                 if ( fit
->binding 
== ld::Fixup::bindingByNameUnbound 
) { 
 425                                         leftString 
= fit
->u
.name
; 
 427                                 else if ( fit
->binding 
== ld::Fixup::bindingDirectlyBound 
) { 
 428                                         leftString 
= fit
->u
.target
->name(); 
 431                         const char* rightString 
= NULL
; 
 432                         assert(right
->fixupsBegin() != right
->fixupsEnd()); 
 433                         for (ld::Fixup::iterator fit 
= right
->fixupsBegin(); fit 
!= right
->fixupsEnd(); ++fit
) { 
 434                                 if ( fit
->binding 
== ld::Fixup::bindingByNameUnbound 
) { 
 435                                         rightString 
= fit
->u
.name
; 
 437                                 else if ( fit
->binding 
== ld::Fixup::bindingDirectlyBound 
) { 
 438                                         rightString 
= fit
->u
.target
->name(); 
 441                         assert(leftString 
!= NULL
); 
 442                         assert(rightString 
!= NULL
); 
 443                         diff 
= strcmp(leftString
, rightString
); 
 449                 return (left
->size() < right
->size()); 
 454 class dumper 
: public ld::File::AtomHandler
 
 458         virtual void doAtom(const ld::Atom
&); 
 459         virtual void doFile(const ld::File
&) {}  
 461         void                    dumpAtom(const ld::Atom
& atom
); 
 462         const char*             scopeString(const ld::Atom
&); 
 463         const char*             definitionString(const ld::Atom
&); 
 464         const char*             combineString(const ld::Atom
&); 
 465         const char*             inclusionString(const ld::Atom
&); 
 466         const char*             attributeString(const ld::Atom
&); 
 467         const char*             makeName(const ld::Atom
& atom
); 
 468         const char*             referenceTargetAtomName(const ld::Fixup
* ref
); 
 469         void                    dumpFixup(const ld::Fixup
* ref
); 
 471         uint64_t                addressOfFirstAtomInSection(const ld::Section
&); 
 473         std::vector
<const ld::Atom
*> _atoms
; 
 476 const char*     dumper::scopeString(const ld::Atom
& atom
) 
 478         switch ( (ld::Atom::Scope
)atom
.scope() ) { 
 479                 case ld::Atom::scopeTranslationUnit
: 
 480                         return "translation-unit"; 
 481                 case ld::Atom::scopeLinkageUnit
: 
 483                 case ld::Atom::scopeGlobal
: 
 484                         if ( atom
.autoHide() ) 
 485                                 return "global but automatically hidden"; 
 492 const char*     dumper::definitionString(const ld::Atom
& atom
) 
 494         switch ( (ld::Atom::Definition
)atom
.definition() ) { 
 495                 case ld::Atom::definitionRegular
: 
 497                 case ld::Atom::definitionTentative
: 
 499                 case ld::Atom::definitionAbsolute
: 
 501                 case ld::Atom::definitionProxy
: 
 507 const char*     dumper::combineString(const ld::Atom
& atom
) 
 509         switch ( (ld::Atom::Combine
)atom
.combine() ) { 
 510                 case ld::Atom::combineNever
: 
 512                 case ld::Atom::combineByName
: 
 514                 case ld::Atom::combineByNameAndContent
: 
 515                         return "by-name-and-content"; 
 516                 case ld::Atom::combineByNameAndReferences
: 
 517                         return "by-name-and-references"; 
 522 const char*     dumper::inclusionString(const ld::Atom
& atom
) 
 524         switch ( (ld::Atom::SymbolTableInclusion
)atom
.symbolTableInclusion() ) { 
 525                 case ld::Atom::symbolTableNotIn
: 
 527                 case ld::Atom::symbolTableNotInFinalLinkedImages
: 
 528                         return "not in final linked images"; 
 529                 case ld::Atom::symbolTableIn
: 
 531                 case ld::Atom::symbolTableInAndNeverStrip
: 
 532                         return "in and never strip"; 
 533                 case ld::Atom::symbolTableInAsAbsolute
: 
 534                         return "in as absolute"; 
 535                 case ld::Atom::symbolTableInWithRandomAutoStripLabel
: 
 536                         return "in as random auto-strip label"; 
 543 const char*     dumper::attributeString(const ld::Atom
& atom
) 
 545         static char buffer
[256]; 
 548         if ( atom
.dontDeadStrip() ) 
 549                 strcat(buffer
, "dont-dead-strip "); 
 551         if ( atom
.isThumb() ) 
 552                 strcat(buffer
, "thumb "); 
 554         if ( atom
.isAlias() ) 
 555                 strcat(buffer
, "alias "); 
 557         if ( atom
.contentType() == ld::Atom::typeResolver 
) 
 558                 strcat(buffer
, "resolver "); 
 563 const char* dumper::makeName(const ld::Atom
& atom
) 
 565         static char buffer
[4096]; 
 566         strcpy(buffer
, "???"); 
 567         switch ( atom
.symbolTableInclusion() ) { 
 568                 case ld::Atom::symbolTableNotIn
: 
 569                         if ( atom
.contentType() == ld::Atom::typeCString 
) { 
 570                                 strcpy(buffer
, "cstring="); 
 571                                 strlcat(buffer
, (char*)atom
.rawContentPointer(), 4096); 
 573                         else if ( atom
.section().type() == ld::Section::typeLiteral4 
) { 
 575                                 strcpy(buffer
, "literal4="); 
 576                                 uint32_t value 
= *(uint32_t*)atom
.rawContentPointer(); 
 577                                 sprintf(temp
, "0x%08X", value
); 
 578                                 strcat(buffer
, temp
); 
 580                         else if ( atom
.section().type() == ld::Section::typeLiteral8 
) { 
 582                                 strcpy(buffer
, "literal8="); 
 583                                 uint32_t value1 
= *(uint32_t*)atom
.rawContentPointer(); 
 584                                 uint32_t value2 
= ((uint32_t*)atom
.rawContentPointer())[1]; 
 585                                 sprintf(temp
, "0x%08X%08X", value1
, value2
); 
 586                                 strcat(buffer
, temp
); 
 588                         else if ( atom
.section().type() == ld::Section::typeLiteral16 
) { 
 590                                 strcpy(buffer
, "literal16="); 
 591                                 uint32_t value1 
= *(uint32_t*)atom
.rawContentPointer(); 
 592                                 uint32_t value2 
= ((uint32_t*)atom
.rawContentPointer())[1]; 
 593                                 uint32_t value3 
= ((uint32_t*)atom
.rawContentPointer())[2]; 
 594                                 uint32_t value4 
= ((uint32_t*)atom
.rawContentPointer())[3]; 
 595                                 sprintf(temp
, "0x%08X%08X%08X%08X", value1
, value2
, value3
, value4
); 
 596                                 strcat(buffer
, temp
); 
 598                         else if ( atom
.section().type() == ld::Section::typeCStringPointer 
) { 
 599                                 assert(atom
.fixupsBegin() != atom
.fixupsEnd()); 
 600                                 for (ld::Fixup::iterator fit 
= atom
.fixupsBegin(); fit 
!= atom
.fixupsEnd(); ++fit
) { 
 601                                         if ( fit
->binding 
== ld::Fixup::bindingByContentBound 
) { 
 602                                                 const ld::Atom
* cstringAtom 
= fit
->u
.target
; 
 603                                                 if ( (cstringAtom 
!= NULL
) && (cstringAtom
->contentType() == ld::Atom::typeCString
) ) { 
 604                                                         strlcpy(buffer
, atom
.name(), 4096); 
 605                                                         strlcat(buffer
, "=", 4096); 
 606                                                         strlcat(buffer
, (char*)cstringAtom
->rawContentPointer(), 4096); 
 611                         else if ( atom
.section().type() == ld::Section::typeNonLazyPointer 
) { 
 612                                 assert(atom
.fixupsBegin() != atom
.fixupsEnd()); 
 613                                 for (ld::Fixup::iterator fit 
= atom
.fixupsBegin(); fit 
!= atom
.fixupsEnd(); ++fit
) { 
 614                                         if ( fit
->binding 
== ld::Fixup::bindingByNameUnbound 
) { 
 615                                                 strcpy(buffer
, "non-lazy-pointer-to:"); 
 616                                                 strlcat(buffer
, fit
->u
.name
, 4096); 
 619                                         else if ( fit
->binding 
== ld::Fixup::bindingDirectlyBound 
) { 
 620                                                 strcpy(buffer
, "non-lazy-pointer-to-local:"); 
 621                                                 strlcat(buffer
, fit
->u
.target
->name(), 4096); 
 625                                 strlcpy(buffer
, atom
.name(), 4096); 
 628                                 uint64_t sectAddr 
= addressOfFirstAtomInSection(atom
.section()); 
 629                                 sprintf(buffer
, "%s@%s+0x%08llX", atom
.name(), atom
.section().sectionName(), atom
.objectAddress()-sectAddr
); 
 632                 case ld::Atom::symbolTableNotInFinalLinkedImages
: 
 633                 case ld::Atom::symbolTableIn
: 
 634                 case ld::Atom::symbolTableInAndNeverStrip
: 
 635                 case ld::Atom::symbolTableInAsAbsolute
: 
 636                 case ld::Atom::symbolTableInWithRandomAutoStripLabel
: 
 637                         strlcpy(buffer
, atom
.name(), 4096); 
 643 const char* dumper::referenceTargetAtomName(const ld::Fixup
* ref
) 
 645         static char buffer
[4096]; 
 646         switch ( ref
->binding 
) { 
 647                 case ld::Fixup::bindingNone
: 
 649                 case ld::Fixup::bindingByNameUnbound
: 
 650                         strcpy(buffer
, "by-name("); 
 651                         strlcat(buffer
, ref
->u
.name
, 4096); 
 652                         strlcat(buffer
, ")", 4096); 
 654                         //return ref->u.name; 
 655                 case ld::Fixup::bindingByContentBound
: 
 656                         strcpy(buffer
, "by-content("); 
 657                         strlcat(buffer
, makeName(*ref
->u
.target
), 4096); 
 658                         strlcat(buffer
, ")", 4096); 
 660                 case ld::Fixup::bindingDirectlyBound
: 
 661                         strcpy(buffer
, "direct("); 
 662                         strlcat(buffer
, makeName(*ref
->u
.target
), 4096); 
 663                         strlcat(buffer
, ")", 4096); 
 665                 case ld::Fixup::bindingsIndirectlyBound
: 
 666                         return "BOUND INDIRECTLY"; 
 668         return "BAD BINDING"; 
 672 void dumper::dumpFixup(const ld::Fixup
* ref
) 
 674         if ( ref
->weakImport 
) { 
 675                 printf("weak_import "); 
 677         switch ( (ld::Fixup::Kind
)(ref
->kind
) ) { 
 678                 case ld::Fixup::kindNone
: 
 681                 case ld::Fixup::kindNoneFollowOn
: 
 682                         printf("followed by %s", referenceTargetAtomName(ref
)); 
 684                 case ld::Fixup::kindNoneGroupSubordinate
: 
 685                         printf("group subordinate %s", referenceTargetAtomName(ref
)); 
 687                 case ld::Fixup::kindNoneGroupSubordinateFDE
: 
 688                         printf("group subordinate FDE %s", referenceTargetAtomName(ref
)); 
 690                 case ld::Fixup::kindNoneGroupSubordinateLSDA
: 
 691                         printf("group subordinate LSDA %s", referenceTargetAtomName(ref
)); 
 693                 case ld::Fixup::kindNoneGroupSubordinatePersonality
: 
 694                         printf("group subordinate personality %s", referenceTargetAtomName(ref
)); 
 696                 case ld::Fixup::kindSetTargetAddress
: 
 697                         printf("%s", referenceTargetAtomName(ref
)); 
 699                 case ld::Fixup::kindSubtractTargetAddress
: 
 700                         printf(" - %s", referenceTargetAtomName(ref
)); 
 702                 case ld::Fixup::kindAddAddend
: 
 703                         printf(" + 0x%llX", ref
->u
.addend
); 
 705                 case ld::Fixup::kindSubtractAddend
: 
 706                         printf(" - 0x%llX", ref
->u
.addend
); 
 708                 case ld::Fixup::kindSetTargetImageOffset
: 
 709                         printf("imageOffset(%s)", referenceTargetAtomName(ref
)); 
 711                 case ld::Fixup::kindSetTargetSectionOffset
: 
 712                         printf("sectionOffset(%s)", referenceTargetAtomName(ref
)); 
 714                 case ld::Fixup::kindStore8
: 
 715                         printf(", then store byte"); 
 717                 case ld::Fixup::kindStoreLittleEndian16
: 
 718                         printf(", then store 16-bit little endian"); 
 720                 case ld::Fixup::kindStoreLittleEndianLow24of32
: 
 721                         printf(", then store low 24-bit little endian"); 
 723                 case ld::Fixup::kindStoreLittleEndian32
: 
 724                         printf(", then store 32-bit little endian"); 
 726                 case ld::Fixup::kindStoreLittleEndian64
: 
 727                         printf(", then store 64-bit little endian"); 
 729                 case ld::Fixup::kindStoreBigEndian16
: 
 730                         printf(", then store 16-bit big endian"); 
 732                 case ld::Fixup::kindStoreBigEndianLow24of32
: 
 733                         printf(", then store low 24-bit big endian"); 
 735                 case ld::Fixup::kindStoreBigEndian32
: 
 736                         printf(", then store 32-bit big endian"); 
 738                 case ld::Fixup::kindStoreBigEndian64
: 
 739                         printf(", then store 64-bit big endian"); 
 741                 case ld::Fixup::kindStoreX86BranchPCRel8
: 
 742                         printf(", then store as x86 8-bit pcrel branch"); 
 744                 case ld::Fixup::kindStoreX86BranchPCRel32
: 
 745                         printf(", then store as x86 32-bit pcrel branch"); 
 747                 case ld::Fixup::kindStoreX86PCRel8
: 
 748                         printf(", then store as x86 8-bit pcrel"); 
 750                 case ld::Fixup::kindStoreX86PCRel16
: 
 751                         printf(", then store as x86 16-bit pcrel"); 
 753                 case ld::Fixup::kindStoreX86PCRel32
: 
 754                         printf(", then store as x86 32-bit pcrel"); 
 756                 case ld::Fixup::kindStoreX86PCRel32_1
: 
 757                         printf(", then store as x86 32-bit pcrel from +1"); 
 759                 case ld::Fixup::kindStoreX86PCRel32_2
: 
 760                         printf(", then store as x86 32-bit pcrel from +2"); 
 762                 case ld::Fixup::kindStoreX86PCRel32_4
: 
 763                         printf(", then store as x86 32-bit pcrel from +4"); 
 765                 case ld::Fixup::kindStoreX86PCRel32GOTLoad
: 
 766                         printf(", then store as x86 32-bit pcrel GOT load"); 
 768                 case ld::Fixup::kindStoreX86PCRel32GOTLoadNowLEA
: 
 769                         printf(", then store as x86 32-bit pcrel GOT load -> LEA"); 
 771                 case ld::Fixup::kindStoreX86PCRel32GOT
: 
 772                         printf(", then store as x86 32-bit pcrel GOT access"); 
 774                 case ld::Fixup::kindStoreX86PCRel32TLVLoad
: 
 775                         printf(", then store as x86 32-bit pcrel TLV load"); 
 777                 case ld::Fixup::kindStoreX86PCRel32TLVLoadNowLEA
: 
 778                         printf(", then store as x86 32-bit pcrel TLV load"); 
 780                 case ld::Fixup::kindStoreX86Abs32TLVLoad
: 
 781                         printf(", then store as x86 32-bit absolute TLV load"); 
 783                 case ld::Fixup::kindStoreX86Abs32TLVLoadNowLEA
: 
 784                         printf(", then store as x86 32-bit absolute TLV load -> LEA"); 
 786                 case ld::Fixup::kindStoreARMBranch24
: 
 787                         printf(", then store as ARM 24-bit pcrel branch"); 
 789                 case ld::Fixup::kindStoreThumbBranch22
: 
 790                         printf(", then store as Thumb 22-bit pcrel branch"); 
 792                 case ld::Fixup::kindStoreARMLoad12
: 
 793                         printf(", then store as ARM 12-bit pcrel load"); 
 795                 case ld::Fixup::kindStoreARMLow16
: 
 796                         printf(", then store low-16 in ARM movw"); 
 798                 case ld::Fixup::kindStoreARMHigh16
: 
 799                         printf(", then store high-16 in ARM movt"); 
 801                 case ld::Fixup::kindStoreThumbLow16
: 
 802                         printf(", then store low-16 in Thumb movw"); 
 804                 case ld::Fixup::kindStoreThumbHigh16
: 
 805                         printf(", then store high-16 in Thumb movt"); 
 807                 case ld::Fixup::kindStoreARM64Branch26
: 
 808                         printf(", then store as ARM64 26-bit pcrel branch"); 
 810                 case ld::Fixup::kindStoreARM64Page21
: 
 811                         printf(", then store as ARM64 21-bit pcrel ADRP"); 
 813                 case ld::Fixup::kindStoreARM64PageOff12
: 
 814                         printf(", then store as ARM64 12-bit offset"); 
 816                 case ld::Fixup::kindStoreARM64GOTLoadPage21
: 
 817                         printf(", then store as ARM64 21-bit pcrel ADRP of GOT"); 
 819                 case ld::Fixup::kindStoreARM64GOTLoadPageOff12
: 
 820                         printf(", then store as ARM64 12-bit page offset of GOT"); 
 822                 case ld::Fixup::kindStoreARM64GOTLeaPage21
: 
 823                         printf(", then store as ARM64 21-bit pcrel ADRP of GOT lea"); 
 825                 case ld::Fixup::kindStoreARM64GOTLeaPageOff12
: 
 826                         printf(", then store as ARM64 12-bit page offset of GOT lea"); 
 828                 case ld::Fixup::kindStoreARM64TLVPLoadPage21
: 
 829                         printf(", then store as ARM64 21-bit pcrel ADRP of TLVP"); 
 831                 case ld::Fixup::kindStoreARM64TLVPLoadPageOff12
: 
 832                         printf(", then store as ARM64 12-bit page offset of TLVP"); 
 834                 case ld::Fixup::kindStoreARM64TLVPLoadNowLeaPage21
: 
 835                         printf(", then store as ARM64 21-bit pcrel ADRP of lea of TLVP"); 
 837                 case ld::Fixup::kindStoreARM64TLVPLoadNowLeaPageOff12
: 
 838                         printf(", then store as ARM64 12-bit page offset of lea of TLVP"); 
 840                 case ld::Fixup::kindStoreARM64PointerToGOT
: 
 841                         printf(", then store as 64-bit pointer to GOT entry"); 
 843                 case ld::Fixup::kindStoreARM64PCRelToGOT
: 
 844                         printf(", then store as 32-bit delta to GOT entry"); 
 846                 case ld::Fixup::kindDtraceExtra
: 
 847                         printf("dtrace static probe extra info"); 
 849                 case ld::Fixup::kindStoreX86DtraceCallSiteNop
: 
 850                         printf("x86 dtrace static probe site"); 
 852                 case ld::Fixup::kindStoreX86DtraceIsEnableSiteClear
: 
 853                         printf("x86 dtrace static is-enabled site"); 
 855                 case ld::Fixup::kindStoreARMDtraceCallSiteNop
: 
 856                         printf("ARM dtrace static probe site"); 
 858                 case ld::Fixup::kindStoreARMDtraceIsEnableSiteClear
: 
 859                         printf("ARM dtrace static is-enabled site"); 
 861                 case ld::Fixup::kindStoreThumbDtraceCallSiteNop
: 
 862                         printf("Thumb dtrace static probe site"); 
 864                 case ld::Fixup::kindStoreThumbDtraceIsEnableSiteClear
: 
 865                         printf("Thumb dtrace static is-enabled site"); 
 867                 case ld::Fixup::kindStoreARM64DtraceCallSiteNop
: 
 868                         printf("ARM64 dtrace static probe site"); 
 870                 case ld::Fixup::kindStoreARM64DtraceIsEnableSiteClear
: 
 871                         printf("ARM64 dtrace static is-enabled site"); 
 873                 case ld::Fixup::kindLazyTarget
: 
 874                         printf("lazy reference to external symbol %s", referenceTargetAtomName(ref
)); 
 876                 case ld::Fixup::kindSetLazyOffset
: 
 877                         printf("offset of lazy binding info for %s", referenceTargetAtomName(ref
)); 
 879                 case ld::Fixup::kindIslandTarget
: 
 880                         printf("ultimate target of island %s", referenceTargetAtomName(ref
)); 
 882                 case ld::Fixup::kindDataInCodeStartData
: 
 883                         printf("start of data in code"); 
 885                 case ld::Fixup::kindDataInCodeStartJT8
: 
 886                         printf("start of jump table 8 data in code"); 
 888                 case ld::Fixup::kindDataInCodeStartJT16
: 
 889                         printf("start of jump table 16 data in code"); 
 891                 case ld::Fixup::kindDataInCodeStartJT32
: 
 892                         printf("start of jump table 32 data in code"); 
 894                 case ld::Fixup::kindDataInCodeStartJTA32
: 
 895                         printf("start of jump table absolute 32 data in code"); 
 897                 case ld::Fixup::kindDataInCodeEnd
: 
 898                         printf("end of data in code"); 
 900                 case ld::Fixup::kindLinkerOptimizationHint
: 
 901 #if SUPPORT_ARCH_arm64 
 902                         ld::Fixup::LOH_arm64 extra
; 
 903                         extra
.addend 
= ref
->u
.addend
; 
 904                         printf("ARM64 hint: "); 
 905                         switch(extra
.info
.kind
) { 
 906                                 case LOH_ARM64_ADRP_ADRP
: 
 909                                 case LOH_ARM64_ADRP_LDR
: 
 912                                 case LOH_ARM64_ADRP_ADD_LDR
: 
 913                                         printf("ADRP-ADD-LDR"); 
 915                                 case LOH_ARM64_ADRP_LDR_GOT_LDR
: 
 916                                         printf("ADRP-LDR-GOT-LDR"); 
 918                                 case LOH_ARM64_ADRP_ADD_STR
: 
 919                                         printf("ADRP-ADD-STR"); 
 921                                 case LOH_ARM64_ADRP_LDR_GOT_STR
: 
 922                                         printf("ADRP-LDR-GOT-STR"); 
 924                                 case LOH_ARM64_ADRP_ADD
: 
 928                                         printf("kind=%d", extra
.info
.kind
); 
 931                         printf(", offset1=0x%X", (extra
.info
.delta1 
<< 2)  + ref
->offsetInAtom
); 
 932                         if ( extra
.info
.count 
> 0 ) 
 933                                 printf(", offset2=0x%X", (extra
.info
.delta2 
<< 2) + ref
->offsetInAtom
); 
 934                         if ( extra
.info
.count 
> 1 ) 
 935                                 printf(", offset3=0x%X", (extra
.info
.delta3 
<< 2)  + ref
->offsetInAtom
); 
 936                         if ( extra
.info
.count 
> 2 ) 
 937                                 printf(", offset4=0x%X", (extra
.info
.delta4 
<< 2)  + ref
->offsetInAtom
); 
 940                 case ld::Fixup::kindStoreTargetAddressLittleEndian32
: 
 941                         printf("store 32-bit little endian address of %s", referenceTargetAtomName(ref
)); 
 943                 case ld::Fixup::kindStoreTargetAddressLittleEndian64
: 
 944                         printf("store 64-bit little endian address of %s", referenceTargetAtomName(ref
)); 
 946                 case ld::Fixup::kindStoreTargetAddressBigEndian32
: 
 947                         printf("store 32-bit big endian address of %s", referenceTargetAtomName(ref
)); 
 949                 case ld::Fixup::kindStoreTargetAddressBigEndian64
: 
 950                         printf("store 64-bit big endian address of %s", referenceTargetAtomName(ref
)); 
 952                 case ld::Fixup::kindStoreTargetAddressX86PCRel32
: 
 953                         printf("x86 store 32-bit pc-rel address of %s", referenceTargetAtomName(ref
)); 
 955                 case ld::Fixup::kindStoreTargetAddressX86BranchPCRel32
: 
 956                         printf("x86 store 32-bit pc-rel branch to %s", referenceTargetAtomName(ref
)); 
 958                 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoad
: 
 959                         printf("x86 store 32-bit pc-rel GOT load of %s", referenceTargetAtomName(ref
)); 
 961                 case ld::Fixup::kindStoreTargetAddressX86PCRel32GOTLoadNowLEA
: 
 962                         printf("x86 store 32-bit pc-rel lea of %s", referenceTargetAtomName(ref
)); 
 964                 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoad
: 
 965                         printf("x86 store 32-bit pc-rel TLV load of %s", referenceTargetAtomName(ref
)); 
 967                 case ld::Fixup::kindStoreTargetAddressX86PCRel32TLVLoadNowLEA
: 
 968                         printf("x86 store 32-bit pc-rel TLV lea of %s", referenceTargetAtomName(ref
)); 
 970                 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoad
: 
 971                         printf("x86 store 32-bit absolute TLV load of %s", referenceTargetAtomName(ref
)); 
 973                 case ld::Fixup::kindStoreTargetAddressX86Abs32TLVLoadNowLEA
: 
 974                         printf("x86 store 32-bit absolute TLV lea of %s", referenceTargetAtomName(ref
)); 
 976                 case ld::Fixup::kindStoreTargetAddressARMBranch24
: 
 977                         printf("ARM store 24-bit pc-rel branch to %s", referenceTargetAtomName(ref
)); 
 979                 case ld::Fixup::kindStoreTargetAddressThumbBranch22
: 
 980                         printf("Thumb store 22-bit pc-rel branch to %s", referenceTargetAtomName(ref
)); 
 982                 case ld::Fixup::kindStoreTargetAddressARMLoad12
: 
 983                         printf("ARM store 12-bit pc-rel branch to %s", referenceTargetAtomName(ref
)); 
 985                 case ld::Fixup::kindSetTargetTLVTemplateOffset
: 
 986                 case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian32
: 
 987                 case ld::Fixup::kindSetTargetTLVTemplateOffsetLittleEndian64
: 
 988                         printf("tlv template offset of %s", referenceTargetAtomName(ref
)); 
 990                 case ld::Fixup::kindStoreTargetAddressARM64Branch26
: 
 991                         printf("ARM64 store 26-bit pcrel branch to %s", referenceTargetAtomName(ref
)); 
 993                 case ld::Fixup::kindStoreTargetAddressARM64Page21
: 
 994                         printf("ARM64 store 21-bit pcrel ADRP to %s", referenceTargetAtomName(ref
)); 
 996                 case ld::Fixup::kindStoreTargetAddressARM64PageOff12
: 
 997                         printf("ARM64 store 12-bit page offset of %s", referenceTargetAtomName(ref
)); 
 999                 case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPage21
: 
1000                         printf("ARM64 store 21-bit pcrel ADRP to GOT for %s", referenceTargetAtomName(ref
)); 
1002                 case ld::Fixup::kindStoreTargetAddressARM64GOTLoadPageOff12
: 
1003                         printf("ARM64 store 12-bit page offset of GOT of %s", referenceTargetAtomName(ref
)); 
1005                 case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPage21
: 
1006                         printf("ARM64 store 21-bit pcrel ADRP to GOT lea for %s", referenceTargetAtomName(ref
)); 
1008                 case ld::Fixup::kindStoreTargetAddressARM64GOTLeaPageOff12
: 
1009                         printf("ARM64 store 12-bit page offset of GOT lea of %s", referenceTargetAtomName(ref
)); 
1011                 case ld::Fixup::kindStoreTargetAddressARM64TLVPLoadPage21
: 
1012                         printf("ARM64 store 21-bit pcrel ADRP to TLV for %s", referenceTargetAtomName(ref
)); 
1014                 case ld::Fixup::kindStoreTargetAddressARM64TLVPLoadPageOff12
: 
1015                         printf("ARM64 store 12-bit page offset of TLV of %s", referenceTargetAtomName(ref
)); 
1017                 case ld::Fixup::kindStoreTargetAddressARM64TLVPLoadNowLeaPage21
: 
1018                         printf("ARM64 store 21-bit pcrel ADRP to lea for TLV for %s", referenceTargetAtomName(ref
)); 
1020                 case ld::Fixup::kindStoreTargetAddressARM64TLVPLoadNowLeaPageOff12
: 
1021                         printf("ARM64 store 12-bit page offset of lea for TLV of %s", referenceTargetAtomName(ref
)); 
1024                 //      printf("unknown fixup"); 
1029 uint64_t dumper::addressOfFirstAtomInSection(const ld::Section
& sect
) 
1031         uint64_t lowestAddr 
= (uint64_t)(-1); 
1032         for (std::vector
<const ld::Atom
*>::iterator it
=_atoms
.begin(); it 
!= _atoms
.end(); ++it
) { 
1033                 const ld::Atom
* atom 
= *it
; 
1034                 if ( &atom
->section() == § 
) { 
1035                         if ( atom
->objectAddress() < lowestAddr 
) 
1036                                 lowestAddr 
= atom
->objectAddress(); 
1042 void dumper::doAtom(const ld::Atom
& atom
) 
1044         if ( (sMatchName 
!= NULL
) && (strcmp(sMatchName
, atom
.name()) != 0) ) 
1046         _atoms
.push_back(&atom
); 
1052                 std::sort(_atoms
.begin(), _atoms
.end(), AtomSorter()); 
1054         for (std::vector
<const ld::Atom
*>::iterator it
=_atoms
.begin(); it 
!= _atoms
.end(); ++it
) { 
1055                 this->dumpAtom(**it
); 
1059 void dumper::dumpAtom(const ld::Atom
& atom
) 
1061         printf("name:     %s\n", makeName(atom
));  
1062         printf("size:     0x%0llX\n", atom
.size()); 
1063         printf("align:    %u mod %u\n", atom
.alignment().modulus
, (1 << atom
.alignment().powerOf2
) ); 
1064         printf("scope:    %s\n", scopeString(atom
)); 
1065         if ( sShowDefinitionKind 
)  
1066                 printf("def:      %s\n", definitionString(atom
)); 
1067         if ( sShowCombineKind 
) 
1068                 printf("combine:  %s\n", combineString(atom
)); 
1069         printf("symbol:   %s\n", inclusionString(atom
)); 
1070         printf("attrs:    %s\n", attributeString(atom
)); 
1072                 printf("section:  %s,%s\n", atom
.section().segmentName(), atom
.section().sectionName()); 
1073         if ( atom
.beginUnwind() != atom
.endUnwind() ) { 
1074                 uint32_t lastOffset 
= 0; 
1075                 uint32_t lastCUE 
= 0; 
1077                 const char* label 
= "unwind:"; 
1078                 for (ld::Atom::UnwindInfo::iterator it
=atom
.beginUnwind(); it 
!= atom
.endUnwind(); ++it
) { 
1080                                 printf("%s   0x%08X -> 0x%08X: 0x%08X\n", label
, lastOffset
, it
->startOffset
, lastCUE
); 
1083                         lastOffset 
= it
->startOffset
; 
1084                         lastCUE 
= it
->unwindInfo
; 
1087                 printf("%s   0x%08X -> 0x%08X: 0x%08X\n", label
, lastOffset
, (uint32_t)atom
.size(), lastCUE
); 
1089         if ( atom
.contentType() == ld::Atom::typeCString 
) { 
1090                 uint8_t buffer
[atom
.size()+2]; 
1091                 atom
.copyRawContent(buffer
); 
1092                 buffer
[atom
.size()] = '\0'; 
1093                 printf("content:  \"%s\"\n", buffer
); 
1095         if ( atom
.fixupsBegin() != atom
.fixupsEnd() ) { 
1096                 printf("fixups:\n"); 
1097                 for (unsigned int off
=0; off 
< atom
.size()+1; ++off
) { 
1098                         for (ld::Fixup::iterator it 
= atom
.fixupsBegin(); it 
!= atom
.fixupsEnd(); ++it
) { 
1099                                 if ( it
->offsetInAtom 
== off 
) { 
1100                                         switch ( it
->clusterSize 
) { 
1101                                                 case ld::Fixup::k1of1
: 
1102                                                         printf("    0x%04X ", it
->offsetInAtom
); 
1105                                                 case ld::Fixup::k1of2
: 
1106                                                         printf("    0x%04X ", it
->offsetInAtom
); 
1111                                                 case ld::Fixup::k1of3
: 
1112                                                         printf("    0x%04X ", it
->offsetInAtom
); 
1119                                                 case ld::Fixup::k1of4
: 
1120                                                         printf("    0x%04X ", it
->offsetInAtom
); 
1129                                                 case ld::Fixup::k1of5
: 
1130                                                         printf("    0x%04X ", it
->offsetInAtom
); 
1142                                                         printf("   BAD CLUSTER SIZE: cluster=%d\n", it
->clusterSize
); 
1149         if ( sShowLineInfo 
) { 
1150                 if ( atom
.beginLineInfo() != atom
.endLineInfo() ) { 
1151                         printf("line info:\n"); 
1152                         for (ld::Atom::LineInfo::iterator it 
= atom
.beginLineInfo(); it 
!= atom
.endLineInfo(); ++it
) { 
1153                                 printf("   offset 0x%04X, line %d, file %s\n", it
->atomOffset
, it
->lineNumber
, it
->fileName
); 
1161 static void dumpFile(ld::relocatable::File
* file
) 
1164         if ( sDumpStabs 
&& (file
->debugInfo() == ld::relocatable::File::kDebugInfoStabs
) ) { 
1165                 const std::vector
<ld::relocatable::File::Stab
>* stabs 
= file
->stabs(); 
1166                 if ( stabs 
!= NULL 
) 
1171         file
->forEachAtom(d
); 
1176         std::vector
<ObjectFile::Atom
*> atoms 
= reader
->getAtoms(); 
1178         // make copy of vector and sort (so output is canonical) 
1179         std::vector
<ObjectFile::Atom
*> sortedAtoms(atoms
); 
1181                 std::sort(sortedAtoms
.begin(), sortedAtoms
.end(), AtomSorter()); 
1183         for(std::vector
<ObjectFile::Atom
*>::iterator it
=sortedAtoms
.begin(); it 
!= sortedAtoms
.end(); ++it
) { 
1185                         dumpAtomLikeNM(*it
); 
1193 static ld::relocatable::File
* createReader(const char* path
) 
1195         struct stat stat_buf
; 
1197         int fd 
= ::open(path
, O_RDONLY
, 0); 
1199                 throwf("cannot open file: %s", path
); 
1200         ::fstat(fd
, &stat_buf
); 
1201         uint8_t* p 
= (uint8_t*)::mmap(NULL
, stat_buf
.st_size
, PROT_READ
, MAP_FILE 
| MAP_PRIVATE
, fd
, 0); 
1203         if ( p 
== (uint8_t*)(-1) ) 
1204                 throwf("cannot mmap file: %s", path
); 
1205         const mach_header
* mh 
= (mach_header
*)p
; 
1206         uint64_t fileLen 
= stat_buf
.st_size
; 
1207         bool foundFatSlice 
= false; 
1208         if ( mh
->magic 
== OSSwapBigToHostInt32(FAT_MAGIC
) ) { 
1209                 const struct fat_header
* fh 
= (struct fat_header
*)p
; 
1210                 const struct fat_arch
* archs 
= (struct fat_arch
*)(p 
+ sizeof(struct fat_header
)); 
1211                 if ( (uint32_t)sPreferredArch 
==  0xFFFFFFFF ) { 
1212                         // just dump first slice of fat .o file 
1213                         if ( OSSwapBigToHostInt32(fh
->nfat_arch
) > 0 )  { 
1214                                 p 
= p 
+ OSSwapBigToHostInt32(archs
[0].offset
); 
1215                                 mh 
= (struct mach_header
*)p
; 
1216                                 fileLen 
= OSSwapBigToHostInt32(archs
[0].size
); 
1217                                 sPreferredArch 
= OSSwapBigToHostInt32(archs
[0].cputype
); 
1218                                 sPreferredSubArch 
= OSSwapBigToHostInt32(archs
[0].cpusubtype
); 
1219                                 foundFatSlice 
= true; 
1223                         for (unsigned long i
=0; i 
< OSSwapBigToHostInt32(fh
->nfat_arch
); ++i
) { 
1224                                 if ( OSSwapBigToHostInt32(archs
[i
].cputype
) == (uint32_t)sPreferredArch 
) { 
1225                                         if ( ((uint32_t)sPreferredSubArch 
== 0xFFFFFFFF) || ((uint32_t)sPreferredSubArch 
== OSSwapBigToHostInt32(archs
[i
].cpusubtype
)) ) { 
1226                                                 p 
= p 
+ OSSwapBigToHostInt32(archs
[i
].offset
); 
1227                                                 mh 
= (struct mach_header
*)p
; 
1228                                                 fileLen 
= OSSwapBigToHostInt32(archs
[i
].size
); 
1229                                                 foundFatSlice 
= true; 
1237         mach_o::relocatable::ParserOptions objOpts
; 
1238         objOpts
.architecture            
= sPreferredArch
; 
1239         objOpts
.objSubtypeMustMatch 
= false; 
1240         objOpts
.logAllFiles                     
= false; 
1241         objOpts
.warnUnwindConversionProblems    
= true; 
1242         objOpts
.keepDwarfUnwind         
= false; 
1243         objOpts
.forceDwarfConversion 
= false; 
1244         objOpts
.verboseOptimizationHints 
= true; 
1245         objOpts
.subType                         
= sPreferredSubArch
; 
1247         if ( ! foundFatSlice 
) { 
1248                 cpu_type_t archOfObj
; 
1249                 cpu_subtype_t subArchOfObj
; 
1250                 if ( mach_o::relocatable::isObjectFile(p
, &archOfObj
, &subArchOfObj
) ) { 
1251                         objOpts
.architecture 
= archOfObj
; 
1252                         objOpts
.subType 
= subArchOfObj
; 
1256         ld::relocatable::File
* objResult 
= mach_o::relocatable::parse(p
, fileLen
, path
, stat_buf
.st_mtime
, ld::File::Ordinal::NullOrdinal(), objOpts
); 
1257         if ( objResult 
!= NULL 
) 
1260         // see if it is an llvm object file 
1261         objResult 
= lto::parse(p
, fileLen
, path
, stat_buf
.st_mtime
, ld::File::Ordinal::NullOrdinal(), sPreferredArch
, sPreferredSubArch
, false, true); 
1262         if ( objResult 
!= NULL 
)  
1265         throwf("not a mach-o object file: %s", path
); 
1267         // for peformance testing 
1268         for (int i
=0; i 
< 500; ++i 
) { 
1269                 ld::relocatable::File
* objResult 
= mach_o::relocatable::parse(p
, fileLen
, path
, stat_buf
.st_mtime
, 0, objOpts
); 
1280         fprintf(stderr
, "ObjectDump options:\n" 
1281                         "\t-no_content\tdon't dump contents\n" 
1282                         "\t-no_section\tdon't dump section name\n" 
1283                         "\t-no_defintion\tdon't dump definition kind\n" 
1284                         "\t-no_combine\tdon't dump combine mode\n" 
1285                         "\t-stabs\t\tdump stabs\n" 
1286                         "\t-arch aaa\tonly dump info about arch aaa\n" 
1287                         "\t-only sym\tonly dump info about sym\n" 
1288                         "\t-align\t\tonly print alignment info\n" 
1289                         "\t-name\t\tonly print symbol names\n" 
1293 int main(int argc
, const char* argv
[]) 
1301                 for(int i
=1; i 
< argc
; ++i
) { 
1302                         const char* arg 
= argv
[i
]; 
1303                         if ( arg
[0] == '-' ) { 
1304                                 if ( strcmp(arg
, "-no_content") == 0 ) { 
1305                                         sDumpContent 
= false; 
1307                                 else if ( strcmp(arg
, "-nm") == 0 ) { 
1310                                 else if ( strcmp(arg
, "-stabs") == 0 ) { 
1313                                 else if ( strcmp(arg
, "-no_sort") == 0 ) { 
1316                                 else if ( strcmp(arg
, "-no_section") == 0 ) { 
1317                                         sShowSection 
= false; 
1319                                 else if ( strcmp(arg
, "-no_definition") == 0 ) { 
1320                                         sShowDefinitionKind 
= false; 
1322                                 else if ( strcmp(arg
, "-no_combine") == 0 ) { 
1323                                         sShowCombineKind 
= false; 
1325                                 else if ( strcmp(arg
, "-no_line_info") == 0 ) { 
1326                                         sShowLineInfo 
= false; 
1328                                 else if ( strcmp(arg
, "-arch") == 0 ) { 
1329                                         const char* archName 
= argv
[++i
]; 
1330                                         if ( archName 
== NULL 
) 
1331                                                 throw "-arch missing architecture name"; 
1333                                         for (const ArchInfo
* t
=archInfoArray
; t
->archName 
!= NULL
; ++t
) { 
1334                                                 if ( strcmp(t
->archName
,archName
) == 0 ) { 
1335                                                         sPreferredArch 
= t
->cpuType
; 
1337                                                                 sPreferredSubArch 
= t
->cpuSubType
; 
1342                                                 throwf("unknown architecture %s", archName
); 
1344                                 else if ( strcmp(arg
, "-only") == 0 ) { 
1345                                         sMatchName 
= ++i
<argc
? argv
[i
]: NULL
; 
1347                                 else if ( strcmp(arg
, "-align") == 0 ) { 
1348                                         sPrintRestrict 
= true; 
1351                                 else if ( strcmp(arg
, "-name") == 0 ) { 
1352                                         sPrintRestrict 
= true; 
1357                                         throwf("unknown option: %s\n", arg
); 
1361                                 ld::relocatable::File
* reader 
= createReader(arg
); 
1366         catch (const char* msg
) { 
1367                 fprintf(stderr
, "ObjDump failed: %s\n", msg
);