Root/
Source at commit 1146 created 12 years 11 months ago. By azimutz, Sync with trunk (r1145). Add nVidia dev id's, 0DF4 for "GeForce GT 450M" (issue 99) and 1251 for "GeForce GTX 560M" (thanks to oSxFr33k for testing). | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 2010 Evan Lojewski. All rights reserved.␊ |
3 | *␉␊ |
4 | *␉dyldsymboltool␊ |
5 | *␊ |
6 | *␉␉Generates a dylib file for the dyld implimentation in chameleon␊ |
7 | *␉to load and link. This is used to import the boot symbols into the␊ |
8 | *␉module system. ␊ |
9 | */␊ |
10 | ␊ |
11 | #include <stdio.h>␊ |
12 | #include <stdlib.h>␊ |
13 | #include <mach/mach.h>␊ |
14 | #include <sys/file.h>␊ |
15 | #include <mach-o/loader.h>␊ |
16 | #include <mach-o/nlist.h>␊ |
17 | ␊ |
18 | ␊ |
19 | #define DYLIB_NAME "Symbols"␊ |
20 | #define VOID_SYMBOL "_load_all_modules"␊ |
21 | #define START_SYMBOL "start"␊ |
22 | ␊ |
23 | typedef struct symbols_dylib␊ |
24 | {␊ |
25 | ␉struct mach_header␉␉header;␊ |
26 | ␉struct dylib_command␉dylib_info;␊ |
27 | ␉char␉␉␉␉␉module_name[sizeof(DYLIB_NAME)];␉␊ |
28 | ␉struct symtab_command␉symtab;␊ |
29 | } symbols_dylib_t;␊ |
30 | ␊ |
31 | ␊ |
32 | typedef struct symbolList_t␊ |
33 | {␊ |
34 | ␉char*␉␉␉␉␉name;␊ |
35 | ␉uint32_t␉␉␉␉addr;␊ |
36 | ␉int␉␉␉␉␉␉pos;␊ |
37 | ␉struct symbolList_t*␉next;␊ |
38 | } symbolList_t;␊ |
39 | ␊ |
40 | ␊ |
41 | int num_symbols(symbolList_t* list);␊ |
42 | int string_size(symbolList_t* list);␊ |
43 | void add_symbol(symbolList_t** list, char* name, uint32_t addr);␊ |
44 | ␊ |
45 | ␊ |
46 | int main(int argc, char *argv[])␊ |
47 | {␊ |
48 | ␉if(argc < 3) ␊ |
49 | ␉{␊ |
50 | ␉␉fprintf(stderr, "usage: dyldsymboltool obj1 [obj2 ...] outfile\n");␊ |
51 | ␊ |
52 | ␉␉exit(-1);␊ |
53 | ␉}␊ |
54 | ␊ |
55 | ␉␊ |
56 | ␊ |
57 | ␉symbols_dylib_t dylib;␊ |
58 | ␉symbolList_t*␉symbols = NULL;␊ |
59 | ␊ |
60 | ␉uint32_t start_addr = 0;␊ |
61 | ␉␊ |
62 | ␉␊ |
63 | ␉␊ |
64 | ␉␊ |
65 | int i;␊ |
66 | ␉for(i = 1; i < argc-1; i++)␊ |
67 | {␊ |
68 | char line[256];␊ |
69 | char* command = malloc(strlen(argv[1]) + sizeof("nm -g "));␊ |
70 | FILE *fpipe;␊ |
71 | ␊ |
72 | // Parse boot.sys (arg1) to get symtab␊ |
73 | sprintf(command, "nm -g %s", argv[i]);␉// TODO: read boot.sym directly, no need for nm␊ |
74 | ␊ |
75 | if ( !(fpipe = (FILE*)popen(command,"r")) )␊ |
76 | { // If fpipe is NULL␊ |
77 | perror("Problems with pipe");␊ |
78 | exit(1);␊ |
79 | }␊ |
80 | ␊ |
81 | ␊ |
82 | while ( fgets( line, sizeof line, fpipe))␊ |
83 | {␊ |
84 | if((strlen(line) < strlen(argv[i]) ||␊ |
85 | strncmp(line, argv[i], strlen(argv[i])) != 0)␊ |
86 | && line[0] != ' ')␊ |
87 | {␊ |
88 | uint32_t address = 0;␊ |
89 | char* addr = strtok(line, " ");␊ |
90 | strtok(NULL, " ");␊ |
91 | char* name = strtok(NULL, " ");␊ |
92 | name[strlen(name)-1] = 0;␉// remove newline␊ |
93 | sscanf(addr, "%x", &address);␊ |
94 | if(strcmp(name, VOID_SYMBOL) == 0) start_addr = address;␊ |
95 | add_symbol(&symbols, name, address);␊ |
96 | }␊ |
97 | } ␊ |
98 | ␊ |
99 | pclose(fpipe);␊ |
100 | ␊ |
101 | free(command);␊ |
102 | }␊ |
103 | ␊ |
104 | ␊ |
105 | ␉␊ |
106 | ␉if(start_addr == 0)␊ |
107 | ␉{␊ |
108 | ␉␉fprintf(stderr, "Unable to locate Symbol.dylib start function\n");␊ |
109 | ␊ |
110 | //exit(1);␊ |
111 | ␉}␊ |
112 | else␊ |
113 | {␊ |
114 | add_symbol(&symbols, START_SYMBOL, start_addr);␊ |
115 | ␉}␊ |
116 | ␉␊ |
117 | ␉/* Header command info */␊ |
118 | ␉dylib.header.ncmds = 2;␊ |
119 | ␉dylib.header.sizeofcmds = sizeof(dylib) - sizeof(struct mach_header);// + dylib.symtab.nsyms * sizeof(struct nlist) + dylib.symtab.strsize;␊ |
120 | ␉␊ |
121 | ␉dylib.header.magic = MH_MAGIC;␊ |
122 | ␉dylib.header.cputype = CPU_TYPE_X86;␊ |
123 | ␉dylib.header.cpusubtype = /*CPUSUBTYPE_I386*/ 3;␊ |
124 | ␉dylib.header.filetype = MH_DYLIB;␊ |
125 | ␉dylib.header.flags = MH_NOUNDEFS | MH_DYLDLINK | MH_NO_REEXPORTED_DYLIBS;␊ |
126 | ␉␉␊ |
127 | ␉/* Load Commands - dylib id */␊ |
128 | ␉dylib.dylib_info.cmd = LC_ID_DYLIB;␊ |
129 | ␉dylib.dylib_info.cmdsize = sizeof(struct dylib_command) + sizeof(dylib.module_name);␉// todo: verify␊ |
130 | ␉dylib.dylib_info.dylib.name.offset = sizeof(struct dylib_command);␊ |
131 | ␉dylib.dylib_info.dylib.timestamp = 0;␉// TODO: populate with time␊ |
132 | ␉dylib.dylib_info.dylib.current_version = 0;␉␉␉// TODO␊ |
133 | ␉dylib.dylib_info.dylib.compatibility_version = 0;␉// TODO␊ |
134 | ␉␊ |
135 | ␉␊ |
136 | ␉//int offset = dylib.dylib_info.cmdsize%4 ? 4 - (dylib.dylib_info.cmdsize % 4) : 0;␊ |
137 | ␉//dylib.dylib_info.cmdsize += offset;␊ |
138 | ␉//dylib.header.sizeofcmds += offset;␊ |
139 | ␉␊ |
140 | ␉sprintf(dylib.module_name, "%s", DYLIB_NAME);␊ |
141 | ␉␊ |
142 | ␉/* Load Commands - Symtable */␊ |
143 | ␉dylib.symtab.cmd = LC_SYMTAB;␊ |
144 | ␉dylib.symtab.symoff = sizeof(dylib);␉␊ |
145 | ␉dylib.symtab.nsyms = num_symbols(symbols);␊ |
146 | ␉dylib.symtab.stroff = sizeof(dylib) + dylib.symtab.nsyms * sizeof(struct nlist);␊ |
147 | ␉dylib.symtab.strsize = string_size(symbols);␊ |
148 | ␉dylib.symtab.cmdsize = sizeof(struct symtab_command);␊ |
149 | ␉␊ |
150 | ␉␊ |
151 | ␊ |
152 | ␉FILE* outfile = fopen(argv[argc-1], "w");␊ |
153 | ␉fwrite(&dylib,␉sizeof(dylib)␉/* Sizeof header + module name */␊ |
154 | ␉␉␉␉␉, 1, outfile);␊ |
155 | ␉␊ |
156 | ␉char* symtab = malloc(dylib.symtab.stroff + dylib.symtab.strsize - sizeof(dylib) + 1); // Add extra 1 for last symbol␊ |
157 | ␉bzero(symtab, dylib.symtab.nsyms * sizeof(struct nlist) + dylib.symtab.strsize + 1);␊ |
158 | ␉char* orig = symtab;␊ |
159 | ␉␊ |
160 | ␉//symtab += offset;␊ |
161 | ␉␊ |
162 | ␉␊ |
163 | ␉while(symbols)␊ |
164 | ␉{␊ |
165 | ␉␉␊ |
166 | ␉␉((struct nlist*)symtab)->n_un.n_strx = symbols->pos;␊ |
167 | ␉␉((struct nlist*)symtab)->n_type = 0xF;␉// TODO: read from boot.sys␊ |
168 | ␉␉((struct nlist*)symtab)->n_sect = 0;␊ |
169 | ␉␉((struct nlist*)symtab)->n_desc = REFERENCE_FLAG_DEFINED;␊ |
170 | ␉␉((struct nlist*)symtab)->n_value = (uint32_t)symbols->addr;␊ |
171 | ␉␉symtab+= sizeof(struct nlist);␊ |
172 | ␉␉␊ |
173 | ␉␉strcpy(orig + dylib.symtab.stroff - sizeof(dylib) + symbols->pos, symbols->name);␊ |
174 | ␊ |
175 | ␉␉symbols = symbols->next;␊ |
176 | ␉}␊ |
177 | ␊ |
178 | ␉fwrite(orig,␉ ␊ |
179 | ␉␉␉␉␉dylib.symtab.stroff␉+␉␉␉␉␉// Sizeof symbol nlists ␊ |
180 | ␉␉␉␉␉dylib.symtab.strsize - sizeof(dylib) + 1␉// sizeof symbol strings␊ |
181 | ␉␉␉␉␉, 1, outfile);␊ |
182 | ␊ |
183 | ␉␊ |
184 | ␉fclose(outfile);␊ |
185 | ␉␊ |
186 | ␉exit(0);␊ |
187 | }␊ |
188 | ␊ |
189 | int num_symbols(symbolList_t* list)␊ |
190 | {␊ |
191 | ␉int retVal = 0;␊ |
192 | ␉while(list)␊ |
193 | ␉{␊ |
194 | ␉␉retVal++;␊ |
195 | ␉␉list = list->next;␊ |
196 | ␉}␊ |
197 | ␉return retVal;␊ |
198 | }␊ |
199 | ␊ |
200 | int string_size(symbolList_t* list)␊ |
201 | {␊ |
202 | ␉int retVal = 0;␊ |
203 | ␉while(list)␊ |
204 | ␉{␊ |
205 | ␉␉retVal += strlen(list->name)+1;␊ |
206 | ␉␉list = list->next;␊ |
207 | ␉}␊ |
208 | ␉return retVal;␊ |
209 | ␉␊ |
210 | }␊ |
211 | ␊ |
212 | void add_symbol(symbolList_t** list, char* name, uint32_t addr)␊ |
213 | {␊ |
214 | ␉symbolList_t* entry = malloc(sizeof(symbolList_t));␊ |
215 | ␉entry->next = (*list);␊ |
216 | ␉␊ |
217 | ␉if(*list) entry->pos = (*list)->pos + strlen((*list)->name) + 1;␊ |
218 | ␉else entry->pos = 1;␊ |
219 | ␉*list = entry;␊ |
220 | ␉␊ |
221 | ␉entry->addr = addr;␊ |
222 | ␉entry->name = malloc(strlen(name)+1);␊ |
223 | ␉strcpy(entry->name, name);␊ |
224 | }␊ |
225 |