FreeCalypso > hg > freecalypso-reveng
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 } |