static void *ORLRead( void *_list, size_t len ) /**********************************************/ { file_list *list = _list; void *result; readcache *cache; result = CachePermRead( list, ORLFilePos + ORLPos, len ); ORLPos += len; _ChkAlloc( cache, sizeof( readcache ) ); cache->next = ReadCacheList; ReadCacheList = cache; cache->data = result; return( result ); }
static void ReadARStringTable( file_list *list, unsigned long *loc, unsigned size ) /*********************************************************************************/ { char *data; unsigned i; if( list->strtab == NULL && size > 0 ) { list->strtab = CachePermRead( list, *loc, size ); data = list->strtab; for( i = 0; i < size; ++i ) { if( *data == '\n' || *data == '/' && *(data + 1) == '\n' ) *data = '\0'; ++data; } } }
static void ReadARDictData( file_list *list, unsigned long *loc, unsigned size, int numdicts ) /********************************************************************************************/ { ar_dict_entry *dict; char *data; unsigned_32 num; unsigned_32 index; /* a dictionary in an AR archive commonly starts with a header marked with '/ '. Be careful, more AR formats exists, GNU, BSD and COFF. Each handle dictionaries a little bit different way. GNU (Linux) and BSD AR archives commonly have only one dictionary which is of the form: (all numbers in *big* endian format) unsigned_32: number of entries (num) num unsigned_32's: offset within AR file of the object file that the symbol name belongs too. num zero terminated strings: the symbols themselves (unsorted). COFF AR archieves however use two dictionaries. First one is the same as for GNU and BSD, but WLINK uses second one, more efficient dictionary: (all numbers in *little* endian format) unsigned_32: number of files in object nfiles unsigned_32's: offsets of the files within the archive unsigned_32: number of entries (num) num unsigned_16's: the file number that the symbol belongs to num zero terminated strings: the symbols themselves (sorted case-sensitively). however WLINK needs to be able to parse both kinds. (dict->offsettab == NULL) means that we only know about an unsorted dictionary and it will be sorted later. */ dict = &list->u.dict->a; data = CachePermRead( list, *loc, size ); if( numdicts == 1 ) { num = _ReadBigEndian32UN( data ); /* number of symbols */ data += sizeof( unsigned_32 ); dict->filepostab = (unsigned_32 *)data; for( index = 0; index < num; index++ ) { dict->filepostab[index] = _ReadBigEndian32UN( data ); data += sizeof( unsigned_32 ); } dict->num_entries = num; dict->offsettab = NULL; dict->symbtab = NULL; if( num > 0 ) { _ChkAlloc( dict->symbtab, sizeof( char * ) * num ); } } else /* if( numdicts == 2 ) */ { num = _ReadLittleEndian32UN( data ); /* number of files */ data += sizeof( unsigned_32 ); dict->filepostab = (unsigned_32 *)data; /* first file off */ for( index = 0; index < num; index++ ) { dict->filepostab[index] = _ReadLittleEndian32UN( data ); data += sizeof( unsigned_32 ); } num = _ReadLittleEndian32UN( data ); /* number of symbols */ data += sizeof( unsigned_32 ); dict->offsettab = (unsigned_16 *)data; /* first offset */ for( index = 0; index < num; index++ ) { dict->offsettab[index] = _ReadLittleEndian16UN( data ); data += sizeof( unsigned_16 ); } dict->num_entries = num; if( num > 0 && dict->symbtab == NULL ) { _ChkAlloc( dict->symbtab, sizeof( char * ) * num ); } } for( index = 0; index < num; index++ ) { dict->symbtab[index] = data; data += strlen( data ) + 1; } }