123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640 |
- /* $Id$ */
- /* a.out file reading ... */
- #include "rd.h"
- #include "misc.h"
- #include <assert.h>
- #include <alloc.h>
- #if defined(__sun)
- #if ! defined(sun)
- #define sun
- #endif
- #endif
- #if defined(__i386)
- #define i386
- #endif
- #if defined(__mc68020)
- #define mc68020
- #endif
- #if defined(__sparc)
- #if ! defined(sparc)
- #define sparc
- #endif
- #endif
- #if defined(__vax)
- #define vax
- #endif
- #if defined(__solaris) || defined(__solaris__)
- #define solaris
- #endif
- #if ! defined(solaris)
- #if defined(sun) || defined(vax)
- struct exec {
- #ifdef sun
- short a_x;
- unsigned short a_magic;
- #else
- unsigned long a_magic;
- #endif
- unsigned long a_text;
- unsigned long a_data;
- unsigned long a_bss;
- unsigned long a_syms;
- unsigned long a_entry;
- unsigned long a_trsize;
- unsigned long a_drsize;
- };
- #define OMAGIC 0407
- #define NMAGIC 0410
- #define ZMAGIC 0413
- #define N_BADMAG(x) \
- ((x).a_magic!=OMAGIC && (x).a_magic!=NMAGIC && (x).a_magic!=ZMAGIC)
- #ifdef sun
- #define N_TXTOFF(x) ((x).a_magic == ZMAGIC ? 0 : sizeof(struct exec))
- #else
- #define N_TXTOFF(x) (sizeof(struct exec))
- #endif
- #define N_STROFF(x) (N_TXTOFF(x)+(x).a_text+(x).a_data+(x).a_trsize+(x).a_drsize+(x).a_syms)
- #ifdef sparc
- #define RELOC_SIZE 12
- #else
- #define RELOC_SIZE 8
- #endif
- struct nlist {
- union {
- char *n_name;
- long n_strx;
- } n_un;
- unsigned char n_type;
- char n_other;
- short n_desc;
- unsigned long n_value;
- };
- #define N_UNDF 0
- #define N_ABS 2
- #define N_TEXT 4
- #define N_DATA 6
- #define N_BSS 8
- #define N_FN 0x1e
- #define N_EXT 01
- #define N_STAB 0xe0
- #include <stdio.h>
- static FILE *inf;
- static struct exec bh;
- static long seg_strings;
- static struct outhead hh;
- #define readf(a, b, c) (fread((char *)(a), (b), (int)(c), inf))
- int
- rd_open(f)
- char *f;
- {
- if ((inf = fopen(f, "r")) == NULL) return 0;
- return 1;
- }
- rd_ohead(h)
- struct outhead *h;
- {
- if (! readf(&bh, sizeof(struct exec), 1)) rd_fatal();
- if (N_BADMAG(bh)) rd_fatal();
- h->oh_magic = O_CONVERTED;
- h->oh_stamp = 0;
- h->oh_nsect = 4;
- h->oh_nname = 3 + bh.a_syms / sizeof(struct nlist);
- h->oh_nrelo = (bh.a_trsize + bh.a_drsize) / RELOC_SIZE;
- h->oh_flags = h->oh_nrelo ? HF_LINK : 0;
- #if defined(sun)
- if (bh.a_magic == ZMAGIC) bh.a_text -= sizeof(struct exec);
- #endif
- h->oh_nemit = bh.a_text + bh.a_data;
- #if defined(sun)
- if (bh.a_magic == ZMAGIC) bh.a_text += sizeof(struct exec);
- #endif
- fseek(inf, N_STROFF(bh), 0);
- h->oh_nchar = getw(inf) + 6 + 6 + 5 - 4; /* ".text", ".data", ".bss",
- minus the size word */
- seg_strings = h->oh_nchar - 17;
- fseek(inf, N_TXTOFF(bh)+bh.a_text+bh.a_data, 0);
- hh = *h;
- #if defined(sun)
- if (bh.a_magic == ZMAGIC) bh.a_text -= sizeof(struct exec);
- #endif
- }
- /*ARGSUSED1*/
- rd_name(names, count)
- register struct outname *names;
- unsigned int count; /* ignored; complete namelist is read */
- {
- names->on_valu = 0; names->on_foff = seg_strings + OFF_CHAR(hh);
- names->on_desc = 0; names->on_type = S_MIN | S_SCT;
- names++;
- names->on_valu = 0; names->on_foff = seg_strings + OFF_CHAR(hh) + 6;
- names->on_desc = 0; names->on_type = (S_MIN+2) | S_SCT;
- names++;
- names->on_valu = 0; names->on_foff = seg_strings + OFF_CHAR(hh) + 12;
- names->on_desc = 0; names->on_type = (S_MIN+3) | S_SCT;
- names++;
- count = bh.a_syms / sizeof(struct nlist);
- while (count > 0) {
- struct nlist n;
- if (! readf(&n, sizeof(struct nlist), 1)) rd_fatal();
- count--;
- names->on_desc = n.n_desc;
- if (n.n_un.n_strx - 4 < 0) names->on_foff = 0;
- else names->on_foff = OFF_CHAR(hh) - 4 + n.n_un.n_strx;
- names->on_valu = n.n_value;
- if (n.n_type & N_STAB) {
- names->on_type = n.n_type << 8;
- names++;
- continue;
- }
- switch(n.n_type & ~N_EXT) {
- case N_ABS:
- names->on_type = S_ABS;
- break;
- case N_TEXT:
- names->on_type = S_MIN;
- break;
- case N_DATA:
- names->on_type = S_MIN + 2;
- names->on_valu -= bh.a_text;
- break;
- case N_BSS:
- names->on_type = S_MIN + 3;
- names->on_valu -= bh.a_text + bh.a_data;
- break;
- case N_UNDF:
- if (! names->on_valu) {
- names->on_type = S_UND;
- break;
- }
- names->on_type = (S_MIN + 3) | S_COM;
- break;
- case N_FN:
- names->on_type = S_FIL;
- break;
- default:
- rd_fatal();
- }
- if (n.n_type & N_EXT) names->on_type |= S_EXT;
- names++;
- }
- }
- extern char *strcpy();
- rd_string(strings, count)
- register char *strings;
- long count;
- {
- #if defined(sun)
- if (bh.a_magic == ZMAGIC) bh.a_text += sizeof(struct exec);
- #endif
- fseek(inf, N_STROFF(bh)+4, 0);
- if (! readf(strings, (int)count-17, 1)) rd_fatal();
- strings += count-17;
- strcpy(strings, ".text"); strings += 6;
- strcpy(strings, ".data"); strings += 6;
- strcpy(strings, ".bss");
- }
- rd_close()
- {
- fclose(inf);
- }
- #endif
- #endif
- #if defined(i386)
- #include <stdio.h>
- #include <alloc.h>
- struct xexec {
- unsigned short x_magic;
- #define XMAGIC 01006
- unsigned short x_ext;
- long x_text;
- long x_data;
- long x_bss;
- long x_syms;
- long x_reloc;
- long x_entry;
- char x_cpu;
- char x_relsym;
- unsigned short x_renv;
- };
- struct xseg {
- unsigned short xs_type;
- unsigned short xs_attr;
- unsigned short xs_seg;
- unsigned short xs_sres;
- long xs_filpos;
- long xs_psize;
- long xs_vsize;
- long xs_rbase;
- long xs_lres;
- long xs_lres2;
- };
- static FILE *inf;
- static struct outname *names;
- static char *strings;
- #define readf(a, b, c) (fread((char *)(a), (b), (int)(c), inf))
- #define getshort(val, p) (val = (*p++ & 0377), val |= (*p++ & 0377) << 8)
- #define getlong(val, p) (val = (*p++ & 0377), \
- val |= (*p++ & 0377) << 8, \
- val |= (*p++ & 0377L) << 16, \
- val |= (*p++ & 0377L) << 24)
- static
- get_names(h, sz)
- struct outhead *h;
- long sz;
- {
- register char *xnms = malloc((unsigned) sz);
- register char *p;
- register struct outname *onm = (struct outname *) malloc((((unsigned)sz+8)/9)*sizeof(struct outname));
- struct xnm {
- unsigned short s_type, s_seg;
- long s_value;
- } xnm;
- if (xnms == 0 || onm == 0) No_Mem();
- if (!readf(xnms, (unsigned) sz, 1)) rd_fatal();
- names = onm;
- strings = p = xnms;
- while (sz > 0) {
- getshort(xnm.s_type, xnms);
- getshort(xnm.s_seg, xnms);
- getlong(xnm.s_value, xnms);
- onm->on_desc = 0;
- if (xnm.s_type & S_STB) {
- onm->on_type = xnm.s_type;
- onm->on_desc = xnm.s_seg;
- }
- else {
- switch(xnm.s_type & 0x1f) {
- case 0x1f:
- onm->on_type = S_FIL;
- break;
- case 0x8:
- onm->on_type = S_SCT;
- break;
- case 0:
- onm->on_type = S_UND;
- break;
- case 1:
- onm->on_type = S_ABS;
- break;
- default:
- onm->on_type = xnm.s_type & 0x1f;
- break;
- }
- }
- if (xnm.s_type & 0x20) onm->on_type |= S_EXT;
- onm->on_valu = xnm.s_value;
- sz -= 9;
- if (*xnms == '\0') {
- onm->on_foff = -1;
- xnms++;
- }
- else {
- onm->on_foff = p - strings;
- while (*p++ = *xnms++) sz--;
- }
- onm++;
- }
- h->oh_nname = onm - names;
- h->oh_nchar = p - strings;
- while (--onm >= names) {
- if (onm->on_foff == -1) onm->on_foff = 0;
- else onm->on_foff += OFF_CHAR(*h);
- }
- names = (struct outname *) realloc((char *) names, h->oh_nname * sizeof(struct outname));
- strings = realloc(strings, (unsigned) h->oh_nchar);
- }
- int
- rd_open(f)
- char *f;
- {
- if ((inf = fopen(f, "r")) == NULL) return 0;
- return 1;
- }
- rd_ohead(h)
- struct outhead *h;
- {
- int sepid;
- struct xexec xhdr;
- struct xseg xseg[3];
- if (! readf(&xhdr, sizeof(xhdr), 1)) rd_fatal();
- if (xhdr.x_magic != XMAGIC) rd_fatal();
- h->oh_magic = O_CONVERTED;
- h->oh_stamp = 0;
- h->oh_nsect = 4;
- h->oh_nrelo = 0;
- h->oh_flags = 0;
- h->oh_nemit = xhdr.x_text+xhdr.x_data;
- sepid = (xhdr.x_renv & 02) ? 1 : 0;
- fseek(inf, 0140L, 0);
- if (! readf(&xseg[0], sizeof(xseg[0]), sepid + 2)) rd_fatal();
- fseek(inf, xseg[sepid+1].xs_filpos, 0);
- get_names(h, xhdr.x_syms);
- fclose(inf);
- }
- rd_name(nm, count)
- struct outname *nm;
- unsigned int count;
- {
- memcpy(nm, names, (int) count * sizeof(struct outname));
- free((char *) names);
- }
- rd_string(nm, count)
- char *nm;
- long count;
- {
- memcpy(nm, strings, (int) count);
- free((char *) strings);
- }
- rd_close()
- {
- }
- #endif
- #if defined(solaris)
- #include <libelf.h>
- #include <sys/elf_M32.h>
- #include <stb.h>
- struct nlist {
- union {
- char *n_name;
- long n_strx;
- } n_un;
- unsigned char n_type;
- char n_other;
- short n_desc;
- unsigned long n_value;
- };
- static int fildes;
- static Elf *elf;
- static Elf32_Ehdr *ehdr;
- static struct nlist *dbtab;
- static char *dbstringtab;
- static Elf32_Sym *tab;
- static char *stringtab;
- static struct outhead hh;
- static struct nlist *maxdn;
- #define N_STAB 0xe0
- int
- rd_open(f)
- char *f;
- {
- if ((fildes = open(f, 0)) < 0) return 0;
- elf_version(EV_CURRENT);
- if ((elf = elf_begin(fildes, ELF_C_READ, (Elf *) 0)) == 0) {
- close(fildes);
- return 0;
- }
- if ((ehdr = elf32_getehdr(elf)) == NULL) {
- elf_end(elf);
- close(fildes);
- return 0;
- }
- return 1;
- }
- rd_ohead(h)
- struct outhead *h;
- {
- Elf_Scn *scn = 0;
- Elf32_Shdr *shdr;
- Elf_Data *sectnames;
- Elf_Data *dt;
- register struct nlist *dn;
- register Elf32_Sym *n;
- long text_offset, data_offset, bss_offset, fun_offset;
- int fixnamoff = 0, newfixnamoff = 0;
- h->oh_magic = O_CONVERTED;
- h->oh_stamp = 0;
- h->oh_nsect = 4;
- h->oh_nrelo = 0;
- h->oh_flags = 0;
- h->oh_nemit = 0;
- h->oh_nname = 0;
- scn = elf_getscn(elf, (size_t) ehdr->e_shstrndx);
- sectnames = elf_getdata(scn, (Elf_Data *) 0);
- scn = 0;
- while ((scn = elf_nextscn(elf, scn)) != 0) {
- shdr = elf32_getshdr(scn);
- switch(shdr->sh_type) {
- case SHT_PROGBITS:
- /* Get stab symbol table. Elf does not know about it,
- and, unfortunately, no relocation is done on it.
- */
- h->oh_nemit += shdr->sh_size;
- if (! strcmp(".stab", (char *)(sectnames->d_buf)+shdr->sh_name)) {
- dt = elf_getdata(scn, (Elf_Data *) 0);
- if (dt->d_size == 0) {
- fatal("(part of) symbol table is missing");
- }
- dbtab = (struct nlist *) Malloc(dt->d_size);
- memcpy((char *) dbtab, (char *) dt->d_buf, dt->d_size);
- maxdn = (struct nlist *)((char *)dbtab+dt->d_size);
- break;
- }
- break;
- case SHT_STRTAB:
- /* Get the stab string table, as well as the usual string
- table.
- */
- if (! strcmp(".stabstr", (char *)(sectnames->d_buf)+shdr->sh_name)) {
- dt = elf_getdata(scn, (Elf_Data *) 0);
- if (dt->d_size == 0) {
- fatal("(part of) symbol table is missing");
- }
- dbstringtab = dt->d_buf;
- h->oh_nchar = dt->d_size;
- break;
- }
- if (! strcmp(".strtab", (char *)(sectnames->d_buf)+shdr->sh_name)) {
- dt = elf_getdata(scn, (Elf_Data *) 0);
- if (dt->d_size == 0) {
- fatal("(part of) symbol table is missing");
- }
- stringtab = dt->d_buf;
- }
- break;
- case SHT_SYMTAB:
- /* Get the symbol table. */
- if (! strcmp(".symtab", (char *)(sectnames->d_buf)+shdr->sh_name)) {
- dt = elf_getdata(scn, (Elf_Data *) 0);
- if (dt->d_size == 0) {
- fatal("(part of) symbol table is missing");
- }
- tab = dt->d_buf;
- }
- break;
- }
- }
- /* Convert offsets in stab symbol table. */
- n = tab;
- dn = dbtab;
- while (dn < maxdn) {
- int i;
- if (dn->n_un.n_strx) {
- dn->n_un.n_strx += fixnamoff;
- }
- switch(dn->n_type) {
- case 0:
- fixnamoff = newfixnamoff;
- newfixnamoff += dn->n_value;
- break;
- case N_SO:
- h->oh_nname++;
- i = 0;
- while (i < 3) {
- while (stringtab[n->st_name] != 'B') n++;
- if (! strcmp("Btext.text", &(stringtab[n->st_name]))) {
- text_offset = n->st_value; i++;
- }
- else if (! strcmp("Bdata.data", &(stringtab[n->st_name]))) {
- data_offset = n->st_value; i++;
- }
- else if (! strcmp("Bbss.bss", &(stringtab[n->st_name]))) {
- bss_offset = n->st_value; i++;
- }
- n++;
- }
- break;
- case N_GSYM:
- h->oh_nname++;
- /* Fortunately, we don't use this in ACK, so we don't
- have to handle it here. The problem is that we don't know
- which segment it comes from.
- */
- break;
- case N_STSYM:
- h->oh_nname++;
- dn->n_value += data_offset;
- break;
- case N_LCSYM:
- h->oh_nname++;
- dn->n_value += bss_offset;
- break;
- case N_FUN:
- h->oh_nname++;
- dn->n_value += text_offset;
- fun_offset = dn->n_value;
- break;
- case N_MAIN:
- dn->n_value += text_offset;
- break;
- case N_LBRAC:
- case N_RBRAC:
- case N_SLINE:
- h->oh_nname++;
- dn->n_value += fun_offset;
- break;
- case N_SOL:
- case N_EINCL:
- case N_BINCL:
- case N_PSYM:
- case N_SSYM:
- case N_SCOPE:
- case N_RSYM:
- case N_LSYM:
- h->oh_nname++;
- /* Nothing to be done. */
- break;
- }
- dn++;
- }
- hh = *h;
- }
- rd_name(nm, count)
- struct outname *nm;
- unsigned int count;
- {
- register struct nlist *dn = dbtab;
- register struct outname *n = nm;
- while (dn < maxdn) {
- if (dn->n_type & N_STAB) {
- n->on_type = dn->n_type << 8;
- n->on_valu = dn->n_value;
- n->on_desc = dn->n_desc;
- if (dn->n_un.n_strx == 0) n->on_foff = 0;
- else n->on_foff = OFF_CHAR(hh) + dn->n_un.n_strx;
- n++;
- }
- dn++;
- }
- free(dbtab);
- }
- rd_string(nm, count)
- char *nm;
- long count;
- {
- memcpy(nm, dbstringtab, count);
- }
- rd_close()
- {
- elf_end(elf);
- close(fildes);
- }
- #endif
|