From 7ec998a36abbf393636900fa56c28d0486bed0bb Mon Sep 17 00:00:00 2001 From: "Koine Yuusuke(koinec)" Date: Sun, 17 Mar 2019 20:35:09 +0900 Subject: [PATCH] 2019/03/17(Sun) 20:35 (LibGoblin) * WorkBackup --- libgoblin/drd64_libgoblin_debug_objinfo.c | 18 +++- libgoblin/drd64_libgoblin_elf.c | 2 +- libgoblin/drd64_libgoblin_elf_rela.c | 155 +++++++++++++----------------- libgoblin/drd64_libgoblin_objinfo.c | 41 ++++++++ libgoblin/drd64_libgoblin_objinfo.h | 3 + libgoblin/drd64_libgoblin_type.h | 20 +++- 6 files changed, 146 insertions(+), 93 deletions(-) diff --git a/libgoblin/drd64_libgoblin_debug_objinfo.c b/libgoblin/drd64_libgoblin_debug_objinfo.c index e2c9269..0ba2f11 100644 --- a/libgoblin/drd64_libgoblin_debug_objinfo.c +++ b/libgoblin/drd64_libgoblin_debug_objinfo.c @@ -46,7 +46,8 @@ static char gstr_type[256][9] = { "OBJECT", "COMMON", "TLS", - "", "", "", "", "", "", "", "", + "REL", + "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", @@ -241,6 +242,17 @@ void /*--------------------------------------------------------------------*/ void + Debug_ObjectInfo_Print_Rel( + LibGoblin_ObjectInfo *p_obj, + char *pstr_space, + Byte b_level ) +{ + //Debug_ObjectInfo_Print_SymbolCommon( p_obj, pstr_space, b_level ); + return; +} + +/*--------------------------------------------------------------------*/ +void Debug_ObjectInfo_Print_Section( LibGoblin_ObjectInfo *p_obj, char *pstr_space, @@ -488,6 +500,10 @@ void Debug_ObjectInfo_Print_TLS( p_obj, pstr_space, b_level ); break; + case OBJINFO_TYPE_REL: + Debug_ObjectInfo_Print_Rel( p_obj, pstr_space, b_level ); + break; + default: break; } diff --git a/libgoblin/drd64_libgoblin_elf.c b/libgoblin/drd64_libgoblin_elf.c index cf7b4f8..7e4486e 100644 --- a/libgoblin/drd64_libgoblin_elf.c +++ b/libgoblin/drd64_libgoblin_elf.c @@ -181,7 +181,7 @@ int return i_result; } - Debug_ObjectInfo_Print_AllGroupLink( p_pginfo, 0xff ); + //Debug_ObjectInfo_Print_AllGroupLink( p_pginfo, 0xff ); /* Analyze Dwarf-Debug Info. */ diff --git a/libgoblin/drd64_libgoblin_elf_rela.c b/libgoblin/drd64_libgoblin_elf_rela.c index 3845dba..9e0678b 100644 --- a/libgoblin/drd64_libgoblin_elf_rela.c +++ b/libgoblin/drd64_libgoblin_elf_rela.c @@ -40,71 +40,25 @@ Comment: /*---------------------------------------------------------------------- ----------------------------------------------------------------------*/ -/* -LIBGOBLIN_ELF_RELA_EXTERN -LibGoblin_ObjectInfo * - ELF64_Symtab_RegistSymbol_toObjectInfo( - LibGoblin_ProgramInfo *p_pginfo, - Elf64_Sym *p_sym, - Byte *pb_strtab ) -{ - LibGoblin_SrcFile *p_srcfile; - LibGoblin_ObjectInfo *p_obj = NULL; - - if(( 0x00000000 == p_sym->st_value ) - && ( STT_NOTYPE == ELF64_ST_TYPE( p_sym->st_info ) )) - { goto goto_ELF64_Symtab_RegistSymbol_toObjectInfo_post; } - - 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 ); - goto goto_ELF64_Symtab_RegistSymbol_toObjectInfo_post; - } - - p_obj = ObjectInfo_InsetObject( p_pginfo, - (PtrValue)p_sym->st_value, (QWord)p_sym->st_size, NULL, 0x01 ); - - p_obj->pstr_name = (char *)(pb_strtab + p_sym->st_name); - p_obj->dw_hash = Common_CalcDJBhash( (char *)(pb_strtab + p_sym->st_name) ); - - p_obj->info.symbol.b_type = ELF64_ST_TYPE( p_sym->st_info ); - switch( ELF64_ST_TYPE( p_sym->st_info ) ) { - case STT_NOTYPE: - p_obj->b_type = OBJINFO_TYPE_NULL; break; - case STT_OBJECT: - p_obj->b_type = OBJINFO_TYPE_OBJECT; break; - case STT_FUNC: - p_obj->b_type = OBJINFO_TYPE_FUNCTION; break; - case STT_SECTION: - p_obj->b_type = OBJINFO_TYPE_SECTION; break; - case STT_COMMON: - p_obj->b_type = OBJINFO_TYPE_COMMON; break; - case STT_TLS: - p_obj->b_type = OBJINFO_TYPE_TLS; break; - default: - p_obj->b_type = OBJINFO_TYPE_NULL; break; - } - - p_obj->info.symbol.b_binding = ELF64_ST_BIND( p_sym->st_info ); - p_obj->info.symbol.b_visibility = p_sym->st_other; - p_obj->info.symbol.w_secindex = p_sym->st_shndx; - if(( SHN_UNDEF == p_sym->st_shndx ) && ( STT_NOTYPE != ELF64_ST_TYPE( p_sym->st_info ) )) - { p_obj->dw_status |= OBJINFO_STATUS_DYNAMIC; } - -goto_ELF64_Symtab_RegistSymbol_toObjectInfo_post: - return p_obj; -} -*/ - -/*---------------------------------------------------------------------- -----------------------------------------------------------------------*/ int ELF64_Rela_ReadIndicateSection_Rela( LibGoblin_BinaryInfo *p_binfo, Byte b_secid ) { - Elf64_Rela *p_rela; + DWord dw_cnt; + DWord dw_maxrels; + DWord dw_symbol; + DWord dw_type; + Byte *pb_dynstr; + Elf64_Sym *pelf_sym; + Elf64_Rela *pelf_rela; + PtrValue ptr_origin; LibGoblin_SectionInfo *psec_rela; + LibGoblin_SectionInfo *psec_dynsym; + LibGoblin_SectionInfo *psec_dynstr; + LibGoblin_ProgramInfo *p_pginfo; + LibGoblin_ObjectInfo *pobj_rel; + LibGoblin_ObjectInfo *pobj_origin; psec_rela = Section_GetSectionInfo_fromBinaryInfo( p_binfo, b_secid ); if( NULL == psec_rela ) { @@ -113,40 +67,69 @@ int if( NULL == psec_rela->pb_data ) { return 0x00; } - - -/* - Byte *pb_symtab; - Byte *pb_strtab; - int i_result = 0x00; - DWord dw_symbols; - DWord dw_cnt; - Elf64_Shdr *p_shdr; - Elf64_Sym *p_sym = NULL; - LibGoblin_SectionInfo *p_secinfo; - LibGoblin_SectionInfo *p_secstr; - LibGoblin_ProgramInfo *p_pginfo; - - assert( NULL != p_binfo ); - - p_shdr = (Elf64_Shdr *)(p_secinfo->pb_sechdr); - if( 0 == p_shdr->sh_entsize ) { - return -0x02; + pelf_rela = (Elf64_Rela *)psec_rela->pb_data; + + // ---------------- + psec_dynsym = Section_GetSectionInfo_fromBinaryInfo( p_binfo, LIBGOBLIN_SECTION_ID_DYNSYM ); + if( NULL == psec_dynsym ) { return 0x00; } + if( NULL == psec_dynsym->pb_data ) { return 0x00; } + + // ---------------- + psec_dynstr = Section_GetSectionInfo_fromBinaryInfo( p_binfo, LIBGOBLIN_SECTION_ID_DYNSTR ); + if( NULL == psec_dynstr ) { return 0x00; } + if( NULL == psec_dynstr->pb_data ) { + return -0x01; } - dw_symbols = (DWord)p_shdr->sh_size / (DWord)p_shdr->sh_entsize; + pb_dynstr = psec_dynstr->pb_data; + + dw_maxrels = (DWord)psec_rela->qw_size / sizeof( Elf64_Rela ); 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++ ) { - ELF64_Symtab_RegistSymbol_toObjectInfo( p_pginfo, p_sym, pb_strtab ); - } + 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 ); + dw_type = ELF64_R_TYPE( pelf_rela->r_info ); + + ptr_origin = 0x00000000; + if( 1 < dw_symbol ) { + pelf_sym = ((Elf64_Sym *)psec_dynsym->pb_data + dw_symbol); + ptr_origin = (PtrValue)pelf_sym->st_value; + } + if( 0 > pelf_rela->r_addend ) + { ptr_origin -= (PtrValue)((Int64)-1 * pelf_rela->r_addend); } + else + { ptr_origin += pelf_rela->r_addend; } + + printf(" debug: r_offset = %lxh, r_addend = %lxh, type = %xh, symbol = %xh origin = %lxh\n", + pelf_rela->r_offset, pelf_rela->r_addend, dw_type, dw_symbol, ptr_origin ); + + + pobj_rel = ObjectInfo_SearchAddressSize( + p_pginfo, (PtrValue)pelf_rela->r_offset, sizeof( void * ) ); + if( NULL == pobj_rel ) { + // r_offset - Location to be relocated. + pobj_rel = ObjectInfo_InsetObject( + p_pginfo, (PtrValue)pelf_rela->r_offset, sizeof( void * ), NULL, 0x01 ); + pobj_rel->b_type = OBJINFO_TYPE_REL; + } + assert( NULL != pobj_rel ); + + pobj_rel->dw_status |= OBJINFO_STATUS_REL; + + + if( (PtrValue)pelf_rela->r_offset != ptr_origin ) { + pobj_origin = ObjectInfo_SearchAddressSize( + p_pginfo, (PtrValue)ptr_origin, 0x00000000 ); + + if( NULL != pobj_origin ) { + pobj_origin->dynamic.i_objid_rel = pobj_rel->i_id; + pobj_rel->rel.i_objid_origin = pobj_origin->i_id; + } + } - if( 0x00 != i_result ) { - return -0x04; } -*/ return 0x00; } diff --git a/libgoblin/drd64_libgoblin_objinfo.c b/libgoblin/drd64_libgoblin_objinfo.c index 49038ae..42a7ef4 100644 --- a/libgoblin/drd64_libgoblin_objinfo.c +++ b/libgoblin/drd64_libgoblin_objinfo.c @@ -281,6 +281,47 @@ goto_ObjectInfo_InsetObject_post: ----------------------------------------------------------------------*/ LIBGOBLIN_OBJINFO_EXTERN LibGoblin_ObjectInfo * + ObjectInfo_SearchAddressSize( + LibGoblin_ProgramInfo *p_pginfo, + PtrValue ptr_value, + QWord qw_size ) +{ + LibGoblin_ObjectInfo *p_objnow; + LibGoblin_ObjectInfo *p_objret = NULL; + + // Check exist MasterObject --- + if( NO_OBJ == p_pginfo->objinfo.i_topid ) + { goto goto_ObjectInfo_SearchObjectInfo_post; } + + + // Search ObjectInfo Inset Location. (Address Order)--- + p_objnow = OBJINFO( p_pginfo, p_pginfo->objinfo.i_topid ); + assert( NULL != p_objnow ); + + do { + if( p_objnow->addr.ptr_addr.value > ptr_value ) + { break; } + else if( p_objnow->addr.ptr_addr.value == ptr_value ) { + if(( 0 == qw_size ) + || (( 0 < qw_size ) && ( p_objnow->addr.qw_size == qw_size ))) { + p_objret = p_objnow; + break; + } + } + + p_objnow = ((NO_OBJ != p_objnow->addrlink.i_next_id) + ? OBJINFO( p_pginfo, p_objnow->addrlink.i_next_id ) : NULL ); + }while( NULL != p_objnow ); + + goto_ObjectInfo_SearchObjectInfo_post: + return p_objret; +} + + +/*---------------------------------------------------------------------- +----------------------------------------------------------------------*/ +LIBGOBLIN_OBJINFO_EXTERN +LibGoblin_ObjectInfo * ObjectInfo_SearchDynamicSymbol( LibGoblin_ProgramInfo *p_pginfo, PtrValue ptr_value, diff --git a/libgoblin/drd64_libgoblin_objinfo.h b/libgoblin/drd64_libgoblin_objinfo.h index d6c5f7d..0d783db 100644 --- a/libgoblin/drd64_libgoblin_objinfo.h +++ b/libgoblin/drd64_libgoblin_objinfo.h @@ -72,6 +72,9 @@ LIBGOBLIN_OBJINFO_EXTERN LibGoblin_ProgramInfo *p_pginfo, PtrValue ptr_value, QWord qw_size, LibGoblin_ObjectInfo *p_parent, Byte b_mode ); LIBGOBLIN_OBJINFO_EXTERN + LibGoblin_ObjectInfo *ObjectInfo_SearchAddressSize( + LibGoblin_ProgramInfo *p_pginfo, PtrValue ptr_value, QWord qw_size ); +LIBGOBLIN_OBJINFO_EXTERN LibGoblin_ObjectInfo *ObjectInfo_SearchDynamicSymbol( LibGoblin_ProgramInfo *p_pginfo, PtrValue ptr_value, char *pstr_symname ); LIBGOBLIN_OBJINFO_EXTERN diff --git a/libgoblin/drd64_libgoblin_type.h b/libgoblin/drd64_libgoblin_type.h index eb7446c..b0b899c 100644 --- a/libgoblin/drd64_libgoblin_type.h +++ b/libgoblin/drd64_libgoblin_type.h @@ -47,6 +47,8 @@ typedef struct { QWord qw_size; char *pstr_secname; int i_fid; + + int i_objid; } LibGoblin_SectionInfo; @@ -63,11 +65,12 @@ typedef struct { /*=====================================================================*/ -#define OBJINFO_STATUS_INVALID 0x00 -#define OBJINFO_STATUS_VALID 0x01 // bit 0 -#define OBJINFO_STATUS_DYNAMIC 0x02 // bit 1 -#define OBJINFO_STATUS_RESOLV1 0x04 // bit 2 (Specified BinaryInfo & Index) -#define OBJINFO_STATUS_RESOLV2 0x08 // bit 3 (Loaded .so) +#define OBJINFO_STATUS_INVALID 0x00000000 +#define OBJINFO_STATUS_VALID 0x00000001 // bit 0 +#define OBJINFO_STATUS_DYNAMIC 0x00000002 // bit 1 +#define OBJINFO_STATUS_RESOLV1 0x00000004 // bit 2 (Specified BinaryInfo & Index) +#define OBJINFO_STATUS_RESOLV2 0x00000008 // bit 3 (Loaded .so) +#define OBJINFO_STATUS_REL 0x00000100 #define OBJINFO_TYPE_NULL 0x00 #define OBJINFO_TYPE_MASTER 0x01 @@ -77,6 +80,7 @@ typedef struct { #define OBJINFO_TYPE_OBJECT 0x05 #define OBJINFO_TYPE_COMMON 0x06 #define OBJINFO_TYPE_TLS 0x07 +#define OBJINFO_TYPE_REL 0x08 typedef struct { int i_id; @@ -152,8 +156,14 @@ typedef struct { struct { int i_binfo_origin; int i_dynsym_index; + + int i_objid_rel; } dynamic; + struct { + int i_objid_origin; + } rel; + int i_secid; int i_srcid; // SourceInfo struct ID -- 2.11.0