Chameleon

Chameleon Svn Source Tree

Root/branches/xZenu/src/util/dyldsymboltool.c

Source at commit 1406 created 12 years 10 months ago.
By meklort, Revert drivers.c so that kexts are only loaded when OSBundleRequired is set and that value is not safe mode. Added some comments about it too.
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
23typedef struct symbols_dylib
24{
25struct mach_headerheader;
26struct dylib_commanddylib_info;
27charmodule_name[sizeof(DYLIB_NAME)];
28struct symtab_commandsymtab;
29} symbols_dylib_t;
30
31
32typedef struct symbolList_t
33{
34char*name;
35uint32_taddr;
36intpos;
37struct symbolList_t*next;
38} symbolList_t;
39
40
41int num_symbols(symbolList_t* list);
42int string_size(symbolList_t* list);
43void add_symbol(symbolList_t** list, char* name, uint32_t addr);
44
45
46int main(int argc, char *argv[])
47{
48if(argc < 3)
49{
50fprintf(stderr, "usage: dyldsymboltool obj1 [obj2 ...] outfile\n");
51
52exit(-1);
53}
54
55
56
57symbols_dylib_t dylib;
58symbolList_t*symbols = NULL;
59
60uint32_t start_addr = 0;
61
62
63
64
65 int i;
66for(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
106if(start_addr == 0)
107{
108fprintf(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 */
118dylib.header.ncmds = 2;
119dylib.header.sizeofcmds = sizeof(dylib) - sizeof(struct mach_header);// + dylib.symtab.nsyms * sizeof(struct nlist) + dylib.symtab.strsize;
120
121dylib.header.magic = MH_MAGIC;
122// TODO: make configurable *or* read from orig file
123dylib.header.cputype = CPU_TYPE_X86;
124dylib.header.cpusubtype = /*CPUSUBTYPE_I386*/ 3;
125dylib.header.filetype = MH_DYLIB;
126dylib.header.flags = MH_NOUNDEFS | MH_DYLDLINK | MH_NO_REEXPORTED_DYLIBS;
127
128/* Load Commands - dylib id */
129dylib.dylib_info.cmd = LC_ID_DYLIB;
130dylib.dylib_info.cmdsize = sizeof(struct dylib_command) + sizeof(dylib.module_name);// todo: verify
131dylib.dylib_info.dylib.name.offset = sizeof(struct dylib_command);
132dylib.dylib_info.dylib.timestamp = 0;// TODO: populate with time
133dylib.dylib_info.dylib.current_version = 0;// TODO
134dylib.dylib_info.dylib.compatibility_version = 0;// TODO
135
136
137//int offset = dylib.dylib_info.cmdsize%4 ? 4 - (dylib.dylib_info.cmdsize % 4) : 0;
138//dylib.dylib_info.cmdsize += offset;
139//dylib.header.sizeofcmds += offset;
140
141sprintf(dylib.module_name, "%s", DYLIB_NAME);
142
143/* Load Commands - Symtable */
144dylib.symtab.cmd = LC_SYMTAB;
145dylib.symtab.symoff = sizeof(dylib);
146dylib.symtab.nsyms = num_symbols(symbols);
147dylib.symtab.stroff = sizeof(dylib) + dylib.symtab.nsyms * sizeof(struct nlist);
148dylib.symtab.strsize = string_size(symbols);
149dylib.symtab.cmdsize = sizeof(struct symtab_command);
150
151
152
153FILE* outfile = fopen(argv[argc-1], "w");
154fwrite(&dylib,sizeof(dylib)/* Sizeof header + module name */
155, 1, outfile);
156
157char* symtab = malloc(dylib.symtab.stroff + dylib.symtab.strsize - sizeof(dylib) + 1); // Add extra 1 for last symbol
158memset(symtab, 0, dylib.symtab.nsyms * sizeof(struct nlist) + dylib.symtab.strsize + 1);
159char* orig = symtab;
160
161//symtab += offset;
162
163
164while(symbols)
165{
166
167((struct nlist*)symtab)->n_un.n_strx = symbols->pos;
168((struct nlist*)symtab)->n_type = 0xF;// TODO: read from boot.sys
169((struct nlist*)symtab)->n_sect = 0;
170((struct nlist*)symtab)->n_desc = REFERENCE_FLAG_DEFINED;
171((struct nlist*)symtab)->n_value = (uint32_t)symbols->addr;
172symtab+= sizeof(struct nlist);
173
174strcpy(orig + dylib.symtab.stroff - sizeof(dylib) + symbols->pos, symbols->name);
175
176symbols = symbols->next;
177}
178
179fwrite(orig,
180dylib.symtab.stroff+// Sizeof symbol nlists
181dylib.symtab.strsize - sizeof(dylib) + 1// sizeof symbol strings
182, 1, outfile);
183
184
185fclose(outfile);
186
187exit(0);
188}
189
190int num_symbols(symbolList_t* list)
191{
192int retVal = 0;
193while(list)
194{
195retVal++;
196list = list->next;
197}
198return retVal;
199}
200
201int string_size(symbolList_t* list)
202{
203int retVal = 0;
204while(list)
205{
206retVal += strlen(list->name)+1;
207list = list->next;
208}
209return retVal;
210
211}
212
213void add_symbol(symbolList_t** list, char* name, uint32_t addr)
214{
215symbolList_t* entry = malloc(sizeof(symbolList_t));
216entry->next = (*list);
217
218if(*list) entry->pos = (*list)->pos + strlen((*list)->name) + 1;
219else entry->pos = 1;
220*list = entry;
221
222entry->addr = addr;
223entry->name = malloc(strlen(name)+1);
224strcpy(entry->name, name);
225}
226

Archive Download this file

Revision: 1406