char *GetARName( ar_header *header, file_list *list, unsigned long *loc ) /***********************************************************************/ { char *buf; char *name; unsigned long val; size_t len; name = NULL; if( header->name[0] == '/' ) { val = GetARValue( &header->name[1], AR_NAME_LEN - 1 ); buf = list->strtab + val; len = strlen( buf ); } else if( header->name[0] == '#' && header->name[1] == '1' && header->name[2] == '/') { len = GetARValue( &header->name[3], AR_NAME_LEN - 3 ); buf = CacheRead( list, *loc, len ); *loc += len; } else { len = AR_NAME_LEN; buf = memchr( header->name, '/', len ); if( buf != NULL ) { len = buf - header->name; } buf = header->name; } if( len > 0 ) { name = ChkToString( buf, len ); } return( name ); }
char *IdentifyObject( file_list *list, unsigned long *loc, unsigned long *size ) /******************************************************************************/ { ar_header *ar_hdr; char *name; unsigned long ar_loc; name = NULL; *size = 0; if( list->status & STAT_AR_LIB ) { ar_loc = MAKE_EVEN( *loc ); /* AR headers are word aligned. */ ar_hdr = CacheRead( list, ar_loc, sizeof( ar_header ) ); ar_loc += sizeof( ar_header ); name = GetARName( ar_hdr, list, &ar_loc ); *size = GetARValue( ar_hdr->size, AR_SIZE_LEN ); *loc = ar_loc; } if( !IsORL( list, *loc ) ) { if( IsOMF( list, *loc ) ) { ObjFormat |= FMT_OMF; name = GetOMFName( list, loc ); if( list->status & STAT_AR_LIB ) { *loc = ar_loc; /* Restore the location. */ } } } return( name ); }
int CheckLibraryType( file_list *list, unsigned long *loc, bool makedict ) /************************************************************************/ { unsigned_8 *header; int reclength; reclength = 0; header = CacheRead( list, *loc, sizeof( lib_header ) ); if( header[0] == 0xf0 && header[1] == 0x01 ) { // COFF object for PPC } else if( header[0] == LIB_HEADER_REC ) { // reading from a library list->status |= STAT_OMF_LIB; reclength = ReadOMFDict( list, header, makedict ); if( reclength < 0 ) { return( -1 ); } *loc += ROUND_UP( sizeof( lib_header ), reclength ); } else if( memcmp( header, AR_IDENT, AR_IDENT_LEN ) == 0 ) { list->status |= STAT_AR_LIB; reclength = 2; *loc += AR_IDENT_LEN; if( !ReadARDict( list, loc, makedict ) ) { return( -1 ); } } return( reclength ); }
static char *ReadBlock(long blockNum, long blockOffset, long length, char *buffer, long cache) { long long offset; offset = 1ULL * blockNum * gBlockSize; if (cache && ((blockOffset + length) <= gBlockSize)) { CacheRead(gCurrentIH, gTempBlock, offset, gBlockSize, 1); if (buffer != 0) bcopy(gTempBlock + blockOffset, buffer, length); else buffer = gTempBlock + blockOffset; } else { offset += blockOffset; CacheRead(gCurrentIH, buffer, offset, length, 0); } return buffer; }
static bool EndOfLib( file_list *list, unsigned long loc ) /********************************************************/ { unsigned_8 *id; if( list->status & STAT_OMF_LIB ) { id = CacheRead( list, loc, sizeof( unsigned_8 ) ); return( *id == LIB_TRAILER_REC ); } else { return( FALSE ); } }
static char * ReadBlock( long fragNum, long blockOffset, long length, char * buffer, long cache ) { long long offset; long blockNum; blockNum = fragNum / gFragsPerBlock; fragNum -= blockNum * gFragsPerBlock; blockOffset += fragNum * gFragSize; offset = gPartitionBase + 1ULL * blockNum * gBlockSize; if (cache && ((blockOffset + length) <= gBlockSize)) { CacheRead(gCurrentIH, gTempBlock, offset, gBlockSize, 1); if (buffer != 0) bcopy(gTempBlock + blockOffset, buffer, length); else buffer = gTempBlock + blockOffset; } else { offset += blockOffset; CacheRead(gCurrentIH, buffer, offset, length, 0); } return buffer; }
void * CachePermRead( file_list *list, unsigned long pos, unsigned len ) /*****************************************************************************/ { char * buf; char * result; buf = CacheRead( list, pos, len ); if( list->file->flags & INSTAT_FULL_CACHE ) return buf; if( Multipage ) { _LnkReAlloc( result, buf, len ); _ChkAlloc( TokBuff, TokSize ); Multipage = FALSE; // indicate that last read is permanent. } else { _ChkAlloc( result, len ); memcpy( result, buf, len ); } return result; }
static bool ReadARDict( file_list *list, unsigned long *loc, bool makedict ) /**************************************************************************/ { ar_header *ar_hdr; unsigned long size; int numdicts; numdicts = 0; if( makedict ) { if( list->u.dict == NULL ) { _ChkAlloc( list->u.dict, sizeof( dict_entry ) ); } } for( ;; ) { ar_hdr = CacheRead( list, *loc, sizeof( ar_header ) ); size = GetARValue( ar_hdr->size, AR_SIZE_LEN ); if( ar_hdr->name[0] == '/' && ar_hdr->name[1] == ' ' ) { ++numdicts; *loc += sizeof( ar_header ); if( makedict ) ReadARDictData( list, loc, size, numdicts ); *loc += MAKE_EVEN( size ); } else if( ar_hdr->name[0] == '/' && ar_hdr->name[1] == '/' ) { *loc += sizeof( ar_header ); ReadARStringTable( list, loc, size ); *loc += MAKE_EVEN( size ); } else { break; // found an actual object file } } if( makedict ) { if( numdicts == 0 ) { Locator( list->file->name, NULL, 0 ); LnkMsg( ERR+MSG_NO_DICT_FOUND, NULL ); _LnkFree( list->u.dict ); list->u.dict = NULL; return( FALSE ); } if( !(LinkFlags & CASE_FLAG) || numdicts == 1 ) { SortARDict( &list->u.dict->a ); } } return( TRUE ); }
static long ReadExtent(char * extent, long extentSize, long extentFile, long offset, long size, void * buffer, long cache) { long lastOffset, blockNumber, countedBlocks = 0; long nextExtent = 0, sizeRead = 0, readSize; long nextExtentBlock, currentExtentBlock = 0; long long readOffset; long extentDensity, sizeofExtent, currentExtentSize; char *currentExtent, *extentBuffer = 0, *bufferPos = buffer; if (offset >= extentSize) return 0; if (gIsHFSPlus) { extentDensity = kHFSPlusExtentDensity; sizeofExtent = sizeof(HFSPlusExtentDescriptor); } else { extentDensity = kHFSExtentDensity; sizeofExtent = sizeof(HFSExtentDescriptor); } lastOffset = offset + size; while (offset < lastOffset) { blockNumber = offset / gBlockSize; // Find the extent for the offset. for (; ; nextExtent++) { if (nextExtent < extentDensity) { if ((countedBlocks+GetExtentSize(extent, nextExtent)-1)<blockNumber) { countedBlocks += GetExtentSize(extent, nextExtent); continue; } currentExtent = extent + nextExtent * sizeofExtent; break; } if (extentBuffer == 0) { extentBuffer = malloc(sizeofExtent * extentDensity); if (extentBuffer == 0) return -1; } nextExtentBlock = nextExtent / extentDensity; if (currentExtentBlock != nextExtentBlock) { ReadExtentsEntry(extentFile, countedBlocks, extentBuffer); currentExtentBlock = nextExtentBlock; } currentExtentSize = GetExtentSize(extentBuffer, nextExtent % extentDensity); if ((countedBlocks + currentExtentSize - 1) >= blockNumber) { currentExtent = extentBuffer + sizeofExtent * (nextExtent % extentDensity); break; } countedBlocks += currentExtentSize; } readOffset = ((blockNumber - countedBlocks) * gBlockSize) + (offset % gBlockSize); readSize = GetExtentSize(currentExtent, 0) * gBlockSize - readOffset; if (readSize > (size - sizeRead)) readSize = size - sizeRead; readOffset += (long long)GetExtentStart(currentExtent, 0) * gBlockSize; CacheRead(gCurrentIH, bufferPos, gAllocationOffset + readOffset, readSize, cache); sizeRead += readSize; offset += readSize; bufferPos += readSize; } if (extentBuffer) free(extentBuffer); return sizeRead; }