FreeCalypso > hg > freecalypso-reveng
view objgrep/tables.c @ 389:623316d1ece7
compal/iMelody: capturing initial observations
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Thu, 31 Mar 2022 20:56:56 +0000 |
parents | 77cd647375e5 |
children |
line wrap: on
line source
/* * This C module contains functions for the initial parsing * of the section and symbol tables. */ #include <sys/types.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <strings.h> #include "filestruct.h" #include "intstruct.h" #include "globals.h" extern unsigned get_u16(), get_u32(); initial_parse_hdr() { unsigned symtab_offset; filehdr_struct = (struct external_filehdr *) objfilemap; if (get_u16(filehdr_struct->f_magic) != 0xC2) { fprintf(stderr, "error: %s is not a TI COFF2 object\n", objfilename); exit(2); } if (get_u16(filehdr_struct->f_target_id) != 0x97) { fprintf(stderr, "error: TI COFF object %s is not for TMS470\n", objfilename); exit(2); } if (get_u16(filehdr_struct->f_opthdr)) { fprintf(stderr, "error: %s has the \"optional\" header present\n", objfilename); exit(2); } sections_raw = (struct external_scnhdr *) (objfilemap + sizeof(struct external_filehdr)); nsections = get_u16(filehdr_struct->f_nscns); symtab_offset = get_u32(filehdr_struct->f_symptr); symtab_raw = (struct external_syment *)(objfilemap + symtab_offset); nsymtab = get_u32(filehdr_struct->f_nsyms); strtab_offset = symtab_offset + sizeof(struct external_syment) * nsymtab; } static char * get_secorsym_name(ptr) u_char *ptr; { char *alloc; if (ptr[0]) { if (ptr[7]) { alloc = malloc(9); if (!alloc) { perror("malloc"); exit(2); } bcopy(ptr, alloc, 8); alloc[8] = '\0'; return(alloc); } else return((char *) ptr); } if (ptr[1] || ptr[2] || ptr[3]) { fprintf(stderr, "error: malformed name in %s at offset 0x%x\n", objfilename, ptr - objfilemap); exit(2); } return(objfilemap + strtab_offset + get_u32(ptr+4)); } get_int_section_table() { unsigned n; sections = malloc(sizeof(struct internal_scnhdr) * nsections); if (!sections) { perror("malloc"); exit(2); } for (n = 0; n < nsections; n++) { sections[n].name = get_secorsym_name(sections_raw[n].s_name); if (get_u32(sections_raw[n].s_paddr)) fprintf(stderr, "warning: section #%u (%s) has nonzero paddr\n", n, sections[n].name); if (get_u32(sections_raw[n].s_vaddr)) fprintf(stderr, "warning: section #%u (%s) has nonzero vaddr\n", n, sections[n].name); sections[n].size = get_u32(sections_raw[n].s_size); sections[n].data_offset = get_u32(sections_raw[n].s_scnptr); sections[n].reloc_offset = get_u32(sections_raw[n].s_relptr); sections[n].line_offset = get_u32(sections_raw[n].s_lnnoptr); sections[n].nreloc = get_u32(sections_raw[n].s_nreloc); sections[n].nlineent = get_u32(sections_raw[n].s_nlnno); sections[n].flags = get_u32(sections_raw[n].s_flags); if (get_u16(sections_raw[n].s_reserved)) fprintf(stderr, "warning: section #%u (%s): some nonzero value in s_reserved bytes\n", n, sections[n].name); if (get_u16(sections_raw[n].s_page)) fprintf(stderr, "warning: section #%u (%s): some nonzero value in s_page bytes\n", n, sections[n].name); sections[n].nsymbols = 0; sections[n].recov_flag = 0; } } get_int_symbol_table() { unsigned n; struct internal_syment *in; symtab = malloc(sizeof(struct internal_syment *) * nsymtab); if (!symtab) { perror("malloc"); exit(2); } for (n = 0; n < nsymtab; ) { in = malloc(sizeof(struct internal_syment)); if (!in) { perror("malloc"); exit(2); } symtab[n] = in; in->number = n; in->name = get_secorsym_name(symtab_raw[n].e_name); in->value = get_u32(symtab_raw[n].e_value); in->scnum = get_s16(symtab_raw[n].e_scnum); if (in->scnum > 0) { if (in->scnum > nsections) { fprintf(stderr, "symtab entry #%u: scnum too big\n", n); exit(2); } in->section = sections + in->scnum - 1; in->section->nsymbols++; } else if (in->scnum < -2) { fprintf(stderr, "symtab entry #%u: scnum < -2\n", n); exit(2); } else in->section = 0; in->type = get_u16(symtab_raw[n].e_type); in->class = symtab_raw[n].e_sclass; switch (symtab_raw[n++].e_numaux) { case 0: in->aux = 0; continue; case 1: if (n >= nsymtab) { fprintf(stderr, "error: last symbol's aux spills over\n"); exit(2); } symtab[n] = 0; in->aux = (u_char *)(symtab_raw + n); n++; continue; default: n--; fprintf(stderr, "symtab entry #%u: invalid numaux\n", n); exit(2); } } }