640 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			640 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* $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
 |