scc

simple c99 compiler
git clone git://git.simple-cc.org/scc
Log | Files | Refs | README | LICENSE

coff32getsyms.c (1400B)


      1 #include <stdio.h>
      2 #include <ctype.h>
      3 
      4 #include <scc/mach.h>
      5 
      6 #include "../libmach.h"
      7 #include "coff32.h"
      8 
      9 static int
     10 typeof(Coff32 *coff, SYMENT *ent)
     11 {
     12 	int c;
     13 	SCNHDR *scn;
     14 	long flags;
     15 
     16 	switch (ent->n_scnum) {
     17 	case N_DEBUG:
     18 		c = 'N';
     19 		break;
     20 	case N_ABS:
     21 		c = 'a';
     22 		break;
     23 	case N_UNDEF:
     24 		c = (ent->n_value != 0) ? 'C' : 'U';
     25 		break;
     26 	default:
     27 		if (ent->n_scnum > coff->hdr.f_nscns)
     28 			return -1;
     29 		scn = &coff->scns[ent->n_scnum-1];
     30 		flags = scn->s_flags;
     31 		if (flags & STYP_TEXT)
     32 			c = 't';
     33 		else if (flags & STYP_DATA)
     34 			c = 'd';
     35 		else if (flags & STYP_BSS)
     36 			c = 'b';
     37 		else
     38 			c = '?';
     39 		break;
     40 	}
     41 
     42 	if (ent->n_sclass == C_EXT)
     43 		c = toupper(c);
     44 
     45 	return c;
     46 }
     47 
     48 static char *
     49 symname(Coff32 *coff, SYMENT *ent)
     50 {
     51 	long off;
     52 
     53 	if (ent->n_zeroes != 0)
     54 		return ent->n_name;
     55 
     56 	off = ent->n_offset;
     57 	if (off >= coff->strsiz)
     58 		return NULL;
     59 	return &coff->strtbl[off];
     60 }
     61 
     62 int
     63 coff32getsyms(Obj *obj)
     64 {
     65 	int t;
     66 	long i;
     67 	char *s;
     68 	Objsym *sym;
     69 	SYMENT *ent;
     70 	Coff32 *coff = obj->data;
     71 
     72 	for (i = 0; i < coff->hdr.f_nsyms; i += ent->n_numaux + 1) {
     73 		ent = &coff->ents[i];
     74 
     75 		if ((t = typeof(coff, ent)) < 0)
     76 			return -1;
     77 
     78 		if ((s = symname(coff, ent)) == NULL)
     79 			return -1;
     80 
     81 		if ((sym = objlookup(obj, s, 1)) == NULL)
     82 			return -1;
     83 
     84 		sym->type = t;
     85 		sym->value = ent->n_value;
     86 		sym->size = (sym->type == 'C') ? ent->n_value : 0;
     87 		sym->sect = ent->n_scnum-1;
     88 	}
     89 
     90 	return i;
     91 }