Index: trunk/i386/util/dyldsymboltool.c =================================================================== --- trunk/i386/util/dyldsymboltool.c (revision 0) +++ trunk/i386/util/dyldsymboltool.c (revision 771) @@ -0,0 +1,210 @@ +/* + * Copyright (c) 2010 Evan Lojewski. All rights reserved. + * + * dyldsymboltool + * + * Generates a dylib file for the dyld implimentation in chameleon + * to load and link. This is used to import the boot symbols into the + * module system. + */ + +#include +#include +#include +#include +#include +#include + + +#define DYLIB_NAME "Symbols" +#define VOID_SYMBOL "_load_all_modules" +#define START_SYMBOL "start" + +typedef struct symbols_dylib +{ + struct mach_header header; + struct dylib_command dylib_info; + char module_name[sizeof(DYLIB_NAME)]; + struct symtab_command symtab; +} symbols_dylib_t; + + +typedef struct symbolList_t +{ + char* name; + uint32_t addr; + int pos; + struct symbolList_t* next; +} symbolList_t; + + +int num_symbols(symbolList_t* list); +int string_size(symbolList_t* list); +void add_symbol(symbolList_t** list, char* name, uint32_t addr); + + +int main(int argc, char *argv[]) +{ + if(argc != 3) + { + fprintf(stderr, "usage: dyldsymboltool bootFile loadAddr outfile\n"); + + exit(-1); + } + + + char line[256]; + char* command = malloc(strlen(argv[1]) + sizeof("nm -g ")); + FILE *fpipe; + + symbols_dylib_t dylib; + symbolList_t* symbols = NULL; + + uint32_t start_addr = 0; + + + + + + + // Parse boot.sys (arg1) to get symtab + sprintf(command, "nm -g %s", argv[1]); // TODO: read boot.sym directly, no need for nm + + if ( !(fpipe = (FILE*)popen(command,"r")) ) + { // If fpipe is NULL + perror("Problems with pipe"); + exit(1); + } + + while ( fgets( line, sizeof line, fpipe)) + { + uint32_t address = 0; + char* addr = strtok(line, " "); + strtok(NULL, " "); + char* name = strtok(NULL, " "); + name[strlen(name)-1] = 0; // remove newline + sscanf(addr, "%x", &address); + if(strcmp(name, VOID_SYMBOL) == 0) start_addr = address; + add_symbol(&symbols, name, address); + } + + + pclose(fpipe); + + if(start_addr == 0) + { + fprintf(stderr, "Unable to locate Symbol.dylib start function\n"); + exit(1); + } + + add_symbol(&symbols, START_SYMBOL, start_addr); + + + /* Header command info */ + dylib.header.ncmds = 2; + dylib.header.sizeofcmds = sizeof(dylib) - sizeof(struct mach_header);// + dylib.symtab.nsyms * sizeof(struct nlist) + dylib.symtab.strsize; + + dylib.header.magic = MH_MAGIC; + dylib.header.cputype = CPU_TYPE_X86; + dylib.header.cpusubtype = /*CPUSUBTYPE_I386*/ 3; + dylib.header.filetype = MH_DYLIB; + dylib.header.flags = MH_NOUNDEFS | MH_DYLDLINK | MH_NO_REEXPORTED_DYLIBS; + + /* Load Commands - dylib id */ + dylib.dylib_info.cmd = LC_ID_DYLIB; + dylib.dylib_info.cmdsize = sizeof(struct dylib_command) + sizeof(dylib.module_name); // todo: verify + dylib.dylib_info.dylib.name.offset = sizeof(struct dylib_command); + dylib.dylib_info.dylib.timestamp = 0; // TODO: populate with time + dylib.dylib_info.dylib.current_version = 0; // TODO + dylib.dylib_info.dylib.compatibility_version = 0; // TODO + + + //int offset = dylib.dylib_info.cmdsize%4 ? 4 - (dylib.dylib_info.cmdsize % 4) : 0; + //dylib.dylib_info.cmdsize += offset; + //dylib.header.sizeofcmds += offset; + + sprintf(dylib.module_name, "%s", DYLIB_NAME); + + /* Load Commands - Symtable */ + dylib.symtab.cmd = LC_SYMTAB; + dylib.symtab.symoff = sizeof(dylib); + dylib.symtab.nsyms = num_symbols(symbols); + dylib.symtab.stroff = sizeof(dylib) + dylib.symtab.nsyms * sizeof(struct nlist); + dylib.symtab.strsize = string_size(symbols); + dylib.symtab.cmdsize = sizeof(struct symtab_command); + + + + FILE* outfile = fopen(argv[2], "w"); + fwrite(&dylib, sizeof(dylib) /* Sizeof header + module name */ + , 1, outfile); + + char* symtab = malloc(dylib.symtab.stroff + dylib.symtab.strsize - sizeof(dylib) + 1); // Add extra 1 for last symbol + bzero(symtab, dylib.symtab.nsyms * sizeof(struct nlist) + dylib.symtab.strsize + 1); + char* orig = symtab; + + //symtab += offset; + + + while(symbols) + { + + ((struct nlist*)symtab)->n_un.n_strx = symbols->pos; + ((struct nlist*)symtab)->n_type = 0xF; // TODO: read from boot.sys + ((struct nlist*)symtab)->n_sect = 0; + ((struct nlist*)symtab)->n_desc = REFERENCE_FLAG_DEFINED; + ((struct nlist*)symtab)->n_value = (uint32_t)symbols->addr; + symtab+= sizeof(struct nlist); + + strcpy(orig + dylib.symtab.stroff - sizeof(dylib) + symbols->pos, symbols->name); + + symbols = symbols->next; + } + + fwrite(orig, + dylib.symtab.stroff + // Sizeof symbol nlists + dylib.symtab.strsize - sizeof(dylib) + 1 // sizeof symbol strings + , 1, outfile); + + + fclose(outfile); + + exit(0); +} + +int num_symbols(symbolList_t* list) +{ + int retVal = 0; + while(list) + { + retVal++; + list = list->next; + } + return retVal; +} + +int string_size(symbolList_t* list) +{ + int retVal = 0; + while(list) + { + retVal += strlen(list->name)+1; + list = list->next; + } + return retVal; + +} + +void add_symbol(symbolList_t** list, char* name, uint32_t addr) +{ + symbolList_t* entry = malloc(sizeof(symbolList_t)); + entry->next = (*list); + + if(*list) entry->pos = (*list)->pos + strlen((*list)->name) + 1; + else entry->pos = 1; + *list = entry; + + entry->addr = addr; + entry->name = malloc(strlen(name)+1); + strcpy(entry->name, name); +} Index: trunk/i386/util/Makefile =================================================================== --- trunk/i386/util/Makefile (revision 770) +++ trunk/i386/util/Makefile (revision 771) @@ -18,7 +18,7 @@ CFILES = machOconv.c ALLSRC = $(CFILES) $(MFILES) $(HFILES) $(EXPORT_HFILES) -PROGRAMS = machOconv bdmesg +PROGRAMS = machOconv bdmesg dyldsymboltool OUTFILES = $(PROGRAMS) @@ -26,24 +26,39 @@ all embedtheme: $(DIRS_NEEDED) $(PROGRAMS) +dyldsymboltool: dyldsymboltool.o32 dyldsymboltool.o64 + @echo "\t[LD32] $@_32" + @$(CC) $(CFLAGS) $(LDFLAGS) $(DEFINES) -arch i386 -o $(SYMROOT)/$(@F)_32 $(OBJROOT)/$(@F).o32 + @echo "\t[LD64] $@_64" + @$(CC) $(CFLAGS) $(LDFLAGS) $(DEFINES) -arch x86_64 -o $(SYMROOT)/$(@F)_64 $(OBJROOT)/$(@F).o64 + @echo "\t[LIPO] $@" + @lipo -create -arch i386 $(SYMROOT)/$(@F)_32 -arch x86_64 $(SYMROOT)/$(@F)_64 -output $(SYMROOT)/$(@F) + @$(RM) $(SYMROOT)/$(@F)_32 $(SYMROOT)/$(@F)_64 + + machOconv: machOconv.o32 machOconv.o64 - $(CC) $(CFLAGS) $(LDFLAGS) $(DEFINES) -arch i386 -o $(SYMROOT)/$(@F)_32 $(OBJROOT)/$(@F).o32 - $(CC) $(CFLAGS) $(LDFLAGS) $(DEFINES) -arch x86_64 -o $(SYMROOT)/$(@F)_64 $(OBJROOT)/$(@F).o64 - lipo -create -arch i386 $(SYMROOT)/$(@F)_32 -arch x86_64 $(SYMROOT)/$(@F)_64 -output $(SYMROOT)/$(@F) - $(RM) $(SYMROOT)/$(@F)_32 $(SYMROOT)/$(@F)_64 + @echo "\t[LD32] $@_32" + @$(CC) $(CFLAGS) $(LDFLAGS) $(DEFINES) -arch i386 -o $(SYMROOT)/$(@F)_32 $(OBJROOT)/$(@F).o32 + @echo "\t[LD64] $@_64" + @$(CC) $(CFLAGS) $(LDFLAGS) $(DEFINES) -arch x86_64 -o $(SYMROOT)/$(@F)_64 $(OBJROOT)/$(@F).o64 + @echo "\t[LIPO] $@" + @lipo -create -arch i386 $(SYMROOT)/$(@F)_32 -arch x86_64 $(SYMROOT)/$(@F)_64 -output $(SYMROOT)/$(@F) + @$(RM) $(SYMROOT)/$(@F)_32 $(SYMROOT)/$(@F)_64 bdmesg: bdmesg.o32 bdmesg.o64 - $(CC) $(CFLAGS) $(LDFLAGS) -framework IOKit -framework CoreFoundation -mmacosx-version-min=10.5 \ + @echo "\t[LD32] $@_32" + @$(CC) $(CFLAGS) $(LDFLAGS) -framework IOKit -framework CoreFoundation -mmacosx-version-min=10.5 \ -arch i386 -o $(SYMROOT)/$(@F)_32 $(OBJROOT)/$(@F).o32 - $(CC) $(CFLAGS) $(LDFLAGS) -framework IOKit -framework CoreFoundation -mmacosx-version-min=10.5 \ + @echo "\t[LD64] $@_64" + @$(CC) $(CFLAGS) $(LDFLAGS) -framework IOKit -framework CoreFoundation -mmacosx-version-min=10.5 \ -arch x86_64 -o $(SYMROOT)/$(@F)_64 $(OBJROOT)/$(@F).o64 - lipo -create -arch i386 $(SYMROOT)/$(@F)_32 -arch x86_64 $(SYMROOT)/$(@F)_64 -output $(SYMROOT)/$(@F) - $(RM) $(SYMROOT)/$(@F)_32 $(SYMROOT)/$(@F)_64 + @echo "\t[LIPO] $@" + @lipo -create -arch i386 $(SYMROOT)/$(@F)_32 -arch x86_64 $(SYMROOT)/$(@F)_64 -output $(SYMROOT)/$(@F) + @$(RM) $(SYMROOT)/$(@F)_32 $(SYMROOT)/$(@F)_64 include ../MakeInc.dir #dependencies --include $(OBJROOT)/Makedep - +-include $(OBJROOT)/Makedep \ No newline at end of file