1 /*DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64
4 for INTEL64(R), AMD64(R)
6 Copyright(C) 2007-2009 Koine Yuusuke(koinec). All rights reserved.
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
11 1. Redistributions of source code must retain the above copyright notice,
12 this list of conditions and the following disclaimer.
13 2. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
17 THIS SOFTWARE IS PROVIDED BY Koine Yuusuke(koinec) ``AS IS'' AND ANY
18 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL Koine Yuusuke(koinec) OR CONTRIBUTORS BE
21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27 OF THE POSSIBILITY OF SUCH DAMAGE.
29 DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64*/
31 /* File Info -----------------------------------------------------------
35 ----------------------------------------------------------------------*/
37 #define DRD64_SRC_LIBGOBLIN_ELF_DYNSYM
38 #include"drd64_libgoblin.h"
41 /*----------------------------------------------------------------------
42 ----------------------------------------------------------------------*/
44 ELF_DynSym_ReSetPLTsize_inObjectInfo(
45 LibGoblin_ProgramInfo *p_pginfo,
46 LibGoblin_BinaryInfo *p_binfo )
49 LibGoblin_SectionInfo *psec_plt;
50 LibGoblin_ObjectInfo *pobj_plt;
51 LibGoblin_ObjectInfo *pobj_now;
52 LibGoblin_ObjectInfo *pobj_next;
54 psec_plt = Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_PLT );
55 assert( NULL != psec_plt );
56 if( NULL == psec_plt->pb_data ) {
60 pobj_plt = ObjectInfo_GetObjectInfo( p_pginfo, psec_plt->i_objid );
61 assert( NULL != pobj_plt );
63 pobj_now = ObjectInfo_GetGroupChildTop( p_pginfo, pobj_plt );
64 while( NULL != pobj_now ) {
65 pobj_next = ObjectInfo_GetGroupNext( p_pginfo, pobj_now );
67 if( 0 == pobj_now->addr.qw_size ) {
68 if( NULL != pobj_next ) {
69 qw_size = pobj_next->addr.ptr_addr.value - pobj_now->addr.ptr_addr.value;
72 qw_size = (pobj_plt->addr.ptr_addr.value + pobj_plt->addr.qw_size)
73 - pobj_now->addr.ptr_addr.value;
75 pobj_now->addr.qw_size = qw_size;
85 /*----------------------------------------------------------------------
86 ----------------------------------------------------------------------*/
87 LIBGOBLIN_ELF_DYNSYM_EXTERN
89 ELF64_DynSym_ReadSection(
90 LibGoblin_BinaryInfo *p_binfo )
100 Word *pw_gnuver = NULL;
110 GnuVer_VerNeed *p_verneed;
111 GnuVer_VerNeed *p_vernow;
112 LibGoblin_SectionInfo *psec_gnuver = NULL;
113 LibGoblin_SectionInfo *psec_dynsym;
114 LibGoblin_SectionInfo *psec_dynstr;
115 LibGoblin_SectionInfo *psec_plt;
116 LibGoblin_ObjectInfo *p_obj;
117 LibGoblin_ProgramInfo *p_pginfo;
118 LibGoblin_BinaryInfo *p_binlib;
120 // Check exist .dynsym section ---
121 psec_dynsym = Section_GetSectionInfo(
122 p_binfo, LIBGOBLIN_SECTION_ID_DYNSYM );
123 assert( NULL != psec_dynsym );
124 if( NULL == psec_dynsym->pb_sechdr ) {
127 p_shdr = (Elf64_Shdr *)(psec_dynsym->pb_sechdr);
129 // Check exist .dynstr section ---
130 psec_dynstr = Section_GetSectionInfo(
131 p_binfo, LIBGOBLIN_SECTION_ID_DYNSTR );
132 assert( NULL != psec_dynstr );
133 if( NULL == psec_dynstr->pb_data ) {
136 pb_dynstr = psec_dynstr->pb_data;
138 // Check exist .plt section ---
139 psec_plt = Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_PLT );
140 assert( NULL != psec_plt );
141 if( NULL == psec_plt->pb_data ) {
145 // Read & Generate DynSym_Version struct data ---
146 p_verneed = ELF64_GnuVer_GenerateGnuVerNeed( &dw_vermax, p_binfo );
147 if( NULL != p_verneed ) {
148 psec_gnuver = Section_GetSectionInfo(
149 p_binfo, LIBGOBLIN_SECTION_ID_GNU_VERSION );
150 assert( NULL != psec_gnuver );
151 if( NULL == psec_gnuver->pb_data ) {
154 pw_gnuver = (Word *)psec_gnuver->pb_data;
157 dw_symbols = (DWord)p_shdr->sh_size / (DWord)p_shdr->sh_entsize;
159 // Read .dymsym & .gnu.version for ObjectInfo
160 p_pginfo = ProgInfo_GetProgInfo( p_binfo->i_pginfo );
161 assert( NULL != p_pginfo );
164 p_sym = (Elf64_Sym *)psec_dynsym->pb_data;
165 for( dw_sym = 0; dw_sym < dw_symbols; dw_sym++, p_sym++ ) {
166 if( NULL != pw_gnuver ) { w_gnuver = (*pw_gnuver++) & 0x7fff; }
169 if(( 0x00000000 == p_sym->st_value )
170 && ( STT_NOTYPE == ELF64_ST_TYPE( p_sym->st_info ) ))
173 // Source file. -- XXX: WARNING!!
174 if( STT_FILE == ELF64_ST_TYPE( p_sym->st_info ) ) {
175 // XXX - WARNING Msg.
179 // If p_sym->st_shndx != 0(UNDEF),
180 // the symbol object is implemented in self-object.
181 //if( SHN_UNDEF != p_sym->st_shndx ) { continue; }
182 if( SHN_UNDEF != p_sym->st_shndx ) {
183 ptr_addr = (PtrValue)p_sym->st_value;
184 qw_size = p_sym->st_size;
185 pstr_symname = (char *)(pb_dynstr + p_sym->st_name);
189 // Search DynSym_Version ---
190 i_bid = p_binfo->i_id;
192 p_vernow = p_verneed;
193 for( dw_cnt = 0; dw_cnt < dw_vermax; dw_cnt++, p_vernow++ ) {
194 if( w_gnuver == p_vernow->dw_other ) {
195 i_bid = p_vernow->i_binfo_id;
201 if( i_bid == p_binfo->i_id ) {
202 i_bid = BinInfo_SearchNextSlave( p_binfo->i_id, i_bid );
206 pstr_symname = (char *)(pb_dynstr + p_sym->st_name);
208 // Check .gnu.hash ---
211 while( -0x01 != i_bid ) {
212 p_binlib = BinaryInfo_GetBinInfo( i_bid );
213 assert( NULL != p_binlib );
215 i_result = ELF64_GnuHash_SearchDynSym(
216 p_binlib, pstr_symname, p_vernow, &b_bindtemp );
217 if( 0 <= i_result ) {
218 i_symindex = i_result;
219 b_binding = b_bindtemp;
220 if( STB_WEAK != b_binding ) { break; }
223 i_bid = BinInfo_SearchNextSlave( p_binfo->i_id, i_bid );
226 if( 0 > i_symindex ) { continue; }
228 // If dynsym addr = 0x00000000, Search PLT addr. from .got addr. ---
229 // for FreeBSD 11.x or older ---
230 if( 0x00000000 == p_sym->st_value ) {
231 ptr_addr = ELF64_Rela_GetPLTaddr_fromGOT( p_binfo, pstr_symname );
232 qw_size = psec_plt->qw_entsize;
234 // for FreeBSD 12.x ---
236 ptr_addr = (PtrValue)p_sym->st_value;
237 qw_size = p_sym->st_size;
239 dw_status = OBJINFO_STATUS_DYNAMIC;
242 if( 0x00000000 < ptr_addr ) {
243 ptr_addr += p_binfo->ptr_loadbase;
244 p_obj = ObjectInfo_SearchDynamicSymbol( p_pginfo, ptr_addr, pstr_symname, dw_status );
245 // If the target program is stripped, p_obj = NULL because don't exist .symtab section.
246 if( NULL == p_obj ) {
247 p_obj = ELF64_Symtab_RegistSymbol_toObjectInfo(
248 p_pginfo, p_binfo, ptr_addr, qw_size, p_sym, pb_dynstr );
251 if(( NULL != p_obj ) && ( OBJINFO_STATUS_DYNAMIC == dw_status )) {
252 p_obj->dynamic.i_binfo_origin = i_bid;
253 p_obj->dynamic.i_dynsym_index = i_symindex;
254 p_obj->dw_status |= (OBJINFO_STATUS_DYNAMIC | OBJINFO_STATUS_RESOLV1);
259 ELF64_GnuVer_FreeGnuVerNeed( p_verneed );
261 // If PLT entsize = 0 in .plt, ReSet PLT entsize from diffrent Next&Now PLT addr.
262 // for FreeBSD 12.x ---
263 ELF_DynSym_ReSetPLTsize_inObjectInfo( p_pginfo, p_binfo );
270 /* EOF of drd64_.c ----------------------------------- */