FreeCalypso > hg > freecalypso-reveng
comparison leo-obj/tool/tables.c @ 130:87b82398a08b
leo-obj project subtree started, tiobjd tool moved into it
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 06 Apr 2014 22:14:39 +0000 |
parents | ticoff/tables.c@a314d6aa9bf1 |
children | fd772de226cb |
comparison
equal
deleted
inserted
replaced
129:597143ba1c37 | 130:87b82398a08b |
---|---|
1 /* | |
2 * This C module will contain 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 static char * | |
18 get_secorsym_name(ptr) | |
19 u_char *ptr; | |
20 { | |
21 char *alloc; | |
22 | |
23 if (ptr[0]) { | |
24 if (ptr[7]) { | |
25 alloc = malloc(9); | |
26 if (!alloc) { | |
27 perror("malloc"); | |
28 exit(1); | |
29 } | |
30 bcopy(ptr, alloc, 8); | |
31 alloc[8] = '\0'; | |
32 return(alloc); | |
33 } else | |
34 return((char *) ptr); | |
35 } | |
36 if (ptr[1] || ptr[2] || ptr[3]) { | |
37 fprintf(stderr, "error: malformed name in %s at offset 0x%x\n", | |
38 objfilename, ptr - filemap); | |
39 exit(1); | |
40 } | |
41 return(filemap + strtab_offset + get_u32(ptr+4)); | |
42 } | |
43 | |
44 get_int_section_table() | |
45 { | |
46 unsigned n; | |
47 | |
48 sections = malloc(sizeof(struct internal_scnhdr) * nsections); | |
49 if (!sections) { | |
50 perror("malloc"); | |
51 exit(1); | |
52 } | |
53 for (n = 0; n < nsections; n++) { | |
54 sections[n].name = get_secorsym_name(sections_raw[n].s_name); | |
55 if (get_u32(sections_raw[n].s_paddr)) | |
56 fprintf(stderr, | |
57 "warning: section #%u (%s) has nonzero paddr\n", | |
58 n, sections[n].name); | |
59 if (get_u32(sections_raw[n].s_vaddr)) | |
60 fprintf(stderr, | |
61 "warning: section #%u (%s) has nonzero vaddr\n", | |
62 n, sections[n].name); | |
63 sections[n].size = get_u32(sections_raw[n].s_size); | |
64 sections[n].data_offset = get_u32(sections_raw[n].s_scnptr); | |
65 sections[n].reloc_offset = get_u32(sections_raw[n].s_relptr); | |
66 sections[n].line_offset = get_u32(sections_raw[n].s_lnnoptr); | |
67 sections[n].nreloc = get_u32(sections_raw[n].s_nreloc); | |
68 sections[n].nlineent = get_u32(sections_raw[n].s_nlnno); | |
69 sections[n].flags = get_u32(sections_raw[n].s_flags); | |
70 if (get_u16(sections_raw[n].s_reserved)) | |
71 fprintf(stderr, | |
72 "warning: section #%u (%s): some nonzero value in s_reserved bytes\n", | |
73 n, sections[n].name); | |
74 if (get_u16(sections_raw[n].s_page)) | |
75 fprintf(stderr, | |
76 "warning: section #%u (%s): some nonzero value in s_page bytes\n", | |
77 n, sections[n].name); | |
78 sections[n].nsymbols = 0; | |
79 sections[n].sorted_symbols = 0; | |
80 sections[n].int_relocs = 0; | |
81 if (!strncmp(sections[n].name, ".text", 5)) | |
82 sections[n].disasm_mode = DISASM_MODE_CODE; | |
83 else if (!strcmp(sections[n].name, ".const")) | |
84 sections[n].disasm_mode = DISASM_MODE_DATA; | |
85 else if (!strcmp(sections[n].name, ".cinit")) | |
86 sections[n].disasm_mode = DISASM_MODE_DATA; | |
87 else if (!strcmp(sections[n].name, ".data")) | |
88 sections[n].disasm_mode = DISASM_MODE_DATA; | |
89 else if (!strcmp(sections[n].name, ".bss")) | |
90 sections[n].disasm_mode = DISASM_MODE_BSS; | |
91 else | |
92 sections[n].disasm_mode = DISASM_MODE_UNKNOWN; | |
93 sections[n].hints = 0; | |
94 } | |
95 } | |
96 | |
97 get_int_symbol_table() | |
98 { | |
99 unsigned n; | |
100 struct internal_syment *in; | |
101 | |
102 symtab = malloc(sizeof(struct internal_syment *) * nsymtab); | |
103 if (!symtab) { | |
104 perror("malloc"); | |
105 exit(1); | |
106 } | |
107 for (n = 0; n < nsymtab; ) { | |
108 in = malloc(sizeof(struct internal_syment)); | |
109 if (!in) { | |
110 perror("malloc"); | |
111 exit(1); | |
112 } | |
113 symtab[n] = in; | |
114 in->number = n; | |
115 in->name = get_secorsym_name(symtab_raw[n].e_name); | |
116 in->value = get_u32(symtab_raw[n].e_value); | |
117 in->scnum = get_s16(symtab_raw[n].e_scnum); | |
118 if (in->scnum > 0) { | |
119 if (in->scnum > nsections) { | |
120 fprintf(stderr, | |
121 "symtab entry #%u: scnum too big\n", n); | |
122 exit(1); | |
123 } | |
124 in->section = sections + in->scnum - 1; | |
125 in->section->nsymbols++; | |
126 } else if (in->scnum < -2) { | |
127 fprintf(stderr, | |
128 "symtab entry #%u: scnum < -2\n", n); | |
129 exit(1); | |
130 } else | |
131 in->section = 0; | |
132 in->type = get_u16(symtab_raw[n].e_type); | |
133 in->class = symtab_raw[n].e_sclass; | |
134 switch (symtab_raw[n++].e_numaux) { | |
135 case 0: | |
136 in->aux = 0; | |
137 continue; | |
138 case 1: | |
139 if (n >= nsymtab) { | |
140 fprintf(stderr, | |
141 "error: last symbol's aux spills over\n"); | |
142 exit(1); | |
143 } | |
144 symtab[n] = 0; | |
145 in->aux = (u_char *)(symtab_raw + n); | |
146 n++; | |
147 continue; | |
148 default: | |
149 n--; | |
150 fprintf(stderr, "symtab entry #%u: invalid numaux\n", | |
151 n); | |
152 exit(1); | |
153 } | |
154 } | |
155 } |