/* * decode.c * * Find all the symbols in an ALF or AOF file. * * © 1994-1998 Straylight */ /*----- 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 #include #include #include "decode.h" #include "aof/chunk.h" #include "aof/aof.h" #include "aof/alf.h" #include "error.h" static int decode__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 int decode__listALF(chunk_header *c, hashtable h, FILE *fp, char *name, int entry) { int size=c->table[entry].size; /* Help the compiler a bit */ char *data=malloc(size); /* Allocate memory for chunk */ name=name; { if (!data) error(NOMEM); } { /* --- Note to the squeamish --- * * * I've done naughty things with fpos_t here to avoid reading the file * sequentially. This file isn't doing anything particularly portable * anyway, so this is no great hardship. */ fpos_t off; /* To set file position */ off.__lo=c->table[entry].offset; /* Widge the position indicator */ fsetpos(fp,&off); /* Set the file offset nicely */ fread(data,1,size,fp); /* Read external names table */ } { int i=0; /* Counter through data */ alf_symTable *tbl; /* Pointer to actual structures */ while (idata)) /* Try to add the symbol name */ error(NOMEM); i+=tbl->entryLength; /* Bump the index along a bit */ } } { free(data); } return (0); } static int decode__listAOF(chunk_header *c, hashtable h, FILE *fp, char *name, int sym, int str) { int sizeSym=c->table[sym].size; /* Help the compiler a bit */ int sizeStr=c->table[str].size; /* Help the compiler a bit */ aof_symbol *symbol=malloc(sizeSym); /* Memory for symbol table */ char *string=malloc(sizeStr); /* Memory for string table */ int symbols; /* Number of symbol entries */ int headoff=0; /* Offset to AOF header chunk */ int err=0; /* No errors yet */ /* --- Check we got the memory --- */ { if (!symbol || !string) error(NOMEM); } if (!err) { if (headoff=decode__findChunk(c,"OBJ_HEAD"),headoff==-1) { error(BADFILE,name); err=1; } } if (!err) { /* --- Note to the squeamish --- * * * I've done naughty things with fpos_t here to avoid reading the file * sequentially. This file isn't doing anything particularly portable * anyway, so this is no great hardship. */ fpos_t off; /* To set file position */ off.__lo=c->table[headoff].offset+12l; /* Find number of symbols */ fsetpos(fp,&off); /* Set the file offset nicely */ fread(&symbols,sizeof(symbols),1,fp); /* Read symbol count */ off.__lo=c->table[sym].offset; /* Widge the position indicator */ fsetpos(fp,&off); /* Set the file offset nicely */ fread(symbol,1,sizeSym,fp); /* Read symbol table */ off.__lo=c->table[str].offset; /* Widge the position indicator */ fsetpos(fp,&off); /* Set the file offset nicely */ fread(string,1,sizeStr,fp); /* Read string table */ } if (!err) { int i; /* Counter through data */ for (i=0;ihdr=ch; fread(chf->table,sizeof(chunk_tableEntry),ch.maxChunks,fp); } } } if (!err) { int index; /* Index of symbol table chunk */ int string; /* Index of string table chunk */ if (index=decode__findChunk(chf,"OFL_SYMT"),index!=-1) decode__listALF(chf,h,fp,filename,index); else if ( (index=decode__findChunk(chf,"OBJ_SYMT"),index!=-1) && (string=decode__findChunk(chf,"OBJ_STRT"),string!=-1)) decode__listAOF(chf,h,fp,filename,index,string); else { error(BADFILE,filename); err=1; } } { if (fp) fclose(fp); /* Don't need this any more */ free(chf); /* Get rid of that too */ } return (err); }