home *** CD-ROM | disk | FTP | other *** search
- /*
- * @(#)readTree.c 1.2 3/18/87
- */
- #include "assert.h"
- #include "nodes.h"
- #include "symbols.h"
- #include "system.h"
- #include "version.h"
- #include "error.h"
- #include <a.out.h>
-
- #undef VERBOSE
-
- NodePtr readTree(fileName)
- char *fileName;
- {
- FILE *inf;
- struct exec h;
- int stsize;
- char *text, *data;
- struct relocation_info *treloc, *dreloc;
- struct nlist *syms;
- static struct sts {
- int size;
- char strings[20];
- } *stringTable;
- register int i;
- register struct relocation_info *rl;
- int numRelocations;
-
- inf = fopen(fileName, "r");
- if (inf == NULL) {
- fprintf(stderr, "Can't open file \"%s\"\n", fileName);
- return (NULL);
- }
- if (fread((char *)&h, sizeof(h), 1, inf) != 1) assert(FALSE);
- #ifdef VERBOSE
- fprintf(stdout, "magic = 0%o\n", h.a_magic);
- fprintf(stdout, "text = %d\n", h.a_text);
- fprintf(stdout, "data = %d\n", h.a_data);
- fprintf(stdout, "bss = %d\n", h.a_bss);
- fprintf(stdout, "syms = %d\n", h.a_syms);
- fprintf(stdout, "entry = 0x%x\n", h.a_entry);
- fprintf(stdout, "trsize = %d\n", h.a_trsize);
- fprintf(stdout, "drsize = %d\n", h.a_drsize);
- troff = N_TXTOFF(h)+h.a_text+h.a_data;
- droff = troff + h.a_trsize;
- fprintf(stdout, "troff = %d\n", troff);
- fprintf(stdout, "droff = %d\n", droff);
- fprintf(stdout, "symoff = %d\n", N_SYMOFF(h));
- fprintf(stdout, "stroff = %d\n", N_STROFF(h));
- #endif
- text = (char *) malloc((unsigned)h.a_text);
- data = (char *) malloc((unsigned)h.a_data);
- treloc = (struct relocation_info *) malloc ((unsigned)h.a_trsize);
- dreloc = (struct relocation_info *) malloc ((unsigned)h.a_drsize);
- syms = (struct nlist *) malloc ((unsigned)h.a_syms);
-
- if (h.a_magic != OMAGIC)
- if (fseek(inf, (long)N_TXTOFF(h), 0) == -1) assert(FALSE);
-
- if (h.a_text != 0) if (fread(text, (int)h.a_text, 1, inf) != 1) assert(FALSE);
- if (h.a_data != 0) if (fread(data, (int)h.a_data, 1, inf) != 1) assert(FALSE);
- if (h.a_trsize != 0) if (fread((char *)treloc, (int)h.a_trsize, 1, inf) != 1) assert(FALSE);
- if (h.a_drsize != 0) if (fread((char *)dreloc, (int)h.a_drsize, 1, inf) != 1) assert(FALSE);
- if (h.a_syms != 0) if (fread((char *)syms, (int)h.a_syms, 1, inf) != 1) assert(FALSE);
-
- if (fread((char *)&stsize, sizeof(int), 1, inf) != 1) assert(FALSE);
- #ifdef VERBOSE
- fprintf(stdout, "stsize = %d\n", stsize);
- #endif
- stringTable = (struct sts *) malloc((unsigned)stsize);
- stringTable->size = stsize;
- if (fread(stringTable->strings, stsize - 4, 1, inf) != 1) assert(FALSE);
- if (fclose(inf) == EOF) assert(FALSE);
- assert(h.a_text == 0);
- assert(h.a_trsize == 0);
- if (*(int *) data != TREEMAGIC || *(int *)(data + 4) != TREEVERSION) {
- fprintf(stderr, "Old version tree, see norm.\n");
- numberOfSemanticErrors ++;
- free(text);
- free((char *)treloc);
- free((char *)dreloc);
- free((char *)syms);
- free((char *)stringTable);
- return (NULL);
- }
- #ifdef VERBOSE
- fprintf(stdout, "Data relocation\n");
- #endif
- numRelocations = h.a_drsize / sizeof (struct relocation_info);
- for (i = 0; i < numRelocations; i++) {
- rl = &dreloc[i];
- #ifdef VERBOSE
- fprintf(stdout, "%3d addr 0x%x sym %d pcrel %d len %d ext %d val %u\n",
- i, rl->r_address, rl->r_symbolnum, rl->r_pcrel,
- rl->r_length, rl->r_extern,
- rl->r_length == 0 ? *(&data[rl->r_address]) :
- rl->r_length == 1 ? *((short *)(&data[rl->r_address])) :
- *((long *)(&data[rl->r_address])));
- #endif
- /* actually do the relocation */
- assert(rl->r_length == 2);
- assert(rl->r_extern == 0);
- assert(rl->r_pcrel == 0);
- assert(rl->r_symbolnum == N_DATA);
- *(long *)(&data[rl->r_address]) += (long) data;
- }
- free(text);
- free((char *)treloc);
- free((char *)dreloc);
- free((char *)syms);
- free((char *)stringTable);
-
- return ((NodePtr) (data + 12));
- }
-