Chameleon

Chameleon Commit Details

Date:2011-02-03 06:44:45 (10 years 23 days ago)
Author:Evan Lojewski
Commit:728
Parents: 727
Message:Updated Symbols.dylib generation. Module linked list rework beginning. USB Legacy off patch still needs fixing. Added a new tool to generate the symbols.dylib. It's a fairly correct dylib file, however nm complains about it (it still works fine though). Updated Symbols.dylib file is smaller (~13%) that the old method and is a bit cleaner. dylib generation needs a bit of cleaning up though)
Changes:
A/branches/meklort/i386/util/dyldsymboltool.c
M/branches/meklort/i386/boot2/drivers.h
M/branches/meklort/i386/boot2/modules_support.s
M/branches/meklort/i386/util/Makefile
M/branches/meklort/i386/modules/KextPatcher/kext_patcher.c
M/branches/meklort/i386/Makefile
M/branches/meklort/i386/boot2/modules.c
M/branches/meklort/i386/boot2/Makefile
M/branches/meklort/i386/modules/USBFix/usb.c
M/branches/meklort/i386/boot2/modules.h
M/branches/meklort/i386/libsaio/xml.c
M/branches/meklort/i386/boot2/drivers.c

File differences

branches/meklort/i386/libsaio/xml.c
9393
9494
9595
96
96
9797
9898
9999
unsigned long signature1;
unsigned long signature2;
unsigned long length;
unsigned long alder32;
unsigned long adler32;
unsigned long version;
unsigned long numDrivers;
unsigned long reserved1;
branches/meklort/i386/boot2/modules.c
7777
7878
7979
80
81
80
8281
8382
8483
......
164163
165164
166165
166
167
168
167169
168170
169171
......
216218
217219
218220
219
220221
221222
222223
......
239240
240241
241242
242
243
244
245
243246
244247
245248
......
250253
251254
252255
253
256
254257
255258
256259
......
341344
342345
343346
347
348
349
344350
345351
346352
......
504510
505511
506512
507
513
508514
509515
510516
......
557563
558564
559565
560
566
561567
562568
563569
564
570
565571
566572
567573
......
578584
579585
580586
581
587
582588
583589
584590
585
591
586592
587593
588594
}
else {
// The module does not have a valid start function
printf("Unable to start %s\n", SYMBOLS_MODULE); DBGPAUSE();
getc();
printf("Unable to start %s\n", SYMBOLS_MODULE); getc();
}
return 0;
}
(*module_start)();// Start the module
DBG("Module %s Loaded.\n", module); DBGPAUSE();
//module_entry = malloc(sizeof(moduleList_t); TODO: mode to module_loaded
}
else {
// The module does not have a valid start function
entry->next = NULL;
entry->addr = (UInt32)addr;
entry->symbol = symbol;
if(strcmp(symbol, "start") == 0)
{
return addr;
new_entry->next = loadedModules;
loadedModules = new_entry;
new_entry->module = (char*)name;
new_entry->name = (char*)name;
new_entry->base_addr = NULL;// TODO
// todo; symbols
new_entry->version = 0; //version;
new_entry->compat = 0; //compat;
}
moduleList_t* entry = loadedModules;
while(entry)
{
if(strcmp(entry->module, name) == 0)
if(strcmp(entry->name, name) == 0)
{
DBG("Located module %s\n", name); DBGPAUSE();
return 1;
UInt32 binaryIndex = 0;
UInt16 cmd = 0;
textSection = 0;
textAddress = 0;// reinitialize text location in case it doesn't exist;
// Parse through the load commands
if(((struct mach_header*)binary)->magic == MH_MAGIC)
{
//if(!moduleName) return NULL;
// bind_macho uses the symbols.
// bind_macho uses the symbols, if the textAdd does not exist (Symbols.dylib, no code), addresses are static and not relative
module_start = (void*)handle_symtable((UInt32)binary, symtabCommand, symbol_handler, is64);
// Rebase the module before binding it.
{
// If the symbol is exported by this module
if(symbolEntry->n_value &&
symbol_handler(symbolString + symbolEntry->n_un.n_strx, (long long)base + symbolEntry->n_value, is64) != 0xFFFFFFFF)
symbol_handler(symbolString + symbolEntry->n_un.n_strx, textAddress ? (long long)base + symbolEntry->n_value : symbolEntry->n_value, is64) != 0xFFFFFFFF)
{
// Module start located. Start is an alias so don't register it
module_start = base + symbolEntry->n_value;
module_start = textAddress ? base + symbolEntry->n_value : symbolEntry->n_value;
}
symbolEntry++;
// If the symbol is exported by this module
if(symbolEntry->n_value &&
symbol_handler(symbolString + symbolEntry->n_un.n_strx, (long long)base + symbolEntry->n_value, is64) != 0xFFFFFFFF)
symbol_handler(symbolString + symbolEntry->n_un.n_strx, textAddress ? (long long)base + symbolEntry->n_value : symbolEntry->n_value, is64) != 0xFFFFFFFF)
{
// Module start located. Start is an alias so don't register it
module_start = base + symbolEntry->n_value;
module_start = textAddress ? base + symbolEntry->n_value : symbolEntry->n_value;
}
symbolEntry++;
branches/meklort/i386/boot2/modules.h
3131
3232
3333
34
3435
3536
3637
......
3839
3940
4041
41
42
43
44
45
46
47
4842
4943
5044
......
5953
6054
6155
56
57
58
59
60
61
62
6263
64
65
66
67
68
6369
70
71
6472
6573
6674
extern unsigned long long textSection;
typedef struct symbolList_t
{
char* symbol;
struct symbolList_t* next;
} symbolList_t;
typedef struct moduleList_t
{
char* module;
unsigned int version;
unsigned int compat;
struct moduleList_t* next;
} moduleList_t;
typedef struct callbackList_t
{
struct moduleHook_t* next;
} moduleHook_t;
typedef struct modulesList_t
{
char*name;
UInt32version;
UInt32compat;
void*base_addr;
symbolList_t*exported_symbols;
symbolList_t*udefined_symbols;
//moduleHook_t*defined_hooks;
struct modulesList_t* next;
} moduleList_t;
int init_module_system();
void load_all_modules();
branches/meklort/i386/boot2/drivers.c
4747
4848
4949
50
50
5151
5252
5353
......
7474
7575
7676
77
77
7878
7979
8080
......
9999
100100
101101
102
102
103103
104104
105105
......
383383
384384
385385
386
387
386
387
388388
389389
390390
......
784784
785785
786786
787
787
788788
789789
790790
long (*LoadExtraDrivers_p)(FileLoadDrivers_t FileLoadDrivers_p);
#endif
unsigned long Mkext_Alder32( unsigned char * buffer, long length );
unsigned long Adler32( unsigned char * buffer, long length );
long FileLoadDrivers(char *dirSpec, long plugin);
#ifndef OPTION_ROM
char * gFileName;
unsigned long
Mkext_Alder32( unsigned char * buffer, long length )
Adler32( unsigned char * buffer, long length )
{
long cnt;
unsigned long result, lowHalf, highHalf;
result = (highHalf << 16) | lowHalf;
return result;
return result;
}
if (( GetPackageElement(signature1) != kDriverPackageSignature1) ||
( GetPackageElement(signature2) != kDriverPackageSignature2) ||
( GetPackageElement(length) > kLoadSize ) ||
( GetPackageElement(alder32) !=
Mkext_Alder32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) )
( GetPackageElement(adler32) !=
Adler32((unsigned char *)&package->version, GetPackageElement(length) - 0x10) ) )
{
return -1;
}
return -1;
}
if (OSSwapBigToHostInt32(kernel_header->adler32) !=
Mkext_Alder32(binary, uncompressed_size)) {
Adler32(binary, uncompressed_size)) {
printf("adler mismatch\n");
return -1;
}
branches/meklort/i386/boot2/drivers.h
7171
7272
7373
74
74
7575
7676
7777
unsigned long signature1;
unsigned long signature2;
unsigned long length;
unsigned long alder32;
unsigned long adler32;
unsigned long version;
unsigned long numDrivers;
unsigned long reserved1;
branches/meklort/i386/boot2/modules_support.s
11
22
33
4
4
5
6
7
#include <architecture/i386/asm_help.h>
LABEL(dyld_stub_binder)
jmp_dyld_stub_binder
jmp_dyld_stub_binder
LABEL(dyld_void_start)
ret
branches/meklort/i386/boot2/Makefile
8484
8585
8686
87
88
87
88
89
8990
9091
9192
......
9798
9899
99100
100
101101
102
103
104
105
102106
103107
104108
......
154158
155159
156160
157
161
158162
159
160
161
162
163163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199164
200165
201166
@cp $(SYMROOT)/boot.sys $(SYMROOT)/boot2.sys
@make Symbols.dylib
@${RM} $(SYMROOT)/boot.sys
@# Generate the Symbols.dylib file
@echo "\t[dyldsymboltool] Symbols.dylib"
@$(SYMROOT)/dyldsymboltool $(SYMROOT)/boot.sys $(SYMROOT)/Symbols.dylib
@echo "\t[LD] boot.sys"
@$(LD) -static -Wl,-preload -Wl,-segaddr,__INIT,$(BOOT2ADDR) \
@${RM} $(OBJROOT)/Symbols.o
@${RM} $(SYMROOT)/${SYMBOLS_MODULE}
@${RM} $(SYMROOT)/Symbols.h
@make Symbols.dylib
@# Generate the Symbols.dylib file
@echo "\t[dyldsymboltool] Symbols.dylib"
@$(SYMROOT)/dyldsymboltool $(SYMROOT)/boot.sys $(SYMROOT)/Symbols.dylib
@${RM} $(SYMROOT)/boot.sys
@echo "\t[LD] boot.sys"
@$(LD) -static -Wl,-preload -Wl,-segaddr,__INIT,$(BOOT2ADDR) \
@echo "#define I386BOOT_CHAMELEONREVISION \"`svnversion -n | tr -d [:alpha:]`\"" >> $(SYMROOT)/vers.h
embedded.h:
@cd $(SYMROOT)/../../doc && xxd -i BootHelp.txt > $(SYMROOT)/embedded.h
@cd $(SYMROOT)/../../doc && xxd -i BootHelp.txt > $(SYMROOT)/embedded.h
Symbols.dylib: Symbols.o
@echo ================= Compiling ${SYMBOLS_MODULE} =================
@echo "start" >> ${OBJROOT}/Symbols.save
@echo "_lookup_symbol" >> ${OBJROOT}/Symbols.save
@echo "\t[LD] $@"
@ld -arch i386 \
-undefined dynamic_lookup \
-alias _Symbols_start start \
-dylib -read_only_relocs suppress \
-S -x -dead_strip_dylibs \
-no_uuid \
-bind_at_load \
-current_version 1.0.0 \
-compatibility_version 1.0.0 \
-final_output Symbols \
-exported_symbols_list ${OBJROOT}/Symbols.save \
${OBJROOT}/Symbols.o \
-macosx_version_min 10.6 \
-o $(SYMROOT)/${SYMBOLS_MODULE}
@##size $(SYMROOT)/${SYMBOLS_MODULE}
Symbols.o:
@rm -rf $(SYMROOT)/Symbols.h
@echo "typedef struct {" >> $(SYMROOT)/Symbols.h
@echo "char*symbol;" >> $(SYMROOT)/Symbols.h
@echo "unsigned intaddr;" >> $(SYMROOT)/Symbols.h
@echo "} symbol_t;" >> $(SYMROOT)/Symbols.h
@echo "" >> $(SYMROOT)/Symbols.h
@nm -g $(SYMROOT)/boot.sys | tr . _ | awk '{print "static char "$$3"_string[] = \""$$3"\";"}' >> $(SYMROOT)/Symbols.h
@echo "symbol_t symbolList[] = {" >> $(SYMROOT)/Symbols.h
@nm -g $(SYMROOT)/boot.sys | tr . _ | awk '{print "{.symbol = "$$3"_string, .addr = 0x"$$1"},";}' >> $(SYMROOT)/Symbols.h
@echo "};" >> $(SYMROOT)/Symbols.h
@echo "\t[CC] $@"
@$(CC) $(CPPFLAGS) $(CFLAGS) $(DEFINES) -c Symbols.c $(INC) -o $(OBJROOT)/Symbols.o
install_i386:: all $(INSTALLDIR)
cp $(SYMROOT)/boot $(OTHER_FILES) $(INSTALLDIR)
cd $(INSTALLDIR); chmod u+w boot $(OTHER_FILES)
branches/meklort/i386/modules/KextPatcher/kext_patcher.c
2020
2121
2222
23
24
25
2326
2427
2528
......
8992
9093
9194
92
9395
9496
9597
......
161163
162164
163165
164
166
165167
166168
167169
......
317319
318320
319321
320
322
321323
322
324
323325
324326
325327
#include "hex_editor.h"
unsigned long Adler32( unsigned char * buffer, long length );
#define kHDACodec"HDACodec"
}
unsigned long Mkext_Alder32( unsigned char * buffer, long length );
void KextPatcher_hook(void* current, void* arg2, void* arg3, void* arg4);
( MKEXT_GET_SIGNATURE(package)!= MKEXT_SIGN ) ||
( MKEXT_GET_LENGTH(package)> kLoadSize ) ||
( MKEXT_GET_CHECKSUM(package) !=
Mkext_Alder32((unsigned char *)&package->version, MKEXT_GET_LENGTH(package) - 0x10) ) )
Adler32((unsigned char *)&package->version, MKEXT_GET_LENGTH(package) - 0x10) ) )
{
return;
// Don't try to patch a b
// re alder32 the new mkext2 package
// re adler32 the new mkext2 package
MKEXT_HDR_CAST(package)->adler32 =
MKEXT_SWAP(Mkext_Alder32((unsigned char *)&package->version,
MKEXT_SWAP(Adler32((unsigned char *)&package->version,
MKEXT_GET_LENGTH(package) - 0x10));
}
}
branches/meklort/i386/modules/USBFix/usb.c
4949
5050
5151
52
53
52
53
5454
5555
5656
int usb_loop()
{
int retVal = 1;
bool fix_ehci, fix_uhci, fix_usb, fix_legacy;
fix_ehci = fix_uhci = fix_usb = fix_legacy = true;
bool fix_ehci, fix_uhci, fix_usb, fix_legacy = false;
fix_ehci = fix_uhci = fix_usb = true;
if (getBoolForKey(kUSBBusFix, &fix_usb, &bootInfo->bootConfig))
{
branches/meklort/i386/Makefile
2727
2828
2929
30
30
3131
3232
3333
# The order of building is important.
SUBDIRS = util libsa libsaio boot2 boot1 boot0 cdboot modules
#SUBDIRS=util
all embedtheme optionrom tags debug install installhdrs:
@for i in ${SUBDIRS}; \
do \
branches/meklort/i386/util/dyldsymboltool.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/*
* Copyright (c) 2010 Evan Lojewski. All rights reserved.
*
*dyldsymboltool
*
*Generates a dylib ile for the dyld implimentation in chameleon
*to load and link. This is used to import the boot symbols into the
*module system.
*/
#include <stdio.h>
#include <stdlib.h>
#include <mach/mach.h>
#include <sys/file.h>
#include <mach-o/loader.h>
#include <mach-o/nlist.h>
#define DYLIB_NAME "Symbols"
#define VOID_SYMBOL "dyld_void_start"
#define START_SYMBOL "start"
typedef struct symbols_dylib
{
struct mach_headerheader;
struct dylib_commanddylib_info;
charmodule_name[sizeof(DYLIB_NAME)];
struct symtab_commandsymtab;
} symbols_dylib_t;
typedef struct symbolList_t
{
char*name;
uint32_taddr;
intpos;
struct symbolList_t*next;
} symbolList_t;
int num_symbols(symbolList_t* list);
int string_size(symbolList_t* list);
void add_symbol(symbolList_t** list, char* name, uint32_t addr);
int main(int argc, char *argv[])
{
if(argc != 3)
{
fprintf(stderr, "usage: dyldsymboltool bootFile loadAddr outfile\n");
exit(-1);
}
char line[256];
char* command = malloc(strlen(argv[1]) + sizeof("nm -g "));
FILE *fpipe;
symbols_dylib_t dylib;
symbolList_t*symbols = NULL;
uint32_t start_addr = 0;
// Parse boot.sys (arg1) to get symtab
sprintf(command, "nm -g %s", argv[1]);// TODO: read boot.sym directly, no need for nm
if ( !(fpipe = (FILE*)popen(command,"r")) )
{ // If fpipe is NULL
perror("Problems with pipe");
exit(1);
}
while ( fgets( line, sizeof line, fpipe))
{
uint32_t address = 0;
char* addr = strtok(line, " ");
strtok(NULL, " ");
char* name = strtok(NULL, " ");
name[strlen(name)-1] = 0;// remove newline
sscanf(addr, "%x", &address);
if(strcmp(name, VOID_SYMBOL) == 0) start_addr = address;
add_symbol(&symbols, name, address);
}
pclose(fpipe);
if(start_addr == 0)
{
fprintf(stderr, "Unable to locate Symbol.dylib start function\n");
exit(1);
}
add_symbol(&symbols, START_SYMBOL, start_addr);
/* Header command info */
dylib.header.ncmds = 2;
dylib.header.sizeofcmds = sizeof(dylib) - sizeof(struct mach_header);// + dylib.symtab.nsyms * sizeof(struct nlist) + dylib.symtab.strsize;
dylib.header.magic = MH_MAGIC;
dylib.header.cputype = CPU_TYPE_X86;
dylib.header.cpusubtype = /*CPUSUBTYPE_I386*/ 3;
dylib.header.filetype = MH_DYLIB;
dylib.header.flags = MH_NOUNDEFS | MH_DYLDLINK | MH_NO_REEXPORTED_DYLIBS;
/* Load Commands - dylib id */
dylib.dylib_info.cmd = LC_ID_DYLIB;
dylib.dylib_info.cmdsize = sizeof(struct dylib_command) + sizeof(dylib.module_name);// todo: verify
dylib.dylib_info.dylib.name.offset = sizeof(struct dylib_command);
dylib.dylib_info.dylib.timestamp = 0;// TODO: populate with time
dylib.dylib_info.dylib.current_version = 0;// TODO
dylib.dylib_info.dylib.compatibility_version = 0;// TODO
//int offset = dylib.dylib_info.cmdsize%4 ? 4 - (dylib.dylib_info.cmdsize % 4) : 0;
//dylib.dylib_info.cmdsize += offset;
//dylib.header.sizeofcmds += offset;
sprintf(dylib.module_name, "%s", DYLIB_NAME);
/* Load Commands - Symtable */
dylib.symtab.cmd = LC_SYMTAB;
dylib.symtab.symoff = sizeof(dylib);
dylib.symtab.nsyms = num_symbols(symbols);
dylib.symtab.stroff = sizeof(dylib) + dylib.symtab.nsyms * sizeof(struct nlist);
dylib.symtab.strsize = string_size(symbols);
dylib.symtab.cmdsize = sizeof(struct symtab_command);
FILE* outfile = fopen(argv[2], "w");
fwrite(&dylib,sizeof(dylib)/* Sizeof header + module name */
, 1, outfile);
char* symtab = malloc(dylib.symtab.stroff + dylib.symtab.strsize - sizeof(dylib) + 1); // Add extra 1 for last symbol
bzero(symtab, dylib.symtab.nsyms * sizeof(struct nlist) + dylib.symtab.strsize + 1);
char* orig = symtab;
//symtab += offset;
while(symbols)
{
((struct nlist*)symtab)->n_un.n_strx = symbols->pos;
((struct nlist*)symtab)->n_type = 0xF;// TODO: read from boot.sys
((struct nlist*)symtab)->n_sect = 0;
((struct nlist*)symtab)->n_desc = REFERENCE_FLAG_DEFINED;
((struct nlist*)symtab)->n_value = (uint32_t)symbols->addr;
symtab+= sizeof(struct nlist);
strcpy(orig + dylib.symtab.stroff - sizeof(dylib) + symbols->pos, symbols->name);
symbols = symbols->next;
}
fwrite(orig,
dylib.symtab.stroff+// Sizeof symbol nlists
dylib.symtab.strsize - sizeof(dylib) + 1// sizeof symbol strings
, 1, outfile);
fclose(outfile);
exit(0);
}
int num_symbols(symbolList_t* list)
{
int retVal = 0;
while(list)
{
retVal++;
list = list->next;
}
return retVal;
}
int string_size(symbolList_t* list)
{
int retVal = 0;
while(list)
{
retVal += strlen(list->name)+1;
list = list->next;
}
return retVal;
}
void add_symbol(symbolList_t** list, char* name, uint32_t addr)
{
symbolList_t* entry = malloc(sizeof(symbolList_t));
entry->next = (*list);
if(*list) entry->pos = (*list)->pos + strlen((*list)->name) + 1;
else entry->pos = 1;
*list = entry;
entry->addr = addr;
entry->name = malloc(strlen(name)+1);
strcpy(entry->name, name);
}
branches/meklort/i386/util/Makefile
1818
1919
2020
21
21
2222
2323
2424
......
2626
2727
2828
29
30
31
32
33
2934
3035
3136
CFILES = machOconv.c
ALLSRC = $(CFILES) $(MFILES) $(HFILES) $(EXPORT_HFILES)
PROGRAMS = machOconv bdmesg
PROGRAMS = machOconv bdmesg dyldsymboltool
OUTFILES = $(PROGRAMS)
all embedtheme optionrom: $(DIRS_NEEDED) $(PROGRAMS)
dyldsymboltool: dyldsymboltool.o
@echo "\t[LD] $@"
@$(CC) $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $(SYMROOT)/$(@F) dyldsymboltool.o
machOconv: machOconv.o
@echo "\t[LD] $@"
@$(CC) $(CFLAGS) $(LDFLAGS) $(DEFINES) -o $(SYMROOT)/$(@F) machOconv.o

Archive Download the corresponding diff file

Revision: 728