1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- 
   3  * Copyright (c) 2005-2007 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@ 
  26 #ifndef __OBJECTFILE__ 
  27 #define __OBJECTFILE__ 
  36 // These classes represent the abstract Atoms and References that are the basis of the linker. 
  37 // An Atom and a Reference correspond to a Node and Edge in graph theory. 
  39 // A Reader is a class which parses an object file and presents it as Atoms and References. 
  40 // All linking operations are done on Atoms and References.  This makes the linker file 
  41 // format independent. 
  43 // A Writer takes a vector of Atoms with all References resolved and produces an executable file. 
  48 namespace ObjectFile 
{ 
  62                                                 ReaderOptions() : fFullyLoadArchives(false), fLoadAllObjcObjectsFromArchives(false), fFlatNamespace(false), fLinkingMainExecutable(false),  
  63                                                                                 fForFinalLinkedImage(false), fForStatic(false), fForDyld(false), fMakeTentativeDefinitionsReal(false),  
  64                                                                                 fWhyLoad(false), fRootSafe(false), fSetuidSafe(false),fDebugInfoStripping(kDebugInfoFull
), 
  65                                                                                 fLogObjectFiles(false), fLogAllFiles(false), 
  66                                                                                 fTraceDylibs(false), fTraceIndirectDylibs(false), fTraceArchives(false),  
  67                                                                                 fTraceOutputFile(NULL
), fVersionMin(kMinUnset
) {} 
  68         enum DebugInfoStripping 
{ kDebugInfoNone
, kDebugInfoMinimal
, kDebugInfoFull 
}; 
  69         enum VersionMin 
{ kMinUnset
, k10_1
, k10_2
, k10_3
, k10_4
, k10_5 
}; 
  76         bool                                    fFullyLoadArchives
; 
  77         bool                                    fLoadAllObjcObjectsFromArchives
; 
  79         bool                                    fLinkingMainExecutable
; 
  80         bool                                    fForFinalLinkedImage
; 
  83         bool                                    fMakeTentativeDefinitionsReal
; 
  87         DebugInfoStripping              fDebugInfoStripping
; 
  91         bool                                    fTraceIndirectDylibs
; 
  93         const char*                             fTraceOutputFile
; 
  94         VersionMin                              fVersionMin
; 
  95         std::vector
<AliasPair
>  fAliases
; 
 102         enum DebugInfoKind 
{ kDebugInfoNone
=0, kDebugInfoStabs
=1, kDebugInfoDwarf
=2, kDebugInfoStabsUUID
=3 }; 
 112         enum ObjcConstraint 
{ kObjcNone
,  kObjcRetainRelease
,  kObjcRetainReleaseOrGC
,  kObjcGC 
}; 
 113         enum CpuConstraint  
{ kCpuAny
,  kCpuG3
,  kCpuG4
,  kCpuG5  
}; 
 118                 virtual                         ~DylibHander()  {} 
 119                 virtual Reader
*         findDylib(const char* installPath
, const char* fromPath
) = 0; 
 123         static Reader
* createReader(const char* path
, const ReaderOptions
& options
); 
 125         virtual const char*                                     getPath() = 0; 
 126         virtual time_t                                          getModificationTime() = 0; 
 127         virtual DebugInfoKind                           
getDebugInfoKind() = 0; 
 128         virtual std::vector
<class Atom
*>&       getAtoms() = 0; 
 129         virtual std::vector
<class Atom
*>*       getJustInTimeAtomsFor(const char* name
) = 0; 
 130         virtual std::vector
<Stab
>*                      getStabs() = 0; 
 131         virtual ObjcConstraint                          
getObjCConstraint()                     { return kObjcNone
; } 
 132         virtual CpuConstraint                           
getCpuConstraint()                      { return kCpuAny
; } 
 133         virtual bool                                            objcReplacementClasses()        { return false; } 
 135         // For relocatable object files only 
 136         virtual bool                                            canScatterAtoms()                       { return true; } 
 137         virtual void                                            optimize(std::vector
<ObjectFile::Atom
*>&, std::vector
<ObjectFile::Atom
*>&, uint32_t)            { } 
 139         // For Dynamic Libraries only 
 140         virtual const char*                                     getInstallPath()                        { return NULL
; } 
 141         virtual uint32_t                                        getTimestamp()                          { return 0; } 
 142         virtual uint32_t                                        getCurrentVersion()                     { return 0; } 
 143         virtual uint32_t                                        getCompatibilityVersion()       { return 0; } 
 144         virtual void                                            processIndirectLibraries(DylibHander
* handler
)  { } 
 145         virtual void                                            setExplicitlyLinked()           { } 
 146         virtual bool                                            explicitlyLinked()                      { return false; } 
 147         virtual bool                                            implicitlyLinked()                      { return false; } 
 148         virtual bool                                            providedExportAtom()            { return false; } 
 149         virtual const char*                                     parentUmbrella()                        { return NULL
; } 
 150         virtual std::vector
<const char*>*       getAllowableClients()           { return NULL
; } 
 161         virtual const char*                     getName() const  = 0; 
 162         virtual bool                            isContentReadable() const = 0; 
 163         virtual bool                            isContentWritable() const = 0; 
 164         virtual bool                            isContentExecutable() const = 0; 
 166         uint64_t                                        getBaseAddress() const { return fBaseAddress
; } 
 167         void                                            setBaseAddress(uint64_t addr
) { fBaseAddress 
= addr
; } 
 168         virtual bool                            hasFixedAddress() const { return false; } 
 171                                                                 Segment() : fBaseAddress(0) {} 
 172         virtual                                         ~Segment() {} 
 173         uint64_t                                        fBaseAddress
; 
 181         unsigned int    getIndex() { return fIndex
; } 
 182         uint64_t                getBaseAddress() { return fBaseAddress
; } 
 183         void                    setBaseAddress(uint64_t addr
) { fBaseAddress 
= addr
; } 
 187                                         Section() : fOther(NULL
), fBaseAddress(0), fIndex(0)  {} 
 188         uint64_t                fBaseAddress
; 
 195                                 Alignment(int p2
, int m
=0) : powerOf2(p2
), modulus(m
) {} 
 196         uint8_t         trailingZeros() const { return (modulus
==0) ? powerOf2 
: __builtin_ctz(modulus
); } 
 202 // An atom is the fundamental unit of linking.  A C function or global variable is an atom. 
 203 // An atom has content and some attributes. The content of a function atom is the instructions 
 204 // that implement the function.  The content of a global variable atom is its initial bits. 
 207 // The name of an atom is the label name generated by the compiler.  A C compiler names foo() 
 208 // as _foo.  A C++ compiler names foo() as __Z3foov. 
 209 // The name refers to the first byte of the content.  An atom cannot have multiple entry points. 
 210 // Such code is modeled as multiple atoms, each having a "follow on" reference to the next. 
 211 // A "follow on" reference is a contraint to the linker to the atoms must be laid out contiguously. 
 214 // An atom is in one of three scopes: translation-unit, linkage-unit, or global.  These correspond 
 215 // to the C visibility of static, hidden, default. 
 218 // An atom is one of five defintion kinds: 
 219 //      regular                 Most atoms. 
 220 //      weak                    C++ compiler makes some functions weak if there might be multiple copies 
 221 //                                      that the linker needs to coalesce. 
 222 //      tentative               A straggler from ancient C when the extern did not exist. "int foo;" is ambiguous. 
 223 //                                      It could be a prototype or it could be a definition. 
 224 //      external                This is a "proxy" atom produced by a dylib reader.  It has no content.  It exists 
 225 //                                      so that all References can be resolved. 
 226 //      external-weak   Same as external, but the definition in the dylib is weak. 
 228 // SymbolTableInclusion: 
 229 // An atom may or may not be in the symbol table in an object file. 
 230 //  in                          Most atoms for functions or global data 
 231 //      not-in                  Anonymous atoms such literal c-strings, or other compiler generated data 
 232 //      in-never-strip  Atom whose name the strip tool should never remove (e.g. REFERENCED_DYNAMICALLY in mach-o) 
 235 // When a reader is created it is given a base ordinal number.  All atoms created by the reader 
 236 // should return a contiguous range of ordinal values that start at the base ordinal.  The ordinal 
 237 // values are used by the linker to sort the atom graph when producing the output file.  
 242         enum Scope 
{ scopeTranslationUnit
, scopeLinkageUnit
, scopeGlobal 
}; 
 243         enum DefinitionKind 
{ kRegularDefinition
, kWeakDefinition
, kTentativeDefinition
, kExternalDefinition
, kExternalWeakDefinition
, kAbsoluteSymbol 
}; 
 244         enum SymbolTableInclusion 
{ kSymbolTableNotIn
, kSymbolTableIn
, kSymbolTableInAndNeverStrip
, kSymbolTableInAsAbsolute 
}; 
 246         virtual Reader
*                                                 getFile() const = 0; 
 247         virtual bool                                                    getTranslationUnitSource(const char** dir
, const char** name
) const = 0; 
 248         virtual const char*                                             getName() const = 0; 
 249         virtual const char*                                             getDisplayName() const = 0; 
 250         virtual Scope                                                   
getScope() const = 0; 
 251         virtual DefinitionKind                                  
getDefinitionKind() const = 0; 
 252         virtual SymbolTableInclusion                    
getSymbolTableInclusion() const = 0; 
 253         virtual bool                                                    dontDeadStrip() const = 0; 
 254         virtual bool                                                    isZeroFill() const = 0; 
 255         virtual uint64_t                                                getSize() const = 0; 
 256         virtual std::vector
<ObjectFile::Reference
*>&  getReferences() const = 0; 
 257         virtual bool                                                    mustRemainInSection() const = 0; 
 258         virtual const char*                                             getSectionName() const = 0; 
 259         virtual Segment
&                                                getSegment() const = 0; 
 260         virtual Atom
&                                                   getFollowOnAtom() const = 0; 
 261         virtual uint32_t                                                getOrdinal() const = 0; 
 262         virtual std::vector
<LineInfo
>*                  getLineInfo() const = 0; 
 263         virtual Alignment                                               
getAlignment() const = 0; 
 264         virtual void                                                    copyRawContent(uint8_t buffer
[]) const = 0; 
 265         virtual void                                                    setScope(Scope
) = 0; 
 268                         uint64_t                                                getSectionOffset() const        { return fSectionOffset
; } 
 269                         uint64_t                                                getAddress() const      { return fSection
->getBaseAddress() + fSectionOffset
; } 
 270                         class Section
*                                  getSection() const { return fSection
; } 
 272         virtual void                                                    setSectionOffset(uint64_t offset
) { fSectionOffset 
= offset
; } 
 273         virtual void                                                    setSection(class Section
* sect
) { fSection 
= sect
; } 
 276                                                                                         Atom() :  fSectionOffset(0), fSection(NULL
) {} 
 279                 uint64_t                                                        fSectionOffset
; 
 280                 class Section
*                                          fSection
; 
 285 // A Reference is a directed edge to another Atom.  When an instruction in 
 286 // the content of an Atom refers to another Atom, that is represented by a 
 289 // There are two kinds of references: direct and by-name.  With a direct Reference, 
 290 // the target is bound by the Reader that created it.  For instance a reference to a 
 291 // static would produce a direct reference.  A by-name reference requires the linker 
 292 // to find the target Atom with the required name in order to be bound. 
 294 // For a link to succeed all References must be bound. 
 296 // A Reference has an optional "from" target.  This is used when the content to fix-up 
 297 // is the difference of two Atom address.  For instance, if a pointer sized data Atom 
 298 // is to contain A - B, then the Atom would have on Reference with a target of "A" and 
 299 // a from-target of "B". 
 301 // A Reference also has a fix-up-offset.  This is the offset into the content of the 
 302 // Atom holding the reference where the fix-up (relocation) will be applied. 
 309         enum TargetBinding 
{ kUnboundByName
, kBoundDirectly
, kBoundByName
, kDontBind 
}; 
 311         virtual TargetBinding   
getTargetBinding() const = 0; 
 312         virtual TargetBinding   
getFromTargetBinding() const = 0; 
 313         virtual uint8_t                 getKind() const = 0; 
 314         virtual uint64_t                getFixUpOffset() const = 0; 
 315         virtual const char*             getTargetName() const = 0; 
 316         virtual Atom
&                   getTarget() const = 0; 
 317         virtual uint64_t                getTargetOffset() const = 0; 
 318         virtual Atom
&                   getFromTarget() const = 0; 
 319         virtual const char*             getFromTargetName() const = 0; 
 320         virtual uint64_t                getFromTargetOffset() const = 0; 
 322         virtual void                    setTarget(Atom
&, uint64_t offset
) = 0; 
 323         virtual void                    setFromTarget(Atom
&) = 0; 
 324         virtual const char*             getDescription() const = 0; 
 328         virtual                                 ~Reference() {} 
 332 };      // namespace ObjectFile 
 335 #endif // __OBJECTFILE__