Chameleon

Chameleon Svn Source Tree

Root/tags/2.0/i386/util/dyldsymboltool.c

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
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;
122dylib.header.cputype = CPU_TYPE_X86;
123dylib.header.cpusubtype = /*CPUSUBTYPE_I386*/ 3;
124dylib.header.filetype = MH_DYLIB;
125dylib.header.flags = MH_NOUNDEFS | MH_DYLDLINK | MH_NO_REEXPORTED_DYLIBS;
126
127/* Load Commands - dylib id */
128dylib.dylib_info.cmd = LC_ID_DYLIB;
129dylib.dylib_info.cmdsize = sizeof(struct dylib_command) + sizeof(dylib.module_name);// todo: verify
130dylib.dylib_info.dylib.name.offset = sizeof(struct dylib_command);
131dylib.dylib_info.dylib.timestamp = 0;// TODO: populate with time
132dylib.dylib_info.dylib.current_version = 0;// TODO
133dylib.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
140sprintf(dylib.module_name, "%s", DYLIB_NAME);
141
142/* Load Commands - Symtable */
143dylib.symtab.cmd = LC_SYMTAB;
144dylib.symtab.symoff = sizeof(dylib);
145dylib.symtab.nsyms = num_symbols(symbols);
146dylib.symtab.stroff = sizeof(dylib) + dylib.symtab.nsyms * sizeof(struct nlist);
147dylib.symtab.strsize = string_size(symbols);
148dylib.symtab.cmdsize = sizeof(struct symtab_command);
149
150
151
152FILE* outfile = fopen(argv[argc-1], "w");
153fwrite(&dylib,sizeof(dylib)/* Sizeof header + module name */
154, 1, outfile);
155
156char* symtab = malloc(dylib.symtab.stroff + dylib.symtab.strsize - sizeof(dylib) + 1); // Add extra 1 for last symbol
157bzero(symtab, dylib.symtab.nsyms * sizeof(struct nlist) + dylib.symtab.strsize + 1);
158char* orig = symtab;
159
160//symtab += offset;
161
162
163while(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;
171symtab+= sizeof(struct nlist);
172
173strcpy(orig + dylib.symtab.stroff - sizeof(dylib) + symbols->pos, symbols->name);
174
175symbols = symbols->next;
176}
177
178fwrite(orig,
179dylib.symtab.stroff+// Sizeof symbol nlists
180dylib.symtab.strsize - sizeof(dylib) + 1// sizeof symbol strings
181, 1, outfile);
182
183
184fclose(outfile);
185
186exit(0);
187}
188
189int num_symbols(symbolList_t* list)
190{
191int retVal = 0;
192while(list)
193{
194retVal++;
195list = list->next;
196}
197return retVal;
198}
199
200int string_size(symbolList_t* list)
201{
202int retVal = 0;
203while(list)
204{
205retVal += strlen(list->name)+1;
206list = list->next;
207}
208return retVal;
209
210}
211
212void add_symbol(symbolList_t** list, char* name, uint32_t addr)
213{
214symbolList_t* entry = malloc(sizeof(symbolList_t));
215entry->next = (*list);
216
217if(*list) entry->pos = (*list)->pos + strlen((*list)->name) + 1;
218else entry->pos = 1;
219*list = entry;
220
221entry->addr = addr;
222entry->name = malloc(strlen(name)+1);
223strcpy(entry->name, name);
224}
225

Archive Download this file

Revision: 1808