/* Copyright (C) 1995 Charles Sandmann (sandmann@clio.rice.edu) This software may be freely distributed with above copyright, no warranty. Based on code by DJ Delorie, it's really his, enhanced, bugs fixed. */ #include #include #include /* Linux violates POSIX.1 and defines this, but it shouldn't. We fix it. */ #undef _POSIX_SOURCE #include "../../include/coff.h" #include "../../include/sys/dxe.h" /* This next function is needed for cross-compiling when the machine isn't little-endian like the i386 */ static void dosswap(void *vdata, const char *pattern) { static int endian = 1; unsigned char *data, c; if (*(unsigned char *)(&endian) == 1) return; data = (unsigned char *)vdata; while (*pattern) { if (*pattern >= '1' && *pattern <= '9') { data += (*pattern-'0'); } else if (*pattern == 's') { c = data[1]; data[1] = data[0]; data[0] = c; data += 2; } else if (*pattern == 'l') { c = data[3]; data[3] = data[0]; data[0] = c; c = data[1]; data[1] = data[2]; data[2] = c; data += 4; } else data++; pattern++; } } static void exit_cleanup(void) { remove("dxe__tmp.o"); } int main(int argc, char **argv) { int errors = 0; unsigned bss_start = 0; FILHDR fh; FILE *input_f, *output_f; SCNHDR sc; char *data, *strings; SYMENT *sym; RELOC *relocs; int strsz; size_t i; dxe_header dh; if (argc < 4) { printf("Usage: dxegen output.dxe symbol input.o [input2.o ... -lgcc -lc]\n"); return 1; } input_f = fopen(argv[3], "rb"); if (!input_f) { perror(argv[3]); return 1; } fread(&fh, 1, FILHSZ, input_f); dosswap(&fh, "sslllss"); if (fh.f_nscns != 1 || argc > 4) { char command[1024], *libdir; fclose(input_f); #ifdef DXE_LD strcpy(command, DXE_LD); #else strcpy(command, "ld"); #endif strcat(command, " -X -S -r -o dxe__tmp.o -L"); libdir = getenv("DXE_LD_LIBRARY_PATH"); if (libdir) strcat(command, libdir); else { libdir = getenv("DJDIR"); if (!libdir) { fprintf(stderr, "Error: neither DXE_LD_LIBRARY_PATH nor DJDIR are set in environment\n"); exit(1); } strcat(command, libdir); strcat(command, "/lib"); } strcat(command, " "); for(i=3;argv[i];i++) { strcat(command, argv[i]); strcat(command, " "); } strcat(command," -T dxe.ld "); printf("%s\n",command); i = system(command); if(i) return i; input_f = fopen("dxe__tmp.o", "rb"); if (!input_f) { perror(argv[3]); return 1; } else atexit(exit_cleanup); fread(&fh, 1, FILHSZ, input_f); dosswap(&fh, "sslllss"); if (fh.f_nscns != 1) { printf("Error: input file has more than one section; use -M for map\n"); return 1; } } fseek(input_f, fh.f_opthdr, 1); fread(&sc, 1, SCNHSZ, input_f); dosswap(&sc, "8llllllssl"); dh.magic = DXE_MAGIC; dh.symbol_offset = -1; dh.element_size = sc.s_size; dh.nrelocs = sc.s_nreloc; data = malloc(sc.s_size); fseek(input_f, sc.s_scnptr, 0); fread(data, 1, sc.s_size, input_f); sym = malloc(sizeof(SYMENT)*fh.f_nsyms); fseek(input_f, fh.f_symptr, 0); fread(sym, fh.f_nsyms, SYMESZ, input_f); fread(&strsz, 1, 4, input_f); dosswap(&strsz, "l"); strings = malloc(strsz); fread(strings+4, 1, strsz-4, input_f); strings[0] = 0; for (i=0; i