OSDN Git Service

2019/02/24(Sun) 18:41
authorKoine Yuusuke(koinec) <koinec@users.osdn.me>
Sun, 24 Feb 2019 09:41:19 +0000 (18:41 +0900)
committerKoine Yuusuke(koinec) <koinec@users.osdn.me>
Sun, 24 Feb 2019 09:41:19 +0000 (18:41 +0900)
 (LibGoblin)
  * WorkBackup

libgoblin/drd64_libgoblin_elf_dynsym.c

index c3a29c8..8fe4b62 100644 (file)
@@ -47,22 +47,22 @@ typedef struct      {
 
 /*----------------------------------------------------------------------
 ----------------------------------------------------------------------*/
-LIBGOBLIN_ELF_DYNSYM_EXTERN
-int
-       ELF64_DynSym_ReadSection(
+DynSym_Version *
+       ELF64_DynSym_GenerateDynSymVersion(
+                       DWord   *dw_maxver,
                        LibGoblin_BinaryInfo    *p_binfo )
 {
        Byte    *pb_gnuver_r;
        Byte    *pb_dynstr;
        Byte    *pb_now;
        int             i_bid;
-       DWord   dw_cnt;
+       DWord   dw_vermax       = 0;
        DWord   dw_symbols;
        DWord   dw_next;
        Elf64_Shdr      *p_shdr;
        Elf64_Verneed   *p_verneed;
        Elf64_Vernaux   *p_vernaux;
-       DynSym_Version  *p_version;
+       DynSym_Version  *p_version      = NULL;
        DynSym_Version  *p_vertemp;
        LibGoblin_SectionInfo   *psec_gnuver_r;
        LibGoblin_SectionInfo   *psec_dynsym;
@@ -72,39 +72,34 @@ int
        // Check exist .dynsym section ---
        psec_dynsym     = LibGoblin_Section_GetSectionInfo_fid(
                                                        p_binfo, LIBGOBLIN_SECTION_ID_DYNSYM );
-       if( NULL == psec_dynsym )       {
-               return 0x00;
-       }
+       if( NULL == psec_dynsym )
+               { goto  goto_ELF64_DynSym_GenerateDynSymVersion_post; }
        p_shdr  = (Elf64_Shdr *)(psec_dynsym->pb_sechdr);
        assert( NULL != p_shdr );
 
        psec_dynstr     = LibGoblin_Section_GetSectionInfo_fid(
                                                        p_binfo, LIBGOBLIN_SECTION_ID_DYNSTR );
-       if( NULL == psec_dynstr )       {
-               return 0x00;
-       }
+       if( NULL == psec_dynstr )
+               { goto  goto_ELF64_DynSym_GenerateDynSymVersion_post; }
        pb_dynstr       = psec_dynstr->pb_data;
 
+       psec_gnuver_r   = LibGoblin_Section_GetSectionInfo_fid(
+                                                       p_binfo, LIBGOBLIN_SECTION_ID_GNU_VERSION_R );
+       if( NULL == psec_gnuver_r )
+               { goto  goto_ELF64_DynSym_GenerateDynSymVersion_post; }
+       pb_gnuver_r     = psec_gnuver_r->pb_data;
+
 
        // Alloc Temp. DynSym Version Struct ---
        dw_symbols      = (DWord)p_shdr->sh_size / (DWord)p_shdr->sh_entsize;
        p_version       = (DynSym_Version *)malloc( sizeof(DynSym_Version) * dw_symbols );
-       if( NULL == p_version ) {
-               return -0x01;
-       }
+       if( NULL == p_version )
+               { goto  goto_ELF64_DynSym_GenerateDynSymVersion_post; }
        memset( p_version, 0x00, (sizeof(DynSym_Version) * dw_symbols) );
 
 
-       // Read .gnu.version_r for Temp-Data
-       //   Read Pass1 - Check max vna_other value.
-       psec_gnuver_r   = LibGoblin_Section_GetSectionInfo_fid(
-                                                       p_binfo, LIBGOBLIN_SECTION_ID_GNU_VERSION_R );
-       if( NULL == psec_gnuver_r )
-               { goto  goto_ELF64_DynSym_ReadSection_phase2; }
-       pb_gnuver_r     = psec_gnuver_r->pb_data;
-
-       dw_next = 0;
-       dw_cnt  = 0;
+       // Read .gnu.version_r for Temp-Data --------------------------------
+       dw_next         = 0;
        p_vertemp       = p_version;
        pb_now  = pb_gnuver_r;
        do      {
@@ -112,7 +107,8 @@ int
                p_verneed       = (Elf64_Verneed *)pb_now;
                p_vernaux       = (Elf64_Vernaux *)(pb_now + p_verneed->vn_aux);
 
-               i_bid   = BinInfo_SearchFilename( (char *)(pb_dynstr + p_verneed->vn_file), p_binfo );
+               i_bid   = BinInfo_SearchFilename(
+                                               (char *)(pb_dynstr + p_verneed->vn_file), p_binfo );
 
                p_vertemp->pv_verneed   = (void *)p_verneed;
                p_vertemp->pv_vernaux   = (void *)p_vernaux;
@@ -120,10 +116,9 @@ int
                p_vertemp->i_binfo_id   = i_bid;
                p_vertemp++;
 
-               dw_cnt++;
-               if( dw_cnt >= dw_symbols )      {
-                       goto    goto_ELF64_DynSym_ReadSection_err;
-               }
+               dw_vermax++;
+               if( dw_vermax >= dw_symbols )
+                       { goto  goto_ELF64_DynSym_GenerateDynSymVersion_post; }
 
                /*
                printf("  [Verneed] vn_version= %d, vn_cnt= %d, vn_file= %s, binfo= %d\n",
@@ -139,78 +134,85 @@ int
                dw_next = p_verneed->vn_next;
        } while( 0 < dw_next );
 
-
-
-
-goto_ELF64_DynSym_ReadSection_err:
-       free( p_version );
-
-/*
-       for( dw_cnt = 0; dw_cnt < dw_symbols; dw_cnt++ )        {
-
-       }
-*/
+goto_ELF64_DynSym_GenerateDynSymVersion_post:
+       *dw_maxver      = dw_vermax;
        
-       //   Read Pass2 - Read Data for Temp-Data
-
-       // Read .dymsym & .gnu.version for ObjectInfo
+       return p_version;
+}
 
-goto_ELF64_DynSym_ReadSection_phase2:
 
-/*
-       Byte            *pb_symtab;
-       Byte            *pb_strtab;
-       int                     i_result        = 0x00;
-       DWord           dw_symbols;
-       DWord           dw_cnt;
+/*----------------------------------------------------------------------
+----------------------------------------------------------------------*/
+LIBGOBLIN_ELF_DYNSYM_EXTERN
+int
+       ELF64_DynSym_ReadSection(
+                       LibGoblin_BinaryInfo    *p_binfo )
+{
+       Byte    *pb_dynstr;
+       //Byte  *pb_now;
+       int             i_bid;
+       DWord   dw_cnt;
+       DWord   dw_vermax;
+       DWord   dw_symbols;
        Elf64_Shdr      *p_shdr;
-       Elf64_Sym       *p_sym  = NULL;
-       LibGoblin_SectionInfo   *p_secinfo;
-       LibGoblin_SectionInfo   *p_secstr;
-       LibGoblin_SrcFile               *p_srcfile;
+       Elf64_Sym       *p_sym;
+       DynSym_Version  *p_version;
+       LibGoblin_SectionInfo   *psec_gversion  = NULL;
+       LibGoblin_SectionInfo   *psec_dynsym;
+       LibGoblin_SectionInfo   *psec_dynstr;
+       //LibGoblin_SrcFile             *p_srcfile;
        LibGoblin_ObjectInfo    *p_obj;
        LibGoblin_ProgramInfo   *p_pginfo;
-       
-       assert( NULL != p_binfo );
 
-       // Check BinaryInfo & Get SymbolEntires
-       p_secinfo       = LibGoblin_Section_GetSectionInfo_fid(
+
+       // Check exist .dynsym section ---
+       psec_dynsym     = LibGoblin_Section_GetSectionInfo_fid(
                                                        p_binfo, LIBGOBLIN_SECTION_ID_DYNSYM );
-       if( NULL == p_secinfo ) {
+       if( NULL == psec_dynsym )       {
                return 0x00;
        }
-       pb_symtab       = p_secinfo->pb_data;
+       p_shdr  = (Elf64_Shdr *)(psec_dynsym->pb_sechdr);
+       assert( NULL != p_shdr );
 
-       p_secstr        = LibGoblin_Section_GetSectionInfo_fid(
-                                                       p_binfo, LIBGOBLIN_SECTION_ID_STRTAB );
-       if( NULL == p_secstr )  {
+       psec_dynstr     = LibGoblin_Section_GetSectionInfo_fid(
+                                                       p_binfo, LIBGOBLIN_SECTION_ID_DYNSTR );
+       if( NULL == psec_dynstr )       {
                return 0x00;
        }
-       pb_strtab       = p_secstr->pb_data;
+       pb_dynstr       = psec_dynstr->pb_data;
+
+       // Read & Generate DynSym_Version struct data ---
+       p_version       = ELF64_DynSym_GenerateDynSymVersion( &dw_vermax, p_binfo );
+       if( NULL != p_version ) {
+               psec_gversion   = LibGoblin_Section_GetSectionInfo_fid(
+                                                               p_binfo, LIBGOBLIN_SECTION_ID_GNU_VERSION );
+               if( NULL == psec_gversion )     {
+                       return 0x00;
+               }
 
-       p_shdr  = (Elf64_Shdr *)(p_secinfo->pb_sechdr);
-       if( 0 == p_shdr->sh_entsize )   {
-               return -0x02;
        }
+
        dw_symbols      = (DWord)p_shdr->sh_size / (DWord)p_shdr->sh_entsize;
 
+       // Read .dymsym & .gnu.version for ObjectInfo
        p_pginfo        = ProgInfo_GetProgInfo( p_binfo->i_pginfo );
        assert( NULL != p_pginfo );
 
-       p_sym   = (Elf64_Sym *)pb_symtab;
-       for( dw_cnt = 0; ((dw_cnt < dw_symbols) && (0x00 == i_result)); dw_cnt++, p_sym++ )     {
+       p_sym   = (Elf64_Sym *)psec_dynsym->pb_data;
+       for( dw_cnt = 0; dw_cnt < dw_symbols; dw_cnt++, p_sym++ )       {
+               /*
+               // NODATA symbol.
+               if(( 0x00000000 == p_sym->st_value )
+                               && ( STT_NOTYPE == ELF64_ST_TYPE( p_sym->st_info ) ))
+                       { continue; }
 
-               // Source file.
+               // Source file. -- XXX: WARNING!!
                if( STT_FILE == ELF64_ST_TYPE( p_sym->st_info ) )       {
                        p_srcfile       = SrcFile_DispenseSrcFile( (char *)pb_strtab + p_sym->st_name );
                        assert( NULL != p_srcfile );
                        continue;
                }
 
-               if(( 0x00000000 == p_sym->st_value )
-                               && ( STT_NOTYPE == ELF64_ST_TYPE( p_sym->st_info ) ))
-                       { continue; }
-
        // st_value - Symbol value.
        // st_size - Size of associated object.
                p_obj   = ObjectInfo_InsetObject( p_pginfo,
@@ -252,12 +254,14 @@ goto_ELF64_DynSym_ReadSection_phase2:
 
                // st_shndx - Section index of symbol.
                p_obj->info.symbol.w_secindex   = p_sym->st_shndx;
+               */
        }
 
-       if( 0x00 != i_result )  {
-               return -0x04;
-       }
-*/
+
+       if( NULL != p_version )
+               { free( p_version ); }
+
+       
        return 0x00;
 }