/* * dissect an aof file into areas */ /*----- Licensing note ----------------------------------------------------* * * This file is part of Straylight's Dynamic Linking System (SDLS) * * SDLS is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * SDLS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with SDLS. If not, write to the Free Software Foundation, * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "aof/chunk.h" #define aof_RELOC (0xC5E2D080ul) /* Relocatable object type */ typedef struct { unsigned long type; /* Type of object file */ int version; /* Version number of the format */ int areas; /* Number of AREAs defined */ int symbols; /* Number of symbols in table */ int entryArea; /* Index of AREA with ENTRY att */ int entryOff; /* Offset in AREA for ENTRY */ } aof_fixedHeader; typedef struct { int name; /* AREA name (OBJ_STRT offset) */ int alignment :8; /* AREA alignment (must be 2) */ int :1; /* Reserved bit */ int code :1; /* AREA contains code */ int common :1; /* Common AREA definition */ int commonRef :1; /* Reference to common AREA */ int zinit :1; /* AREA is zero-initialised */ int readonly :1; /* AREA is (sort-of) readonly */ int :1; /* Reserved bit */ int debug :1; /* AREA contains debug tables */ int :16; /* Reserved shortword */ int size; /* Size of this AREA */ int relocs; /* Number of relocations */ int :32; /* Reserved word */ } aof_areaEntry; typedef struct { aof_fixedHeader hdr; /* The fixed header info */ aof_areaEntry table[1]; /* AREA table (unsized array) */ } aof_header; typedef struct { int name; /* Name string table entry */ int defined :1; /* Symbol defined in file */ int export :1; /* Symbol is exported globally */ int absolute :1; /* Symbol not relative to AREA */ int ignoreCase :1; /* Symbol is not case sensitive */ int weak :1; /* Symbol is weak external ref */ int strong :1; /* Symbol is strong global */ int common :1; /* Symbol is in a common AREA */ int :32-7; /* Pad out to integer boundary */ int value; /* Value of the symbol */ int area; /* Offset of AREA name */ } aof_symbol; typedef struct { int offset; /* Offset of word to relocate */ union { struct { int symbol :16; /* Symbol to relocate by/to */ int field :2; /* Field size to alter */ int type :1; /* Relocation type */ int symreloc :1; /* Relocation is symbol-relative*/ int :12; /* Reserved bits */ } type_1; /* Type 1 relocation directive */ struct { int symbol :24; /* Symbol to relocate by/to */ int field :2; /* Field size to alter */ int type :1; /* Relocation type */ int symreloc :1; /* Relocation is symbol-relative*/ int :3; /* Reserved bits */ int set_me :1; /* Set this bit for type 2 */ } type_2; /* Type 2 relocation directive */ } t; } aof_relocstr; enum { aof_BYTE, aof_HALFWORD, aof_FULLWORD }; enum { aof_ADDITIVE, aof_PCRELATIVE }; #include #include #include #include #include static char *nicely(char *name) { char *p=name; while (*name) { if (!isalnum(*name)) *name='_'; name++; } if (strlen(p)>10) p[10]=0; return (p); } static int oscli(char *cmd,...) { char buffer[256]; va_list ap; va_start(ap,cmd); vsprintf(buffer,cmd,ap); va_end(ap); return (system(buffer)); } static int findChunk(chunk_header *c,char *name) { int i; for (i=0;ihdr.maxChunks;i++) { if (c->table[i].offset && !memcmp(c->table[i].chunkName,name,8)) return (i); } return (-1); } static void get(void *p,FILE *fp,size_t size,size_t offset) { fpos_t off; off.__lo=offset; fsetpos(fp,&off); fread(p,size,1,fp); } static int dissect(char *aof,char *dir) { FILE *fp; FILE *out; chunk_fixedHeader ch={0,0,0}; chunk_header *chf; aof_header *header; char *area; char *string; int h; int a; int s; int bit=0; char name[256]; int i; oscli("cdir %s",dir); fp=fopen(aof,"rb"); if (!fp) { fprintf(stderr,"couldn't open '%s'\n",aof); return (1); } fread(&ch,sizeof(ch),1,fp); if (ch.id!=chunk_MAGIC) { fprintf(stderr,"bad aof '%s'\n",aof); return (1); } chf=malloc(sizeof(chunk_fixedHeader)+ ch.maxChunks*sizeof(chunk_tableEntry)); if (!chf) { fprintf(stderr,"no memory\n"); exit(1); } chf->hdr=ch; fread(chf->table,sizeof(chunk_tableEntry),ch.maxChunks,fp); h=findChunk(chf,"OBJ_HEAD"); a=findChunk(chf,"OBJ_AREA"); s=findChunk(chf,"OBJ_STRT"); if (h==-1 || a==-1 || s==-1) { fprintf(stderr,"bad aof '%s'\n",aof); return (1); } header=malloc(chf->table[h].size); area=malloc(chf->table[a].size); string=malloc(chf->table[s].size); if (!header || !area || !string) { fprintf(stderr,"no memory\n"); exit(1); } get(header,fp,chf->table[h].size,chf->table[h].offset); get(area,fp,chf->table[a].size,chf->table[a].offset); get(string,fp,chf->table[s].size,chf->table[s].offset); for (i=0;ihdr.areas;i++) { if (header->table[i].zinit) continue; sprintf(name,"%s.%s",dir,nicely(string+header->table[i].name)); out=fopen(name,"wb"); if (!out) { fprintf(stderr,"couldn't write '%s'\n",name); continue; } fwrite(area+bit,1,header->table[i].size,out); bit+=header->table[i].size+header->table[i].relocs*8; fclose(out); } return (0); } int main(int argc,char *argv[]) { if (argc!=3) { fprintf(stderr,"dissect \n"); exit(1); } return (dissect(argv[1],argv[2])); }