coff32setsym.c - scc - simple c99 compiler
(HTM) git clone git://git.simple-cc.org/scc
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Submodules
(DIR) README
(DIR) LICENSE
---
coff32setsym.c (1946B)
---
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
12 static int
13 defent(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
55 static char *
56 symname(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
78 Symbol *
79 coff32setsym(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 }