Root/
Source at commit 1274 created 12 years 11 months ago. By meklort, Module changes, makefile changes. | |
---|---|
1 | /*␊ |
2 | * Copyright (c) 2010 Evan Lojewski. All rights reserved.␊ |
3 | *␉␊ |
4 | *␉dyldsymboltool␊ |
5 | *␊ |
6 | *␉␉Generates a dylib ile 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 bootFile loadAddr outfile\n");␊ |
51 | ␊ |
52 | ␉␉exit(-1);␊ |
53 | ␉}␊ |
54 | ␊ |
55 | ␉␊ |
56 | ␉char line[256];␊ |
57 | ␉char* command = malloc(strlen(argv[1]) + sizeof("nm -g "));␊ |
58 | ␉FILE *fpipe;␊ |
59 | ␊ |
60 | ␉symbols_dylib_t dylib;␊ |
61 | ␉symbolList_t*␉symbols = NULL;␊ |
62 | ␊ |
63 | ␉uint32_t start_addr = 0;␊ |
64 | ␉␊ |
65 | ␉␊ |
66 | ␉␊ |
67 | ␉␊ |
68 | ␊ |
69 | ␉␊ |
70 | ␉// Parse boot.sys (arg1) to get symtab␊ |
71 | ␉sprintf(command, "nm -g %s", argv[1]);␉// TODO: read boot.sym directly, no need for nm␊ |
72 | ␊ |
73 | ␉if ( !(fpipe = (FILE*)popen(command,"r")) )␊ |
74 | ␉{ // If fpipe is NULL␊ |
75 | ␉␉perror("Problems with pipe");␊ |
76 | ␉␉exit(1);␊ |
77 | ␉}␊ |
78 | ␉␊ |
79 | ␉while ( fgets( line, sizeof line, fpipe))␊ |
80 | ␉{␊ |
81 | ␉␉uint32_t address = 0;␊ |
82 | ␉␉char* addr = strtok(line, " ");␊ |
83 | ␉␉strtok(NULL, " ");␊ |
84 | ␉␉char* name = strtok(NULL, " ");␊ |
85 | ␉␉name[strlen(name)-1] = 0;␉// remove newline␊ |
86 | ␉␉sscanf(addr, "%x", &address);␊ |
87 | ␉␉if(strcmp(name, VOID_SYMBOL) == 0) start_addr = address;␊ |
88 | ␉␉add_symbol(&symbols, name, address);␊ |
89 | ␉}␊ |
90 | ␉␊ |
91 | ␉␊ |
92 | ␉pclose(fpipe);␊ |
93 | ␉␊ |
94 | ␉if(start_addr == 0)␊ |
95 | ␉{␊ |
96 | ␉␉fprintf(stderr, "Unable to locate Symbol.dylib start function\n");␊ |
97 | ␉␉exit(1);␊ |
98 | ␉}␊ |
99 | ␉␊ |
100 | ␉add_symbol(&symbols, START_SYMBOL, start_addr);␊ |
101 | ␉␊ |
102 | ␉␊ |
103 | ␉/* Header command info */␊ |
104 | ␉dylib.header.ncmds = 2;␊ |
105 | ␉dylib.header.sizeofcmds = sizeof(dylib) - sizeof(struct mach_header);// + dylib.symtab.nsyms * sizeof(struct nlist) + dylib.symtab.strsize;␊ |
106 | ␉␊ |
107 | ␉dylib.header.magic = MH_MAGIC;␊ |
108 | ␉dylib.header.cputype = CPU_TYPE_X86;␊ |
109 | ␉dylib.header.cpusubtype = /*CPUSUBTYPE_I386*/ 3;␊ |
110 | ␉dylib.header.filetype = MH_DYLIB;␊ |
111 | ␉dylib.header.flags = MH_NOUNDEFS | MH_DYLDLINK | MH_NO_REEXPORTED_DYLIBS;␊ |
112 | ␉␉␊ |
113 | ␉/* Load Commands - dylib id */␊ |
114 | ␉dylib.dylib_info.cmd = LC_ID_DYLIB;␊ |
115 | ␉dylib.dylib_info.cmdsize = sizeof(struct dylib_command) + sizeof(dylib.module_name);␉// todo: verify␊ |
116 | ␉dylib.dylib_info.dylib.name.offset = sizeof(struct dylib_command);␊ |
117 | ␉dylib.dylib_info.dylib.timestamp = 0;␉// TODO: populate with time␊ |
118 | ␉dylib.dylib_info.dylib.current_version = 0;␉␉␉// TODO␊ |
119 | ␉dylib.dylib_info.dylib.compatibility_version = 0;␉// TODO␊ |
120 | ␉␊ |
121 | ␉␊ |
122 | ␉//int offset = dylib.dylib_info.cmdsize%4 ? 4 - (dylib.dylib_info.cmdsize % 4) : 0;␊ |
123 | ␉//dylib.dylib_info.cmdsize += offset;␊ |
124 | ␉//dylib.header.sizeofcmds += offset;␊ |
125 | ␉␊ |
126 | ␉sprintf(dylib.module_name, "%s", DYLIB_NAME);␊ |
127 | ␉␊ |
128 | ␉/* Load Commands - Symtable */␊ |
129 | ␉dylib.symtab.cmd = LC_SYMTAB;␊ |
130 | ␉dylib.symtab.symoff = sizeof(dylib);␉␊ |
131 | ␉dylib.symtab.nsyms = num_symbols(symbols);␊ |
132 | ␉dylib.symtab.stroff = sizeof(dylib) + dylib.symtab.nsyms * sizeof(struct nlist);␊ |
133 | ␉dylib.symtab.strsize = string_size(symbols);␊ |
134 | ␉dylib.symtab.cmdsize = sizeof(struct symtab_command);␊ |
135 | ␉␊ |
136 | ␉␊ |
137 | ␊ |
138 | ␉FILE* outfile = fopen(argv[2], "w");␊ |
139 | ␉fwrite(&dylib,␉sizeof(dylib)␉/* Sizeof header + module name */␊ |
140 | ␉␉␉␉␉, 1, outfile);␊ |
141 | ␉␊ |
142 | ␉char* symtab = malloc(dylib.symtab.stroff + dylib.symtab.strsize - sizeof(dylib) + 1); // Add extra 1 for last symbol␊ |
143 | ␉bzero(symtab, dylib.symtab.nsyms * sizeof(struct nlist) + dylib.symtab.strsize + 1);␊ |
144 | ␉char* orig = symtab;␊ |
145 | ␉␊ |
146 | ␉//symtab += offset;␊ |
147 | ␉␊ |
148 | ␉␊ |
149 | ␉while(symbols)␊ |
150 | ␉{␊ |
151 | ␉␉␊ |
152 | ␉␉((struct nlist*)symtab)->n_un.n_strx = symbols->pos;␊ |
153 | ␉␉((struct nlist*)symtab)->n_type = 0xF;␉// TODO: read from boot.sys␊ |
154 | ␉␉((struct nlist*)symtab)->n_sect = 0;␊ |
155 | ␉␉((struct nlist*)symtab)->n_desc = REFERENCE_FLAG_DEFINED;␊ |
156 | ␉␉((struct nlist*)symtab)->n_value = (uint32_t)symbols->addr;␊ |
157 | ␉␉symtab+= sizeof(struct nlist);␊ |
158 | ␉␉␊ |
159 | ␉␉strcpy(orig + dylib.symtab.stroff - sizeof(dylib) + symbols->pos, symbols->name);␊ |
160 | ␊ |
161 | ␉␉symbols = symbols->next;␊ |
162 | ␉}␊ |
163 | ␊ |
164 | ␉fwrite(orig,␉ ␊ |
165 | ␉␉␉␉␉dylib.symtab.stroff␉+␉␉␉␉␉// Sizeof symbol nlists ␊ |
166 | ␉␉␉␉␉dylib.symtab.strsize - sizeof(dylib) + 1␉// sizeof symbol strings␊ |
167 | ␉␉␉␉␉, 1, outfile);␊ |
168 | ␊ |
169 | ␉␊ |
170 | ␉fclose(outfile);␊ |
171 | ␉␊ |
172 | ␉exit(0);␊ |
173 | }␊ |
174 | ␊ |
175 | int num_symbols(symbolList_t* list)␊ |
176 | {␊ |
177 | ␉int retVal = 0;␊ |
178 | ␉while(list)␊ |
179 | ␉{␊ |
180 | ␉␉retVal++;␊ |
181 | ␉␉list = list->next;␊ |
182 | ␉}␊ |
183 | ␉return retVal;␊ |
184 | }␊ |
185 | ␊ |
186 | int string_size(symbolList_t* list)␊ |
187 | {␊ |
188 | ␉int retVal = 0;␊ |
189 | ␉while(list)␊ |
190 | ␉{␊ |
191 | ␉␉retVal += strlen(list->name)+1;␊ |
192 | ␉␉list = list->next;␊ |
193 | ␉}␊ |
194 | ␉return retVal;␊ |
195 | ␉␊ |
196 | }␊ |
197 | ␊ |
198 | void add_symbol(symbolList_t** list, char* name, uint32_t addr)␊ |
199 | {␊ |
200 | ␉symbolList_t* entry = malloc(sizeof(symbolList_t));␊ |
201 | ␉entry->next = (*list);␊ |
202 | ␉␊ |
203 | ␉if(*list) entry->pos = (*list)->pos + strlen((*list)->name) + 1;␊ |
204 | ␉else entry->pos = 1;␊ |
205 | ␉*list = entry;␊ |
206 | ␉␊ |
207 | ␉entry->addr = addr;␊ |
208 | ␉entry->name = malloc(strlen(name)+1);␊ |
209 | ␉strcpy(entry->name, name);␊ |
210 | }␊ |
211 |