Chameleon

Chameleon Svn Source Tree

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

Source at commit 1317 created 9 years 5 months ago.
By meklort, Update ppc boot2 file. File now compiles.
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: 1317