# HG changeset patch # User Michael Spacefalcon # Date 1398672279 0 # Node ID fd772de226cb31de49e6d59a98968fc15ed71d32 # Parent fbdb7686a9e99592f0fea0b7d711b209b376f3ce tiobjd: started implementing rich symbolic info parsing diff -r fbdb7686a9e9 -r fd772de226cb leo-obj/tool/Makefile --- a/leo-obj/tool/Makefile Mon Apr 28 05:55:40 2014 +0000 +++ b/leo-obj/tool/Makefile Mon Apr 28 08:04:39 2014 +0000 @@ -2,7 +2,7 @@ CFLAGS= -O2 PROG= tiobjd OBJS= armdis.o atcommon.o basics.o disasm.o globals.o hints.o ln.o lowlevel.o\ - main.o profile.o reloc.o symtab.o tables.o thumbdis.o + main.o profile.o reloc.o richsym.o symtab.o tables.o thumbdis.o HDRS= coffconst.h filestruct.h globals.h intstruct.h all: ${PROG} diff -r fbdb7686a9e9 -r fd772de226cb leo-obj/tool/coffconst.h --- a/leo-obj/tool/coffconst.h Mon Apr 28 05:55:40 2014 +0000 +++ b/leo-obj/tool/coffconst.h Mon Apr 28 08:04:39 2014 +0000 @@ -30,6 +30,31 @@ #define C_FILE 103 /* file name */ #define C_LINE 104 /* line # reformatted as symbol table entry */ +/* Type of a symbol, in low 4 bits of the word. */ + +#define T_VOID 0 /* seen in void ptrs in our objects */ +#define T_CHAR 2 /* character */ +#define T_SHORT 3 /* short integer */ +#define T_INT 4 /* integer */ +#define T_LONG 5 /* long integer */ +#define T_FLOAT 6 /* floating point */ +#define T_DOUBLE 7 /* double word */ +#define T_STRUCT 8 /* structure */ +#define T_UNION 9 /* union */ +#define T_ENUM 10 /* enumeration */ +#define T_MOE 11 /* member of enumeration*/ +#define T_UCHAR 12 /* unsigned character */ +#define T_USHORT 13 /* unsigned short */ +#define T_UINT 14 /* unsigned integer */ +#define T_ULONG 15 /* unsigned long */ + +/* Derived types, in n_type. */ + +#define DT_NON 0 /* no derived type */ +#define DT_PTR 1 /* pointer */ +#define DT_FCN 2 /* function */ +#define DT_ARY 3 /* array */ + /* Reloc types */ #define RTYPE_LONG 0x11 diff -r fbdb7686a9e9 -r fd772de226cb leo-obj/tool/intstruct.h --- a/leo-obj/tool/intstruct.h Mon Apr 28 05:55:40 2014 +0000 +++ b/leo-obj/tool/intstruct.h Mon Apr 28 08:04:39 2014 +0000 @@ -33,6 +33,8 @@ int class; u_char *aux; struct internal_scnhdr *section; + char *struct_name; + char *struct_name_raw; }; struct internal_reloc { diff -r fbdb7686a9e9 -r fd772de226cb leo-obj/tool/richsym.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/leo-obj/tool/richsym.c Mon Apr 28 08:04:39 2014 +0000 @@ -0,0 +1,184 @@ +/* + * Code for working with the "rich" symbolic info + * present in TI's GPF libraries + */ + +#include +#include +#include +#include +#include +#include "intstruct.h" +#include "coffconst.h" +#include "globals.h" + +extern unsigned get_u16(), get_u32(); +extern char *storage_class_to_string(); + +static int +try_typedef_hack(struct_sym) + struct internal_syment *struct_sym; +{ + unsigned tpdef_cand; + struct internal_syment *tpdef_sym; + + if (!struct_sym->aux) + return(0); + tpdef_cand = get_u32(struct_sym->aux + 12); + if (tpdef_cand >= nsymtab) + return(0); + tpdef_sym = symtab[tpdef_cand]; + if (!tpdef_sym) + return(0); + if (tpdef_sym->class != C_TPDEF) + return(0); + if (tpdef_sym->type != struct_sym->type) + return(0); + if (tpdef_sym->name[0] != '_') + return(0); + if (!tpdef_sym->aux) + return(0); + if (get_u32(tpdef_sym->aux) != struct_sym->number) + return(0); + struct_sym->struct_name = tpdef_sym->name + 1; + return(1); +} + +static void +preen_strtag_sym(sym, kw, expect_type) + struct internal_syment *sym; + char *kw; +{ + char *buf; + int isund, len; + + isund = (sym->name[0] == '_'); + len = strlen(kw) + 1 + strlen(sym->name) + 1; + if (isund) + len--; + else + len += 2; + buf = malloc(len); + if (!buf) { + perror("malloc"); + exit(1); + } + if (isund) + sprintf(buf, "%s %s", kw, sym->name + 1); + else + sprintf(buf, "%s \"%s\"", kw, sym->name); + sym->struct_name = buf; + sym->struct_name_raw = buf; + if (sym->type != expect_type) { + fprintf(stderr, + "warning: type/class mismatch on tag symbol #%u\n", + sym->number); + return; + } + if (isund) + return; + try_typedef_hack(sym); +} + +richsym_initial_preen() +{ + unsigned n; + struct internal_syment *sym; + + for (n = 0; n < nsymtab; n++) { + sym = symtab[n]; + if (!sym) + continue; + switch (sym->class) { + case C_STRTAG: + preen_strtag_sym(sym, "struct", T_STRUCT); + continue; + case C_UNTAG: + preen_strtag_sym(sym, "union", T_UNION); + continue; + case C_ENTAG: + preen_strtag_sym(sym, "enum", T_ENUM); + continue; + } + } +} + +char * +get_struct_type_name(idx, expect_class, is_typedef) + unsigned idx; +{ + struct internal_syment *sym; + + if (idx >= nsymtab) { +inv_idx: fprintf(stderr, + "error: ref to invalid syment #%u for struct tag\n", + idx); + exit(1); + } + sym = symtab[idx]; + if (!sym) + goto inv_idx; + if (sym->class != expect_class) { + fprintf(stderr, + "error: ref to syment #%u for struct tag, class != %s\n", + idx, storage_class_to_string(expect_class, 0)); + exit(1); + } + if (is_typedef) + return(sym->struct_name_raw); + else + return(sym->struct_name); +} + +char * +get_base_type_of_syment(sym, is_typedef) + struct internal_syment *sym; +{ + switch (sym->type & 0xF) { + case T_VOID: + return("void"); + case T_CHAR: + if (is_typedef) + return("signed char"); + else + return("char"); + case T_SHORT: + return("short"); + case T_INT: + return("int"); + case T_LONG: + return("long"); + case T_FLOAT: + return("float"); + case T_DOUBLE: + return("double"); + case T_STRUCT: + return get_struct_type_name(get_u32(sym->aux), C_STRTAG, + is_typedef); + case T_UNION: + return get_struct_type_name(get_u32(sym->aux), C_UNTAG, + is_typedef); + case T_ENUM: + return get_struct_type_name(get_u32(sym->aux), C_ENTAG, + is_typedef); + case T_UCHAR: + if (is_typedef) + return("unsigned char"); + else + return("u_char"); + case T_USHORT: + if (is_typedef) + return("unsigned short"); + else + return("u_short"); + case T_UINT: + return("unsigned"); + case T_ULONG: + if (is_typedef) + return("unsigned long"); + else + return("u_long"); + default: + return("__unknown_base_type"); + } +} diff -r fbdb7686a9e9 -r fd772de226cb leo-obj/tool/tables.c --- a/leo-obj/tool/tables.c Mon Apr 28 05:55:40 2014 +0000 +++ b/leo-obj/tool/tables.c Mon Apr 28 08:04:39 2014 +0000 @@ -131,6 +131,8 @@ in->section = 0; in->type = get_u16(symtab_raw[n].e_type); in->class = symtab_raw[n].e_sclass; + in->struct_name = 0; + in->struct_name_raw = 0; switch (symtab_raw[n++].e_numaux) { case 0: in->aux = 0;