fixes, start removing mscrt
[ia32rtools.git] / tools / asmproc.c
CommitLineData
ede51255 1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4
5#include "my_assert.h"
6
7static int my_isblank(char c)
8{
9 return c == '\t' || c == ' ' || c == '\r' || c == '\n';
10}
11
12static char *sskip(char *s)
13{
14 while (my_isblank(*s))
15 s++;
16
17 return s;
18}
19
20static char *next_word(char *w, size_t wsize, char *s)
21{
22 size_t i;
23
24 s = sskip(s);
25
26 for (i = 0; i < wsize - 1; i++) {
27 if (*s == 0 || my_isblank(s[i]))
28 break;
29 w[i] = s[i];
30 }
31 w[i] = 0;
32
33 if (*s != 0 && !my_isblank(s[i]))
34 printf("warning: '%s' truncated\n", w);
35
36 return s + i;
37}
38
39struct sl_item {
40 char *name;
368deb23 41 unsigned int callsites:1;
8022df01 42 unsigned int found:1;
ede51255 43};
44
45static int cmp_sym(const void *p1_, const void *p2_)
46{
47 const struct sl_item *p1 = p1_, *p2 = p2_;
48 const char *s1 = p1->name, *s2 = p2->name;
49 int i;
50
51 for (i = 0; ; i++) {
0c5547d1 52 if ((s1[i] | s2[i]) == 0)
53 break;
54
ede51255 55 if (s1[i] == s2[i])
56 continue;
57
0c5547d1 58 if (s1[i] == 0 && s2[i] == '@')
59 break;
60 if (s1[i] == '@' && s2[i] == 0)
ede51255 61 break;
62
63 return s1[i] - s2[i];
64 }
65
66 return 0;
67}
68
69static int cmp_sym_sort(const void *p1_, const void *p2_)
70{
71 const struct sl_item *p1 = p1_, *p2 = p2_;
72 const char *s1 = p1->name, *s2 = p2->name;
73 int ret;
74
75 ret = cmp_sym(p1_, p2_);
76 if (ret == 0) {
77 printf("%s: dupe sym: '%s' '%s'\n", __func__, s1, s2);
78 exit(1);
79 }
80 return ret;
81}
82
368deb23 83void read_list(struct sl_item **sl_in, int *cnt, int *alloc,
84 FILE *f, int callsites)
ede51255 85{
86 struct sl_item *sl = *sl_in;
87 int c = *cnt;
88 char line[256];
89 char word[256];
ede51255 90
91 while (fgets(line, sizeof(line), f) != NULL) {
0c5547d1 92 next_word(word, sizeof(word), line);
93 if (word[0] == 0 || word[0] == ';' || word[0] == '#')
ede51255 94 continue;
95
96 sl[c].name = strdup(word);
368deb23 97 sl[c].callsites = callsites;
8022df01 98 sl[c].found = 0;
ede51255 99 c++;
100
101 if (c >= *alloc) {
102 *alloc *= 2;
103 sl = realloc(sl, *alloc * sizeof(sl[0]));
104 my_assert_not(sl, NULL);
8022df01 105 memset(sl + c, 0, (*alloc - c) * sizeof(sl[0]));
ede51255 106 }
107 }
108
109 *sl_in = sl;
110 *cnt = c;
111}
112
8022df01 113const char *sym_use(const struct sl_item *sym)
114{
115 static char buf[256+3];
116 int ret;
117
0c5547d1 118 ret = snprintf(buf, sizeof(buf), "rm_%s", sym->name);
8022df01 119 if (ret >= sizeof(buf)) {
120 printf("truncation detected: '%s'\n", buf);
121 exit(1);
122 }
123
124 return buf;
125}
126
ede51255 127int main(int argc, char *argv[])
128{
8022df01 129 struct sl_item *symlist, *sym, ssym = { NULL, };
368deb23 130 int patch_callsites = 0;
ede51255 131 FILE *fout, *fin, *f;
132 int symlist_alloc;
133 int symlist_cnt;
134 char line[256];
135 char word[256];
136 char word2[256];
137 char word3[256];
138 char word4[256];
139 char *p;
8022df01 140 int i;
ede51255 141
368deb23 142 if (argc < 4) {
143 // -c - patch callsites
144 printf("usage:\n%s <asmf_out> <asmf_in> [[-c] <listf>]*>\n",
ede51255 145 argv[0]);
146 return 1;
147 }
148
149 symlist_alloc = 16;
150 symlist_cnt = 0;
8022df01 151 symlist = calloc(symlist_alloc, sizeof(symlist[0]));
ede51255 152 my_assert_not(symlist, NULL);
153
368deb23 154 for (i = 3; i < argc; i++) {
0c5547d1 155 if (strcmp(argv[i], "-c") == 0) {
368deb23 156 patch_callsites = 1;
157 continue;
158 }
159
160 f = fopen(argv[i], "r");
161 my_assert_not(f, NULL);
162 read_list(&symlist, &symlist_cnt, &symlist_alloc,
163 f, patch_callsites);
164 fclose(f);
ede51255 165
368deb23 166 patch_callsites = 0;
167 }
ede51255 168
169 qsort(symlist, symlist_cnt, sizeof(symlist[0]), cmp_sym_sort);
170
8022df01 171#if 0
172 printf("symlist:\n");
173 for (i = 0; i < symlist_cnt; i++)
368deb23 174 printf("%d '%s'\n", symlist[i].callsites, symlist[i].name);
8022df01 175#endif
ede51255 176
177 fin = fopen(argv[2], "r");
178 my_assert_not(fin, NULL);
179
180 fout = fopen(argv[1], "w");
181 my_assert_not(fout, NULL);
182
183 while (fgets(line, sizeof(line), fin))
184 {
185 p = sskip(line);
186 if (*p == 0 || *p == ';')
187 goto pass;
188
189 p = sskip(next_word(word, sizeof(word), p));
190 if (*p == 0 || *p == ';')
191 goto pass; // need at least 2 words
192
193 p = next_word(word2, sizeof(word2), p);
194
195 if (!strcasecmp(word2, "proc") || !strcasecmp(word2, "endp")) {
196 ssym.name = word;
197 sym = bsearch(&ssym, symlist, symlist_cnt,
198 sizeof(symlist[0]), cmp_sym);
199 if (sym != NULL) {
8022df01 200 sym->found = 1;
ede51255 201 fprintf(fout, "rm_%s\t%s%s", word, word2, p);
202 continue;
203 }
204 }
205
206 if (!strcasecmp(word, "call") || !strcasecmp(word, "jmp")) {
207 ssym.name = word2;
208 sym = bsearch(&ssym, symlist, symlist_cnt,
209 sizeof(symlist[0]), cmp_sym);
368deb23 210 if (sym != NULL && sym->callsites) {
8022df01 211 fprintf(fout, "\t\t%s\t%s%s", word,
212 sym_use(sym), p);
ede51255 213 continue;
214 }
215 }
216
217 p = sskip(p);
218 if (*p == 0 || *p == ';')
219 goto pass; // need at least 3 words
220
221 p = next_word(word3, sizeof(word3), p);
222
223 if (!strcasecmp(word, "dd") && !strcasecmp(word2, "offset")) {
224 ssym.name = word3;
225 sym = bsearch(&ssym, symlist, symlist_cnt,
226 sizeof(symlist[0]), cmp_sym);
368deb23 227 if (sym != NULL && sym->callsites) {
8022df01 228 fprintf(fout, "\t\tdd offset %s%s",
229 sym_use(sym), p);
ede51255 230 continue;
231 }
232 }
233
234 p = sskip(p);
235 if (*p == 0 || *p == ';')
236 goto pass; // need at least 4 words
237
238 p = next_word(word4, sizeof(word4), p);
239
240 if (!strcasecmp(word2, "dd") && !strcasecmp(word3, "offset")) {
241 ssym.name = word4;
242 sym = bsearch(&ssym, symlist, symlist_cnt,
243 sizeof(symlist[0]), cmp_sym);
368deb23 244 if (sym != NULL && sym->callsites) {
8022df01 245 fprintf(fout, "%s\tdd offset %s%s", word,
246 sym_use(sym), p);
ede51255 247 continue;
248 }
249 }
250
251pass:
252 fwrite(line, 1, strlen(line), fout);
253 }
254
8022df01 255 for (i = 0; i < symlist_cnt; i++) {
256 if (!symlist[i].found)
257 printf("warning: sym '%s' not found\n", symlist[i].name);
258 }
259
ede51255 260 fclose(fin);
261 fclose(fout);
262
263 return 0;
264}