1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-* 
   3  * Copyright (c) 2009 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 #ifndef __OUTPUT_FILE_H__ 
  26 #define __OUTPUT_FILE_H__ 
  29 #include <sys/types.h> 
  32 #include <sys/sysctl.h> 
  37 #include <mach/mach_time.h> 
  38 #include <mach/vm_statistics.h> 
  39 #include <mach/mach_init.h> 
  40 #include <mach/mach_host.h> 
  42 #include <mach-o/dyld.h> 
  55                                                                 OutputFile(const Options
& opts
); 
  58         // iterates all atoms in initial files 
  59         void                                            write(ld::Internal
&); 
  60         bool                                            findSegment(ld::Internal
& state
, uint64_t addr
, uint64_t* start
, uint64_t* end
, uint32_t* index
); 
  61         void                                            setLazyBindingInfoOffset(uint64_t lpAddress
, uint32_t lpInfoOffset
); 
  62         uint32_t                                        dylibCount(); 
  63         const ld::dylib::File
*          dylibByOrdinal(unsigned int ordinal
); 
  64         uint32_t                                        dylibToOrdinal(const ld::dylib::File
*); 
  65         uint32_t                                        encryptedTextStartOffset()      { return _encryptedTEXTstartOffset
; } 
  66         uint32_t                                        encryptedTextEndOffset()        { return _encryptedTEXTendOffset
; } 
  67         int                                                     compressedOrdinalForAtom(const ld::Atom
* target
); 
  68         uint64_t                                        fileSize() const { return _fileSize
; } 
  71         bool                                            hasWeakExternalSymbols
; 
  72         bool                                            usesWeakExternalSymbols
; 
  73         bool                                            overridesWeakExternalSymbols
; 
  74         bool                                            _noReExportedDylibs
; 
  75         bool                                            hasThreadLocalVariableDefinitions
; 
  78         ld::Internal::FinalSection
*     headerAndLoadCommandsSection
; 
  79         ld::Internal::FinalSection
*     rebaseSection
; 
  80         ld::Internal::FinalSection
*     bindingSection
; 
  81         ld::Internal::FinalSection
*     weakBindingSection
; 
  82         ld::Internal::FinalSection
*     lazyBindingSection
; 
  83         ld::Internal::FinalSection
*     exportSection
; 
  84         ld::Internal::FinalSection
*     splitSegInfoSection
; 
  85         ld::Internal::FinalSection
*     functionStartsSection
; 
  86         ld::Internal::FinalSection
*     dataInCodeSection
; 
  87         ld::Internal::FinalSection
*     dependentDRsSection
; 
  88         ld::Internal::FinalSection
*     symbolTableSection
; 
  89         ld::Internal::FinalSection
*     stringPoolSection
; 
  90         ld::Internal::FinalSection
*     localRelocationsSection
; 
  91         ld::Internal::FinalSection
*     externalRelocationsSection
; 
  92         ld::Internal::FinalSection
*     sectionRelocationsSection
; 
  93         ld::Internal::FinalSection
