scc

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

coff32getsym.c (1234B)


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