예제 #1
0
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 );
    }
}
예제 #2
0
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 );
}
예제 #3
0
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 );
}
예제 #4
0
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 );
}
예제 #5
0
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 );
        }
    }
}
예제 #6
0
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 );
}
예제 #7
0
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 );
}
예제 #8
0
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 );
    }
}
예제 #9
0
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;
}
예제 #10
0
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;
}
예제 #11
0
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;
}
예제 #12
0
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 );
}
예제 #13
0
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, &section_table[ curr->index ] );
            curr->index = count++;
        }
        _ClientWrite( file, (const char *)section_table, section_table_size );
        _ClientFree( file, section_table );
    }
}
예제 #14
0
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 );
    }
}
예제 #15
0
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 );
}
예제 #16
0
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 );
}
예제 #17
0
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 );
}
예제 #18
0
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 );
}
예제 #19
0
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 );
}
예제 #20
0
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;

}
예제 #21
0
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 );
}
예제 #22
0
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 );
}