FreeCalypso > hg > freecalypso-reveng
changeset 145:25d3ead621f8
tiobjd: ctypes command implemented
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Tue, 29 Apr 2014 04:49:17 +0000 |
parents | fd772de226cb |
children | 70631c246df0 |
files | leo-obj/tool/main.c leo-obj/tool/richsym.c |
diffstat | 2 files changed, 185 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/leo-obj/tool/main.c Mon Apr 28 08:04:39 2014 +0000 +++ b/leo-obj/tool/main.c Tue Apr 29 04:49:17 2014 +0000 @@ -10,6 +10,7 @@ #include "globals.h" extern int cmd_basics(); +extern int cmd_ctypes(); extern int cmd_disasm(); extern int cmd_ln(); extern int cmd_nm(); @@ -25,6 +26,7 @@ int (*func)(); } cmdtab[] = { {"basics", cmd_basics}, + {"ctypes", cmd_ctypes}, {"disasm", cmd_disasm}, {"dumpsym", cmd_symtab}, /* backward compat */ {"hdr", dump_filehdr_info},
--- a/leo-obj/tool/richsym.c Mon Apr 28 08:04:39 2014 +0000 +++ b/leo-obj/tool/richsym.c Tue Apr 29 04:49:17 2014 +0000 @@ -15,6 +15,8 @@ extern unsigned get_u16(), get_u32(); extern char *storage_class_to_string(); +int richsym_print_bitsize; + static int try_typedef_hack(struct_sym) struct internal_syment *struct_sym; @@ -182,3 +184,184 @@ return("__unknown_base_type"); } } + +richsym_print_in_c(prefix, sym, is_typedef) + char *prefix; + struct internal_syment *sym; +{ + char *base_type, *s1, *s2; + int dertype, last_ptr, narray; + + base_type = get_base_type_of_syment(sym, is_typedef); + dertype = sym->type >> 4; + s1 = malloc(strlen(sym->name)); + if (!s1) { + perror("malloc"); + exit(1); + } + strcpy(s1, sym->name + 1); + last_ptr = 0; + narray = 0; + for (; dertype; dertype >>= 2) { + switch (dertype & 3) { + case DT_NON: + fprintf(stderr, + "error: symbol #%u: DT_NON followed by more derived types\n", + sym->number); + exit(1); + case DT_PTR: + s2 = malloc(strlen(s1) + 2); + if (!s2) { + perror("malloc"); + exit(1); + } + sprintf(s2, "*%s", s1); + free(s1); + s1 = s2; + last_ptr = 1; + continue; + } + if (last_ptr) { + s2 = malloc(strlen(s1) + 3); + if (!s2) { + perror("malloc"); + exit(1); + } + sprintf(s2, "(%s)", s1); + free(s1); + s1 = s2; + } + switch (dertype & 3) { + case DT_FCN: + s2 = malloc(strlen(s1) + 3); + if (!s2) { + perror("malloc"); + exit(1); + } + sprintf(s2, "%s()", s1); + free(s1); + s1 = s2; + break; + case DT_ARY: + if (narray >= 4) { + fprintf(stderr, + "error: symbol #%u: too many [] types\n", + sym->number); + exit(1); + } + s2 = malloc(strlen(s1) + 8); + if (!s2) { + perror("malloc"); + exit(1); + } + sprintf(s2, "%s[%u]", s1, + get_u16(sym->aux + 8 + narray * 2)); + free(s1); + s1 = s2; + narray++; + break; + default: + fprintf(stderr, + "BUG in richsym_print_in_c(): bad derived type\n"); + exit(1); + } + last_ptr = 0; + } + printf("%s%s %s;", prefix, base_type, s1); + free(s1); + if (richsym_print_bitsize) + printf("\t/* %u bits */", get_u32(sym->aux + 4)); + putchar('\n'); +} + +cmd_ctypes(argc, argv) + char **argv; +{ + int c; + unsigned n; + struct internal_syment *sym; + + while ((c = getopt(argc, argv, "b")) != EOF) + switch (c) { + case 'b': + richsym_print_bitsize++; + continue; + default: + /* error msg already printed */ + exit(1); + } + + get_int_section_table(); + get_int_symbol_table(); + richsym_initial_preen(); + for (n = 0; n < nsymtab; n++) { + sym = symtab[n]; + if (!sym) + continue; + switch (sym->class) { + case C_FILE: + printf("/* from %s */\n", sym->name); + continue; + case C_STRTAG: + case C_UNTAG: + case C_ENTAG: + printf("%s {", sym->struct_name_raw); + if (richsym_print_bitsize && sym->aux) + printf("\t/* %u bits */", get_u32(sym->aux+4)); + putchar('\n'); + continue; + case C_EOS: + fputs("};", stdout); + if (richsym_print_bitsize && sym->aux) + printf("\t/* %u bits */", get_u32(sym->aux+4)); + putchar('\n'); + continue; + case C_MOS: + case C_MOU: + case C_MOE: + case C_TPDEF: + break; + default: + continue; + } + if (sym->name[0] != '_') { + printf( + "/* symbol #%u of class %s has no leading underscore */\n", + sym->number, + storage_class_to_string(sym->class, 0)); + continue; + } + if (!sym->aux && sym->class != C_MOE) { + printf( + "/* symbol #%u of class %s has no aux record */\n", + sym->number, + storage_class_to_string(sym->class, 0)); + continue; + } + switch (sym->class) { + case C_MOS: + case C_MOU: + if (sym->scnum != -1) + printf("\t/* MOS/MOU section != ABS! */\n"); + else if (richsym_print_bitsize >= 2) + printf("\t/* offset: %u bits\n", sym->value); + richsym_print_in_c("\t", sym, 0); + continue; + case C_MOE: + if (sym->scnum != -1) { + printf("\t/* MOE section != ABS! */\n"); + continue; + } + printf("\t%s = %u;", sym->name + 1, sym->value); + if (sym->value >= 10) + printf("\t/* 0x%x */", sym->value); + putchar('\n'); + continue; + case C_TPDEF: + richsym_print_in_c("typedef ", sym, + !(sym->type & 0xFFF0)); + continue; + } + } + exit(0); +}