orl_return CoffCreateRelocs( coff_sec_handle orig_sec, coff_sec_handle reloc_sec ) { orl_return return_val; unsigned num_relocs; int loop; coff_reloc ORLUNALIGNED *rel; orl_reloc * o_rel; orl_reloc * prev_rel; if( reloc_sec->coff_file_hnd->symbol_handles == NULL ) { return_val = CoffCreateSymbolHandles( reloc_sec->coff_file_hnd ); if( return_val != ORL_OKAY ) return( return_val ); } num_relocs = reloc_sec->size / sizeof( coff_reloc ); reloc_sec->assoc.reloc.num_relocs = num_relocs; reloc_sec->assoc.reloc.relocs = (orl_reloc *) _ClientSecAlloc( reloc_sec, sizeof( orl_reloc ) * num_relocs ); if( reloc_sec->assoc.reloc.relocs == NULL ) return( ORL_OUT_OF_MEMORY ); rel = (coff_reloc *) reloc_sec->contents; o_rel = (orl_reloc *) reloc_sec->assoc.reloc.relocs; for( loop = 0; loop < num_relocs; loop++ ) { o_rel->section = (orl_sec_handle) orig_sec; if( reloc_sec->coff_file_hnd->machine_type == ORL_MACHINE_TYPE_ALPHA && rel->type == IMAGE_REL_ALPHA_MATCH ) { o_rel->type = ORL_RELOC_TYPE_HALF_LO; prev_rel = o_rel - 1; o_rel->symbol = prev_rel->symbol; o_rel->offset = prev_rel->offset + rel->sym_tab_index; } else { o_rel->type = CoffConvertRelocType( reloc_sec->coff_file_hnd, rel->type ); if( o_rel->type == ORL_RELOC_TYPE_PAIR ) { o_rel->symbol = NULL; } else { o_rel->symbol = (orl_symbol_handle) &(reloc_sec->coff_file_hnd->symbol_handles[rel->sym_tab_index]); } o_rel->offset = rel->offset - orig_sec->hdr->offset; } o_rel->addend = 0; o_rel->frame = NULL; rel++; o_rel++; } return( ORL_OKAY ); }
orl_return ElfCreateRelocs( elf_sec_handle orig_sec, elf_sec_handle reloc_sec ) { orl_return return_val; int num_relocs; int loop; unsigned char *rel; Elf32_Rel *rel32; Elf32_Rela *rela32; Elf64_Rel *rel64; Elf64_Rela *rela64; orl_reloc *o_rel; if( reloc_sec->assoc.reloc.symbol_table->assoc.sym.symbols == NULL ) { return_val = ElfCreateSymbolHandles( reloc_sec->assoc.reloc.symbol_table ); if( return_val != ORL_OKAY ) return( return_val ); } switch( reloc_sec->type ) { case ORL_SEC_TYPE_RELOCS: num_relocs = reloc_sec->size / reloc_sec->entsize; reloc_sec->assoc.reloc.relocs = (orl_reloc *) _ClientSecAlloc( reloc_sec, sizeof( orl_reloc ) * num_relocs ); if( reloc_sec->assoc.reloc.relocs == NULL ) return( ORL_OUT_OF_MEMORY ); rel = reloc_sec->contents; o_rel = (orl_reloc *) reloc_sec->assoc.reloc.relocs; for( loop = 0; loop < num_relocs; loop++ ) { o_rel->section = (orl_sec_handle) orig_sec; if( reloc_sec->elf_file_hnd->flags & ORL_FILE_FLAG_64BIT_MACHINE ) { rel64 = (Elf64_Rel *)rel; fix_rel64_byte_order( reloc_sec->elf_file_hnd, rel64 ); o_rel->symbol = (orl_symbol_handle)&(reloc_sec->assoc.reloc.symbol_table->assoc.sym.symbols[rel64->r_info.u._32[I64HI32]]); o_rel->type = ElfConvertRelocType( reloc_sec->elf_file_hnd, (elf_reloc_type)rel64->r_info.u._32[I64LO32] ); o_rel->offset = (orl_sec_offset)rel64->r_offset.u._32[I64LO32]; } else { rel32 = (Elf32_Rel *)rel; fix_rel_byte_order( reloc_sec->elf_file_hnd, rel32 ); o_rel->symbol = (orl_symbol_handle) &(reloc_sec->assoc.reloc.symbol_table->assoc.sym.symbols[ELF32_R_SYM( rel32->r_info )]); o_rel->type = ElfConvertRelocType( reloc_sec->elf_file_hnd, ELF32_R_TYPE( rel32->r_info ) ); o_rel->offset = rel32->r_offset; } o_rel->addend = 0; o_rel->frame = NULL; rel += reloc_sec->entsize; o_rel++; } break; case ORL_SEC_TYPE_RELOCS_EXPADD: num_relocs = reloc_sec->size / reloc_sec->entsize; reloc_sec->assoc.reloc.relocs = (orl_reloc *) _ClientSecAlloc( reloc_sec, sizeof( orl_reloc ) * num_relocs ); if( reloc_sec->assoc.reloc.relocs == NULL ) return( ORL_OUT_OF_MEMORY ); rel = reloc_sec->contents; o_rel = (orl_reloc *)reloc_sec->assoc.reloc.relocs; for( loop = 0; loop < num_relocs; loop++ ) { o_rel->section = (orl_sec_handle) orig_sec; if( reloc_sec->elf_file_hnd->flags & ORL_FILE_FLAG_64BIT_MACHINE ) { rela64 = (Elf64_Rela *)rel; fix_rela64_byte_order( reloc_sec->elf_file_hnd, rela64 ); o_rel->symbol = (orl_symbol_handle)&(reloc_sec->assoc.reloc.symbol_table->assoc.sym.symbols[rela64->r_info.u._32[I64HI32]]); o_rel->type = ElfConvertRelocType( reloc_sec->elf_file_hnd, (elf_reloc_type)rela64->r_info.u._32[I64LO32] ); o_rel->offset = (orl_sec_offset)rela64->r_offset.u._32[I64LO32]; o_rel->addend = (orl_reloc_addend)rela64->r_addend.u._32[I64LO32]; } else { rela32 = (Elf32_Rela *)rel; fix_rela_byte_order( reloc_sec->elf_file_hnd, rela32 ); o_rel->symbol = (orl_symbol_handle)&(reloc_sec->assoc.reloc.symbol_table->assoc.sym.symbols[ELF32_R_SYM( rela32->r_info )]); o_rel->type = ElfConvertRelocType( reloc_sec->elf_file_hnd, ELF32_R_TYPE( rela32->r_info ) ); o_rel->offset = rela32->r_offset; o_rel->addend = rela32->r_addend; } o_rel->frame = NULL; rel += reloc_sec->entsize; o_rel++; } break; default: break; } return( ORL_OKAY ); }
orl_return ElfCreateSymbolHandles( elf_sec_handle elf_sec_hnd ) { int loop; int num_syms; elf_symbol_handle current; unsigned char *current_sym; Elf32_Sym *current_sym32; Elf64_Sym *current_sym64; int st_name; num_syms = elf_sec_hnd->size / elf_sec_hnd->entsize; elf_sec_hnd->assoc.sym.symbols = (elf_symbol_handle) _ClientSecAlloc( elf_sec_hnd, sizeof( elf_symbol_handle_struct ) * num_syms ); if( !(elf_sec_hnd->assoc.sym.symbols) ) return( ORL_OUT_OF_MEMORY ); current = elf_sec_hnd->assoc.sym.symbols; current_sym = elf_sec_hnd->contents; for( loop = 0; loop < num_syms; loop++ ) { if( elf_sec_hnd->elf_file_hnd->flags & ORL_FILE_FLAG_64BIT_MACHINE ) { current_sym64 = (Elf64_Sym *)current_sym; fix_sym64_byte_order( elf_sec_hnd->elf_file_hnd, current_sym64 ); st_name = current_sym64->st_name; current->value.u._32[I64LO32] = current_sym64->st_value.u._32[I64LO32]; current->value.u._32[I64HI32] = current_sym64->st_value.u._32[I64HI32]; current->info = current_sym64->st_info; current->shndx = current_sym64->st_shndx; } else { current_sym32 = (Elf32_Sym *)current_sym; fix_sym_byte_order( elf_sec_hnd->elf_file_hnd, current_sym32 ); st_name = current_sym32->st_name; current->value.u._32[I64LO32] = current_sym32->st_value; current->value.u._32[I64HI32] = 0; current->info = current_sym32->st_info; current->shndx = current_sym32->st_shndx; } if( st_name == 0 ) { current->name = NULL; } else { current->name = (char *)&(elf_sec_hnd->assoc.sym.string_table->contents[st_name]); } current->file_format = ORL_ELF; current->elf_file_hnd = elf_sec_hnd->elf_file_hnd; switch( ELF32_ST_BIND( current->info ) ) { case STB_LOCAL: current->binding = ORL_SYM_BINDING_LOCAL; break; case STB_GLOBAL: current->binding = ORL_SYM_BINDING_GLOBAL; break; case STB_WEAK: current->binding = ORL_SYM_BINDING_WEAK; break; default: current->binding = ORL_SYM_BINDING_NONE; // other? break; } switch( ELF32_ST_TYPE( current->info ) ) { case STT_OBJECT: current->type = ORL_SYM_TYPE_OBJECT; break; case STT_FUNC: current->type = ORL_SYM_TYPE_FUNCTION; break; case STT_SECTION: current->type = ORL_SYM_TYPE_SECTION; break; case STT_FILE: current->type = ORL_SYM_TYPE_FILE; break; default: current->type = ORL_SYM_TYPE_NOTYPE; break; } switch( current->shndx ) { case SHN_ABS: current->type |= ORL_SYM_TYPE_ABSOLUTE; break; case SHN_COMMON: current->type |= ORL_SYM_TYPE_COMMON; break; case SHN_UNDEF: current->type |= ORL_SYM_TYPE_UNDEFINED; break; } current++; current_sym += elf_sec_hnd->entsize; } return( ORL_OKAY ); }