Root/
Source at commit 334 created 13 years 8 months ago. By meklort, Missing 'l' | |
---|---|
1 | /*␊ |
2 | * Copyright 2009 Evan Lojewski. All rights reserved.␊ |
3 | *␊ |
4 | */␊ |
5 | ␊ |
6 | #include "boot.h"␊ |
7 | #include "bootstruct.h"␊ |
8 | #include "multiboot.h"␊ |
9 | #include "modules.h"␊ |
10 | ␊ |
11 | ␊ |
12 | unsigned int (*lookup_symbol)(const char*) = NULL;␊ |
13 | ␊ |
14 | ␊ |
15 | void rebase_macho(void* base, char* rebase_stream, UInt32 size);␊ |
16 | void bind_macho(void* base, char* bind_stream, UInt32 size);␊ |
17 | ␊ |
18 | int load_module(const char* module)␊ |
19 | {␊ |
20 | ␉char modString[128];␊ |
21 | ␉int fh = -1;␊ |
22 | ␉sprintf(modString, "/Extra/modules/%s.dylib", module);␊ |
23 | ␉fh = open(modString, 0);␊ |
24 | ␉if(fh < 0)␊ |
25 | ␉{␊ |
26 | ␉␉printf("Unable to locate module %s\n", modString);␊ |
27 | ␉␉getc();␊ |
28 | ␉␉return ERROR;␊ |
29 | ␉}␊ |
30 | ␉␊ |
31 | ␉unsigned int moduleSize = file_size(fh);␊ |
32 | ␉char* module_base = (char*) malloc(moduleSize);␊ |
33 | ␉if (read(fh, module_base, moduleSize) == moduleSize)␊ |
34 | ␉{␊ |
35 | ␉␉void (*module_start)(void) = NULL;␊ |
36 | ␊ |
37 | ␉␉printf("Module %s read in.\n", modString);␊ |
38 | ␊ |
39 | ␉␉// Module loaded into memory, parse it␊ |
40 | ␉␉module_start = parse_mach(module_base);␊ |
41 | ␊ |
42 | ␉␉if(module_start)␊ |
43 | ␉␉{␊ |
44 | ␉␉␉(*module_start)();␉// Start the module␊ |
45 | ␉␉␉printf("Module started\n");␊ |
46 | ␉␉}␊ |
47 | ␉␉else {␊ |
48 | ␉␉␉printf("Unabel to locate module start\n");␊ |
49 | ␉␉}␊ |
50 | ␊ |
51 | ␉␉␊ |
52 | ␉␉getc();␊ |
53 | ␉␉␊ |
54 | ␉␉// TODO: Add module to loaded list if loaded successfuly␊ |
55 | ␉␉␊ |
56 | ␉}␊ |
57 | ␉else␊ |
58 | ␉{␊ |
59 | ␉␉printf("Unable to read in module %s.dylib\n.", module);␊ |
60 | ␉␉getc();␊ |
61 | ␉}␊ |
62 | ␉return 1;␊ |
63 | }␊ |
64 | ␊ |
65 | ␊ |
66 | void* parse_mach(void* binary)␊ |
67 | {␊ |
68 | ␉int (*module_init)(void) = NULL;␊ |
69 | ␉void (*module_start)(void) = NULL;␊ |
70 | ␊ |
71 | ␊ |
72 | ␉char* moduleName = NULL;␊ |
73 | ␉UInt32 moduleVersion = 0;␊ |
74 | ␉UInt32 moduleCompat = 0;␊ |
75 | ␉␊ |
76 | ␉char* symbolStub = NULL;␊ |
77 | ␉char* nonlazy = NULL;␊ |
78 | ␉char* nonlazy_variables = NULL;␊ |
79 | ␊ |
80 | ␉char* symbolTable = NULL;␊ |
81 | ␉// TODO convert all of the structs a union␊ |
82 | ␉struct load_command *loadCommand;␊ |
83 | ␉struct dylib_command* dylibCommand;␊ |
84 | ␉struct dyld_info_command* dyldInfoCommand;␊ |
85 | ␉struct symtab_command* symtabCommand;␊ |
86 | ␉struct segment_command* segmentCommand;␊ |
87 | ␉struct dysymtab_command* dysymtabCommand;␊ |
88 | ␉struct section* section;␊ |
89 | ␉UInt32 binaryIndex = sizeof(struct mach_header);␊ |
90 | ␉UInt16 cmd = 0;␊ |
91 | ␊ |
92 | ␉// Parse hthrough th eload commands␊ |
93 | ␉if(((struct mach_header*)binary)->magic != MH_MAGIC)␊ |
94 | ␉{␊ |
95 | ␉␉printf("Module is not 32bit\n");␊ |
96 | ␉␉return NULL;␉// 32bit only␊ |
97 | ␉}␊ |
98 | ␉␊ |
99 | ␉if(((struct mach_header*)binary)->filetype != MH_DYLIB)␊ |
100 | ␉{␊ |
101 | ␉␉printf("Module is not a dylib. Unable to load.\n");␊ |
102 | ␉␉return NULL; // Module is in the incorrect format␊ |
103 | ␉}␊ |
104 | ␉␊ |
105 | ␉while(cmd < ((struct mach_header*)binary)->ncmds)␉// TODO: for loop instead␊ |
106 | ␉{␊ |
107 | ␉␉cmd++;␊ |
108 | ␉␉␊ |
109 | ␉␉loadCommand = binary + binaryIndex;␊ |
110 | ␉␉UInt32 cmdSize = loadCommand->cmdsize;␊ |
111 | ␊ |
112 | ␉␉␊ |
113 | ␉␉switch ((loadCommand->cmd & 0x7FFFFFFF))␊ |
114 | ␉␉{␊ |
115 | ␉␉␉case LC_SYMTAB:␊ |
116 | ␉␉␉␉symtabCommand = binary + binaryIndex;␊ |
117 | ␊ |
118 | ␉␉␉␉UInt32 symbolIndex = 0;␊ |
119 | ␉␉␉␉char* symbolString = (UInt32)binary + (char*)symtabCommand->stroff;␊ |
120 | ␉␉␉␉symbolTable = binary + symtabCommand->symoff;␊ |
121 | ␉␉␉␉␊ |
122 | ␉␉␉␉int externalIndex = 0;␊ |
123 | ␉␉␉␉while(symbolIndex < symtabCommand->nsyms)␊ |
124 | ␉␉␉␉{␊ |
125 | ␉␉␉␉␉␊ |
126 | ␉␉␉␉␉struct nlist* symbolEntry = binary + symtabCommand->symoff + (symbolIndex * sizeof(struct nlist));␊ |
127 | ␉␉␉␉␉␊ |
128 | ␉␉␉␉␉// If the symbol is exported by this module␊ |
129 | ␉␉␉␉␉if(symbolEntry->n_value)␊ |
130 | ␉␉␉␉␉{␊ |
131 | ␉␉␉␉␉␉if(strcmp(symbolString + symbolEntry->n_un.n_strx, "_start") == 0)␊ |
132 | ␉␉␉␉␉␉{␊ |
133 | ␉␉␉␉␉␉␉// Module init located. Don't register it, only called once␊ |
134 | ␉␉␉␉␉␉␉module_init = binary + symbolEntry->n_value;␊ |
135 | ␉␉␉␉␉␉}␊ |
136 | ␉␉␉␉␉␉else if(strcmp(symbolString + symbolEntry->n_un.n_strx, "start") == 0)␊ |
137 | ␉␉␉␉␉␉{␊ |
138 | ␉␉␉␉␉␉␉// Module start located. Start is an alias so don't register it␊ |
139 | ␉␉␉␉␉␉␉module_start = binary + symbolEntry->n_value;␊ |
140 | ␉␉␉␉␉␉}␊ |
141 | ␉␉␉␉␉␉else␊ |
142 | ␉␉␉␉␉␉{␊ |
143 | ␉␉␉␉␉␉␉add_symbol(symbolString + symbolEntry->n_un.n_strx, binary + symbolEntry->n_value); ␊ |
144 | ␉␉␉␉␉␉}␊ |
145 | ␉␉␉␉␉}␊ |
146 | ␉␉␉␉␉// External symbol␊ |
147 | ␉␉␉␉␉else if(symbolEntry->n_type & 0x01 && symbolStub)␊ |
148 | ␉␉␉␉␉{␊ |
149 | ␉␉␉␉␉␉printf("Located external symbol %s", symbolString + symbolEntry->n_un.n_strx);␊ |
150 | ␉␉␉␉␉␉printf(" stub at 0x%X, (0x%X)\n", symbolStub + STUB_ENTRY_SIZE * externalIndex - (UInt32)binary, symbolStub + STUB_ENTRY_SIZE * externalIndex);␊ |
151 | ␉␉␉␉␉␉getc();␊ |
152 | ␉␉␉␉␉␉// Patch stub␊ |
153 | ␉␉␉␉␉␉if(lookup_symbol == NULL)␊ |
154 | ␉␉␉␉␉␉{␊ |
155 | ␉␉␉␉␉␉␉printf("Symbol.dylib not loaded. Module loader not setup.\n");␊ |
156 | ␉␉␉␉␉␉␉return NULL;␊ |
157 | ␉␉␉␉␉␉}␊ |
158 | ␉␉␉␉␉␉else␊ |
159 | ␉␉␉␉␉␉{␊ |
160 | ␉␉␉␉␉␉␉void* symbolAddress = (void*)lookup_symbol(symbolString + symbolEntry->n_un.n_strx);␊ |
161 | ␉␉␉␉␉␉␉␊ |
162 | ␉␉␉␉␉␉␉if((0xFFFFFFFF == (UInt32)symbolAddress) && ␊ |
163 | ␉␉␉␉␉␉␉ strcmp(symbolString + symbolEntry->n_un.n_strx, SYMBOL_DYLD_STUB_BINDER) != 0)␊ |
164 | ␉␉␉␉␉␉␉{␊ |
165 | ␉␉␉␉␉␉␉␉printf("Unable to locate symbol %s\n", symbolString + symbolEntry->n_un.n_strx);␊ |
166 | ␉␉␉␉␉␉␉␉␊ |
167 | ␉␉␉␉␉␉␉}␊ |
168 | ␉␉␉␉␉␉␉else ␊ |
169 | ␉␉␉␉␉␉␉{␊ |
170 | ␉␉␉␉␉␉␉␉char* patchLocation = symbolStub + STUB_ENTRY_SIZE * externalIndex;␊ |
171 | ␉␉␉␉␉␉␉␉//patch with far jump ;␊ |
172 | ␉␉␉␉␉␉␉␉/*␊ |
173 | ␉␉␉␉␉␉␉␉printf("0x%X 0x%X 0x%X 0x%X 0x%X 0x%X\n", ␊ |
174 | ␉␉␉␉␉␉␉␉␉ patchLocation[0],␊ |
175 | ␉␉␉␉␉␉␉␉␉ patchLocation[1],␊ |
176 | ␉␉␉␉␉␉␉␉␉ patchLocation[2],␊ |
177 | ␉␉␉␉␉␉␉␉␉ patchLocation[3],␊ |
178 | ␉␉␉␉␉␉␉␉␉ patchLocation[4],␊ |
179 | ␉␉␉␉␉␉␉␉␉ patchLocation[5]);␊ |
180 | ␉␉␉␉␉␉␉␉*/␊ |
181 | ␉␉␉␉␉␉␉␉␊ |
182 | ␉␉␉␉␉␉␉␉// Point the symbol stub to the nonlazy pointers␊ |
183 | ␉␉␉␉␉␉␉␉patchLocation[0] = 0xFF;␉// Should already be this␊ |
184 | ␉␉␉␉␉␉␉␉patchLocation[1] = 0x25;␉// Should already be this␊ |
185 | ␉␉␉␉␉␉␉␉patchLocation[2] = ((UInt32)(nonlazy + externalIndex * 4) & 0x000000FF) >> 0;␊ |
186 | ␉␉␉␉␉␉␉␉patchLocation[3] = ((UInt32)(nonlazy + externalIndex * 4) & 0x0000FF00) >> 8;␊ |
187 | ␉␉␉␉␉␉␉␉patchLocation[4] = ((UInt32)(nonlazy + externalIndex * 4) & 0x00FF0000) >> 16;␊ |
188 | ␉␉␉␉␉␉␉␉patchLocation[5] = ((UInt32)(nonlazy + externalIndex * 4) & 0xFF000000) >> 24;␊ |
189 | ␉␉␉␉␉␉␉␉␊ |
190 | ␉␉␉␉␉␉␉␉// Set the nonlazy pointer to the correct address␊ |
191 | ␉␉␉␉␉␉␉␉patchLocation = (nonlazy + externalIndex*4);␊ |
192 | ␉␉␉␉␉␉␉␉patchLocation[0] =((UInt32)symbolAddress & 0x000000FF) >> 0;␊ |
193 | ␉␉␉␉␉␉␉␉patchLocation[1] =((UInt32)symbolAddress & 0x0000FF00) >> 8;␊ |
194 | ␉␉␉␉␉␉␉␉patchLocation[2] =((UInt32)symbolAddress & 0x00FF0000) >> 16;␊ |
195 | ␉␉␉␉␉␉␉␉patchLocation[3] =((UInt32)symbolAddress & 0xFF000000) >> 24;␊ |
196 | ␉␉␉␉␉␉␉␉␊ |
197 | ␉␉␉␉␉␉␉␉␊ |
198 | ␉␉␉␉␉␉␉␉externalIndex++;␊ |
199 | ␊ |
200 | ␉␉␉␉␉␉␉}␊ |
201 | ␊ |
202 | ␉␉␉␉␉␉␉␉␉␉␉␉␉␉␊ |
203 | ␉␉␉␉␉␉}␊ |
204 | ␉␉␉␉␉␉␉␉␉␉␉ ␊ |
205 | ␉␉␉␉␉}␊ |
206 | ␊ |
207 | ␉␉␉␉␉symbolEntry+= sizeof(struct nlist);␊ |
208 | ␉␉␉␉␉symbolIndex++;␉// TODO remove␊ |
209 | ␉␉␉␉}␊ |
210 | ␉␉␉␉break;␊ |
211 | ␊ |
212 | ␉␉␉case LC_SEGMENT:␊ |
213 | ␉␉␉␉segmentCommand = binary + binaryIndex;␊ |
214 | ␊ |
215 | ␉␉␉␉UInt32 sections = segmentCommand->nsects;␊ |
216 | ␉␉␉␉section = binary + binaryIndex + sizeof(struct segment_command);␊ |
217 | ␉␉␉␉while(sections)␊ |
218 | ␉␉␉␉{␊ |
219 | ␉␉␉␉␉// Look for the __symbol_stub section␊ |
220 | ␉␉␉␉␉if(strcmp(section->sectname, "__nl_symbol_ptr") == 0)␊ |
221 | ␉␉␉␉␉{␊ |
222 | ␉␉␉␉␉␉/*printf("\tSection non lazy pointers at 0x%X, %d symbols\n",␊ |
223 | ␉␉␉␉␉␉␉ section->offset, ␊ |
224 | ␉␉␉␉␉␉␉ section->size / 4);␊ |
225 | ␉␉␉␉␉␉*/␊ |
226 | ␉␉␉␉␉␉switch(section->flags)␊ |
227 | ␉␉␉␉␉␉{␊ |
228 | ␉␉␉␉␉␉␉case S_NON_LAZY_SYMBOL_POINTERS:␊ |
229 | ␉␉␉␉␉␉␉␉nonlazy_variables = binary + section->offset;␊ |
230 | ␉␉␉␉␉␉␉␉␉break;␊ |
231 | ␉␉␉␉␉␉␉␉␊ |
232 | ␉␉␉␉␉␉␉case S_LAZY_SYMBOL_POINTERS:␊ |
233 | ␉␉␉␉␉␉␉␉nonlazy = binary + section->offset;␊ |
234 | ␉␉␉␉␉␉␉␉// Fucntions␊ |
235 | ␉␉␉␉␉␉␉␉break;␊ |
236 | ␉␉␉␉␉␉␉␉␊ |
237 | ␉␉␉␉␉␉␉default:␊ |
238 | ␉␉␉␉␉␉␉␉printf("Unhandled __nl_symbol_ptr section\n");␊ |
239 | ␉␉␉␉␉␉␉␉getc();␊ |
240 | ␉␉␉␉␉␉␉␉break;␊ |
241 | ␉␉␉␉␉␉}␊ |
242 | ␉␉␉␉␉␉//getc();␊ |
243 | ␉␉␉␉␉}␊ |
244 | ␉␉␉␉␉else if(strcmp(section->sectname, "__symbol_stub") == 0)␊ |
245 | ␉␉␉␉␉{␊ |
246 | ␉␉␉␉␉␉/*printf("\tSection __symbol_stub at 0x%X (0x%X), %d symbols\n",␊ |
247 | ␉␉␉␉␉␉␉ section->offset, ␊ |
248 | ␉␉␉␉␉␉␉ section->size / 6);*/␊ |
249 | ␉␉␉␉␉␉symbolStub = binary + section->offset;␊ |
250 | ␉␉␉␉␉␉//getc();␊ |
251 | ␉␉␉␉␉}␊ |
252 | ␊ |
253 | ␉␉␉␉␉␊ |
254 | ␉␉␉␉␉sections--;␊ |
255 | ␉␉␉␉␉section++;␊ |
256 | ␉␉␉␉}␊ |
257 | ␉␉␉␉␉␉ ␊ |
258 | ␉␉␉␉␊ |
259 | ␉␉␉␉break;␊ |
260 | ␉␉␉␉␊ |
261 | ␉␉␉case LC_DYSYMTAB:␊ |
262 | ␉␉␉␉dysymtabCommand = binary + binaryIndex;␊ |
263 | ␉␉␉␉//printf("Unhandled loadcommand LC_DYSYMTAB\n");␊ |
264 | ␉␉␉␉break;␊ |
265 | ␉␉␉␉␊ |
266 | ␉␉␉case LC_LOAD_DYLIB:␊ |
267 | ␉␉␉␉//printf("Unhandled loadcommand LC_LOAD_DYLIB\n");␊ |
268 | ␉␉␉␉break;␊ |
269 | ␉␉␉␉␊ |
270 | ␉␉␉case LC_ID_DYLIB:␊ |
271 | ␉␉␉␉dylibCommand = binary + binaryIndex;␊ |
272 | ␉␉␉␉moduleName =␉binary + binaryIndex + ((UInt32)*((UInt32*)&dylibCommand->dylib.name));␊ |
273 | ␉␉␉␉moduleVersion =␉dylibCommand->dylib.current_version;␊ |
274 | ␉␉␉␉moduleCompat =␉dylibCommand->dylib.compatibility_version;␊ |
275 | ␉␉␉␉break;␊ |
276 | ␊ |
277 | ␉␉␉case LC_DYLD_INFO:␊ |
278 | ␉␉␉␉dyldInfoCommand = binary + binaryIndex;␊ |
279 | ␉␉␉␉/*␊ |
280 | ␉␉␉␉ printf("LC_DYLD_INFO:\n"␊ |
281 | ␉␉␉␉␉ "\tRebase Offset: 0x%X\n"␊ |
282 | ␉␉␉␉␉ "\tBind Offset: 0x%X\n"␊ |
283 | ␉␉␉␉␉ "\tWeak Bind Offset: 0x%X\n"␊ |
284 | ␉␉␉␉␉ "\tLazy Bind Offset: 0x%X\n"␊ |
285 | ␉␉␉␉␉ "\tExport Offset: 0x%X\n",␊ |
286 | ␉␉␉␉␉ dyldInfoCommand->rebase_off,␊ |
287 | ␉␉␉␉␉ dyldInfoCommand->bind_off,␊ |
288 | ␉␉␉␉␉ dyldInfoCommand->weak_bind_off,␊ |
289 | ␉␉␉␉␉ dyldInfoCommand->lazy_bind_off,␊ |
290 | ␉␉␉␉␉ dyldInfoCommand->export_off);␊ |
291 | ␉␉␉␉*/␊ |
292 | ␉␉␉␉if(dyldInfoCommand->bind_off)␊ |
293 | ␉␉␉␉{␊ |
294 | ␉␉␉␉␉bind_macho(binary, (char*)dyldInfoCommand->bind_off, dyldInfoCommand->bind_size);␊ |
295 | ␉␉␉␉}␊ |
296 | ␉␉␉␉␊ |
297 | ␉␉␉␉/*␊ |
298 | ␉␉␉␉ // This is done later on using the __symbol_stub instead␊ |
299 | ␉␉␉␉if(dyldInfoCommand->lazy_bind_off)␊ |
300 | ␉␉␉␉{␊ |
301 | ␉␉␉␉␉bind_macho(binary, (char*)dyldInfoCommand->lazy_bind_off, dyldInfoCommand->lazy_bind_size);␊ |
302 | ␉␉␉␉␉␊ |
303 | ␉␉␉␉}*/␊ |
304 | ␉␉␉␉␊ |
305 | ␉␉␉␉if(dyldInfoCommand->rebase_off)␊ |
306 | ␉␉␉␉{␊ |
307 | ␉␉␉␉␉rebase_macho(binary, (char*)dyldInfoCommand->rebase_off, dyldInfoCommand->rebase_size);␊ |
308 | ␉␉␉␉}␊ |
309 | ␉␉␉␉␊ |
310 | ␉␉␉␉␊ |
311 | ␉␉␉␉break;␊ |
312 | ␊ |
313 | ␉␉␉case LC_UUID:␊ |
314 | ␉␉␉␉// We don't care about the UUID at the moment␊ |
315 | ␉␉␉␉break;␊ |
316 | ␉␉␉␉␊ |
317 | ␉␉␉default:␊ |
318 | ␉␉␉␉printf("Unhandled loadcommand 0x%X\n", loadCommand->cmd & 0x7FFFFFFF);␊ |
319 | ␉␉␉␉break;␊ |
320 | ␉␉␊ |
321 | ␉␉}␊ |
322 | ␊ |
323 | ␉␉binaryIndex += cmdSize;␊ |
324 | ␉}␊ |
325 | ␉if(!moduleName) return NULL;␊ |
326 | ␉␊ |
327 | ␉␊ |
328 | ␉// TODO: Initialize the module.␊ |
329 | ␉printf("Calling _start\n");␊ |
330 | ␉␊ |
331 | ␉getc();␊ |
332 | ␉if(module_init) ␊ |
333 | ␉{␊ |
334 | ␉␉jump_pointer(module_init);␊ |
335 | ␉ }␊ |
336 | ␉module_loaded(moduleName, moduleVersion, moduleCompat);␊ |
337 | ␉getc();␊ |
338 | ␉ //*/␊ |
339 | ␉return module_start; // TODO populate w/ address of _start␊ |
340 | ␉␊ |
341 | }␊ |
342 | ␊ |
343 | ␊ |
344 | // This is for debugging, remove the jump_pointer funciton later␊ |
345 | int jump_pointer(int (*pointer)())␊ |
346 | {␊ |
347 | ␉printf("Jumping to function at 0x%X\n", pointer);␊ |
348 | ␊ |
349 | ␉getc();␊ |
350 | ␉return (*pointer)();␊ |
351 | }␊ |
352 | ␊ |
353 | // Based on code from dylibinfo.cpp and ImageLoaderMachOCompressed.cpp␊ |
354 | void rebase_macho(void* base, char* rebase_stream, UInt32 size)␊ |
355 | {␊ |
356 | ␉rebase_stream += (UInt32)base;␊ |
357 | ␉␊ |
358 | ␉UInt8 immediate = 0;␊ |
359 | ␉UInt8 opcode = 0;␊ |
360 | ␉UInt8 type = 0;␊ |
361 | ␉␊ |
362 | ␉UInt32 segmentAddress = 0;␊ |
363 | ␉UInt32 address = 0;␊ |
364 | ␉␊ |
365 | ␉␊ |
366 | ␉␊ |
367 | ␉UInt32 tmp = 0;␊ |
368 | ␉UInt32 tmp2 = 0;␊ |
369 | ␉UInt8 bits = 0;␊ |
370 | ␉int index = 0;␊ |
371 | ␉␊ |
372 | ␉int done = 0;␊ |
373 | ␉unsigned int i = 0;␊ |
374 | ␉␊ |
375 | ␉while(/*!done &&*/ i < size)␊ |
376 | ␉{␊ |
377 | ␉␉immediate = rebase_stream[i] & REBASE_IMMEDIATE_MASK;␊ |
378 | ␉␉opcode = rebase_stream[i] & REBASE_OPCODE_MASK;␊ |
379 | ␊ |
380 | ␉␉␊ |
381 | ␉␉switch(opcode)␊ |
382 | ␉␉{␊ |
383 | ␉␉␉case REBASE_OPCODE_DONE:␊ |
384 | ␉␉␉␉// Rebase complete.␊ |
385 | ␉␉␉␉done = 1;␊ |
386 | ␉␉␉␉break;␊ |
387 | ␉␉␉␉␊ |
388 | ␉␉␉case REBASE_OPCODE_SET_TYPE_IMM:␊ |
389 | ␉␉␉␉// Set rebase type (pointer, absolute32, pcrel32)␊ |
390 | ␉␉␉␉//printf("Rebase type = 0x%X\n", immediate);␊ |
391 | ␉␉␉␉// NOTE: This is currently NOT used␊ |
392 | ␉␉␉␉type = immediate;␊ |
393 | ␉␉␉␉break;␊ |
394 | ␉␉␉␉␊ |
395 | ␉␉␉case REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:␊ |
396 | ␉␉␉␉// Locate address to begin rebasing␊ |
397 | ␉␉␉␉segmentAddress = 0;␊ |
398 | ␊ |
399 | ␉␉␉␉struct segment_command* segCommand = NULL;␊ |
400 | ␉␉␉␉␊ |
401 | ␉␉␉␉unsigned int binIndex = 0;␊ |
402 | ␉␉␉␉index = 0;␊ |
403 | ␉␉␉␉do␊ |
404 | ␉␉␉␉{␊ |
405 | ␉␉␉␉␉segCommand = base + sizeof(struct mach_header) + binIndex;␊ |
406 | ␉␉␉␉␉␊ |
407 | ␉␉␉␉␉␊ |
408 | ␉␉␉␉␉binIndex += segCommand->cmdsize;␊ |
409 | ␉␉␉␉␉index++;␊ |
410 | ␉␉␉␉}␊ |
411 | ␉␉␉␉while(index <= immediate);␊ |
412 | ␊ |
413 | ␊ |
414 | ␉␉␉␉segmentAddress = segCommand->fileoff;␊ |
415 | ␉␉␉␉␊ |
416 | ␉␉␉␉tmp = 0;␊ |
417 | ␉␉␉␉bits = 0;␊ |
418 | ␉␉␉␉do␊ |
419 | ␉␉␉␉{␊ |
420 | ␉␉␉␉␉tmp |= (rebase_stream[++i] & 0x7f) << bits;␊ |
421 | ␉␉␉␉␉bits += 7;␊ |
422 | ␉␉␉␉}␊ |
423 | ␉␉␉␉while(rebase_stream[i] & 0x80);␊ |
424 | ␉␉␉␉␊ |
425 | ␉␉␉␉segmentAddress += tmp;␊ |
426 | ␉␉␉␉␊ |
427 | ␉␉␉␉//printf("Address = 0x%X\n", segmentAddress);␊ |
428 | ␉␉␉␉break;␊ |
429 | ␉␉␉␉␊ |
430 | ␉␉␉case REBASE_OPCODE_ADD_ADDR_ULEB:␊ |
431 | ␉␉␉␉// Add value to rebase address␊ |
432 | ␉␉␉␉tmp = 0;␊ |
433 | ␉␉␉␉bits = 0;␊ |
434 | ␉␉␉␉do␊ |
435 | ␉␉␉␉{␊ |
436 | ␉␉␉␉␉tmp <<= bits;␊ |
437 | ␉␉␉␉␉tmp |= rebase_stream[++i] & 0x7f;␊ |
438 | ␉␉␉␉␉bits += 7;␊ |
439 | ␉␉␉␉}␊ |
440 | ␉␉␉␉while(rebase_stream[i] & 0x80);␊ |
441 | ␉␉␉␉␊ |
442 | ␉␉␉␉address +=␉tmp; ␊ |
443 | ␉␉␉␉//printf("Address (add) = 0x%X\n", address);␊ |
444 | ␉␉␉␉break;␊ |
445 | ␉␉␉␉␊ |
446 | ␉␉␉case REBASE_OPCODE_ADD_ADDR_IMM_SCALED:␊ |
447 | ␉␉␉␉address += immediate * sizeof(void*);␊ |
448 | ␉␉␉␉//printf("Address (immscaled) = 0x%X\n", address);␊ |
449 | ␊ |
450 | ␉␉␉␉break;␊ |
451 | ␉␉␉␉␊ |
452 | ␉␉␉case REBASE_OPCODE_DO_REBASE_IMM_TIMES:␊ |
453 | ␉␉␉␉//printf("Rebase %d time(s)\n", immediate);␊ |
454 | ␉␉␉␉index = 0;␊ |
455 | ␉␉␉␉for (index = 0; index < immediate; ++index) {␊ |
456 | ␉␉␉␉␉//printf("\tRebasing 0x%X\n", segmentAddress);␊ |
457 | ␉␉␉␉␉␊ |
458 | ␉␉␉␉␉UInt32* addr = base + segmentAddress;␊ |
459 | ␉␉␉␉␉addr[0] += (UInt32)base;␊ |
460 | ␉␉␉␉␉␊ |
461 | ␉␉␉␉␉␊ |
462 | ␉␉␉␉␉segmentAddress += sizeof(void*);␊ |
463 | ␉␉␉␉}␊ |
464 | ␉␉␉␉break;␊ |
465 | ␉␉␉␉␊ |
466 | ␉␉␉case REBASE_OPCODE_DO_REBASE_ULEB_TIMES:␊ |
467 | ␉␉␉␉tmp = 0;␊ |
468 | ␉␉␉␉bits = 0;␊ |
469 | ␉␉␉␉do␊ |
470 | ␉␉␉␉{␊ |
471 | ␉␉␉␉␉tmp |= (rebase_stream[++i] & 0x7f) << bits;␊ |
472 | ␉␉␉␉␉bits += 7;␊ |
473 | ␉␉␉␉}␊ |
474 | ␉␉␉␉while(rebase_stream[i] & 0x80);␊ |
475 | ␉␉␉␉␊ |
476 | ␉␉␉␉//printf("Rebase %d time(s)\n", tmp);␊ |
477 | ␉␉␉␉␊ |
478 | ␉␉␉␉index = 0;␊ |
479 | ␉␉␉␉for (index = 0; index < tmp; ++index) {␊ |
480 | ␉␉␉␉␉//printf("\tRebasing 0x%X\n", segmentAddress);␊ |
481 | ␉␉␉␉␉␊ |
482 | ␉␉␉␉␉UInt32* addr = base + segmentAddress;␊ |
483 | ␉␉␉␉␉addr[0] += (UInt32)base;␊ |
484 | ␉␉␉␉␉␊ |
485 | ␉␉␉␉␉segmentAddress += sizeof(void*);␊ |
486 | ␉␉␉␉}␊ |
487 | ␉␉␉␉break;␊ |
488 | ␉␉␉␉␊ |
489 | ␉␉␉case REBASE_OPCODE_DO_REBASE_ADD_ADDR_ULEB:␊ |
490 | ␉␉␉␉tmp = 0;␊ |
491 | ␉␉␉␉bits = 0;␊ |
492 | ␉␉␉␉do␊ |
493 | ␉␉␉␉{␊ |
494 | ␉␉␉␉␉tmp |= (rebase_stream[++i] & 0x7f) << bits;␊ |
495 | ␉␉␉␉␉bits += 7;␊ |
496 | ␉␉␉␉}␊ |
497 | ␉␉␉␉while(rebase_stream[i] & 0x80);␊ |
498 | ␉␉␉␉␊ |
499 | ␉␉␉␉␊ |
500 | ␉␉␉␉//printf("Rebase and add 0x%X\n", tmp);␊ |
501 | ␉␉␉␉//printf("\tRebasing 0x%X\n", segmentAddress);␊ |
502 | ␉␉␉␉UInt32* addr = base + segmentAddress;␊ |
503 | ␉␉␉␉addr[0] += (UInt32)base;␊ |
504 | ␉␉␉␉␊ |
505 | ␉␉␉␉segmentAddress += tmp + sizeof(void*);␊ |
506 | ␉␉␉␉break;␊ |
507 | ␉␉␉␉␊ |
508 | ␉␉␉case REBASE_OPCODE_DO_REBASE_ULEB_TIMES_SKIPPING_ULEB:␊ |
509 | ␉␉␉␉tmp = 0;␊ |
510 | ␉␉␉␉bits = 0;␊ |
511 | ␉␉␉␉do␊ |
512 | ␉␉␉␉{␊ |
513 | ␉␉␉␉␉tmp |= (rebase_stream[++i] & 0x7f) << bits;␊ |
514 | ␉␉␉␉␉bits += 7;␊ |
515 | ␉␉␉␉}␊ |
516 | ␉␉␉␉while(rebase_stream[i] & 0x80);␊ |
517 | ␉␉␉␉␊ |
518 | ␉␉␉␉␊ |
519 | ␉␉␉␉tmp2 = 0;␊ |
520 | ␉␉␉␉bits = 0;␊ |
521 | ␉␉␉␉do␊ |
522 | ␉␉␉␉{␊ |
523 | ␉␉␉␉␉tmp2 |= (rebase_stream[++i] & 0x7f) << bits;␊ |
524 | ␉␉␉␉␉bits += 7;␊ |
525 | ␉␉␉␉}␊ |
526 | ␉␉␉␉while(rebase_stream[i] & 0x80);␊ |
527 | ␉␉␉␉␊ |
528 | ␉␉␉␉//printf("Rebase 0x%X times, skiping 0x%X\n",tmp, tmp2);␊ |
529 | ␉␉␉␉index = 0;␊ |
530 | ␉␉␉␉for (index = 0; index < tmp; ++index) {␊ |
531 | ␉␉␉␉␉//printf("\tRebasing 0x%X\n", segmentAddress);␊ |
532 | ␊ |
533 | ␉␉␉␉␉UInt32* addr = base + segmentAddress;␊ |
534 | ␉␉␉␉␉addr[0] += (UInt32)base;␊ |
535 | ␉␉␉␉␉␊ |
536 | ␉␉␉␉␉segmentAddress += tmp2 + sizeof(void*);␊ |
537 | ␉␉␉␉}␊ |
538 | ␉␉␉␉break;␊ |
539 | ␉␉}␊ |
540 | ␉␉i++;␊ |
541 | ␉}␊ |
542 | }␊ |
543 | ␊ |
544 | // Based on code from dylibinfo.cpp and ImageLoaderMachOCompressed.cpp␊ |
545 | // NOTE: this uses 32bit values, and not 64bit values. ␊ |
546 | // There is apossibility that this could cause issues,␊ |
547 | // however the macho file is 32 bit, so it shouldn't matter too much␊ |
548 | void bind_macho(void* base, char* bind_stream, UInt32 size)␊ |
549 | {␉␊ |
550 | ␉␊ |
551 | ␉␊ |
552 | ␉bind_stream += (UInt32)base;␊ |
553 | ␉␊ |
554 | ␉UInt8 immediate = 0;␊ |
555 | ␉UInt8 opcode = 0;␊ |
556 | ␉UInt8 type = 0;␊ |
557 | ␉␊ |
558 | ␉UInt32 segmentAddress = 0;␊ |
559 | ␉␊ |
560 | ␉UInt32 address = 0;␊ |
561 | ␉␊ |
562 | ␉SInt32 addend = 0;␊ |
563 | ␉SInt32 libraryOrdinal = 0;␊ |
564 | ␊ |
565 | ␉const char* symbolName = NULL;␊ |
566 | ␉UInt8 symboFlags = 0;␊ |
567 | ␉UInt32 symbolAddr = 0xFFFFFFFF;␊ |
568 | ␉// Temperary variables␊ |
569 | ␉UInt8 bits = 0;␊ |
570 | ␉UInt32 tmp = 0;␊ |
571 | ␉UInt32 tmp2 = 0;␊ |
572 | ␉␊ |
573 | ␉UInt32 index = 0;␊ |
574 | ␉int done = 0;␊ |
575 | ␉unsigned int i = 0;␊ |
576 | ␉␊ |
577 | ␉while(/*!done &&*/ i < size)␊ |
578 | ␉{␊ |
579 | ␉␉immediate = bind_stream[i] & BIND_IMMEDIATE_MASK;␊ |
580 | ␉␉opcode = bind_stream[i] & BIND_OPCODE_MASK;␊ |
581 | ␉␉␊ |
582 | ␉␉␊ |
583 | ␉␉switch(opcode)␊ |
584 | ␉␉{␊ |
585 | ␉␉␉case BIND_OPCODE_DONE:␊ |
586 | ␉␉␉␉done = 1; ␊ |
587 | ␉␉␉␉break;␊ |
588 | ␉␉␉␉␊ |
589 | ␉␉␉case BIND_OPCODE_SET_DYLIB_ORDINAL_IMM:␊ |
590 | ␉␉␉␉libraryOrdinal = immediate;␊ |
591 | ␉␉␉␉//printf("BIND_OPCODE_SET_DYLIB_ORDINAL_IMM: %d\n", libraryOrdinal);␊ |
592 | ␉␉␉␉break;␊ |
593 | ␉␉␉␉␊ |
594 | ␉␉␉case BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB:␊ |
595 | ␉␉␉␉libraryOrdinal = 0;␊ |
596 | ␉␉␉␉bits = 0;␊ |
597 | ␉␉␉␉do␊ |
598 | ␉␉␉␉{␊ |
599 | ␉␉␉␉␉libraryOrdinal |= (bind_stream[++i] & 0x7f) << bits;␊ |
600 | ␉␉␉␉␉bits += 7;␊ |
601 | ␉␉␉␉}␊ |
602 | ␉␉␉␉while(bind_stream[i] & 0x80);␊ |
603 | ␉␉␉␉␊ |
604 | ␉␉␉␉//printf("BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB: %d\n", libraryOrdinal);␊ |
605 | ␊ |
606 | ␉␉␉␉break;␊ |
607 | ␉␉␉␉␊ |
608 | ␉␉␉case BIND_OPCODE_SET_DYLIB_SPECIAL_IMM:␊ |
609 | ␉␉␉␉// NOTE: this is wrong, fortunately we don't use it␊ |
610 | ␉␉␉␉libraryOrdinal = -immediate;␊ |
611 | ␉␉␉␉//printf("BIND_OPCODE_SET_DYLIB_SPECIAL_IMM: %d\n", libraryOrdinal);␊ |
612 | ␊ |
613 | ␉␉␉␉break;␊ |
614 | ␉␉␉␉␊ |
615 | ␉␉␉case BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM:␊ |
616 | ␉␉␉␉symboFlags = immediate;␊ |
617 | ␉␉␉␉symbolName = (char*)&bind_stream[++i];␊ |
618 | ␉␉␉␉i += strlen((char*)&bind_stream[i]);␊ |
619 | ␉␉␉␉//printf("BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM: %s, 0x%X\n", symbolName, symboFlags);␊ |
620 | ␊ |
621 | ␉␉␉␉symbolAddr = lookup_symbol(symbolName);␊ |
622 | ␊ |
623 | ␉␉␉␉break;␊ |
624 | ␉␉␉␉␊ |
625 | ␉␉␉case BIND_OPCODE_SET_TYPE_IMM:␊ |
626 | ␉␉␉␉// Set bind type (pointer, absolute32, pcrel32)␊ |
627 | ␉␉␉␉type = immediate;␊ |
628 | ␉␉␉␉//printf("BIND_OPCODE_SET_TYPE_IMM: %d\n", type);␊ |
629 | ␊ |
630 | ␉␉␉␉break;␊ |
631 | ␉␉␉␉␊ |
632 | ␉␉␉case BIND_OPCODE_SET_ADDEND_SLEB:␊ |
633 | ␉␉␉␉addend = 0;␊ |
634 | ␉␉␉␉bits = 0;␊ |
635 | ␉␉␉␉do␊ |
636 | ␉␉␉␉{␊ |
637 | ␉␉␉␉␉addend |= (bind_stream[++i] & 0x7f) << bits;␊ |
638 | ␉␉␉␉␉bits += 7;␊ |
639 | ␉␉␉␉}␊ |
640 | ␉␉␉␉while(bind_stream[i] & 0x80);␊ |
641 | ␉␉␉␉␊ |
642 | ␉␉␉␉if(!(bind_stream[i-1] & 0x40)) addend *= -1;␊ |
643 | ␉␉␉␉␊ |
644 | ␉␉␉␉//printf("BIND_OPCODE_SET_ADDEND_SLEB: %d\n", addend);␊ |
645 | ␉␉␉␉break;␊ |
646 | ␉␉␉␉␊ |
647 | ␉␉␉case BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB:␊ |
648 | ␉␉␉␉segmentAddress = 0;␊ |
649 | ␊ |
650 | ␉␉␉␉// Locate address␊ |
651 | ␉␉␉␉struct segment_command* segCommand = NULL;␊ |
652 | ␉␉␉␉␊ |
653 | ␉␉␉␉unsigned int binIndex = 0;␊ |
654 | ␉␉␉␉index = 0;␊ |
655 | ␉␉␉␉do␊ |
656 | ␉␉␉␉{␊ |
657 | ␉␉␉␉␉segCommand = base + sizeof(struct mach_header) + binIndex;␊ |
658 | ␉␉␉␉␉binIndex += segCommand->cmdsize;␊ |
659 | ␉␉␉␉␉index++;␊ |
660 | ␉␉␉␉}␊ |
661 | ␉␉␉␉while(index <= immediate);␊ |
662 | ␉␉␉␉␊ |
663 | ␉␉␉␉segmentAddress = segCommand->fileoff;␊ |
664 | ␉␉␉␉␊ |
665 | ␉␉␉␉// Read in offset␊ |
666 | ␉␉␉␉tmp = 0;␊ |
667 | ␉␉␉␉bits = 0;␊ |
668 | ␉␉␉␉do␊ |
669 | ␉␉␉␉{␊ |
670 | ␉␉␉␉␉tmp |= (bind_stream[++i] & 0x7f) << bits;␊ |
671 | ␉␉␉␉␉bits += 7;␊ |
672 | ␉␉␉␉}␊ |
673 | ␉␉␉␉while(bind_stream[i] & 0x80);␊ |
674 | ␉␉␉␉␊ |
675 | ␉␉␉␉segmentAddress += tmp;␊ |
676 | ␉␉␉␉␊ |
677 | ␉␉␉␉//printf("BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB: 0x%X\n", segmentAddress);␊ |
678 | ␉␉␉␉break;␊ |
679 | ␉␉␉␉␊ |
680 | ␉␉␉case BIND_OPCODE_ADD_ADDR_ULEB:␊ |
681 | ␉␉␉␉// Read in offset␊ |
682 | ␉␉␉␉tmp = 0;␊ |
683 | ␉␉␉␉bits = 0;␊ |
684 | ␉␉␉␉do␊ |
685 | ␉␉␉␉{␊ |
686 | ␉␉␉␉␉tmp |= (bind_stream[++i] & 0x7f) << bits;␊ |
687 | ␉␉␉␉␉bits += 7;␊ |
688 | ␉␉␉␉}␊ |
689 | ␉␉␉␉while(bind_stream[i] & 0x80);␊ |
690 | ␉␉␉␉␊ |
691 | ␉␉␉␉segmentAddress += tmp;␊ |
692 | ␉␉␉␉//printf("BIND_OPCODE_ADD_ADDR_ULEB: 0x%X\n", segmentAddress);␊ |
693 | ␉␉␉␉break;␊ |
694 | ␉␉␉␉␊ |
695 | ␉␉␉case BIND_OPCODE_DO_BIND:␊ |
696 | ␉␉␉␉//printf("BIND_OPCODE_DO_BIND\n");␊ |
697 | ␉␉␉␉if(symbolAddr != 0xFFFFFFFF)␊ |
698 | ␉␉␉␉{␊ |
699 | ␉␉␉␉␉address = segmentAddress + (UInt32)base;␊ |
700 | ␉␉␉␉␉␊ |
701 | ␉␉␉␉␉((char*)address)[0] = (symbolAddr & 0x000000FF) >> 0;␊ |
702 | ␉␉␉␉␉((char*)address)[1] = (symbolAddr & 0x0000FF00) >> 8;␊ |
703 | ␉␉␉␉␉((char*)address)[2] = (symbolAddr & 0x00FF0000) >> 16;␊ |
704 | ␉␉␉␉␉((char*)address)[3] = (symbolAddr & 0xFF000000) >> 24;␊ |
705 | ␉␉␉␉}␊ |
706 | ␉␉␉␉else if(strcmp(symbolName, SYMBOL_DYLD_STUB_BINDER) != 0)␊ |
707 | ␉␉␉␉{␊ |
708 | ␉␉␉␉␉printf("Unable to bind symbol %s\n", symbolName);␊ |
709 | ␉␉␉␉}␊ |
710 | ␉␉␉␉␊ |
711 | ␉␉␉␉segmentAddress += sizeof(void*);␊ |
712 | ␉␉␉␉break;␊ |
713 | ␉␉␉␉␊ |
714 | ␉␉␉case BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB:␊ |
715 | ␉␉␉␉//printf("BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB\n");␊ |
716 | ␉␉␉␉␊ |
717 | ␉␉␉␉␊ |
718 | ␉␉␉␉// Read in offset␊ |
719 | ␉␉␉␉tmp = 0;␊ |
720 | ␉␉␉␉bits = 0;␊ |
721 | ␉␉␉␉do␊ |
722 | ␉␉␉␉{␊ |
723 | ␉␉␉␉␉tmp |= (bind_stream[++i] & 0x7f) << bits;␊ |
724 | ␉␉␉␉␉bits += 7;␊ |
725 | ␉␉␉␉}␊ |
726 | ␉␉␉␉while(bind_stream[i] & 0x80);␊ |
727 | ␉␉␉␉␊ |
728 | ␉␉␉␉␊ |
729 | ␉␉␉␉␊ |
730 | ␉␉␉␉if(symbolAddr != 0xFFFFFFFF)␊ |
731 | ␉␉␉␉{␊ |
732 | ␉␉␉␉␉address = segmentAddress + (UInt32)base;␊ |
733 | ␉␉␉␉␉␊ |
734 | ␉␉␉␉␉((char*)address)[0] = (symbolAddr & 0x000000FF) >> 0;␊ |
735 | ␉␉␉␉␉((char*)address)[1] = (symbolAddr & 0x0000FF00) >> 8;␊ |
736 | ␉␉␉␉␉((char*)address)[2] = (symbolAddr & 0x00FF0000) >> 16;␊ |
737 | ␉␉␉␉␉((char*)address)[3] = (symbolAddr & 0xFF000000) >> 24;␊ |
738 | ␉␉␉␉}␊ |
739 | ␉␉␉␉else if(strcmp(symbolName, SYMBOL_DYLD_STUB_BINDER) != 0)␊ |
740 | ␉␉␉␉{␊ |
741 | ␉␉␉␉␉printf("Unable to bind symbol %s\n", symbolName);␊ |
742 | ␉␉␉␉}␊ |
743 | ␉␉␉␉segmentAddress += tmp + sizeof(void*);␊ |
744 | ␊ |
745 | ␉␉␉␉␊ |
746 | ␉␉␉␉break;␊ |
747 | ␉␉␉␉␊ |
748 | ␉␉␉case BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED:␊ |
749 | ␉␉␉␉//printf("BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED\n");␊ |
750 | ␉␉␉␉␊ |
751 | ␉␉␉␉if(symbolAddr != 0xFFFFFFFF)␊ |
752 | ␉␉␉␉{␊ |
753 | ␉␉␉␉␉address = segmentAddress + (UInt32)base;␊ |
754 | ␉␉␉␉␉␊ |
755 | ␉␉␉␉␉((char*)address)[0] = (symbolAddr & 0x000000FF) >> 0;␊ |
756 | ␉␉␉␉␉((char*)address)[1] = (symbolAddr & 0x0000FF00) >> 8;␊ |
757 | ␉␉␉␉␉((char*)address)[2] = (symbolAddr & 0x00FF0000) >> 16;␊ |
758 | ␉␉␉␉␉((char*)address)[3] = (symbolAddr & 0xFF000000) >> 24;␊ |
759 | ␉␉␉␉}␊ |
760 | ␉␉␉␉else if(strcmp(symbolName, SYMBOL_DYLD_STUB_BINDER) != 0)␊ |
761 | ␉␉␉␉{␊ |
762 | ␉␉␉␉␉printf("Unable to bind symbol %s\n", symbolName);␊ |
763 | ␉␉␉␉}␊ |
764 | ␉␉␉␉segmentAddress += (immediate * sizeof(void*)) + sizeof(void*);␊ |
765 | ␊ |
766 | ␉␉␉␉␊ |
767 | ␉␉␉␉break;␊ |
768 | ␉␉␉␉␊ |
769 | ␉␉␉case BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB:␊ |
770 | ␊ |
771 | ␉␉␉␉tmp = 0;␊ |
772 | ␉␉␉␉bits = 0;␊ |
773 | ␉␉␉␉do␊ |
774 | ␉␉␉␉{␊ |
775 | ␉␉␉␉␉tmp |= (bind_stream[++i] & 0x7f) << bits;␊ |
776 | ␉␉␉␉␉bits += 7;␊ |
777 | ␉␉␉␉}␊ |
778 | ␉␉␉␉while(bind_stream[i] & 0x80);␊ |
779 | ␊ |
780 | ␉␉␉␉␊ |
781 | ␉␉␉␉tmp2 = 0;␊ |
782 | ␉␉␉␉bits = 0;␊ |
783 | ␉␉␉␉do␊ |
784 | ␉␉␉␉{␊ |
785 | ␉␉␉␉␉tmp2 |= (bind_stream[++i] & 0x7f) << bits;␊ |
786 | ␉␉␉␉␉bits += 7;␊ |
787 | ␉␉␉␉}␊ |
788 | ␉␉␉␉while(bind_stream[i] & 0x80);␊ |
789 | ␉␉␉␉␊ |
790 | ␉␉␉␉␊ |
791 | ␉␉␉␉//printf("BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB 0x%X 0x%X\n", tmp, tmp2);␊ |
792 | ␊ |
793 | ␉␉␉␉␊ |
794 | ␉␉␉␉if(symbolAddr != 0xFFFFFFFF)␊ |
795 | ␉␉␉␉{␊ |
796 | ␉␉␉␉␉for(index = 0; index < tmp; index++)␊ |
797 | ␉␉␉␉␉{␊ |
798 | ␉␉␉␉␉␉␊ |
799 | ␉␉␉␉␉␉address = segmentAddress + (UInt32)base;␊ |
800 | ␉␉␉␉␉␉␊ |
801 | ␉␉␉␉␉␉((char*)address)[0] = (symbolAddr & 0x000000FF) >> 0;␊ |
802 | ␉␉␉␉␉␉((char*)address)[1] = (symbolAddr & 0x0000FF00) >> 8;␊ |
803 | ␉␉␉␉␉␉((char*)address)[2] = (symbolAddr & 0x00FF0000) >> 16;␊ |
804 | ␉␉␉␉␉␉((char*)address)[3] = (symbolAddr & 0xFF000000) >> 24;␊ |
805 | ␉␉␉␉␉␉␊ |
806 | ␉␉␉␉␉␉segmentAddress += tmp2 + sizeof(void*);␊ |
807 | ␉␉␉␉␉}␊ |
808 | ␉␉␉␉}␊ |
809 | ␉␉␉␉else if(strcmp(symbolName, SYMBOL_DYLD_STUB_BINDER) != 0)␊ |
810 | ␉␉␉␉{␊ |
811 | ␉␉␉␉␉printf("Unable to bind symbol %s\n", symbolName);␊ |
812 | ␉␉␉␉}␊ |
813 | ␉␉␉␉␊ |
814 | ␉␉␉␉␊ |
815 | ␉␉␉␉break;␊ |
816 | ␉␉␉␉␊ |
817 | ␉␉}␊ |
818 | ␉␉i++;␊ |
819 | ␉}␊ |
820 | }␊ |
821 | ␊ |
822 | /*␊ |
823 | * add_symbol␊ |
824 | * This function adds a symbol from a module to the list of known symbols ␊ |
825 | * TODO: actualy do something... ␊ |
826 | * possibly change to a pointer and add this to the Symbol module␊ |
827 | */␊ |
828 | void add_symbol(const char* symbol, void* addr)␊ |
829 | {␊ |
830 | ␉printf("Adding symbol %s at 0x%X\n", symbol, addr);␊ |
831 | ␉␊ |
832 | ␉//hack␊ |
833 | ␉if(strcmp(symbol, "_lookup_symbol") == 0)␊ |
834 | ␉{␊ |
835 | ␉␉printf("Initializing lookup symbol function\n");␊ |
836 | ␉␉lookup_symbol = addr;␊ |
837 | ␉}␊ |
838 | }␊ |
839 | ␊ |
840 | ␊ |
841 | /*␊ |
842 | * print out the information about the loaded module␊ |
843 | * In the future, add to a list of laoded modules␊ |
844 | * so that if another module depends on it we don't␊ |
845 | * try to reload the same module.␊ |
846 | */␊ |
847 | void module_loaded(const char* name, UInt32 version, UInt32 compat)␊ |
848 | {␊ |
849 | ␉printf("\%s.dylib Version %d.%d.%d loaded\n"␊ |
850 | ␉␉ "\tCompatibility Version: %d.%d.%d\n",␊ |
851 | ␉␉ name,␊ |
852 | ␉␉ (version >> 16) & 0xFFFF,␊ |
853 | ␉␉ (version >> 8) & 0x00FF,␊ |
854 | ␉␉ (version >> 0) & 0x00FF,␊ |
855 | ␉␉ (compat >> 16) & 0xFFFF,␊ |
856 | ␉␉ (compat >> 8) & 0x00FF,␊ |
857 | ␉␉ (compat >> 0) & 0x00FF);␉␉␊ |
858 | ␉␊ |
859 | }␊ |
860 |