OSDN Git Service

2019/03/31(Sun) 20:56
authorKoine Yuusuke(koinec) <koinec@users.osdn.me>
Sun, 31 Mar 2019 11:55:46 +0000 (20:55 +0900)
committerKoine Yuusuke(koinec) <koinec@users.osdn.me>
Sun, 31 Mar 2019 11:55:46 +0000 (20:55 +0900)
 (LibGoblin)
  * Support FreeBSD 11.x older ld. (without .plt addr in .dynsym)

libgoblin/drd64_libgoblin_elf_dynsym.c
libgoblin/drd64_libgoblin_elf_symtab.c
libgoblin/drd64_libgoblin_elf_symtab.h

index bf2a514..a68cabc 100644 (file)
@@ -52,12 +52,13 @@ int
        int             i_bid;
        int             i_result;
        int             i_symindex;
+       Word    w_gnuver        = 0;
+       Word    *pw_gnuver      = NULL;
        DWord   dw_cnt;
        DWord   dw_sym;
        DWord   dw_vermax;
        DWord   dw_symbols;
-       Word    w_gnuver        = 0;
-       Word    *pw_gnuver      = NULL;
+       QWord   qw_size;
        Elf64_Shdr      *p_shdr;
        Elf64_Sym       *p_sym;
        PtrValue        ptr_addr;
@@ -66,6 +67,7 @@ int
        LibGoblin_SectionInfo   *psec_gnuver    = NULL;
        LibGoblin_SectionInfo   *psec_dynsym;
        LibGoblin_SectionInfo   *psec_dynstr;
+       LibGoblin_SectionInfo   *psec_plt;
        LibGoblin_ObjectInfo    *p_obj;
        LibGoblin_ProgramInfo   *p_pginfo;
        LibGoblin_BinaryInfo    *p_binlib;
@@ -79,6 +81,7 @@ int
        }
        p_shdr  = (Elf64_Shdr *)(psec_dynsym->pb_sechdr);
 
+       // Check exist .dynstr section ---
        psec_dynstr     = Section_GetSectionInfo(
                                                        p_binfo, LIBGOBLIN_SECTION_ID_DYNSTR );
        assert( NULL != psec_dynstr );
@@ -87,6 +90,13 @@ int
        }
        pb_dynstr       = psec_dynstr->pb_data;
 
+       // Check exist .plt section ---
+       psec_plt        = Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_PLT );
+       assert( NULL != psec_plt );
+       if( NULL == psec_plt->pb_data ) {
+               return 0x00;
+       }
+
        // Read & Generate DynSym_Version struct data ---
        p_verneed       = ELF64_GnuVer_GenerateGnuVerNeed( &dw_vermax, p_binfo );
        if( NULL != p_verneed ) {
@@ -164,10 +174,16 @@ int
                if( 0 > i_symindex )    { continue; }
 
                // If dynsym addr = 0x00000000, Search PLT addr. from .got addr. ---
-               if( 0x00000000 == p_sym->st_value )
-                       { ptr_addr      = ELF64_Rela_GetPLTaddr_fromGOT( p_binfo, pstr_symname ); }
-               else
-                       { ptr_addr      = (PtrValue)p_sym->st_value; }
+               //   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( 0x00000000 < ptr_addr )     {
                        ptr_addr        += p_binfo->ptr_loadbase;
@@ -175,33 +191,17 @@ int
                        // 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, p_sym, pb_dynstr );
+                                                                       p_pginfo, p_binfo, ptr_addr, p_sym->st_size, p_sym, pb_dynstr );
                        }
 
                        if( NULL != p_obj )     {
                                p_obj->dynamic.i_binfo_origin   = i_bid;
                                p_obj->dynamic.i_dynsym_index   = i_symindex;
-                               p_obj->dw_status                                |= OBJINFO_STATUS_RESOLV1;
+                               p_obj->dw_status                                |= (OBJINFO_STATUS_DYNAMIC | OBJINFO_STATUS_RESOLV1);
                        }
                }
-
-/*
-               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, ptr_addr, p_sym, pb_dynstr );
-               }
-
-               if( NULL != p_obj )     {
-                       p_obj->dynamic.i_binfo_origin   = i_bid;
-                       p_obj->dynamic.i_dynsym_index   = i_symindex;
-                       p_obj->dw_status                                |= OBJINFO_STATUS_RESOLV1;
-               }
-*/
        }
 
-
        ELF64_GnuVer_FreeGnuVerNeed( p_verneed );
        
        return 0x00;
index a3ed12e..911f31e 100644 (file)
@@ -46,6 +46,7 @@ LibGoblin_ObjectInfo *
                        LibGoblin_ProgramInfo   *p_pginfo,
                        LibGoblin_BinaryInfo    *p_binfo,
                        PtrValue        ptr_loadaddr,
+                       QWord           qw_size,
                        Elf64_Sym       *p_sym,
                        Byte            *pb_strtab )
 {
@@ -70,8 +71,9 @@ LibGoblin_ObjectInfo *
 
        // st_value - Symbol value.
        // st_size - Size of associated object.
-       p_obj   = ObjectInfo_InsetObject( p_pginfo,
-                                                       ptr_loadaddr, (QWord)p_sym->st_size, NULL, 0x01 );
+       //p_obj = ObjectInfo_InsetObject( p_pginfo,
+                                                       //ptr_loadaddr, (QWord)p_sym->st_size, NULL, 0x01 );
+       p_obj   = ObjectInfo_InsetObject( p_pginfo, ptr_loadaddr, qw_size, NULL, 0x01 );
 
        // st_name - String table index of name.
        p_obj->pstr_name        = (char *)(pb_strtab + p_sym->st_name);
@@ -175,7 +177,7 @@ int
                // 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 );
+                                       p_sym->st_size, p_sym, pb_strtab );
        }
 
        if( 0x00 != i_result )  {
index 950c68a..babb42e 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,
-                       PtrValue ptr_loadaddr, Elf64_Sym *p_sym, Byte *pb_strtab );
+                       PtrValue ptr_loadaddr, QWord qw_size, Elf64_Sym *p_sym, Byte *pb_strtab );
 LIBGOBLIN_ELF_SYMTAB_EXTERN
        int ELF64_Symtab_ReadSection(
                        LibGoblin_BinaryInfo    *p_binfo );