Word *pw_gnuver = NULL;
Elf64_Shdr *p_shdr;
Elf64_Sym *p_sym;
+ PtrValue ptr_addr;
GnuVer_VerNeed *p_verneed;
GnuVer_VerNeed *p_vernow;
LibGoblin_SectionInfo *psec_gnuver = NULL;
if( 0 > i_symindex ) { continue; }
- p_obj = ObjectInfo_SearchDynamicSymbol(
- p_pginfo, ((PtrValue)p_sym->st_value + p_binfo->ptr_loadbase), pstr_symname );
+ // If dynsym addr = 0x00000000, Search PLT addr. from .got addr. ---
+//XXX
+ ptr_addr = ELF64_Rela_GetPLTaddr_fromGOT( p_binfo, pstr_symname );
+ if( 0x00000000 == p_sym->st_value )
+ { ptr_addr = ELF64_Rela_GetPLTaddr_fromGOT( p_binfo, pstr_symname ); }
+ else
+ { ptr_addr = (PtrValue)p_sym->st_value + p_binfo->ptr_loadbase; }
+
+ p_obj = ObjectInfo_SearchDynamicSymbol( p_pginfo, ptr_addr, pstr_symname );
// If the target program is stripped, p_obj = NULL because don't exist .symtab section.
if( NULL == p_obj ) {
- p_obj = ELF64_Symtab_RegistSymbol_toObjectInfo( p_pginfo, p_binfo, p_sym, pb_dynstr );
+ p_obj = ELF64_Symtab_RegistSymbol_toObjectInfo(
+ p_pginfo, p_binfo, ptr_addr, p_sym, pb_dynstr );
}
if( NULL != p_obj ) {
/*----------------------------------------------------------------------
----------------------------------------------------------------------*/
+LIBGOBLIN_ELF_RELA_EXTERN
+PtrValue
+ ELF64_Rela_GetPLTaddr_fromGOT(
+ LibGoblin_BinaryInfo *p_binfo,
+ char *pstr_symname )
+{
+ Byte *pb_dynstr;
+ Byte *pb_gotplt;
+ char *pstr_temp;
+ DWord dw_cnt;
+ DWord dw_maxrels;
+ DWord dw_symbol;
+ QWord qw_temp;
+ QWord qw_entsize;
+ PtrValue ptr_ret = 0x00000000;
+ PtrValue *pptr_pltaddr;
+ Elf64_Sym *pelf_sym;
+ Elf64_Rela *pelf_rela;
+ LibGoblin_SectionInfo *psec_rela;
+ LibGoblin_SectionInfo *psec_plt;
+ LibGoblin_SectionInfo *psec_gotplt;
+ LibGoblin_SectionInfo *psec_dynstr;
+ LibGoblin_SectionInfo *psec_dynsym;
+ LibGoblin_BinaryFile *p_bfile;
+
+ // --------------
+ p_bfile = BinaryFile_GetBinaryFile( p_binfo->i_binfile );
+ assert( NULL != p_bfile );
+
+ // --------------
+ psec_rela = Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_RELA_PLT );
+ if( NULL == psec_rela ) {
+ return ptr_ret;
+ }
+ if( NULL == psec_rela->pb_data ) {
+ return ptr_ret;
+ }
+ pelf_rela = (Elf64_Rela *)psec_rela->pb_data;
+ dw_maxrels = (DWord)psec_rela->qw_size / sizeof( Elf64_Rela );
+
+ // --------------
+ psec_dynsym = Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_DYNSYM );
+ if( NULL == psec_dynsym ) { return 0x00; }
+ if( NULL == psec_dynsym->pb_data ) { return 0x00; }
+
+ // --------------
+ psec_dynstr = Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_DYNSTR );
+ if( NULL == psec_dynstr ) { return 0x00; }
+ if( NULL == psec_dynstr->pb_data ) {
+ return -0x01;
+ }
+ pb_dynstr = psec_dynstr->pb_data;
+
+ // --------------
+ psec_gotplt = Section_GetSectionInfo_fromBinaryFile( p_bfile, LIBGOBLIN_SECTION_ID_GOT_PLT );
+ if( NULL == psec_gotplt ) { return 0x00; }
+ if( NULL == psec_gotplt->pb_data ) {
+ return -0x01;
+ }
+ pb_gotplt = psec_gotplt->pb_data;
+
+ // --------------
+ psec_plt = Section_GetSectionInfo_fromBinaryFile( p_bfile, LIBGOBLIN_SECTION_ID_PLT );
+ if( NULL == psec_plt ) { return 0x00; }
+printf(" debug: %s\n", pstr_symname );
+
+ if( 0 == psec_plt->qw_entsize )
+ { return 0x00; }
+
+printf(" debug plt entsize = %lx %lx %lx %d\n", qw_entsize, psec_plt->qw_entsize, psec_plt->qw_size, dw_maxrels );
+
+ for( dw_cnt = 0; dw_cnt < dw_maxrels; dw_cnt++, pelf_rela++ ) {
+ // r_info - Relocation type and symbol index.
+ dw_symbol = ELF64_R_SYM( pelf_rela->r_info );
+ if( 2 > dw_symbol ) { continue; }
+
+ pelf_sym = ((Elf64_Sym *)psec_dynsym->pb_data + dw_symbol);
+
+ pstr_temp = (char *)pb_dynstr + pelf_sym->st_name;
+ if( !strncmp( pstr_symname, pstr_temp, 60 ) ) {
+ if(( 0x00000000 == pelf_rela->r_offset )
+ || (pelf_rela->r_offset < psec_gotplt->ptr_addr.value ))
+ { goto goto_ELF64_Rela_GetPLTaddr_fromGOT; }
+
+ qw_temp = (QWord)pelf_rela->r_offset - (QWord)psec_gotplt->ptr_addr.value;
+ pptr_pltaddr = (PtrValue *)(psec_gotplt->pb_data + qw_temp);
+ ptr_ret = (PtrValue)(*pptr_pltaddr - (*pptr_pltaddr % psec_plt->qw_entsize));
+printf(" debug plt addr = %lx %lx\n", *pptr_pltaddr, ptr_ret );
+ break;
+ }
+ }
+
+goto_ELF64_Rela_GetPLTaddr_fromGOT:
+ return ptr_ret;
+}
+
+
+/*----------------------------------------------------------------------
+----------------------------------------------------------------------*/
int
ELF64_Rela_ReadIndicateSection_Rela(
LibGoblin_BinaryInfo *p_binfo,
#endif
LIBGOBLIN_ELF_RELA_EXTERN
+ PtrValue ELF64_Rela_GetPLTaddr_fromGOT( LibGoblin_BinaryInfo *p_binfo, char *pstr_symname );
+LIBGOBLIN_ELF_RELA_EXTERN
int ELF64_Rela_ReadSection( LibGoblin_BinaryInfo *p_binfo );
#ifdef DRD64_SRC_LIBGOBLIN_ELF_RELA
p_sectbl->i_binfile = p_binfo->i_binfile;
p_sectbl->w_index = (Word)i_cnt;
p_sectbl->qw_flag = p_sechdr->sh_flags;
+ p_sectbl->qw_entsize = p_sechdr->sh_entsize;
p_bfile->i_secindex[ i_cnt ] = i_index;
break;
p_sectbl->i_binfile = p_binfo->i_binfile;
p_sectbl->w_index = (Word)i_cnt;
p_sectbl->qw_flag = p_sechdr->sh_flags;
+ p_sectbl->qw_entsize = p_sechdr->sh_entsize;
p_bfile->i_secindex[ i_cnt ] = i_user_section;
ELF64_Symtab_RegistSymbol_toObjectInfo(
LibGoblin_ProgramInfo *p_pginfo,
LibGoblin_BinaryInfo *p_binfo,
+ PtrValue ptr_loadaddr,
Elf64_Sym *p_sym,
Byte *pb_strtab )
{
// st_value - Symbol value.
// st_size - Size of associated object.
p_obj = ObjectInfo_InsetObject( p_pginfo,
- ((PtrValue)p_sym->st_value + p_binfo->ptr_loadbase),
- (QWord)p_sym->st_size, NULL, 0x01 );
+ ptr_loadaddr, (QWord)p_sym->st_size, NULL, 0x01 );
// st_name - String table index of name.
p_obj->pstr_name = (char *)(pb_strtab + p_sym->st_name);
p_sym = (Elf64_Sym *)pb_symtab;
for( dw_cnt = 0; ((dw_cnt < dw_symbols) && (0x00 == i_result)); dw_cnt++, p_sym++ ) {
- ELF64_Symtab_RegistSymbol_toObjectInfo( p_pginfo, p_binfo, p_sym, pb_strtab );
+
+ // Dynamic Symbol without addr. don't regist ObjectInfo. ---
+ if(( SHN_UNDEF == p_sym->st_shndx ) && ( 0x00000000 == p_sym->st_value ))
+ { continue; }
+
+ // Regist Symbol to ObjectInfo. ---
+ ELF64_Symtab_RegistSymbol_toObjectInfo(
+ p_pginfo, p_binfo, ((PtrValue)p_sym->st_value + p_binfo->ptr_loadbase),
+ p_sym, pb_strtab );
}
if( 0x00 != i_result ) {
LIBGOBLIN_ELF_SYMTAB_EXTERN
LibGoblin_ObjectInfo *ELF64_Symtab_RegistSymbol_toObjectInfo(
LibGoblin_ProgramInfo *p_pginfo, LibGoblin_BinaryInfo *p_binfo,
- Elf64_Sym *p_sym, Byte *pb_strtab );
+ PtrValue ptr_loadaddr, Elf64_Sym *p_sym, Byte *pb_strtab );
LIBGOBLIN_ELF_SYMTAB_EXTERN
int ELF64_Symtab_ReadSection(
LibGoblin_BinaryInfo *p_binfo );
p_globsec->pstr_secname = p_sectbl->pstr_secname;
p_globsec->qw_size = p_sectbl->qw_size;
p_globsec->qw_flag = p_sectbl->qw_flag;
+ p_globsec->qw_entsize = p_sectbl->qw_entsize;
p_globsec->i_binfile = p_sectbl->i_binfile;
if( SHF_ALLOC & p_sectbl->qw_flag )
{ p_globsec->ptr_addr.value = p_sectbl->ptr_addr.value + p_binfo->ptr_loadbase; }
p_globsec->pstr_secname = p_sectbl->pstr_secname;
p_globsec->qw_size = p_sectbl->qw_size;
p_globsec->qw_flag = p_sectbl->qw_flag;
+ p_globsec->qw_entsize = p_sectbl->qw_entsize;
p_globsec->i_binfile = p_sectbl->i_binfile;
if( SHF_ALLOC & p_sectbl->qw_flag )
{ p_globsec->ptr_addr.value = p_sectbl->ptr_addr.value + p_binfo->ptr_loadbase; }
Ptr ptr_addr;
QWord qw_size;
QWord qw_flag;
+ QWord qw_entsize;
char *pstr_secname;
int i_binfile;