]>
git.saurik.com Git - apple/dyld.git/blob - testing/test-cases/kernel-classic-relocs.h
2 #include <mach-o/reloc.h>
3 #include <mach-o/loader.h>
5 typedef int (* FixupsLogFunc
)( const char *, ...);
6 static const int LogFixupsClassic
= 0 ;
8 // We may not have strcmp, so make our own
10 __attribute__ (( section (( "__HIB, __text" ))))
12 __attribute__ (( section (( "__TEXT_EXEC, __text" ))))
14 static int areEqualClassic ( const char * a
, const char * b
) {
24 // Temporary until we have <rdar://problem/57025372>
26 __attribute__ (( section (( "__HIB, __text" ))))
28 __attribute__ (( section (( "__TEXT_EXEC, __text" ))))
30 int slideClassic ( const struct mach_header
* mh
, FixupsLogFunc logFunc
) {
36 // First find the slide and dysymtab fixups load command
37 uint64_t textVMAddr
= 0 ;
38 uint64_t firstWritableVMAddr
= ~ 0ULL ;
39 const struct dysymtab_command
* dynSymbolTable
= 0 ;
40 uint64_t linkeditVMAddr
= 0 ;
41 uint64_t linkeditFileOffset
= 0 ;
43 if ( LogFixupsClassic
) {
44 logFunc ( "[LOG] kernel-classic-relocs: mh %p \n " , mh
);
47 if ( LogFixupsClassic
) {
48 logFunc ( "[LOG] kernel-classic-relocs: parsing load commands \n " );
51 const struct load_command
* startCmds
= 0 ;
52 if ( mh
-> magic
== MH_MAGIC_64
)
53 startCmds
= ( struct load_command
*)(( char *) mh
+ sizeof ( struct mach_header_64
));
54 else if ( mh
-> magic
== MH_MAGIC
)
55 startCmds
= ( struct load_command
*)(( char *) mh
+ sizeof ( struct mach_header
));
57 const uint32_t * h
= ( uint32_t *) mh
;
58 //diag.error("file does not start with MH_MAGIC[_64]: 0x%08X 0x%08X", h[0], h [1]);
59 return 1 ; // not a mach-o file
61 const struct load_command
* const cmdsEnd
= ( struct load_command
*)(( char *) startCmds
+ mh
-> sizeofcmds
);
62 const struct load_command
* cmd
= startCmds
;
63 for ( uint32_t i
= 0 ; i
< mh
-> ncmds
; ++ i
) {
64 if ( LogFixupsClassic
) {
65 logFunc ( "[LOG] kernel-classic-relocs: parsing load command %d with cmd=0x %x \n " , i
, cmd
-> cmd
);
67 const struct load_command
* nextCmd
= ( struct load_command
*)(( char *) cmd
+ cmd
-> cmdsize
);
68 if ( cmd
-> cmdsize
< 8 ) {
69 //diag.error("malformed load command #%d of %d at %p with mh=%p, size (0x%X) too small", i, this->ncmds, cmd, this, cmd->cmdsize);
72 if ( ( nextCmd
> cmdsEnd
) || ( nextCmd
< startCmds
) ) {
73 //diag.error("malformed load command #%d of %d at %p with mh=%p, size (0x%X) is too large, load commands end at %p", i, this->ncmds, cmd, this, cmd->cmdsize, cmdsEnd);
76 if ( cmd
-> cmd
== LC_DYSYMTAB
) {
77 dynSymbolTable
= ( const struct dysymtab_command
*) cmd
;
78 } else if ( cmd
-> cmd
== LC_SEGMENT_64
) {
79 const struct segment_command_64
* seg
= ( const struct segment_command_64
*) cmd
;
80 if ( areEqualClassic ( seg
-> segname
, "__TEXT" ) ) {
81 textVMAddr
= seg
-> vmaddr
;
82 } else if ( areEqualClassic ( seg
-> segname
, "__LINKEDIT" ) ) {
83 linkeditVMAddr
= seg
-> vmaddr
;
84 linkeditFileOffset
= seg
-> fileoff
;
86 if ( ( seg
-> initprot
& VM_PROT_WRITE
) && ( firstWritableVMAddr
== ~ 0ULL ) ) {
87 firstWritableVMAddr
= seg
-> vmaddr
;
88 if ( LogFixupsClassic
) {
89 logFunc ( "[LOG] kernel-classic-relocs: first writable segment %s = 0x %l lx \n " , seg
-> segname
, seg
-> vmaddr
);
96 uintptr_t slide
= ( uintptr_t ) mh
- textVMAddr
;
98 if ( LogFixupsClassic
) {
99 logFunc ( "[LOG] kernel-classic-relocs: slide 0x %l lx \n " , slide
);
102 if ( dynSymbolTable
== 0 )
105 if ( dynSymbolTable
-> nlocrel
== 0 )
108 if ( LogFixupsClassic
) {
109 logFunc ( "[LOG] kernel-classic-relocs: found dynamic symbol table %p \n " , dynSymbolTable
);
110 logFunc ( "[LOG] kernel-classic-relocs: found linkeditVMAddr %p \n " , ( void *) linkeditVMAddr
);
111 logFunc ( "[LOG] kernel-classic-relocs: found linkeditFileOffset %p \n " , ( void *) linkeditFileOffset
);
114 // Now we have the dynamic symbol table, walk it to apply all the rebases
115 uint32_t offsetInLinkedit
= dynSymbolTable
-> locreloff
- linkeditFileOffset
;
116 uintptr_t linkeditStartAddr
= linkeditVMAddr
+ slide
;
117 if ( LogFixupsClassic
) {
118 logFunc ( "[LOG] kernel-classic-relocs: offsetInLinkedit 0x %x \n " , offsetInLinkedit
);
119 logFunc ( "[LOG] kernel-classic-relocs: linkeditStartAddr %p \n " , ( void *) linkeditStartAddr
);
122 const uint64_t relocsStartAddress
= firstWritableVMAddr
;
123 const struct relocation_info
* const relocsStart
= ( const struct relocation_info
*)( linkeditStartAddr
+ offsetInLinkedit
);
124 const struct relocation_info
* const relocsEnd
= & relocsStart
[ dynSymbolTable
-> nlocrel
];
125 for ( const struct relocation_info
* reloc
= relocsStart
; reloc
< relocsEnd
; ++ reloc
) {
126 if ( reloc
-> r_length
== 2 ) {
127 uint32_t * fixupLoc
= ( uint32_t *)( relocsStartAddress
+ reloc
-> r_address
+ slide
);
128 uint32_t slidValue
= * fixupLoc
+ slide
;
129 if ( LogFixupsClassic
) {
130 logFunc ( "[LOG] kernel-classic-relocs: fixupLoc %p = 0x %x + 0x %x + 0x %x \n " , fixupLoc
, relocsStartAddress
, reloc
-> r_address
, slide
);
131 logFunc ( "[LOG] kernel-classic-relocs: slidValue * %p = 0x %x \n " , fixupLoc
, slidValue
);
133 * fixupLoc
= slidValue
;
136 if ( reloc
-> r_length
== 3 ) {
137 uint64_t * fixupLoc
= ( uint64_t *)( relocsStartAddress
+ reloc
-> r_address
+ slide
);
138 uint64_t slidValue
= * fixupLoc
+ slide
;
139 if ( LogFixupsClassic
) {
140 logFunc ( "[LOG] kernel-classic-relocs: fixupLoc %p = 0x %x + 0x %x + 0x %x \n " , fixupLoc
, relocsStartAddress
, reloc
-> r_address
, slide
);
141 logFunc ( "[LOG] kernel-classic-relocs: slidValue * %p = 0x %l lx \n " , fixupLoc
, slidValue
);
143 * fixupLoc
= slidValue
;
146 logFunc ( "[LOG] kernel-fixups: unknown reloc size \n " , reloc
-> r_length
);
150 if ( LogFixupsClassic
) {
151 logFunc ( "[LOG] kernel-classic-relocs: Done \n " );