FreeCalypso > hg > freecalypso-reveng
view ticoff/tables.c @ 118:193926ccd1ec
tiobjd: better handling of section-relative relocs
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Thu, 03 Apr 2014 07:47:03 +0000 |
parents | 5f4141ee175b |
children | 2c6b1319383b |
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; } } 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); } } }