Chameleon

Chameleon Svn Source Tree

Root/branches/meklortOld/i386/util/dyldsymboltool.c

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

Archive Download this file

Revision: 1146