1 /* $Id: rd.c,v 1.7 1994/06/24 11:00:57 ceriel Exp $ */
3 /* a.out file reading ... */
20 #if defined(__mc68020)
34 #if defined(__solaris) || defined(__solaris__)
38 #if ! defined(solaris)
39 #if defined(sun) || defined(vax)
44 unsigned short a_magic;
46 unsigned long a_magic;
52 unsigned long a_entry;
53 unsigned long a_trsize;
54 unsigned long a_drsize;
62 ((x).a_magic!=OMAGIC && (x).a_magic!=NMAGIC && (x).a_magic!=ZMAGIC)
64 #define N_TXTOFF(x) ((x).a_magic == ZMAGIC ? 0 : sizeof(struct exec))
66 #define N_TXTOFF(x) (sizeof(struct exec))
68 #define N_STROFF(x) (N_TXTOFF(x)+(x).a_text+(x).a_data+(x).a_trsize+(x).a_drsize+(x).a_syms)
84 unsigned long n_value;
101 static struct exec bh;
102 static long seg_strings;
103 static struct outhead hh;
105 #define readf(a, b, c) (fread((char *)(a), (b), (int)(c), inf))
111 if ((inf = fopen(f, "r")) == NULL) return 0;
118 if (! readf(&bh, sizeof(struct exec), 1)) rd_fatal();
119 if (N_BADMAG(bh)) rd_fatal();
121 h->oh_magic = O_CONVERTED;
124 h->oh_nname = 3 + bh.a_syms / sizeof(struct nlist);
125 h->oh_nrelo = (bh.a_trsize + bh.a_drsize) / RELOC_SIZE;
126 h->oh_flags = h->oh_nrelo ? HF_LINK : 0;
128 if (bh.a_magic == ZMAGIC) bh.a_text -= sizeof(struct exec);
130 h->oh_nemit = bh.a_text + bh.a_data;
132 if (bh.a_magic == ZMAGIC) bh.a_text += sizeof(struct exec);
134 fseek(inf, N_STROFF(bh), 0);
135 h->oh_nchar = getw(inf) + 6 + 6 + 5 - 4; /* ".text", ".data", ".bss",
136 minus the size word */
137 seg_strings = h->oh_nchar - 17;
138 fseek(inf, N_TXTOFF(bh)+bh.a_text+bh.a_data, 0);
141 if (bh.a_magic == ZMAGIC) bh.a_text -= sizeof(struct exec);
146 rd_name(names, count)
147 register struct outname *names;
148 unsigned int count; /* ignored; complete namelist is read */
150 names->on_valu = 0; names->on_foff = seg_strings + OFF_CHAR(hh);
151 names->on_desc = 0; names->on_type = S_MIN | S_SCT;
153 names->on_valu = 0; names->on_foff = seg_strings + OFF_CHAR(hh) + 6;
154 names->on_desc = 0; names->on_type = (S_MIN+2) | S_SCT;
156 names->on_valu = 0; names->on_foff = seg_strings + OFF_CHAR(hh) + 12;
157 names->on_desc = 0; names->on_type = (S_MIN+3) | S_SCT;
159 count = bh.a_syms / sizeof(struct nlist);
163 if (! readf(&n, sizeof(struct nlist), 1)) rd_fatal();
165 names->on_desc = n.n_desc;
166 if (n.n_un.n_strx - 4 < 0) names->on_foff = 0;
167 else names->on_foff = OFF_CHAR(hh) - 4 + n.n_un.n_strx;
168 names->on_valu = n.n_value;
170 if (n.n_type & N_STAB) {
171 names->on_type = n.n_type << 8;
175 switch(n.n_type & ~N_EXT) {
177 names->on_type = S_ABS;
180 names->on_type = S_MIN;
183 names->on_type = S_MIN + 2;
184 names->on_valu -= bh.a_text;
187 names->on_type = S_MIN + 3;
188 names->on_valu -= bh.a_text + bh.a_data;
191 if (! names->on_valu) {
192 names->on_type = S_UND;
195 names->on_type = (S_MIN + 3) | S_COM;
198 names->on_type = S_FIL;
203 if (n.n_type & N_EXT) names->on_type |= S_EXT;
208 extern char *strcpy();
210 rd_string(strings, count)
211 register char *strings;
215 if (bh.a_magic == ZMAGIC) bh.a_text += sizeof(struct exec);
217 fseek(inf, N_STROFF(bh)+4, 0);
218 if (! readf(strings, (int)count-17, 1)) rd_fatal();
220 strcpy(strings, ".text"); strings += 6;
221 strcpy(strings, ".data"); strings += 6;
222 strcpy(strings, ".bss");
238 unsigned short x_magic;
240 unsigned short x_ext;
249 unsigned short x_renv;
253 unsigned short xs_type;
254 unsigned short xs_attr;
255 unsigned short xs_seg;
256 unsigned short xs_sres;
266 static struct outname *names;
267 static char *strings;
269 #define readf(a, b, c) (fread((char *)(a), (b), (int)(c), inf))
271 #define getshort(val, p) (val = (*p++ & 0377), val |= (*p++ & 0377) << 8)
272 #define getlong(val, p) (val = (*p++ & 0377), \
273 val |= (*p++ & 0377) << 8, \
274 val |= (*p++ & 0377L) << 16, \
275 val |= (*p++ & 0377L) << 24)
281 register char *xnms = malloc((unsigned) sz);
283 register struct outname *onm = (struct outname *) malloc((((unsigned)sz+8)/9)*sizeof(struct outname));
285 unsigned short s_type, s_seg;
289 if (xnms == 0 || onm == 0) No_Mem();
290 if (!readf(xnms, (unsigned) sz, 1)) rd_fatal();
295 getshort(xnm.s_type, xnms);
296 getshort(xnm.s_seg, xnms);
297 getlong(xnm.s_value, xnms);
299 if (xnm.s_type & S_STB) {
300 onm->on_type = xnm.s_type;
301 onm->on_desc = xnm.s_seg;
304 switch(xnm.s_type & 0x1f) {
306 onm->on_type = S_FIL;
309 onm->on_type = S_SCT;
312 onm->on_type = S_UND;
315 onm->on_type = S_ABS;
318 onm->on_type = xnm.s_type & 0x1f;
322 if (xnm.s_type & 0x20) onm->on_type |= S_EXT;
323 onm->on_valu = xnm.s_value;
330 onm->on_foff = p - strings;
331 while (*p++ = *xnms++) sz--;
335 h->oh_nname = onm - names;
336 h->oh_nchar = p - strings;
337 while (--onm >= names) {
338 if (onm->on_foff == -1) onm->on_foff = 0;
339 else onm->on_foff += OFF_CHAR(*h);
341 names = (struct outname *) realloc((char *) names, h->oh_nname * sizeof(struct outname));
342 strings = realloc(strings, (unsigned) h->oh_nchar);
349 if ((inf = fopen(f, "r")) == NULL) return 0;
360 if (! readf(&xhdr, sizeof(xhdr), 1)) rd_fatal();
361 if (xhdr.x_magic != XMAGIC) rd_fatal();
362 h->oh_magic = O_CONVERTED;
367 h->oh_nemit = xhdr.x_text+xhdr.x_data;
368 sepid = (xhdr.x_renv & 02) ? 1 : 0;
369 fseek(inf, 0140L, 0);
370 if (! readf(&xseg[0], sizeof(xseg[0]), sepid + 2)) rd_fatal();
371 fseek(inf, xseg[sepid+1].xs_filpos, 0);
372 get_names(h, xhdr.x_syms);
380 memcpy(nm, names, (int) count * sizeof(struct outname));
381 free((char *) names);
388 memcpy(nm, strings, (int) count);
389 free((char *) strings);
399 #include <sys/elf_M32.h>
407 unsigned char n_type;
410 unsigned long n_value;
415 static Elf32_Ehdr *ehdr;
416 static struct nlist *dbtab;
417 static char *dbstringtab;
418 static Elf32_Sym *tab;
419 static char *stringtab;
420 static struct outhead hh;
421 static struct nlist *maxdn;
429 if ((fildes = open(f, 0)) < 0) return 0;
430 elf_version(EV_CURRENT);
431 if ((elf = elf_begin(fildes, ELF_C_READ, (Elf *) 0)) == 0) {
435 if ((ehdr = elf32_getehdr(elf)) == NULL) {
450 register struct nlist *dn;
451 register Elf32_Sym *n;
452 long text_offset, data_offset, bss_offset, fun_offset;
453 int fixnamoff = 0, newfixnamoff = 0;
455 h->oh_magic = O_CONVERTED;
463 scn = elf_getscn(elf, (size_t) ehdr->e_shstrndx);
464 sectnames = elf_getdata(scn, (Elf_Data *) 0);
467 while ((scn = elf_nextscn(elf, scn)) != 0) {
468 shdr = elf32_getshdr(scn);
469 switch(shdr->sh_type) {
471 /* Get stab symbol table. Elf does not know about it,
472 and, unfortunately, no relocation is done on it.
474 h->oh_nemit += shdr->sh_size;
475 if (! strcmp(".stab", (char *)(sectnames->d_buf)+shdr->sh_name)) {
476 dt = elf_getdata(scn, (Elf_Data *) 0);
477 if (dt->d_size == 0) {
478 fatal("(part of) symbol table is missing");
480 dbtab = (struct nlist *) Malloc(dt->d_size);
481 memcpy((char *) dbtab, (char *) dt->d_buf, dt->d_size);
482 maxdn = (struct nlist *)((char *)dbtab+dt->d_size);
488 /* Get the stab string table, as well as the usual string
491 if (! strcmp(".stabstr", (char *)(sectnames->d_buf)+shdr->sh_name)) {
492 dt = elf_getdata(scn, (Elf_Data *) 0);
493 if (dt->d_size == 0) {
494 fatal("(part of) symbol table is missing");
496 dbstringtab = dt->d_buf;
497 h->oh_nchar = dt->d_size;
500 if (! strcmp(".strtab", (char *)(sectnames->d_buf)+shdr->sh_name)) {
501 dt = elf_getdata(scn, (Elf_Data *) 0);
502 if (dt->d_size == 0) {
503 fatal("(part of) symbol table is missing");
505 stringtab = dt->d_buf;
510 /* Get the symbol table. */
511 if (! strcmp(".symtab", (char *)(sectnames->d_buf)+shdr->sh_name)) {
512 dt = elf_getdata(scn, (Elf_Data *) 0);
513 if (dt->d_size == 0) {
514 fatal("(part of) symbol table is missing");
522 /* Convert offsets in stab symbol table. */
528 if (dn->n_un.n_strx) {
529 dn->n_un.n_strx += fixnamoff;
533 fixnamoff = newfixnamoff;
534 newfixnamoff += dn->n_value;
541 while (stringtab[n->st_name] != 'B') n++;
542 if (! strcmp("Btext.text", &(stringtab[n->st_name]))) {
543 text_offset = n->st_value; i++;
545 else if (! strcmp("Bdata.data", &(stringtab[n->st_name]))) {
546 data_offset = n->st_value; i++;
548 else if (! strcmp("Bbss.bss", &(stringtab[n->st_name]))) {
549 bss_offset = n->st_value; i++;
557 /* Fortunately, we don't use this in ACK, so we don't
558 have to handle it here. The problem is that we don't know
559 which segment it comes from.
565 dn->n_value += data_offset;
570 dn->n_value += bss_offset;
575 dn->n_value += text_offset;
576 fun_offset = dn->n_value;
580 dn->n_value += text_offset;
587 dn->n_value += fun_offset;
599 /* Nothing to be done. */
611 register struct nlist *dn = dbtab;
612 register struct outname *n = nm;
614 if (dn->n_type & N_STAB) {
615 n->on_type = dn->n_type << 8;
616 n->on_valu = dn->n_value;
617 n->on_desc = dn->n_desc;
618 if (dn->n_un.n_strx == 0) n->on_foff = 0;
619 else n->on_foff = OFF_CHAR(hh) + dn->n_un.n_strx;
631 memcpy(nm, dbstringtab, count);