Chameleon

Chameleon Svn Source Tree

Root/branches/meklort/i386/boot2/modules.c

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

Archive Download this file

Revision: 355