OSDN Git Service

2019/04/04(Thr) 05:40
authorKoine Yuusuke(koinec) <koinec@users.osdn.me>
Wed, 3 Apr 2019 20:40:37 +0000 (05:40 +0900)
committerKoine Yuusuke(koinec) <koinec@users.osdn.me>
Wed, 3 Apr 2019 20:40:37 +0000 (05:40 +0900)
 (LibGoblin)
  * Support ELF-Analyze Library.

libgoblin/drd64_libgoblin_elf_dynsym.c
libgoblin/test_libgoblin_loadprog.c

index c5c062f..e621045 100644 (file)
@@ -58,6 +58,7 @@ int
        DWord   dw_sym;
        DWord   dw_vermax;
        DWord   dw_symbols;
+       DWord   dw_status;
        QWord   qw_size;
        Elf64_Shdr      *p_shdr;
        Elf64_Sym       *p_sym;
@@ -133,69 +134,77 @@ int
 
                // If p_sym->st_shndx != 0(UNDEF),
                //   the symbol object is implemented in self-object.
-               if( SHN_UNDEF != p_sym->st_shndx )      { continue; }
-
-               // Search DynSym_Version ---
-               i_bid                   = p_binfo->i_id;
-               if( 1 < w_gnuver )      {
-                       p_vernow        = p_verneed;
-                       for( dw_cnt = 0; dw_cnt < dw_vermax; dw_cnt++, p_vernow++ )     {
-                               if( w_gnuver == p_vernow->dw_other )    {
-                                       i_bid                   = p_vernow->i_binfo_id;
-                                       break;
+               //if( SHN_UNDEF != p_sym->st_shndx )    { continue; }
+               if( SHN_UNDEF != p_sym->st_shndx )      {
+                       ptr_addr                = (PtrValue)p_sym->st_value;
+                       qw_size                 = p_sym->st_size;
+                       pstr_symname    = (char *)(pb_dynstr + p_sym->st_name);
+                       dw_status               = 0x00;
+               }
+               else    {
+                       // Search DynSym_Version ---
+                       i_bid                   = p_binfo->i_id;
+                       if( 1 < w_gnuver )      {
+                               p_vernow        = p_verneed;
+                               for( dw_cnt = 0; dw_cnt < dw_vermax; dw_cnt++, p_vernow++ )     {
+                                       if( w_gnuver == p_vernow->dw_other )    {
+                                               i_bid                   = p_vernow->i_binfo_id;
+                                               break;
+                                       }
                                }
                        }
-               }
 
-               if( i_bid == p_binfo->i_id )    {
-                       i_bid           = BinInfo_SearchNextSlave( p_binfo->i_id, i_bid );
-                       p_vernow        = NULL;
-               }
-
-               pstr_symname    =  (char *)(pb_dynstr + p_sym->st_name);
+                       if( i_bid == p_binfo->i_id )    {
+                               i_bid           = BinInfo_SearchNextSlave( p_binfo->i_id, i_bid );
+                               p_vernow        = NULL;
+                       }
 
-               // Check .gnu.hash ---
-               b_binding       = 255;
-               i_symindex      = -0x01;
-               while( -0x01 != i_bid )         {
-                       p_binlib        = BinaryInfo_GetBinInfo( i_bid );
-                       assert( NULL != p_binlib );
+                       pstr_symname    = (char *)(pb_dynstr + p_sym->st_name);
+
+                       // Check .gnu.hash ---
+                       b_binding       = 255;
+                       i_symindex      = -0x01;
+                       while( -0x01 != i_bid )         {
+                               p_binlib        = BinaryInfo_GetBinInfo( i_bid );
+                               assert( NULL != p_binlib );
+
+                               i_result        = ELF64_GnuHash_SearchDynSym(
+                                                                       p_binlib, pstr_symname, p_vernow, &b_bindtemp );
+                               if( 0 <= i_result )             {
+                                       i_symindex      = i_result;
+                                       b_binding       = b_bindtemp;
+                                       if( STB_WEAK != b_binding )     { break; }
+                               }
 
-                       i_result        = ELF64_GnuHash_SearchDynSym( p_binlib, pstr_symname, p_vernow, &b_bindtemp );
-                       if( 0 <= i_result )             {
-                               i_symindex      = i_result;
-                               b_binding       = b_bindtemp;
-                               if( STB_WEAK != b_binding )     { break; }
+                               i_bid   = BinInfo_SearchNextSlave( p_binfo->i_id, i_bid );
                        }
-
-                       i_bid   = BinInfo_SearchNextSlave( p_binfo->i_id, i_bid );
-               }
                
-               if( 0 > i_symindex )    { continue; }
+                       if( 0 > i_symindex )    { continue; }
 
-               // If dynsym addr = 0x00000000, Search PLT addr. from .got addr. ---
-               //   for FreeBSD 11.x or older ---
-               if( 0x00000000 == p_sym->st_value )     {
-                       ptr_addr        = ELF64_Rela_GetPLTaddr_fromGOT( p_binfo, pstr_symname );
-                       qw_size         = psec_plt->qw_entsize;
-               }
-               //   for FreeBSD 12.x ---
-               else    {
-                       ptr_addr        = (PtrValue)p_sym->st_value;
-                       qw_size         = p_sym->st_size;
+                       // If dynsym addr = 0x00000000, Search PLT addr. from .got addr. ---
+                       //   for FreeBSD 11.x or older ---
+                       if( 0x00000000 == p_sym->st_value )     {
+                               ptr_addr        = ELF64_Rela_GetPLTaddr_fromGOT( p_binfo, pstr_symname );
+                               qw_size         = psec_plt->qw_entsize;
+                       }
+                       //   for FreeBSD 12.x ---
+                       else    {
+                               ptr_addr        = (PtrValue)p_sym->st_value;
+                               qw_size         = p_sym->st_size;
+                       }
+                       dw_status       = OBJINFO_STATUS_DYNAMIC;
                }
 
                if( 0x00000000 < ptr_addr )     {
                        ptr_addr        += p_binfo->ptr_loadbase;
-                       p_obj   = ObjectInfo_SearchDynamicSymbol(
-                                                               p_pginfo, ptr_addr, pstr_symname, OBJINFO_STATUS_DYNAMIC );
+                       p_obj   = ObjectInfo_SearchDynamicSymbol( p_pginfo, ptr_addr, pstr_symname, dw_status );
                        // 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, ptr_addr, qw_size, p_sym, pb_dynstr );
                        }
 
-                       if( NULL != p_obj )     {
+                       if(( NULL != p_obj ) && ( OBJINFO_STATUS_DYNAMIC == dw_status ))        {
                                p_obj->dynamic.i_binfo_origin   = i_bid;
                                p_obj->dynamic.i_dynsym_index   = i_symindex;
                                p_obj->dw_status                                |= (OBJINFO_STATUS_DYNAMIC | OBJINFO_STATUS_RESOLV1);
index f335ac7..1215388 100644 (file)
@@ -101,8 +101,8 @@ void Test_LibGoblin_LoadProg_API_LoadProgram_test00_001( void )
        i_result        = LibGoblin_AnalyzeMainProgram( i_pgid );
        CU_ASSERT( 0x00 == i_result );
 
-       //i_result      = LibGoblin_AnalyzeLibrary( i_pgid, i_bid[2], 0x80000000 );
-       //CU_ASSERT( 0x00 == i_result );
+       i_result        = LibGoblin_AnalyzeLibrary( i_pgid, i_bid[2], 0x80000000 );
+       CU_ASSERT( 0x00 == i_result );
 
        i_result        = LibGoblin_FreeProgInfo( i_pgid );
        CU_ASSERT( 0x00 == i_result );