scc

A fork of https://git.simple-cc.org/scc/ for Qute

git clone https://git.8pit.net/scc.git

  1#include <limits.h>
  2#include <stdio.h>
  3#include <stdlib.h>
  4#include <string.h>
  5
  6#include <scc/mach.h>
  7#include <scc/coff32.h>
  8
  9#include "../libmach.h"
 10#include "fun.h"
 11
 12static int
 13defent(Coff32 *coff, SYMENT *ent, Symbol *sym)
 14{
 15	ent->n_scnum = sym->section + 1;
 16
 17	switch (sym->type) {
 18	case 'N':
 19		/*
 20		 * TODO: What happens with .indent ?
 21		 *       look if the section is STYP_INFO 
 22		 */
 23		ent->n_scnum = N_DEBUG;
 24		break;
 25	case 'A':
 26		ent->n_sclass = C_EXT;
 27	case 'a':
 28		ent->n_scnum = N_ABS;
 29		break;
 30	case 'C':
 31	case 'U':
 32		ent->n_scnum = N_UNDEF;
 33		break;
 34	case 'T':
 35	case 'D':
 36	case 'B':
 37	case 'R':
 38		ent->n_sclass = C_EXT;
 39		break;
 40	case 't':
 41	case 'd':
 42	case 'b':
 43	case 'r':
 44		ent->n_sclass = C_STAT;
 45		break;
 46	case '?':
 47	default:
 48		/* TODO */
 49		return -1;
 50	}
 51
 52	return 0;
 53}
 54
 55static char *
 56symname(Coff32 *coff, SYMENT *ent, Symbol *sym)
 57{
 58	char *p;
 59	unsigned long siz = strlen(sym->name);
 60
 61	if (siz < SYMNMLEN)
 62		return strncpy(ent->n_name, sym->name, SYMNMLEN);
 63
 64	if (coff->strsiz > ULONG_MAX - siz - 1)
 65		return NULL;
 66
 67	siz += coff->strsiz + 1;
 68	if ((p = realloc(coff->strtbl, siz)) == NULL)
 69		return NULL;
 70	coff->strtbl = p;
 71
 72	ent->n_zeroes = 0;
 73	ent->n_offset = coff->strsiz;
 74	coff->strsiz += siz;
 75	return strcpy(&coff->strtbl[ent->n_offset], sym->name);
 76}
 77
 78Symbol *
 79coff32setsym(Obj *obj, int *idx, Symbol *sym)
 80{
 81	int n = *idx;
 82	Entry *ep;
 83	SYMENT *ent;
 84	Coff32 *coff = obj->data;
 85	FILHDR *hdr = &coff->hdr;
 86
 87	hdr->f_flags &= ~F_LSYMS;
 88	if (n >= coff->hdr.f_nsyms) {
 89		if (n > LONG_MAX-1)
 90			return NULL;
 91		if ((ep = realloc(coff->ents, (n+1) * sizeof(*ep))) == NULL)
 92			return NULL;
 93		coff->ents = ep;
 94		coff->hdr.f_nsyms = n+1;
 95	}
 96	ep = &coff->ents[n];
 97	ent = &ep->u.sym;
 98	if (!symname(coff, ent, sym))
 99		return NULL;
100
101	ent->n_value = sym->value;
102	if (defent(coff, ent, sym) < 0)
103		return NULL;
104
105	/*
106	 * TODO: 
107	 *      sym->stype
108	 */
109	ent->n_numaux = 0; /* TODO: debug information */
110
111	*idx += ent->n_numaux;
112
113	return sym;
114}