Revision d219f7e7
b/dyngen.c | ||
---|---|---|
110 | 110 |
|
111 | 111 |
#include "thunk.h" |
112 | 112 |
|
113 |
enum { |
|
114 |
OUT_GEN_OP, |
|
115 |
OUT_CODE, |
|
116 |
OUT_INDEX_OP, |
|
117 |
}; |
|
118 |
|
|
113 | 119 |
/* all dynamically generated functions begin with this code */ |
114 | 120 |
#define OP_PREFIX "op_" |
115 | 121 |
|
... | ... | |
1087 | 1093 |
} |
1088 | 1094 |
|
1089 | 1095 |
/* load an elf object file */ |
1090 |
int load_elf(const char *filename, FILE *outfile, int do_print_enum)
|
|
1096 |
int load_elf(const char *filename, FILE *outfile, int out_type)
|
|
1091 | 1097 |
{ |
1092 | 1098 |
int fd; |
1093 | 1099 |
struct elf_shdr *sec, *symtab_sec, *strtab_sec, *text_sec; |
... | ... | |
1195 | 1201 |
} |
1196 | 1202 |
} |
1197 | 1203 |
|
1198 |
if (do_print_enum) {
|
|
1204 |
if (out_type == OUT_INDEX_OP) {
|
|
1199 | 1205 |
fprintf(outfile, "DEF(end, 0, 0)\n"); |
1200 | 1206 |
for(i = 0, sym = symtab; i < nb_syms; i++, sym++) { |
1201 | 1207 |
const char *name, *p; |
... | ... | |
1205 | 1211 |
text, relocs, nb_relocs, 2); |
1206 | 1212 |
} |
1207 | 1213 |
} |
1214 |
} else if (out_type == OUT_GEN_OP) { |
|
1215 |
/* generate gen_xxx functions */ |
|
1216 |
|
|
1217 |
for(i = 0, sym = symtab; i < nb_syms; i++, sym++) { |
|
1218 |
const char *name; |
|
1219 |
name = strtab + sym->st_name; |
|
1220 |
if (strstart(name, OP_PREFIX, NULL)) { |
|
1221 |
if (sym->st_shndx != (text_sec - shdr)) |
|
1222 |
error("invalid section for opcode (0x%x)", sym->st_shndx); |
|
1223 |
gen_code(name, sym->st_value, sym->st_size, outfile, |
|
1224 |
text, relocs, nb_relocs, 0); |
|
1225 |
} |
|
1226 |
} |
|
1227 |
|
|
1208 | 1228 |
} else { |
1209 | 1229 |
/* generate big code generation switch */ |
1210 | 1230 |
fprintf(outfile, |
... | ... | |
1305 | 1325 |
default: |
1306 | 1326 |
error("unknown ELF architecture"); |
1307 | 1327 |
} |
1308 |
|
|
1328 |
/* flush instruction cache */ |
|
1329 |
fprintf(outfile, "flush_icache_range((unsigned long)gen_code_buf, (unsigned long)gen_code_ptr);\n"); |
|
1330 |
|
|
1309 | 1331 |
fprintf(outfile, "return gen_code_ptr - gen_code_buf;\n"); |
1310 | 1332 |
fprintf(outfile, "}\n\n"); |
1311 | 1333 |
|
1312 |
/* generate gen_xxx functions */ |
|
1313 |
/* XXX: suppress the use of these functions to simplify code */ |
|
1314 |
for(i = 0, sym = symtab; i < nb_syms; i++, sym++) { |
|
1315 |
const char *name; |
|
1316 |
name = strtab + sym->st_name; |
|
1317 |
if (strstart(name, OP_PREFIX, NULL)) { |
|
1318 |
if (sym->st_shndx != (text_sec - shdr)) |
|
1319 |
error("invalid section for opcode (0x%x)", sym->st_shndx); |
|
1320 |
gen_code(name, sym->st_value, sym->st_size, outfile, |
|
1321 |
text, relocs, nb_relocs, 0); |
|
1322 |
} |
|
1323 |
} |
|
1324 | 1334 |
} |
1325 | 1335 |
|
1326 | 1336 |
close(fd); |
... | ... | |
1333 | 1343 |
"usage: dyngen [-o outfile] [-c] objfile\n" |
1334 | 1344 |
"Generate a dynamic code generator from an object file\n" |
1335 | 1345 |
"-c output enum of operations\n" |
1346 |
"-g output gen_op_xx() functions\n" |
|
1336 | 1347 |
); |
1337 | 1348 |
exit(1); |
1338 | 1349 |
} |
1339 | 1350 |
|
1340 | 1351 |
int main(int argc, char **argv) |
1341 | 1352 |
{ |
1342 |
int c, do_print_enum;
|
|
1353 |
int c, out_type;
|
|
1343 | 1354 |
const char *filename, *outfilename; |
1344 | 1355 |
FILE *outfile; |
1345 | 1356 |
|
1346 | 1357 |
outfilename = "out.c"; |
1347 |
do_print_enum = 0;
|
|
1358 |
out_type = OUT_CODE;
|
|
1348 | 1359 |
for(;;) { |
1349 |
c = getopt(argc, argv, "ho:c"); |
|
1360 |
c = getopt(argc, argv, "ho:cg");
|
|
1350 | 1361 |
if (c == -1) |
1351 | 1362 |
break; |
1352 | 1363 |
switch(c) { |
... | ... | |
1357 | 1368 |
outfilename = optarg; |
1358 | 1369 |
break; |
1359 | 1370 |
case 'c': |
1360 |
do_print_enum = 1; |
|
1371 |
out_type = OUT_INDEX_OP; |
|
1372 |
break; |
|
1373 |
case 'g': |
|
1374 |
out_type = OUT_GEN_OP; |
|
1361 | 1375 |
break; |
1362 | 1376 |
} |
1363 | 1377 |
} |
... | ... | |
1367 | 1381 |
outfile = fopen(outfilename, "w"); |
1368 | 1382 |
if (!outfile) |
1369 | 1383 |
error("could not open '%s'", outfilename); |
1370 |
load_elf(filename, outfile, do_print_enum);
|
|
1384 |
load_elf(filename, outfile, out_type);
|
|
1371 | 1385 |
fclose(outfile); |
1372 | 1386 |
return 0; |
1373 | 1387 |
} |
Also available in: Unified diff