FreeCalypso > hg > freecalypso-reveng
comparison objgrep/tables.c @ 167:c25367bb7656
objgrep: written, compiles
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Fri, 04 Jul 2014 00:54:33 +0000 |
parents | leo-obj/tool/tables.c@fd772de226cb |
children | 77cd647375e5 |
comparison
equal
deleted
inserted
replaced
166:861f5ca49581 | 167:c25367bb7656 |
---|---|
1 /* | |
2 * This C module contains functions for the initial parsing | |
3 * of the section and symbol tables. | |
4 */ | |
5 | |
6 #include <sys/types.h> | |
7 #include <stdio.h> | |
8 #include <stdlib.h> | |
9 #include <string.h> | |
10 #include <strings.h> | |
11 #include "filestruct.h" | |
12 #include "intstruct.h" | |
13 #include "globals.h" | |
14 | |
15 extern unsigned get_u16(), get_u32(); | |
16 | |
17 initial_parse_hdr() | |
18 { | |
19 unsigned symtab_offset; | |
20 | |
21 filehdr_struct = (struct external_filehdr *) objfilemap; | |
22 if (get_u16(filehdr_struct->f_magic) != 0xC2) { | |
23 fprintf(stderr, "error: %s is not a TI COFF2 object\n", | |
24 objfilename); | |
25 exit(2); | |
26 } | |
27 if (get_u16(filehdr_struct->f_target_id) != 0x97) { | |
28 fprintf(stderr, "error: TI COFF object %s is not for TMS470\n", | |
29 objfilename); | |
30 exit(2); | |
31 } | |
32 if (get_u16(filehdr_struct->f_opthdr)) { | |
33 fprintf(stderr, | |
34 "error: %s has the \"optional\" header present\n", | |
35 objfilename); | |
36 exit(2); | |
37 } | |
38 sections_raw = (struct external_scnhdr *) | |
39 (objfilemap + sizeof(struct external_filehdr)); | |
40 nsections = get_u16(filehdr_struct->f_nscns); | |
41 symtab_offset = get_u32(filehdr_struct->f_symptr); | |
42 symtab_raw = (struct external_syment *)(objfilemap + symtab_offset); | |
43 nsymtab = get_u32(filehdr_struct->f_nsyms); | |
44 strtab_offset = symtab_offset + | |
45 sizeof(struct external_syment) * nsymtab; | |
46 } | |
47 | |
48 static char * | |
49 get_secorsym_name(ptr) | |
50 u_char *ptr; | |
51 { | |
52 char *alloc; | |
53 | |
54 if (ptr[0]) { | |
55 if (ptr[7]) { | |
56 alloc = malloc(9); | |
57 if (!alloc) { | |
58 perror("malloc"); | |
59 exit(2); | |
60 } | |
61 bcopy(ptr, alloc, 8); | |
62 alloc[8] = '\0'; | |
63 return(alloc); | |
64 } else | |
65 return((char *) ptr); | |
66 } | |
67 if (ptr[1] || ptr[2] || ptr[3]) { | |
68 fprintf(stderr, "error: malformed name in %s at offset 0x%x\n", | |
69 objfilename, ptr - objfilemap); | |
70 exit(2); | |
71 } | |
72 return(objfilemap + strtab_offset + get_u32(ptr+4)); | |
73 } | |
74 | |
75 get_int_section_table() | |
76 { | |
77 unsigned n; | |
78 | |
79 sections = malloc(sizeof(struct internal_scnhdr) * nsections); | |
80 if (!sections) { | |
81 perror("malloc"); | |
82 exit(2); | |
83 } | |
84 for (n = 0; n < nsections; n++) { | |
85 sections[n].name = get_secorsym_name(sections_raw[n].s_name); | |
86 if (get_u32(sections_raw[n].s_paddr)) | |
87 fprintf(stderr, | |
88 "warning: section #%u (%s) has nonzero paddr\n", | |
89 n, sections[n].name); | |
90 if (get_u32(sections_raw[n].s_vaddr)) | |
91 fprintf(stderr, | |
92 "warning: section #%u (%s) has nonzero vaddr\n", | |
93 n, sections[n].name); | |
94 sections[n].size = get_u32(sections_raw[n].s_size); | |
95 sections[n].data_offset = get_u32(sections_raw[n].s_scnptr); | |
96 sections[n].reloc_offset = get_u32(sections_raw[n].s_relptr); | |
97 sections[n].line_offset = get_u32(sections_raw[n].s_lnnoptr); | |
98 sections[n].nreloc = get_u32(sections_raw[n].s_nreloc); | |
99 sections[n].nlineent = get_u32(sections_raw[n].s_nlnno); | |
100 sections[n].flags = get_u32(sections_raw[n].s_flags); | |
101 if (get_u16(sections_raw[n].s_reserved)) | |
102 fprintf(stderr, | |
103 "warning: section #%u (%s): some nonzero value in s_reserved bytes\n", | |
104 n, sections[n].name); | |
105 if (get_u16(sections_raw[n].s_page)) | |
106 fprintf(stderr, | |
107 "warning: section #%u (%s): some nonzero value in s_page bytes\n", | |
108 n, sections[n].name); | |
109 sections[n].nsymbols = 0; | |
110 } | |
111 } | |
112 | |
113 get_int_symbol_table() | |
114 { | |
115 unsigned n; | |
116 struct internal_syment *in; | |
117 | |
118 symtab = malloc(sizeof(struct internal_syment *) * nsymtab); | |
119 if (!symtab) { | |
120 perror("malloc"); | |
121 exit(2); | |
122 } | |
123 for (n = 0; n < nsymtab; ) { | |
124 in = malloc(sizeof(struct internal_syment)); | |
125 if (!in) { | |
126 perror("malloc"); | |
127 exit(2); | |
128 } | |
129 symtab[n] = in; | |
130 in->number = n; | |
131 in->name = get_secorsym_name(symtab_raw[n].e_name); | |
132 in->value = get_u32(symtab_raw[n].e_value); | |
133 in->scnum = get_s16(symtab_raw[n].e_scnum); | |
134 if (in->scnum > 0) { | |
135 if (in->scnum > nsections) { | |
136 fprintf(stderr, | |
137 "symtab entry #%u: scnum too big\n", n); | |
138 exit(2); | |
139 } | |
140 in->section = sections + in->scnum - 1; | |
141 in->section->nsymbols++; | |
142 } else if (in->scnum < -2) { | |
143 fprintf(stderr, | |
144 "symtab entry #%u: scnum < -2\n", n); | |
145 exit(2); | |
146 } else | |
147 in->section = 0; | |
148 in->type = get_u16(symtab_raw[n].e_type); | |
149 in->class = symtab_raw[n].e_sclass; | |
150 switch (symtab_raw[n++].e_numaux) { | |
151 case 0: | |
152 in->aux = 0; | |
153 continue; | |
154 case 1: | |
155 if (n >= nsymtab) { | |
156 fprintf(stderr, | |
157 "error: last symbol's aux spills over\n"); | |
158 exit(2); | |
159 } | |
160 symtab[n] = 0; | |
161 in->aux = (u_char *)(symtab_raw + n); | |
162 n++; | |
163 continue; | |
164 default: | |
165 n--; | |
166 fprintf(stderr, "symtab entry #%u: invalid numaux\n", | |
167 n); | |
168 exit(2); | |
169 } | |
170 } | |
171 } |