static void emitSymbolTable( owl_file_handle file ) { //*************************************************** unsigned count; coff_offset symbol_table_size; owl_symbol_info *symbol; coff_symbol *symbol_buffer; symbol_table_size = numSymbols( file ) * sizeof( coff_symbol ); if( symbol_table_size != 0 ) { lastFunc = NULL; lastBf = NULL; lastFile = NULL; symbol_buffer = _ClientAlloc( file, symbol_table_size ); #if 1 memset( symbol_buffer, 0, symbol_table_size ); #else memset( symbol_buffer, 0xBB, symbol_table_size ); #endif count = 0; for( symbol = file->symbol_table->head; symbol != NULL; symbol = symbol->next ) { if( symbol->flags & OWL_SYM_DEAD ) continue; formatOneSymbol( symbol, &symbol_buffer[ count ] ); count += numAuxSymbols( symbol ) + 1; if( symComdat( symbol ) ) { formatComdatSymbol( symbol, &symbol_buffer[ count ] ); count += 1; } } _ClientWrite( file, (const char *)symbol_buffer, symbol_table_size ); _ClientFree( file, symbol_buffer ); } }
static orl_return addString( omf_sec_handle sh, char *buffer, omf_string_len len ) { omf_string_struct *str; omf_file_handle ofh; assert( sh ); assert( buffer ); ofh = sh->omf_file_hnd; /* Check if we need to allocate more string table */ sh->assoc.string.strings = checkArraySize( ofh, sh->assoc.string.strings, sh->assoc.string.num, STD_INC, sizeof( omf_string_struct * ) ); if( !sh->assoc.string.strings ) return( ORL_OUT_OF_MEMORY ); str = _ClientAlloc( ofh, sizeof( omf_string_struct ) + len ); if( str == NULL ) return( ORL_OUT_OF_MEMORY ); memset( str, 0, sizeof( omf_string_struct ) + len ); memcpy( str->string, buffer, len ); str->string[len] = '\0'; str->len = len; sh->assoc.string.strings[sh->assoc.string.num] = str; sh->assoc.string.num++; return( ORL_OKAY ); }
owl_section_handle OWLENTRY OWLSectionInit( owl_file_handle file, const char *name, owl_section_type type, owl_alignment align ) { //******************************************************************************************************************************** owl_section_handle section; section = _ClientAlloc( file, sizeof( owl_section_info ) ); section->file = file; section->name = OWLStringAdd( file->string_table, name ); section->type = type; section->align = align; section->buffer = ( type & OWL_SEC_ATTR_BSS ) ? NULL : OWLBufferInit( file ); section->linenum_buffer = NULL; section->num_linenums = 0; section->size = 0; section->location = 0; section->first_reloc = NULL; section->last_reloc = NULL; section->num_relocs = 0; section->comdat_sym = NULL; section->comdat_dep = NULL; addSection( file, section ); addSectionSymbol( section, name ); _Log(( file, "OWLSectionInit( %x, '%s', %x, %x ) -> %x\n", file, name, type, align, section )); return( section ); }
static void *checkArraySize( omf_file_handle ofh, void *old_arr, long num, long inc, long elem ) { long size; void *new_arr; assert( ofh ); assert( num >= 0 ); assert( inc > 0 ); assert( elem > 0 ); if( !( num % inc ) ) { size = ( num + inc ) * elem; new_arr = _ClientAlloc( ofh, size ); if( !new_arr ) return( NULL ); memset( new_arr, 0, size ); if( num ) { assert( old_arr ); size = num * elem; memcpy( new_arr, old_arr, size ); _ClientFree( ofh, old_arr ); } old_arr = new_arr; } return( old_arr ); }
static void emitSectionData( owl_file_handle file ) { //**************************************************** owl_section_info *curr; owl_offset relocs_size; owl_reloc_info *reloc; coff_reloc *next_reloc; coff_reloc *reloc_buffer; for( curr = file->sections; curr != NULL; curr = curr->next ) { emitSectionPadding( curr ); if( !_OwlSectionBSS( curr ) ) { OWLBufferEmit( curr->buffer ); } if( curr->first_reloc != NULL ) { relocs_size = sizeof( coff_reloc ) * curr->num_relocs; reloc_buffer = _ClientAlloc( file, relocs_size ); next_reloc = reloc_buffer; for( reloc = curr->first_reloc; reloc != NULL; reloc = reloc->next ) { emitReloc( file, reloc, next_reloc ); next_reloc++; } _ClientWrite( file, (const char *)reloc_buffer, relocs_size ); _ClientFree( file, reloc_buffer ); } // now emit linenumbers if( curr->num_linenums != 0 ) { OWLBufferEmit( curr->linenum_buffer ); } } }
static void prepareStringTable( owl_file_handle file ) { //****************************************************** unsigned size; // we need to emit the string table to a buffer so that we can get offsets via OWLStringOffset // this will be freed in emitStringTable below size = OWLStringTableSize( file->string_table ); file->x.coff.string_table = _ClientAlloc( file, sizeof( coff_string_table ) + size - 1 ); file->x.coff.string_table->size = size + 4; OWLStringEmit( file->string_table, file->x.coff.string_table->buffer ); }
owl_buffer * OWLENTRY OWLBufferInit( owl_file_handle file ) { //*********************************************************** owl_buffer *buffer; buffer = _ClientAlloc( file, sizeof( owl_buffer ) ); buffer->location = 0; buffer->size = 0; buffer->bin_size = INITIAL_BIN_SIZE; buffer->file = file; binInit( buffer ); return( buffer ); }
static void emitSectionPadding( owl_section_info *curr ) { //******************************************************** char *buffer; owl_offset padding; padding = curr->x.coff.alignment_padding; if( padding != 0 ) { buffer = _ClientAlloc( curr->file, padding ); memset( buffer, 0, padding ); _ClientWrite( curr->file, buffer, padding ); _ClientFree( curr->file, buffer ); } }
static void AddCoffString( coff_lib_file *c_file, const char *name, size_t len ) { char *x; len++; // add space for terminator character if( ( c_file->string_table_size + len ) >= c_file->max_string_table_size ) { c_file->max_string_table_size *= 2; x = _ClientAlloc( c_file->coff_file_hnd, c_file->max_string_table_size ); if( x == NULL ) return; memcpy( x, c_file->string_table, c_file->string_table_size ); _ClientFree( c_file->coff_file_hnd, c_file->string_table ); c_file->string_table = x; } memcpy( c_file->string_table + c_file->string_table_size, name, len ); c_file->string_table_size += (unsigned_32)len; }
static void AddCoffString( coff_lib_file *c_file, char *name, int len ) { char *x; len++; if( ( c_file->string_table_size + len ) >= c_file->max_string_table_size ) { c_file->max_string_table_size *= 2; x = _ClientAlloc( c_file->coff_file_hnd, c_file->max_string_table_size ); if( x == NULL ) return; memcpy( x, c_file->string_table, c_file->string_table_size ); _ClientFree( c_file->coff_file_hnd, c_file->string_table ); c_file->string_table = x; } memcpy( c_file->string_table + c_file->string_table_size, name, len ); c_file->string_table_size += len; }
static void bufferCollapse( owl_buffer *buffer ) { //************************************************ char *bin; char *dst; unsigned i; assert( buffer->size == ( buffer->bin_size * NUM_BINS ) ); bin = _ClientAlloc( buffer->file, buffer->size ); for( dst = bin, i = 0; i < NUM_BINS; i++ ) { memcpy( dst, buffer->bins[ i ], buffer->bin_size ); _ClientFree( buffer->file, buffer->bins[ i ] ); buffer->bins[ i ] = NULL; dst += buffer->bin_size; } buffer->bins[ 0 ] = bin; buffer->bin_size = buffer->size; }
static omf_symbol_handle newSymbol( omf_file_handle ofh, orl_symbol_type typ, char *buffer, omf_string_len len ) { omf_symbol_handle sym; assert( ofh ); assert( buffer ); sym = _ClientAlloc( ofh, sizeof( omf_symbol_handle_struct ) + len ); if( sym != NULL ) { memset( sym, 0, sizeof( omf_symbol_handle_struct ) + len ); sym->typ = typ; sym->file_format = ORL_OMF; sym->omf_file_hnd = ofh; memcpy( sym->name.string, buffer, len ); sym->name.string[len] = '\0'; sym->name.len = len; } return( sym ); }
static void emitSectionHeaders( owl_file_handle file ) { //****************************************************** uint_32 section_table_size; coff_section_header *section_table; unsigned count; owl_section_info *curr; section_table_size = numSections( file ) * sizeof( coff_section_header ); if( section_table_size != 0 ) { section_table = _ClientAlloc( file, section_table_size ); count = 0; for( curr = file->sections; curr != NULL; curr = curr->next ) { formatSectionHeader( curr, §ion_table[ curr->index ] ); curr->index = count++; } _ClientWrite( file, (const char *)section_table, section_table_size ); _ClientFree( file, section_table ); } }
static void bufferFill( owl_buffer *buffer, const char *data, owl_offset len ) { //****************************************************************************** unsigned index; char *location; assert( bufferBinBytesLeft( buffer ) >= len ); index = buffer->location / buffer->bin_size; if( buffer->bins[ index ] == NULL ) { buffer->bins[ index ] = _ClientAlloc( buffer->file, buffer->bin_size ); } location = &buffer->bins[ index ][ buffer->location % buffer->bin_size ]; if( ( buffer->location + len ) > buffer->size ) { buffer->size = buffer->location + len; } if( data != NULL ) { memcpy( location, data, len ); } else { memset( location, 0, len ); } }
static orl_return checkSegmentLength( omf_sec_handle sh, uint_32 max ) { omf_bytes conts; assert( sh ); if( max > sh->size ) return( ORL_ERROR ); if( max > sh->assoc.seg.cur_size ) { max = ( max / STD_CODE_SIZE ) + 1; max *= STD_CODE_SIZE; conts = _ClientAlloc( sh->omf_file_hnd, max ); if( !conts ) return( ORL_OUT_OF_MEMORY ); memset( conts, 0, max ); if( sh->contents ) { memcpy( conts, sh->contents, sh->assoc.seg.cur_size ); _ClientFree( sh->omf_file_hnd, sh->contents ); } sh->contents = conts; sh->assoc.seg.cur_size = max; } return( ORL_OKAY ); }
static omf_grp_handle newGroup( omf_file_handle ofh ) { omf_grp_handle gr; assert( ofh ); ofh->groups = checkArraySize( ofh, ofh->groups, ofh->num_groups, STD_INC, sizeof( omf_grp_handle ) ); if( !ofh->groups ) return( NULL ); gr = _ClientAlloc( ofh, sizeof( omf_grp_handle_struct ) ); if( !gr ) return( gr ); memset( gr, 0, sizeof( omf_grp_handle_struct ) ); ofh->groups[ofh->num_groups] = gr; ofh->num_groups++; gr->id = ofh->num_groups; gr->file_format = ORL_OMF; gr->omf_file_hnd = ofh; return( gr ); }
static omf_sec_handle newSection( omf_file_handle ofh, omf_quantity idx, orl_sec_type typ ) { omf_sec_handle sh; assert( ofh ); assert( idx >= OMF_SEC_NEXT_AVAILABLE ); if( idx == OMF_SEC_NEXT_AVAILABLE ) { if( ofh->next_idx < OMF_SEC_DATA_CODE_START ) { ofh->next_idx = OMF_SEC_DATA_CODE_START; } idx = ofh->next_idx; ofh->next_idx++; } else if( idx >= ofh->next_idx ) { ofh->next_idx = idx + 1; } sh = _ClientAlloc( ofh, sizeof( omf_sec_handle_struct ) ); if( !sh ) return( sh ); memset( sh, 0, sizeof( omf_sec_handle_struct ) ); sh->file_format = ORL_OMF; sh->omf_file_hnd = ofh; sh->type = typ; sh->index = idx; if( ofh->first_sec ) { ofh->last_sec->next = sh; } else { ofh->first_sec = sh; } ofh->last_sec = sh; ofh->num_sections++; return( sh ); }
static orl_return load_coff_sec_handles( coff_file_handle coff_file_hnd, coff_file_header *f_hdr ) /**********************************************************************/ { coff_section_header *s_hdr; coff_sec_handle coff_sec_hnd; coff_sec_handle coff_reloc_sec_hnd; coff_quantity i; coff_quantity num_reloc_secs = 0; coff_sec_offset *reloc_sec_offset; coff_sec_size *reloc_sec_size; coff_quantity reloc_secs_created; if( coff_file_hnd->num_sections == 0 ) { reloc_sec_offset = NULL; reloc_sec_size = NULL; coff_file_hnd->orig_sec_hnd = NULL; } else { reloc_sec_offset = (coff_sec_offset *)_ClientAlloc( coff_file_hnd, sizeof( coff_sec_offset ) * coff_file_hnd->num_sections ); if( reloc_sec_offset == NULL ) return( ORL_OUT_OF_MEMORY ); reloc_sec_size = (coff_sec_size *)_ClientAlloc( coff_file_hnd, sizeof( coff_sec_size ) * coff_file_hnd->num_sections ); if( reloc_sec_size == NULL ) { _ClientFree( coff_file_hnd, reloc_sec_offset ); return( ORL_OUT_OF_MEMORY ); } memset( reloc_sec_offset, 0, sizeof( coff_sec_offset ) * coff_file_hnd->num_sections ); memset( reloc_sec_size, 0, sizeof( coff_sec_size ) * coff_file_hnd->num_sections ); coff_file_hnd->orig_sec_hnd = (coff_sec_handle *)_ClientAlloc( coff_file_hnd, sizeof( coff_sec_handle ) * coff_file_hnd->num_sections ); if( coff_file_hnd->orig_sec_hnd == NULL ) { _ClientFree( coff_file_hnd, reloc_sec_offset ); _ClientFree( coff_file_hnd, reloc_sec_size ); return( ORL_OUT_OF_MEMORY ); } } coff_file_hnd->coff_sec_hnd = NULL; s_hdr = (coff_section_header *)coff_file_hnd->s_hdr_table_buffer; for( i = 0; i < coff_file_hnd->num_sections; ++i ) { coff_sec_hnd = (coff_sec_handle)_ClientAlloc( coff_file_hnd, sizeof( ORL_STRUCT( coff_sec_handle ) ) ); if( coff_sec_hnd == NULL ) { free_coff_sec_handles( coff_file_hnd, i ); _ClientFree( coff_file_hnd, reloc_sec_offset ); _ClientFree( coff_file_hnd, reloc_sec_size ); return( ORL_OUT_OF_MEMORY ); } coff_file_hnd->orig_sec_hnd[i] = coff_sec_hnd; if( s_hdr->name[0] != '/' ) { coff_sec_hnd->name = _ClientAlloc( coff_file_hnd, COFF_SEC_NAME_LEN + 1 ); if( coff_sec_hnd->name == NULL ) { free_coff_sec_handles( coff_file_hnd, i ); _ClientFree( coff_file_hnd, reloc_sec_offset ); _ClientFree( coff_file_hnd, reloc_sec_size ); return( ORL_OUT_OF_MEMORY ); } coff_sec_hnd->name_alloced = true; strncpy( coff_sec_hnd->name, s_hdr->name, COFF_SEC_NAME_LEN ); coff_sec_hnd->name[COFF_SEC_NAME_LEN] = 0; } else { coff_sec_hnd->name = s_hdr->name; coff_sec_hnd->name_alloced = false; } coff_sec_hnd->file_format = ORL_COFF; coff_sec_hnd->relocs_done = false; coff_sec_hnd->coff_file_hnd = coff_file_hnd; coff_sec_hnd->size = s_hdr->size; coff_sec_hnd->base = s_hdr->offset; coff_sec_hnd->offset = s_hdr->rawdata_ptr; coff_sec_hnd->hdr = s_hdr; determine_section_specs( coff_sec_hnd, s_hdr ); coff_sec_hnd->contents = NULL; coff_sec_hnd->assoc.normal.reloc_sec = NULL; reloc_sec_offset[i] = s_hdr->reloc_ptr; if( s_hdr->num_relocs > 0 ) { num_reloc_secs++; } reloc_sec_size[i] = s_hdr->num_relocs * sizeof( coff_reloc ); s_hdr++; } /* There are num_reloc_secs + 2 additional section handles to create (one each for the symbol and string tables) */ coff_file_hnd->coff_sec_hnd = (coff_sec_handle *)_ClientAlloc( coff_file_hnd, sizeof( coff_sec_handle ) * (coff_file_hnd->num_sections + num_reloc_secs + 2) ); if( coff_file_hnd->coff_sec_hnd == NULL ) { free_coff_sec_handles( coff_file_hnd, coff_file_hnd->num_sections ); _ClientFree( coff_file_hnd, reloc_sec_offset ); _ClientFree( coff_file_hnd, reloc_sec_size ); return( ORL_OUT_OF_MEMORY ); } memcpy( coff_file_hnd->coff_sec_hnd, coff_file_hnd->orig_sec_hnd, sizeof( coff_sec_handle ) * coff_file_hnd->num_sections ); reloc_secs_created = 0; for( i = 0; i < coff_file_hnd->num_sections; ++i ) { if( reloc_sec_size[i] > 0 ) { reloc_secs_created++; // create a reloc section coff_file_hnd->coff_sec_hnd[coff_file_hnd->num_sections + reloc_secs_created] = (coff_sec_handle)_ClientAlloc( coff_file_hnd, sizeof( ORL_STRUCT( coff_sec_handle ) ) ); coff_reloc_sec_hnd = coff_file_hnd->coff_sec_hnd[coff_file_hnd->num_sections + reloc_secs_created]; if( coff_reloc_sec_hnd == NULL ) { free_coff_sec_handles( coff_file_hnd, coff_file_hnd->num_sections + reloc_secs_created ); _ClientFree( coff_file_hnd, reloc_sec_offset ); _ClientFree( coff_file_hnd, reloc_sec_size ); return( ORL_OUT_OF_MEMORY ); } coff_reloc_sec_hnd->file_format = ORL_COFF; coff_reloc_sec_hnd->coff_file_hnd = coff_file_hnd; coff_reloc_sec_hnd->name = SectionNames[0]; // ".rel" coff_reloc_sec_hnd->name_alloced = false; coff_reloc_sec_hnd->relocs_done = false; coff_reloc_sec_hnd->size = reloc_sec_size[i]; coff_reloc_sec_hnd->base = 0; coff_reloc_sec_hnd->offset = reloc_sec_offset[i]; coff_reloc_sec_hnd->type = ORL_SEC_TYPE_RELOCS; coff_reloc_sec_hnd->flags = ORL_SEC_FLAG_NONE; coff_reloc_sec_hnd->hdr = NULL; coff_reloc_sec_hnd->assoc.reloc.orig_sec = coff_file_hnd->coff_sec_hnd[i]; coff_reloc_sec_hnd->assoc.reloc.relocs = NULL; coff_reloc_sec_hnd->align = 4; coff_file_hnd->coff_sec_hnd[i]->assoc.normal.reloc_sec = coff_reloc_sec_hnd; coff_file_hnd->coff_sec_hnd[coff_file_hnd->num_sections + reloc_secs_created - 1] = coff_reloc_sec_hnd; } } // create the symbol table section coff_file_hnd->symbol_table = (coff_sec_handle)_ClientAlloc( coff_file_hnd, sizeof( ORL_STRUCT( coff_sec_handle ) ) ); if( coff_file_hnd->symbol_table == NULL ) { free_coff_sec_handles( coff_file_hnd, i + coff_file_hnd->num_sections ); _ClientFree( coff_file_hnd, reloc_sec_offset ); _ClientFree( coff_file_hnd, reloc_sec_size ); return( ORL_OUT_OF_MEMORY ); } coff_file_hnd->symbol_table->file_format = ORL_COFF; coff_file_hnd->symbol_table->coff_file_hnd = coff_file_hnd; coff_file_hnd->symbol_table->name = SectionNames[1]; // ".symtab" coff_file_hnd->symbol_table->name_alloced = false; coff_file_hnd->symbol_table->relocs_done = false; coff_file_hnd->symbol_table->size = f_hdr->num_symbols * sizeof( coff_symbol ); coff_file_hnd->symbol_table->base = 0; coff_file_hnd->symbol_table->offset = f_hdr->sym_table; coff_file_hnd->symbol_table->hdr = NULL; coff_file_hnd->symbol_table->assoc.normal.reloc_sec = NULL; coff_file_hnd->symbol_table->type = ORL_SEC_TYPE_SYM_TABLE; coff_file_hnd->symbol_table->flags = ORL_SEC_FLAG_NONE; coff_file_hnd->symbol_table->align = 4; coff_file_hnd->coff_sec_hnd[coff_file_hnd->num_sections + reloc_secs_created] = coff_file_hnd->symbol_table; i++; // create the string table section coff_file_hnd->string_table = (coff_sec_handle)_ClientAlloc( coff_file_hnd, sizeof( ORL_STRUCT( coff_sec_handle ) ) ); if( coff_file_hnd->string_table == NULL ) { free_coff_sec_handles( coff_file_hnd, i + coff_file_hnd->num_sections ); _ClientFree( coff_file_hnd, reloc_sec_offset ); _ClientFree( coff_file_hnd, reloc_sec_size ); return( ORL_OUT_OF_MEMORY ); } coff_file_hnd->string_table->file_format = ORL_COFF; coff_file_hnd->string_table->coff_file_hnd = coff_file_hnd; coff_file_hnd->string_table->name = SectionNames[2]; // ".strtab" coff_file_hnd->string_table->name_alloced = false; coff_file_hnd->string_table->relocs_done = false; coff_file_hnd->string_table->size = 0; // determined later coff_file_hnd->string_table->base = 0; coff_file_hnd->string_table->offset = coff_file_hnd->symbol_table->offset + coff_file_hnd->symbol_table->size; coff_file_hnd->string_table->hdr = NULL; coff_file_hnd->string_table->assoc.normal.reloc_sec = NULL; coff_file_hnd->string_table->type = ORL_SEC_TYPE_STR_TABLE; coff_file_hnd->string_table->flags = ORL_SEC_FLAG_NONE; coff_file_hnd->string_table->align = 4; coff_file_hnd->coff_sec_hnd[coff_file_hnd->num_sections + reloc_secs_created + 1] = coff_file_hnd->string_table; _ClientFree( coff_file_hnd, reloc_sec_offset ); _ClientFree( coff_file_hnd, reloc_sec_size ); coff_file_hnd->num_sections += num_reloc_secs + 2; return( ORL_OKAY ); }
orl_return CoffCreateSymbolHandles( coff_file_handle file_hnd ) { int loop; int prev; // int len; uint_16 type; // type of CoffSymEnt coff_symbol_handle current; coff_sym_section * aux; coff_sym_weak * weak; coff_sec_handle sechdl; if( file_hnd->num_symbols == 0 ){ file_hnd->symbol_handles = NULL; return( ORL_OKAY ); } file_hnd->symbol_handles = (coff_symbol_handle) _ClientAlloc( file_hnd, sizeof( coff_symbol_handle_struct ) * file_hnd->num_symbols ); if( !(file_hnd->symbol_handles) ) return( ORL_OUT_OF_MEMORY ); prev = 0; for( loop = 0; loop < file_hnd->num_symbols; loop++ ) { current = &(file_hnd->symbol_handles[loop]); current->file_format = ORL_COFF; current->coff_file_hnd = file_hnd; current->symbol = (coff_symbol *) &(file_hnd->symbol_table->contents[sizeof( coff_symbol ) * loop]); if( current->symbol->name.non_name.zeros == 0 ) { current->name = (char *)( file_hnd->string_table->contents + current->symbol->name.non_name.offset - sizeof( coff_sec_size ) ); current->name_alloced = COFF_FALSE; } else { // len = strlen( current->symbol->name.name_string ); if( strlen( current->symbol->name.name_string ) >= COFF_SYM_NAME_LEN ) { current->name = _ClientAlloc( file_hnd, COFF_SYM_NAME_LEN + 1 ); strncpy( current->name, current->symbol->name.name_string, COFF_SYM_NAME_LEN ); current->name[COFF_SYM_NAME_LEN] = '\0'; current->name_alloced = COFF_TRUE; } else { current->name = current->symbol->name.name_string; current->name_alloced = COFF_FALSE; } } if( memcmp( current->name, ".bf", 4 ) == 0 ) { if( current->symbol->num_aux >= 1 ) { file_hnd->symbol_handles[prev].has_bf = COFF_TRUE; } } sechdl = NULL; current->type = 0; switch( current->symbol->sec_num ) { case IMAGE_SYM_DEBUG: current->type |= ORL_SYM_TYPE_DEBUG; current->binding = ORL_SYM_BINDING_NONE; break; case IMAGE_SYM_ABSOLUTE: current->type |= ORL_SYM_TYPE_ABSOLUTE; current->binding = ORL_SYM_BINDING_NONE; // ? break; case IMAGE_SYM_UNDEFINED: if( current->symbol->value == 0) { current->type |= ORL_SYM_TYPE_UNDEFINED; } else { current->type |= ORL_SYM_TYPE_COMMON; } break; default: current->type |= ORL_SYM_TYPE_DEFINED; sechdl = file_hnd->orig_sec_hnd[current->symbol->sec_num - 1]; if( sechdl->flags & ORL_SEC_FLAG_COMDAT ) { current->type |= ORL_SYM_CDAT_MASK; } break; } switch( current->symbol->storage_class ) { case IMAGE_SYM_CLASS_EXTERNAL: case IMAGE_SYM_CLASS_LABEL: case IMAGE_SYM_CLASS_UNDEFINED_LABEL: case IMAGE_SYM_CLASS_WEAK_EXTERNAL: if( current->symbol->storage_class == IMAGE_SYM_CLASS_LABEL ) { current->binding = ORL_SYM_BINDING_LOCAL; } else if( (current->symbol->storage_class == IMAGE_SYM_CLASS_EXTERNAL || current->symbol->storage_class == IMAGE_SYM_CLASS_WEAK_EXTERNAL) && current->symbol->sec_num == IMAGE_SYM_UNDEFINED && current->symbol->value == 0 && current->symbol->num_aux == 1 ) { weak = (coff_sym_weak *) (current->symbol + 1); switch( weak->characteristics ) { case IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY: current->binding = ORL_SYM_BINDING_WEAK; break; case IMAGE_WEAK_EXTERN_SEARCH_LIBRARY: current->binding = ORL_SYM_BINDING_LAZY; break; case IMAGE_WEAK_EXTERN_SEARCH_ALIAS: current->binding = ORL_SYM_BINDING_ALIAS; break; } } else { current->binding = ORL_SYM_BINDING_GLOBAL; } type = _CoffComplexType( current->symbol->type ); if( type & IMAGE_SYM_DTYPE_FUNCTION ) { current->type |= ORL_SYM_TYPE_FUNCTION; } else { current->type |= ORL_SYM_TYPE_OBJECT; } break; case IMAGE_SYM_CLASS_STATIC: current->binding = ORL_SYM_BINDING_LOCAL; if( current->symbol->num_aux == 0 ) { if( sechdl != NULL && strcmp( sechdl->name, current->name ) == 0 ) { current->type |= ORL_SYM_TYPE_SECTION; } else { type = _CoffComplexType( current->symbol->type ); if( type & IMAGE_SYM_DTYPE_FUNCTION ) { current->type |= ORL_SYM_TYPE_FUNCTION; } else { current->type |= ORL_SYM_TYPE_OBJECT; } } } else if( current->symbol->num_aux == 1 && current->type & ORL_SYM_CDAT_MASK ) { current->type |= ORL_SYM_TYPE_SECTION; aux = (coff_sym_section *)(current->symbol + 1); current->type &= ~ORL_SYM_CDAT_MASK; current->type |= (aux->selection << ORL_SYM_CDAT_SHIFT) & ORL_SYM_CDAT_MASK; } else { type = _CoffComplexType( current->symbol->type ); if( type & IMAGE_SYM_DTYPE_FUNCTION ) { current->type |= ORL_SYM_TYPE_FUNCTION; } } break; case IMAGE_SYM_CLASS_FUNCTION: // The .bf, .lf and .ef symbols are not regular symbols // and their values in particular must not be interpreted // as offsets/addresses. if( !memcmp( current->name, ".bf", 4 ) || !memcmp( current->name, ".lf", 4 ) || !memcmp( current->name, ".ef", 4 ) ) current->binding = ORL_SYM_BINDING_NONE; else current->binding = ORL_SYM_BINDING_LOCAL; current->type |= ORL_SYM_TYPE_FUNC_INFO; break; case IMAGE_SYM_CLASS_FILE: current->binding = ORL_SYM_BINDING_LOCAL; current->type |= ORL_SYM_TYPE_FILE; break; } prev = loop; loop += current->symbol->num_aux; } return( ORL_OKAY ); }
static void InitCoffFile( coff_lib_file *c_file ) { c_file->string_table = _ClientAlloc( c_file->coff_file_hnd, INIT_MAX_SIZE_COFF_STRING_TABLE ); c_file->max_string_table_size = INIT_MAX_SIZE_COFF_STRING_TABLE; }
static orl_return expandPrevLIData( omf_file_handle ofh ) { omf_sec_handle sh; int size; omf_bytes buffer; orl_return err = ORL_OKAY; unsigned char tmp[1024]; omf_tmp_fixup ftr; orl_sec_offset offset; assert( ofh ); assert( ofh->work_sec ); assert( ofh->lidata ); sh = ofh->work_sec; size = ofh->lidata->size; if( size > 1024 ) { buffer = _ClientAlloc( ofh, size ); if( !buffer ) return( ORL_OUT_OF_MEMORY ); } else { buffer = tmp; } /* we must remember to save the current offset of the lidata and then * restore it */ ofh->lidata->last_fixup = NULL; offset = sh->assoc.seg.cur_offset; /* make a working copy of the LIDATA */ memcpy( buffer, sh->contents + offset, size ); while( ofh->lidata->size > 0 ) { err = writeAndFixupLIData( ofh, sh, buffer ); if( err != ORL_OKAY ) return( err ); } sh->assoc.seg.cur_offset = offset; if( size > 1024 ) { _ClientFree( ofh, buffer ); } assert( !( ofh->status & OMF_STATUS_ADD_MASK ) ); /* Destroy original fixups */ while( ofh->lidata->first_fixup ) { ftr = ofh->lidata->first_fixup; ofh->lidata->first_fixup = ftr->next; _ClientFree( ofh, ftr ); } /* Add the generated fixups */ while( ofh->lidata->new_fixup ) { ftr = ofh->lidata->new_fixup; err = OmfAddFixupp( ofh, ftr->is32, ftr->mode, ftr->location, ftr->offset, ftr->fmethod, ftr->fidx, ftr->tmethod, ftr->tidx, ftr->disp ); if( err != ORL_OKAY ) break; ofh->lidata->new_fixup = ftr->next; _ClientFree( ofh, ftr ); } ofh->lidata->last_fixup = NULL; return( err ); }
static orl_return writeAndFixupLIData( omf_file_handle ofh, omf_sec_handle sh, omf_bytes buffer ) { int wordsize; long tmp; uint_32 repeat; long block; int size; int used; int hi; int lo; omf_bytes ptr; orl_return err = ORL_OKAY; omf_tmp_fixup ftr; omf_tmp_fixup ntr; int x; assert( ofh ); assert( ofh->lidata ); assert( sh ); assert( sh->contents ); assert( buffer ); if( ofh->status & OMF_STATUS_EASY_OMF ) { wordsize = OmfGetWordSize( 0 ); } else { wordsize = OmfGetWordSize( ofh->lidata->is32 ); } tmp = wordsize + 2; if( ofh->lidata->size < tmp ) return( ORL_ERROR ); used = ofh->lidata->used; size = ofh->lidata->size; ptr = buffer + used; repeat = getUWord( ptr, wordsize ); ptr += wordsize; block = getUWord( ptr, 2 ); ptr += 2; lo = used; hi = lo + tmp; size -= tmp; used += tmp; if( findMatchingFixup( ofh->lidata->first_fixup, lo, hi ) ) { return( ORL_ERROR ); } else if( block ) { while( repeat ) { repeat--; ofh->lidata->used = used; ofh->lidata->size = size; for( x = 0; x < block; x++ ) { err = writeAndFixupLIData( ofh, sh, buffer ); if( err != ORL_OKAY ) { break; } } } } else { tmp = *ptr; ptr++; used++; size--; lo = used; hi = used + tmp - 1; while( repeat ) { buffer = sh->contents + sh->assoc.seg.cur_offset; memcpy( buffer, ptr, tmp ); /* create appropriate fixup records */ ftr = findMatchingFixup( ofh->lidata->first_fixup, lo, hi ); while( ftr ) { ntr = _ClientAlloc( ofh, sizeof( omf_tmp_fixup_struct ) ); if( !ntr ) return( ORL_OUT_OF_MEMORY ); memcpy( ntr, ftr, sizeof( omf_tmp_fixup_struct ) ); /* determine new offset as if this was an LEData we were * doing a fixup for */ ntr->offset = ofh->lidata->offset - used + ftr->offset; /* insert into new fixup queue */ if( ofh->lidata->new_fixup ) { ofh->lidata->last_fixup->next = ntr; } else { ofh->lidata->new_fixup = ntr; } ofh->lidata->last_fixup = ntr; ftr = findMatchingFixup( ftr->next, lo, hi ); } ofh->lidata->offset += tmp; sh->assoc.seg.cur_offset += tmp; repeat--; } ofh->lidata->size = size - tmp; ofh->lidata->used = used + tmp; err = ORL_OKAY; } return( err ); }