comparison leo-obj/tool/richsym.c @ 144:fd772de226cb

tiobjd: started implementing rich symbolic info parsing
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Mon, 28 Apr 2014 08:04:39 +0000
parents
children 25d3ead621f8
comparison
equal deleted inserted replaced
143:fbdb7686a9e9 144:fd772de226cb
1 /*
2 * Code for working with the "rich" symbolic info
3 * present in TI's GPF libraries
4 */
5
6 #include <sys/types.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <strings.h>
11 #include "intstruct.h"
12 #include "coffconst.h"
13 #include "globals.h"
14
15 extern unsigned get_u16(), get_u32();
16 extern char *storage_class_to_string();
17
18 static int
19 try_typedef_hack(struct_sym)
20 struct internal_syment *struct_sym;
21 {
22 unsigned tpdef_cand;
23 struct internal_syment *tpdef_sym;
24
25 if (!struct_sym->aux)
26 return(0);
27 tpdef_cand = get_u32(struct_sym->aux + 12);
28 if (tpdef_cand >= nsymtab)
29 return(0);
30 tpdef_sym = symtab[tpdef_cand];
31 if (!tpdef_sym)
32 return(0);
33 if (tpdef_sym->class != C_TPDEF)
34 return(0);
35 if (tpdef_sym->type != struct_sym->type)
36 return(0);
37 if (tpdef_sym->name[0] != '_')
38 return(0);
39 if (!tpdef_sym->aux)
40 return(0);
41 if (get_u32(tpdef_sym->aux) != struct_sym->number)
42 return(0);
43 struct_sym->struct_name = tpdef_sym->name + 1;
44 return(1);
45 }
46
47 static void
48 preen_strtag_sym(sym, kw, expect_type)
49 struct internal_syment *sym;
50 char *kw;
51 {
52 char *buf;
53 int isund, len;
54
55 isund = (sym->name[0] == '_');
56 len = strlen(kw) + 1 + strlen(sym->name) + 1;
57 if (isund)
58 len--;
59 else
60 len += 2;
61 buf = malloc(len);
62 if (!buf) {
63 perror("malloc");
64 exit(1);
65 }
66 if (isund)
67 sprintf(buf, "%s %s", kw, sym->name + 1);
68 else
69 sprintf(buf, "%s \"%s\"", kw, sym->name);
70 sym->struct_name = buf;
71 sym->struct_name_raw = buf;
72 if (sym->type != expect_type) {
73 fprintf(stderr,
74 "warning: type/class mismatch on tag symbol #%u\n",
75 sym->number);
76 return;
77 }
78 if (isund)
79 return;
80 try_typedef_hack(sym);
81 }
82
83 richsym_initial_preen()
84 {
85 unsigned n;
86 struct internal_syment *sym;
87
88 for (n = 0; n < nsymtab; n++) {
89 sym = symtab[n];
90 if (!sym)
91 continue;
92 switch (sym->class) {
93 case C_STRTAG:
94 preen_strtag_sym(sym, "struct", T_STRUCT);
95 continue;
96 case C_UNTAG:
97 preen_strtag_sym(sym, "union", T_UNION);
98 continue;
99 case C_ENTAG:
100 preen_strtag_sym(sym, "enum", T_ENUM);
101 continue;
102 }
103 }
104 }
105
106 char *
107 get_struct_type_name(idx, expect_class, is_typedef)
108 unsigned idx;
109 {
110 struct internal_syment *sym;
111
112 if (idx >= nsymtab) {
113 inv_idx: fprintf(stderr,
114 "error: ref to invalid syment #%u for struct tag\n",
115 idx);
116 exit(1);
117 }
118 sym = symtab[idx];
119 if (!sym)
120 goto inv_idx;
121 if (sym->class != expect_class) {
122 fprintf(stderr,
123 "error: ref to syment #%u for struct tag, class != %s\n",
124 idx, storage_class_to_string(expect_class, 0));
125 exit(1);
126 }
127 if (is_typedef)
128 return(sym->struct_name_raw);
129 else
130 return(sym->struct_name);
131 }
132
133 char *
134 get_base_type_of_syment(sym, is_typedef)
135 struct internal_syment *sym;
136 {
137 switch (sym->type & 0xF) {
138 case T_VOID:
139 return("void");
140 case T_CHAR:
141 if (is_typedef)
142 return("signed char");
143 else
144 return("char");
145 case T_SHORT:
146 return("short");
147 case T_INT:
148 return("int");
149 case T_LONG:
150 return("long");
151 case T_FLOAT:
152 return("float");
153 case T_DOUBLE:
154 return("double");
155 case T_STRUCT:
156 return get_struct_type_name(get_u32(sym->aux), C_STRTAG,
157 is_typedef);
158 case T_UNION:
159 return get_struct_type_name(get_u32(sym->aux), C_UNTAG,
160 is_typedef);
161 case T_ENUM:
162 return get_struct_type_name(get_u32(sym->aux), C_ENTAG,
163 is_typedef);
164 case T_UCHAR:
165 if (is_typedef)
166 return("unsigned char");
167 else
168 return("u_char");
169 case T_USHORT:
170 if (is_typedef)
171 return("unsigned short");
172 else
173 return("u_short");
174 case T_UINT:
175 return("unsigned");
176 case T_ULONG:
177 if (is_typedef)
178 return("unsigned long");
179 else
180 return("u_long");
181 default:
182 return("__unknown_base_type");
183 }
184 }