OSDN Git Service

2019/03/31(Sun) 20:17
authorKoine Yuusuke(koinec) <koinec@users.osdn.me>
Sun, 31 Mar 2019 11:16:56 +0000 (20:16 +0900)
committerKoine Yuusuke(koinec) <koinec@users.osdn.me>
Sun, 31 Mar 2019 11:16:56 +0000 (20:16 +0900)
 (LibGoblin)
  * WorkBackup

libgoblin/drd64_libgoblin_elf_dynsym.c
libgoblin/drd64_libgoblin_elf_rela.c
libgoblin/drd64_libgoblin_elf_rela.h
libgoblin/drd64_libgoblin_elf_section.c
libgoblin/drd64_libgoblin_elf_symtab.c
libgoblin/drd64_libgoblin_elf_symtab.h
libgoblin/drd64_libgoblin_section.c
libgoblin/drd64_libgoblin_type.h

index 0738996..d06ae9f 100644 (file)
@@ -60,6 +60,7 @@ int
        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;
@@ -162,11 +163,19 @@ int
                
                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 )     {
index 9b162f4..a4c20e3 100644 (file)
@@ -40,6 +40,105 @@ Comment:
 
 /*----------------------------------------------------------------------
 ----------------------------------------------------------------------*/
+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,
index 0f2f028..6b19e9c 100644 (file)
@@ -46,6 +46,8 @@ Comment:
 #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
index 80a8f68..ae36cad 100644 (file)
@@ -101,6 +101,7 @@ int
                                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;
@@ -122,6 +123,7 @@ int
                        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;
 
index 9c32be6..a3ed12e 100644 (file)
@@ -45,6 +45,7 @@ LibGoblin_ObjectInfo *
        ELF64_Symtab_RegistSymbol_toObjectInfo(
                        LibGoblin_ProgramInfo   *p_pginfo,
                        LibGoblin_BinaryInfo    *p_binfo,
+                       PtrValue        ptr_loadaddr,
                        Elf64_Sym       *p_sym,
                        Byte            *pb_strtab )
 {
@@ -70,8 +71,7 @@ LibGoblin_ObjectInfo *
        // 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);
@@ -167,7 +167,15 @@ int
 
        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 )  {
index ce4aabf..950c68a 100644 (file)
@@ -52,7 +52,7 @@ Comment:
 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 );
index 4a507d7..b644c3e 100644 (file)
@@ -104,6 +104,7 @@ int
                        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; }
@@ -136,6 +137,7 @@ int
                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; }
index b94f7dc..54906e0 100644 (file)
@@ -46,6 +46,7 @@ typedef struct        {
        Ptr             ptr_addr;
        QWord   qw_size;
        QWord   qw_flag;
+       QWord   qw_entsize;
        char    *pstr_secname;
        int             i_binfile;