*     indirectSymbolTableSection
; 
  96                                                 RebaseInfo(uint8_t t
, uint64_t addr
) : _type(t
), _address(addr
) {} 
 100                 int operator<(const RebaseInfo
& rhs
) const { 
 101                         // sort by type, then address 
 102                         if ( this->_type 
!= rhs
._type 
) 
 103                                 return  (this->_type 
< rhs
._type 
); 
 104                         return  (this->_address 
< rhs
._address 
); 
 109                                                 BindingInfo(uint8_t t
, int ord
, const char* sym
, bool weak_import
, uint64_t addr
, int64_t add
)  
 110                                                         : _type(t
), _flags(weak_import 
? BIND_SYMBOL_FLAGS_WEAK_IMPORT 
: 0 ), _libraryOrdinal(ord
),  
 111                                                                 _symbolName(sym
), _address(addr
), _addend(add
) {} 
 112                                                 BindingInfo(uint8_t t
, const char* sym
, bool non_weak_definition
, uint64_t addr
, int64_t add
)  
 113                                                         : _type(t
), _flags(non_weak_definition 
? BIND_SYMBOL_FLAGS_NON_WEAK_DEFINITION 
: 0 ),  
 114                                                          _libraryOrdinal(0), _symbolName(sym
), _address(addr
), _addend(add
) {} 
 118                 const char*             _symbolName
; 
 123                 int operator<(const BindingInfo
& rhs
) const { 
 124                         // sort by library, symbol, type, then address 
 125                         if ( this->_libraryOrdinal 
!= rhs
._libraryOrdinal 
) 
 126                                 return  (this->_libraryOrdinal 
< rhs
._libraryOrdinal 
); 
 127                         if ( this->_symbolName 
!= rhs
._symbolName 
) 
 128                                 return ( strcmp(this->_symbolName
, rhs
._symbolName
) < 0 ); 
 129                         if ( this->_type 
!= rhs
._type 
) 
 130                                 return  (this->_type 
< rhs
._type 
); 
 131                         return  (this->_address 
< rhs
._address 
); 
 135         struct SplitSegInfoEntry 
{ 
 136                                                 SplitSegInfoEntry(uint64_t a
, ld::Fixup::Kind k
, uint32_t e
=0) : address(a
), kind(k
), extra(e
) {} 
 138                 ld::Fixup::Kind kind
; 
 143         void                                            writeAtoms(ld::Internal
& state
, uint8_t* wholeBuffer
); 
 144         void                                            computeContentUUID(ld::Internal
& state
, uint8_t* wholeBuffer
); 
 145         void                                            buildDylibOrdinalMapping(ld::Internal
&); 
 146         bool                                            hasOrdinalForInstallPath(const char* path
, int* ordinal
); 
 147         void                                            addLoadCommands(ld::Internal
& state
); 
 148         void                                            addLinkEdit(ld::Internal
& state
); 
 149         void                                            addPreloadLinkEdit(ld::Internal
& state
); 
 150         void                                            generateLinkEditInfo(ld::Internal
& state
); 
 151         void                                            buildSymbolTable(ld::Internal
& state
); 
 152         void                                            writeOutputFile(ld::Internal
& state
); 
 153         void                                            assignFileOffsets(ld::Internal
& state
); 
 154         void                                            setSectionSizesAndAlignments(ld::Internal
& state
); 
 155         void                                            addSectionRelocs(ld::Internal
& state
, ld::Internal::FinalSection
* sect
,   
 156                                                                                                 const ld::Atom
* atom
, ld::Fixup
* fixupWithTarget
,  
 157                                                                                                 ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
, 
 158                                                                                                 const ld::Atom
* target
, const ld::Atom
* minusTarget
,  
 159                                                                                                 uint64_t targetAddend
, uint64_t minusTargetAddend
); 
 160         void                                            addDyldInfo(ld::Internal
& state
, ld::Internal::FinalSection
* sect
,   
 161                                                                                                 const ld::Atom
* atom
, ld::Fixup
* fixupWithTarget
, 
 162                                                                                                 ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
, 
 163                                                                                                 const ld::Atom
* target
, const ld::Atom
* minusTarget
,  
 164                                                                                                 uint64_t targetAddend
, uint64_t minusTargetAddend
); 
 165         void                                            addClassicRelocs(ld::Internal
& state
, ld::Internal::FinalSection
* sect
,   
 166                                                                                                 const ld::Atom
* atom
, ld::Fixup
* fixupWithTarget
,  
 167                                                                                                 ld::Fixup
* fixupWithMinusTarget
, ld::Fixup
* fixupWithStore
, 
 168                                                                                                 const ld::Atom
* target
, const ld::Atom
* minusTarget
,  
 169                                                                                                 uint64_t targetAddend
, uint64_t minusTargetAddend
); 
 170         bool                                            useExternalSectionReloc(const ld::Atom
* atom
, const ld::Atom
* target
,  
 171                                                                                                                         ld::Fixup
* fixupWithTarget
); 
 172         uint64_t                                        pageAlign(uint64_t addr
); 
 173         uint64_t                                        pageAlign(uint64_t addr
, uint64_t pageSize
); 
 174         void                                            setLoadCommandsPadding(ld::Internal
& state
); 
 175         void                                            assignAtomAddresses(ld::Internal
& state
); 
 176         void                                            addRebaseInfo(const ld::Atom
* atom
, const ld::Fixup
* fixup
, const ld::Atom
* target
); 
 177         void                                            makeRebasingInfo(ld::Internal
& state
); 
 178         void                                            makeBindingInfo(ld::Internal
& state
); 
 179         void                                            updateLINKEDITAddresses(ld::Internal
& state
); 
 180         void                                            applyFixUps(ld::Internal
& state
, uint64_t mhAddress
, const ld::Atom
*  atom
, uint8_t* buffer
); 
 181         uint64_t                                        addressOf(const ld::Internal
& state
, const ld::Fixup
* fixup
, const ld::Atom
** target
); 
 182         bool                                            targetIsThumb(ld::Internal
& state
, const ld::Fixup
* fixup
); 
 183         uint32_t                                        lazyBindingInfoOffsetForLazyPointerAddress(uint64_t lpAddress
); 
 184         void                                            copyNoOps(uint8_t* from
, uint8_t* to
, bool thumb
); 
 185         bool                                            isPointerToTarget(ld::Fixup::Kind kind
); 
 186         bool                                            isPointerFromTarget(ld::Fixup::Kind kind
); 
 187         bool                                            isPcRelStore(ld::Fixup::Kind kind
); 
 188         bool                                            isStore(ld::Fixup::Kind kind
); 
 189         bool                                            storeAddendOnly(const ld::Atom
* inAtom
, const ld::Atom
* target
, bool pcRel
=false); 
 190         bool                                            setsTarget(ld::Fixup::Kind kind
); 
 191         void                                            addFixupOutInfo(ld::Internal
& state
); 
 192         void                                            makeRelocations(ld::Internal
& state
); 
 193         void                                            makeSectionRelocations(ld::Internal
& state
); 
 194         void                                            makeDyldInfo(ld::Internal
& state
); 
 195         void                                            makeSplitSegInfo(ld::Internal
& state
); 
 196         void                                            writeMapFile(ld::Internal
& state
); 
 197         uint64_t                                        lookBackAddend(ld::Fixup::iterator fit
); 
 198         bool                                            takesNoDiskSpace(const ld::Section
* sect
); 
 199         bool                                            hasZeroForFileOffset(const ld::Section
* sect
); 
 201         void                                            printSectionLayout(ld::Internal
& state
); 
 202         void                                            rangeCheck8(int64_t delta
, ld::Internal
& state
, const ld::Atom
* atom
,  
 203                                                                                                                                                                                         const ld::Fixup
* fixup
); 
 204         void                                            rangeCheck16(int64_t delta
, ld::Internal
& state
, const ld::Atom
* atom
,  
 205                                                                                                                                                                                         const ld::Fixup
* fixup
); 
 206         void                                            rangeCheckBranch32(int64_t delta
, ld::Internal
& state
, const ld::Atom
* atom
,  
 207                                                                                                                                                                                         const ld::Fixup
* fixup
); 
 208         void                                            rangeCheckAbsolute32(int64_t delta
, ld::Internal
& state
, const ld::Atom
* atom
,  
 209                                                                                                                                                                                         const ld::Fixup
* fixup
); 
 210         void                                            rangeCheckRIP32(int64_t delta
, ld::Internal
& state
, const ld::Atom
* atom
,  
 211                                                                                                                                                                                         const ld::Fixup
* fixup
); 
 212         void                                            rangeCheckARM12(int64_t delta
, ld::Internal
& state
, const ld::Atom
* atom
,  
 213                                                                                                                                                                                         const ld::Fixup
* fixup
); 
 214         void                                            rangeCheckARMBranch24(int64_t delta
, ld::Internal
& state
, const ld::Atom
* atom
,  
 215                                                                                                                                                                                         const ld::Fixup
* fixup
); 
 216         void                                            rangeCheckThumbBranch22(int64_t delta
, ld::Internal
& state
, const ld::Atom
* atom
,  
 217                                                                                                                                                                                         const ld::Fixup
* fixup
); 
 218         uint64_t                                        sectionOffsetOf(const ld::Internal
& state
, const ld::Fixup
* fixup
); 
 219         uint64_t                                        tlvTemplateOffsetOf(const ld::Internal
& state
, const ld::Fixup
* fixup
); 
 220         void                                            dumpAtomsBySection(ld::Internal
& state
, bool); 
 221         void                                            synthesizeDebugNotes(ld::Internal
& state
); 
 222         const char*                                     assureFullPath(const char* path
); 
 223         void                                            noteTextReloc(const ld::Atom
* atom
, const ld::Atom
* target
); 
 226         static uint16_t                         get16LE(uint8_t* loc
); 
 227         static void                                     set16LE(uint8_t* loc
, uint16_t value
); 
 228         static uint32_t                         get32LE(uint8_t* loc
); 
 229         static void                                     set32LE(uint8_t* loc
, uint32_t value
); 
 230         static uint64_t                         get64LE(uint8_t* loc
); 
 231         static void                                     set64LE(uint8_t* loc
, uint64_t value
); 
 233         static uint16_t                         get16BE(uint8_t* loc
); 
 234         static void                                     set16BE(uint8_t* loc
, uint16_t value
); 
 235         static uint32_t                         get32BE(uint8_t* loc
); 
 236         static void                                     set32BE(uint8_t* loc
, uint32_t value
); 
 237         static uint64_t                         get64BE(uint8_t* loc
); 
 238         static void                                     set64BE(uint8_t* loc
, uint64_t value
); 
 242         const Options
&                                                  _options
; 
 243         std::map
<const ld::dylib::File
*, int>   _dylibToOrdinal
; 
 244         std::vector
<const ld::dylib::File
*>             _dylibsToLoad
; 
 245         std::vector
<const char*>                                _dylibOrdinalPaths
; 
 246         const bool                                                              _hasDyldInfo
; 
 247         const bool                                                              _hasSymbolTable
; 
 248         const bool                                                              _hasSectionRelocations
; 
 249         const bool                                                              _hasSplitSegInfo
; 
 250         const bool                                                              _hasFunctionStartsInfo
; 
 251         const bool                                                              _hasDataInCodeInfo
; 
 252         const bool                                                              _hasDependentDRInfo
; 
 253                   bool                                                          _hasDynamicSymbolTable
; 
 254                   bool                                                          _hasLocalRelocations
; 
 255                   bool                                                          _hasExternalRelocations
; 
 257         std::map
<uint64_t, uint32_t>                    _lazyPointerAddressToInfoOffset
; 
 258         uint32_t                                                                _encryptedTEXTstartOffset
; 
 259         uint32_t                                                                _encryptedTEXTendOffset
; 
 261         std::vector
<const ld::Atom
*>                    _localAtoms
; 
 262         std::vector
<const ld::Atom
*>                    _exportedAtoms
; 
 263         std::vector
<const ld::Atom
*>                    _importedAtoms
; 
 264         uint32_t                                                                _localSymbolsStartIndex
; 
 265         uint32_t                                                                _localSymbolsCount
; 
 266         uint32_t                                                                _globalSymbolsStartIndex
; 
 267         uint32_t                                                                _globalSymbolsCount
; 
 268         uint32_t                                                                _importSymbolsStartIndex
; 
 269         uint32_t                                                                _importSymbolsCount
; 
 270         std::map
<const ld::Atom
*, uint32_t>             _atomToSymbolIndex
; 
 271         std::vector
<RebaseInfo
>                                 _rebaseInfo
; 
 272         std::vector
<BindingInfo
>                                _bindingInfo
; 
 273         std::vector
<BindingInfo
>                                _lazyBindingInfo
; 
 274         std::vector
<BindingInfo
>                                _weakBindingInfo
; 
 275         std::vector
<SplitSegInfoEntry
>                  _splitSegInfos
; 
 276         class HeaderAndLoadCommandsAbtract
*             _headersAndLoadCommandAtom
; 
 277         class RelocationsAtomAbstract
*                  _sectionsRelocationsAtom
; 
 278         class RelocationsAtomAbstract
*                  _localRelocsAtom
; 
 279         class RelocationsAtomAbstract
*                  _externalRelocsAtom
; 
 280         class ClassicLinkEditAtom
*                              _symbolTableAtom
; 
 281         class ClassicLinkEditAtom
*                              _indirectSymbolTableAtom
; 
 282         class StringPoolAtom
*                                   _stringPoolAtom
; 
 283         class LinkEditAtom
*                                             _rebasingInfoAtom
; 
 284         class LinkEditAtom
*                                             _bindingInfoAtom
; 
 285         class LinkEditAtom
*                                             _lazyBindingInfoAtom
; 
 286         class LinkEditAtom
*                                             _weakBindingInfoAtom
; 
 287         class LinkEditAtom
*                                             _exportInfoAtom
; 
 288         class LinkEditAtom
*                                             _splitSegInfoAtom
; 
 289         class LinkEditAtom
*                                             _functionStartsAtom
; 
 290         class LinkEditAtom
*                                             _dataInCodeAtom
; 
 291         class LinkEditAtom
*                                             _dependentDRInfoAtom
; 
 297 #endif // __OUTPUT_FILE_H__