Root/
Source at commit 1808 created 12 years 3 months ago. By blackosx, Revise layout of package installer 'Welcome' file so it looks cleaner. Change the copyright notice to begin from 2009 as seen in the Chameleon 2.0 r431 installer. Should this date be set earlier? | |
---|---|
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 |