手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>网站运营>建站经验>列表

Elf动态解析符号过程(转载)

来源:互联网 作者:west263.com 时间:2008-04-16
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!

0x4000a971 <_dl_runtime_resolve 17>: pop 靫
0x4000a972 <_dl_runtime_resolve 18>: xchg 陎,(%esp,1)
0x4000a975 <_dl_runtime_resolve 21>: ret x8 //跳到printf函数地址执行
0x4000a978 <_dl_runtime_resolve 24>: nop
0x4000a979 <_dl_runtime_resolve 25>: lea 0x0(%esi,1),%esi
End of assembler dump.
(gdb) b * 0x4000a972
Breakpoint 4 at 0x4000a972: file dl-runtime.c, line 182.
(gdb) c
Continuing.

Breakpoint 4, 0x4000a972 in _dl_runtime_resolve () at dl-runtime.c:182
182 in dl-runtime.c
(gdb) i reg $eax $esp
eax 0x4006804c 1074167884
esp 0xbffffb64 -1073743004
(gdb) b *0x4000a975
Breakpoint 5 at 0x4000a975: file dl-runtime.c, line 182.
(gdb) c
Continuing.

Breakpoint 5, 0x4000a975 in _dl_runtime_resolve () at dl-runtime.c:182
182 in dl-runtime.c
(gdb) si
printf (format=0x1 ) at printf.c:26
26 printf.c: No such file or directory.
(gdb) disass ④ ⑵
Dump of assembler code for function printf:
0x4006804c : push 雙
0x4006804d : mov %esp,雙
0x4006804f : push 離
0x40068050 : call 0x40068055
0x40068055 : pop 離
0x40068056 : add xa2197,離
0x4006805c : lea 0xc(雙),陎
0x4006805f : push 陎
0x40068060 : pushl 0x8(雙)
0x40068063 : mov 0x81c(離),陎
0x40068069 : pushl (陎)
0x4006806b : call 0x400325b4
0x40068070 : mov 0xfffffffc(雙),離
0x40068073 : leave
0x40068074 : ret
End of assembler dump.
(gdb) x/8x 0x8049470
0x8049470 <_GLOBAL_OFFSET_TABLE_>: 0x08049490 0x40013ed0 0x4000a960 0x400fa550
0x8049480 <_GLOBAL_OFFSET_TABLE_ 16>: 0x080482ee 0x400328cc 0x4006804c 0x00000000

GOT[6]已被修正为0x4006804c了

第一次调用printf()的时候需要经过①->②->③->④
以后调用printf()的时候就无需这么复杂了,只要经过⑴->⑵就能够了

link_map结构说明如下:
/* Structure describing a loaded shared object. The `l_next' and `l_prev'
members form a chain of all the shared objects loaded at startup.

These data structures exist in space used by the run-time dynamic linker;
modifying them may have disastrous results.

This data structure might change in future, if necessary. User-level
programs must avoid defining objects of this type. */


★★ glibc中动态解析符号的源代码(glibc 2.1.3的实现)

.text
.globl _dl_runtime_resolve
.type _dl_runtime_resolve, @function
.align 16
_dl_runtime_resolve:
pushl 陎 # Preserve registers otherwise clobbered.
pushl 靫
pushl 韝
movl 16(%esp), 韝 # Copy args pushed by PLT in register. Note
movl 12(%esp), 陎 # that `fixup' takes its parameters in regs.
call fixup # Call resolver.
popl 韝 # Get register content back.
popl 靫
xchgl 陎, (%esp) # Get 陎 contents end store function address.
ret # Jump to function address.

static ElfW(Addr) __attribute__ ((unused))
fixup (
# ifdef ELF_MACHINE_RUNTIME_FIXUP_ARGS
ELF_MACHINE_RUNTIME_FIXUP_ARGS,
# endif
struct link_map *l, ElfW(Word) reloc_offset)
{
const ElfW(Sym) *const symtab
= (const void *) l->l_info[DT_SYMTAB]->d_un.d_ptr;
const char *strtab = (const void *) l->l_info[DT_STRTAB]->d_un.d_ptr;

const PLTREL *const reloc /*计算函数重定位人口*/
= (const void *) (l->l_info[DT_JMPREL]->d_un.d_ptr reloc_offset);

const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];/*计算函数的符号表入口*/
void *const rel_addr = (void *)(l->l_addr reloc->r_offset);/*GOT[n]的地址*/
ElfW(Addr) value;

/* The use of `alloca' here looks ridiculous but it helps. The goal is
to prevent the function from being inlined and thus optimized out.
There is no official way to do this so we use this trick. gcc never
inlines functions which use `alloca'. */
alloca (sizeof (int));

/* Sanity check that we're really looking at a PLT relocation. */
assert (ELFW(R_TYPE)(reloc->r_info) == ELF_MACHINE_JMP_SLOT);/*健壮性检查*/

/* Look up the target symbol. */
switch (l->l_info[VERSYMIDX (DT_VERSYM)] != NULL)
{
default:
{
const ElfW(Half) *vernum =
(const void *) l->l_info[VERSYMIDX (DT_VERSYM)]->d_un.d_ptr;
ElfW(Half) ndx = vernum[ELFW(R_SYM) (reloc->r_info)];
const struct r_found_version *version = &l->l_versions[ndx];

if (version->hash != 0)
{
value = _dl_lookup_versioned_symbol(strtab sym->st_name,
&sym, l->l_scope, l->l_name,
version, ELF_MACHINE_JMP_SLOT);

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!