FreeCalypso > hg > freecalypso-reveng
view leo-obj/tool/tables.c @ 133:daeaa5950d10
tiobjd: Thumb bl w/o reloc: find symbol if there is one
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Mon, 07 Apr 2014 01:22:09 +0000 |
parents | 87b82398a08b |
children | fd772de226cb |
line wrap: on
line source
/* * This C module will contain 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(); 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(1); } 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 - filemap); exit(1); } return(filemap + strtab_offset + get_u32(ptr+4)); } get_int_section_table() { unsigned n; sections = malloc(sizeof(struct internal_scnhdr) * nsections); if (!sections) { perror("malloc"); exit(1); } 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].sorted_symbols = 0; sections[n].int_relocs = 0; if (!strncmp(sections[n].name, ".text", 5)) sections[n].disasm_mode = DISASM_MODE_CODE; else if (!strcmp(sections[n].name, ".const")) sections[n].disasm_mode = DISASM_MODE_DATA; else if (!strcmp(sections[n].name, ".cinit")) sections[n].disasm_mode = DISASM_MODE_DATA; else if (!strcmp(sections[n].name, ".data")) sections[n].disasm_mode = DISASM_MODE_DATA; else if (!strcmp(sections[n].name, ".bss")) sections[n].disasm_mode = DISASM_MODE_BSS; else sections[n].disasm_mode = DISASM_MODE_UNKNOWN; sections[n].hints = 0; } } get_int_symbol_table() { unsigned n; struct internal_syment *in; symtab = malloc(sizeof(struct internal_syment *) * nsymtab); if (!symtab) { perror("malloc"); exit(1); } for (n = 0; n < nsymtab; ) { in = malloc(sizeof(struct internal_syment)); if (!in) { perror("malloc"); exit(1); } 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(1); } in->section = sections + in->scnum - 1; in->section->nsymbols++; } else if (in->scnum < -2) { fprintf(stderr, "symtab entry #%u: scnum < -2\n", n); exit(1); } 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(1); } symtab[n] = 0; in->aux = (u_char *)(symtab_raw + n); n++; continue; default: n--; fprintf(stderr, "symtab entry #%u: invalid numaux\n", n); exit(1); } } }