Initial revision
[ssr] / StraySrc / SDLS / cdll / c / decode
1 /*
2 * decode.c
3 *
4 * Find all the symbols in an ALF or AOF file.
5 *
6 * © 1994-1998 Straylight
7 */
8
9 /*----- Licensing note ----------------------------------------------------*
10 *
11 * This file is part of Straylight's Dynamic Linking System (SDLS)
12 *
13 * SDLS is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 2, or (at your option)
16 * any later version.
17 *
18 * SDLS is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with SDLS. If not, write to the Free Software Foundation,
25 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include "decode.h"
33 #include "aof/chunk.h"
34 #include "aof/aof.h"
35 #include "aof/alf.h"
36 #include "error.h"
37
38 static int decode__findChunk(chunk_header *c,char *name)
39 {
40 int i;
41 for (i=0;i<c->hdr.maxChunks;i++)
42 {
43 if (c->table[i].offset && !memcmp(c->table[i].chunkName,name,8))
44 return (i);
45 }
46 return (-1);
47 }
48
49 static int decode__listALF(chunk_header *c,
50 hashtable h,
51 FILE *fp,
52 char *name,
53 int entry)
54 {
55 int size=c->table[entry].size; /* Help the compiler a bit */
56 char *data=malloc(size); /* Allocate memory for chunk */
57
58 name=name;
59
60 {
61 if (!data)
62 error(NOMEM);
63 }
64
65 {
66 /* --- Note to the squeamish --- *
67 *
68 * I've done naughty things with fpos_t here to avoid reading the file
69 * sequentially. This file isn't doing anything particularly portable
70 * anyway, so this is no great hardship.
71 */
72
73 fpos_t off; /* To set file position */
74 off.__lo=c->table[entry].offset; /* Widge the position indicator */
75 fsetpos(fp,&off); /* Set the file offset nicely */
76 fread(data,1,size,fp); /* Read external names table */
77 }
78
79 {
80 int i=0; /* Counter through data */
81 alf_symTable *tbl; /* Pointer to actual structures */
82 while (i<size) /* Continue until no more */
83 {
84 tbl=(alf_symTable *)(data+i); /* Set up the pointer */
85 if (!hash_add(h,tbl->data)) /* Try to add the symbol name */
86 error(NOMEM);
87 i+=tbl->entryLength; /* Bump the index along a bit */
88 }
89 }
90
91 {
92 free(data);
93 }
94
95 return (0);
96 }
97
98 static int decode__listAOF(chunk_header *c,
99 hashtable h,
100 FILE *fp,
101 char *name,
102 int sym,
103 int str)
104
105 {
106 int sizeSym=c->table[sym].size; /* Help the compiler a bit */
107 int sizeStr=c->table[str].size; /* Help the compiler a bit */
108 aof_symbol *symbol=malloc(sizeSym); /* Memory for symbol table */
109 char *string=malloc(sizeStr); /* Memory for string table */
110 int symbols; /* Number of symbol entries */
111 int headoff=0; /* Offset to AOF header chunk */
112 int err=0; /* No errors yet */
113
114 /* --- Check we got the memory --- */
115
116 {
117 if (!symbol || !string)
118 error(NOMEM);
119 }
120
121 if (!err)
122 {
123 if (headoff=decode__findChunk(c,"OBJ_HEAD"),headoff==-1)
124 {
125 error(BADFILE,name);
126 err=1;
127 }
128 }
129
130 if (!err)
131 {
132 /* --- Note to the squeamish --- *
133 *
134 * I've done naughty things with fpos_t here to avoid reading the file
135 * sequentially. This file isn't doing anything particularly portable
136 * anyway, so this is no great hardship.
137 */
138
139 fpos_t off; /* To set file position */
140
141 off.__lo=c->table[headoff].offset+12l; /* Find number of symbols */
142 fsetpos(fp,&off); /* Set the file offset nicely */
143 fread(&symbols,sizeof(symbols),1,fp); /* Read symbol count */
144 off.__lo=c->table[sym].offset; /* Widge the position indicator */
145 fsetpos(fp,&off); /* Set the file offset nicely */
146 fread(symbol,1,sizeSym,fp); /* Read symbol table */
147 off.__lo=c->table[str].offset; /* Widge the position indicator */
148 fsetpos(fp,&off); /* Set the file offset nicely */
149 fread(string,1,sizeStr,fp); /* Read string table */
150 }
151
152 if (!err)
153 {
154 int i; /* Counter through data */
155 for (i=0;i<symbols;i++)
156 {
157 if (symbol[i].defined && symbol[i].export)
158 {
159 if (!hash_add(h,string+symbol[i].name))
160 error(NOMEM);
161 }
162 }
163 }
164
165 {
166 free(string);
167 free(symbol);
168 }
169
170 return (err);
171 }
172
173 int decode(hashtable h,char *filename)
174 {
175 chunk_header *chf=0; /* Ptr to block to read table */
176 FILE *fp=fopen(filename,"rb"); /* Open for binary reading */
177 int err=0; /* No errors yet */
178
179 {
180 chunk_fixedHeader ch={0,0,0}; /* For reading in the header */
181
182 if (!fp) /* If open failed,... */
183 {
184 error(NOOPENIN,filename); /* Report an error, and */
185 err=1; /* return gracefully */
186 }
187 else
188 {
189 fread(&ch,sizeof(ch),1,fp); /* Read the file's header */
190 if (ch.id!=chunk_MAGIC) /* Check it's a real chunk file */
191 {
192 error(BADFILE,filename);
193 err=1;
194 }
195 else
196 {
197 chf=malloc(sizeof(chunk_fixedHeader)+
198 ch.maxChunks*sizeof(chunk_tableEntry));
199 if (!chf) /* If allocation failed */
200 error(NOMEM);
201 chf->hdr=ch;
202 fread(chf->table,sizeof(chunk_tableEntry),ch.maxChunks,fp);
203 }
204 }
205 }
206
207 if (!err)
208 {
209 int index; /* Index of symbol table chunk */
210 int string; /* Index of string table chunk */
211
212 if (index=decode__findChunk(chf,"OFL_SYMT"),index!=-1)
213 decode__listALF(chf,h,fp,filename,index);
214 else if ( (index=decode__findChunk(chf,"OBJ_SYMT"),index!=-1) &&
215 (string=decode__findChunk(chf,"OBJ_STRT"),string!=-1))
216 decode__listAOF(chf,h,fp,filename,index,string);
217 else
218 {
219 error(BADFILE,filename);
220 err=1;
221 }
222 }
223
224 {
225 if (fp)
226 fclose(fp); /* Don't need this any more */
227 free(chf); /* Get rid of that too */
228 }
229
230 return (err);
231 }