Initial revision
[ssr] / StraySrc / SDLS / cdll / c / dissect
CommitLineData
2ee739cc 1/*
2 * dissect an aof file into areas
3 */
4
5/*----- Licensing note ----------------------------------------------------*
6 *
7 * This file is part of Straylight's Dynamic Linking System (SDLS)
8 *
9 * SDLS is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2, or (at your option)
12 * any later version.
13 *
14 * SDLS is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with SDLS. If not, write to the Free Software Foundation,
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 */
23
24#include "aof/chunk.h"
25
26#define aof_RELOC (0xC5E2D080ul) /* Relocatable object type */
27
28typedef struct
29{
30 unsigned long type; /* Type of object file */
31 int version; /* Version number of the format */
32 int areas; /* Number of AREAs defined */
33 int symbols; /* Number of symbols in table */
34 int entryArea; /* Index of AREA with ENTRY att */
35 int entryOff; /* Offset in AREA for ENTRY */
36}
37aof_fixedHeader;
38
39typedef struct
40{
41 int name; /* AREA name (OBJ_STRT offset) */
42
43 int alignment :8; /* AREA alignment (must be 2) */
44
45 int :1; /* Reserved bit */
46 int code :1; /* AREA contains code */
47 int common :1; /* Common AREA definition */
48 int commonRef :1; /* Reference to common AREA */
49 int zinit :1; /* AREA is zero-initialised */
50 int readonly :1; /* AREA is (sort-of) readonly */
51 int :1; /* Reserved bit */
52 int debug :1; /* AREA contains debug tables */
53 int :16; /* Reserved shortword */
54
55 int size; /* Size of this AREA */
56 int relocs; /* Number of relocations */
57 int :32; /* Reserved word */
58}
59aof_areaEntry;
60
61typedef struct
62{
63 aof_fixedHeader hdr; /* The fixed header info */
64 aof_areaEntry table[1]; /* AREA table (unsized array) */
65}
66aof_header;
67
68typedef struct
69{
70 int name; /* Name string table entry */
71
72 int defined :1; /* Symbol defined in file */
73 int export :1; /* Symbol is exported globally */
74 int absolute :1; /* Symbol not relative to AREA */
75 int ignoreCase :1; /* Symbol is not case sensitive */
76 int weak :1; /* Symbol is weak external ref */
77 int strong :1; /* Symbol is strong global */
78 int common :1; /* Symbol is in a common AREA */
79 int :32-7; /* Pad out to integer boundary */
80
81 int value; /* Value of the symbol */
82 int area; /* Offset of AREA name */
83}
84aof_symbol;
85
86typedef struct
87{
88 int offset; /* Offset of word to relocate */
89 union
90 {
91 struct
92 {
93 int symbol :16; /* Symbol to relocate by/to */
94 int field :2; /* Field size to alter */
95 int type :1; /* Relocation type */
96 int symreloc :1; /* Relocation is symbol-relative*/
97 int :12; /* Reserved bits */
98 }
99 type_1; /* Type 1 relocation directive */
100
101 struct
102 {
103 int symbol :24; /* Symbol to relocate by/to */
104 int field :2; /* Field size to alter */
105 int type :1; /* Relocation type */
106 int symreloc :1; /* Relocation is symbol-relative*/
107 int :3; /* Reserved bits */
108 int set_me :1; /* Set this bit for type 2 */
109 }
110 type_2; /* Type 2 relocation directive */
111 }
112 t;
113}
114aof_relocstr;
115
116enum
117{
118 aof_BYTE,
119 aof_HALFWORD,
120 aof_FULLWORD
121};
122
123enum
124{
125 aof_ADDITIVE,
126 aof_PCRELATIVE
127};
128
129#include <stdlib.h>
130#include <stdio.h>
131#include <string.h>
132#include <ctype.h>
133#include <stdarg.h>
134
135static char *nicely(char *name)
136{
137 char *p=name;
138 while (*name)
139 {
140 if (!isalnum(*name))
141 *name='_';
142 name++;
143 }
144 if (strlen(p)>10)
145 p[10]=0;
146 return (p);
147}
148
149static int oscli(char *cmd,...)
150{
151 char buffer[256];
152 va_list ap;
153 va_start(ap,cmd);
154 vsprintf(buffer,cmd,ap);
155 va_end(ap);
156 return (system(buffer));
157}
158
159static int findChunk(chunk_header *c,char *name)
160{
161 int i;
162 for (i=0;i<c->hdr.maxChunks;i++)
163 {
164 if (c->table[i].offset && !memcmp(c->table[i].chunkName,name,8))
165 return (i);
166 }
167 return (-1);
168}
169
170static void get(void *p,FILE *fp,size_t size,size_t offset)
171{
172 fpos_t off;
173 off.__lo=offset;
174 fsetpos(fp,&off);
175 fread(p,size,1,fp);
176}
177
178static int dissect(char *aof,char *dir)
179{
180 FILE *fp;
181 FILE *out;
182 chunk_fixedHeader ch={0,0,0};
183 chunk_header *chf;
184 aof_header *header;
185 char *area;
186 char *string;
187 int h;
188 int a;
189 int s;
190 int bit=0;
191 char name[256];
192 int i;
193
194 oscli("cdir %s",dir);
195 fp=fopen(aof,"rb");
196 if (!fp)
197 {
198 fprintf(stderr,"couldn't open '%s'\n",aof);
199 return (1);
200 }
201 fread(&ch,sizeof(ch),1,fp);
202 if (ch.id!=chunk_MAGIC)
203 {
204 fprintf(stderr,"bad aof '%s'\n",aof);
205 return (1);
206 }
207 chf=malloc(sizeof(chunk_fixedHeader)+
208 ch.maxChunks*sizeof(chunk_tableEntry));
209 if (!chf)
210 {
211 fprintf(stderr,"no memory\n");
212 exit(1);
213 }
214 chf->hdr=ch;
215 fread(chf->table,sizeof(chunk_tableEntry),ch.maxChunks,fp);
216
217 h=findChunk(chf,"OBJ_HEAD");
218 a=findChunk(chf,"OBJ_AREA");
219 s=findChunk(chf,"OBJ_STRT");
220 if (h==-1 || a==-1 || s==-1)
221 {
222 fprintf(stderr,"bad aof '%s'\n",aof);
223 return (1);
224 }
225
226 header=malloc(chf->table[h].size);
227 area=malloc(chf->table[a].size);
228 string=malloc(chf->table[s].size);
229 if (!header || !area || !string)
230 {
231 fprintf(stderr,"no memory\n");
232 exit(1);
233 }
234
235 get(header,fp,chf->table[h].size,chf->table[h].offset);
236 get(area,fp,chf->table[a].size,chf->table[a].offset);
237 get(string,fp,chf->table[s].size,chf->table[s].offset);
238
239 for (i=0;i<header->hdr.areas;i++)
240 {
241 if (header->table[i].zinit)
242 continue;
243 sprintf(name,"%s.%s",dir,nicely(string+header->table[i].name));
244 out=fopen(name,"wb");
245 if (!out)
246 {
247 fprintf(stderr,"couldn't write '%s'\n",name);
248 continue;
249 }
250 fwrite(area+bit,1,header->table[i].size,out);
251 bit+=header->table[i].size+header->table[i].relocs*8;
252 fclose(out);
253 }
254 return (0);
255}
256
257int main(int argc,char *argv[])
258{
259 if (argc!=3)
260 {
261 fprintf(stderr,"dissect <aof> <dir>\n");
262 exit(1);
263 }
264 return (dissect(argv[1],argv[2]));
265}