文章详情

  • 游戏榜单
  • 软件榜单
关闭导航
热搜榜
热门下载
热门标签
php爱好者> php文档>共享库的全局变量以及gcc相关配置

共享库的全局变量以及gcc相关配置

时间:2009-07-02  来源:hylpro

共享库的全局变量
gcc使用的库版本
编译gcc的配置选项
其他gcc信息dump

1)生成动态链接库libtest.so

---test.h---

#ifndef __TEST_H__
#define __TEST_H__
#include <stdio.h>
#include <stdlib.h>
extern int test_a();
extern int test_b();
extern int test_c();
extern int global_test;
#endif

--test.c--
#include "test.h"
int global_test = 0x123456;
int test_a()
{
printf("in test a \n");
printf("%d\n",global_test);
return 0;
}

gcc -g test.h test.c -fPIC -shared -o libtest.so

2)引用这个动态连接库

--main.c---

include "test.h"
#include <errno.h>
int main()
{
int * ptest =(int *) &global_test;
int *perrno = (int *) & errno;
printf("0x%x\n",(unsigned int)ptest);
printf("0x%x\n",(unsigned int)perrno);

}

gcc -I. -ltest -g main.c -o test

3)反汇编

~/works/dll$ gdb -q test
(gdb) disassemble main
Dump of assembler code for function main:
0x08048514 <main+0>: lea 0x4(%esp),%ecx
0x08048518 <main+4>: and $0xfffffff0,%esp
0x0804851b <main+7>: pushl -0x4(%ecx)
0x0804851e <main+10>: push %ebp
0x0804851f <main+11>: mov %esp,%ebp
0x08048521 <main+13>: push %ecx
0x08048522 <main+14>: sub $0x24,%esp
0x08048525 <main+17>: movl $0x804a018,-0x8(%ebp)
0x0804852c <main+24>: call 0x8048418 <__errno_location@plt>
0x08048531 <main+29>: mov %eax,-0xc(%ebp)
0x08048534 <main+32>: mov -0x8(%ebp),%eax
0x08048537 <main+35>: mov %eax,0x4(%esp)
0x0804853b <main+39>: movl $0x8048630,(%esp)
0x08048542 <main+46>: call 0x8048448 <printf@plt>
0x08048547 <main+51>: mov -0xc(%ebp),%eax
0x0804854a <main+54>: mov %eax,0x4(%esp)
0x0804854e <main+58>: movl $0x8048630,(%esp)
0x08048555 <main+65>: call 0x8048448 <printf@plt>
0x0804855a <main+70>: mov $0x0,%eax
0x0804855f <main+75>: add $0x24,%esp
0x08048562 <main+78>: pop %ecx
0x08048563 <main+79>: pop %ebp
---Type <return> to continue, or q <return> to quit---
0x08048564 <main+80>: lea -0x4(%ecx),%esp
0x08048567 <main+83>: ret
End of assembler dump.
(gdb) info symbol 0x804a018
global_test in section .bss
(gdb) disassemble 0x8048418
Dump of assembler code for function __errno_location@plt:
0x08048418 <__errno_location@plt+0>: jmp *0x804a000
0x0804841e <__errno_location@plt+6>: push $0x0
0x08048423 <__errno_location@plt+11>: jmp 0x8048408 <_init+48>
End of assembler dump.
(gdb)

4)通过gdb我们可以看到,引用libtest.so中定义的全局变量global_test在连接的时候就确定的地址804a01,而引用libc中的errno全局变量却需要通过plt/got来确定最终的问题。为什么?


原因探讨:

从/usr/include/errno.h => /usr/include/bits/errno.h可以看到如下定义:
if !defined _LIBC || defined _LIBC_REENTRANT
/* When using threads, errno is a per-thread value. */
# define errno (*__errno_location ())
# endif
# endif /* !__ASSEMBLER__ */
#endif /* _ERRNO_H */

errno不是纯粹意义上的global variant,所有静态库的数据段可以合并但是text不能,所以有这个现象.


另外一个问题: gcc 连接的时候如何知道用哪个版本的动态连接库:
应该是和所用gcc决定的, 想想在制作发行版的时候对gcc的编译吧, 需要一个libc, 而后,所有的程序都用这个版本的gcc和这个库编译出来的.

查看方法:
gcc -dumpspecs | more 寻找下面的一段:

*link:
%{!static:--eh-frame-hdr} %{m64:-m elf_x86_64} %{!m64:-m elf_i386} --hash-style=both   %{shared:-shared}   %{!shared:  
  %{!static:       %{rdynamic:-export-dynamic}       %{!m64:%{!dynamic-linker:-dynamic-linker %{muclibc:%{mglibc:%e-mgli
bc and -muclibc used together}/lib/ld-uClibc.so.0;:/lib/ld-linux.so.2}}}       %{m64:%{!dynamic-linker:-dynamic-linker %
{muclibc:%{mglibc:%e-mglibc and -muclibc used together}/lib/ld64-uClibc.so.0;:/lib64/ld-linux-x86-64.so.2}}}}     %{stat
ic:-static}}

然后  readelf -a  /lib/ld-linux.so.2  | more 看看, 这个连接器中有几个支持的glibc库版本(猜测):
Version definition section '.gnu.version_d' contains 6 entries:
  Addr: 0x0000000000000638  Offset: 0x000638  Link: 4 (.dynstr)
  000000: Rev: 1  Flags: BASE   Index: 1  Cnt: 1  Name: ld-linux.so.2
  0x001c: Rev: 1  Flags: none  Index: 2  Cnt: 1  Name: GLIBC_2.0
  0x0038: Rev: 1  Flags: none  Index: 3  Cnt: 2  Name: GLIBC_2.1
  0x0054: Parent 1: GLIBC_2.0
  0x005c: Rev: 1  Flags: none  Index: 4  Cnt: 2  Name: GLIBC_2.3
  0x0078: Parent 1: GLIBC_2.1
  0x0080: Rev: 1  Flags: none  Index: 5  Cnt: 2  Name: GLIBC_2.4
  0x009c: Parent 1: GLIBC_2.3
  0x00a4: Rev: 1  Flags: none  Index: 6  Cnt: 2  Name: GLIBC_PRIVATE
  0x00c0: Parent 1: GLIBC_2.4

可以这样:(http://www.linuxsir.org/bbs/showthread.php?t=244899)

gcc -print-file-name=libc.so
/usr/lib/gcc/i486-linux-gnu/4.2.4/../../../../lib/libc.so
cat /usr/lib/gcc/i486-linux-gnu/4.2.4/../../../../lib/libc.so
/* GNU ld script
   Use the shared library, but some functions are only in
   the static library, so try that secondarily.  */
OUTPUT_FORMAT(elf32-i386)
GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a  AS_NEEDED ( /lib/ld-linux.so.2 ) )
readlink /lib/libc.so.6
libc-2.7.so

另外途径是:
/lib/libc.so.6
GNU C Library stable release version 2.7, by Roland McGrath et al.
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.2.4 (Ubuntu 4.2.4-1ubuntu1).
Compiled on a Linux >>2.6.24-16-server<< system on 2008-09-12.
Available extensions:
    crypt add-on version 2.1 by Michael Glad and others
    GNU Libidn by Simon Josefsson
    Native POSIX Threads Library by Ulrich Drepper et al
    BIND-8.2.3-T5B
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.


搜索路径可以用gcc --print-search-dir 来查看
install: /usr/lib/gcc/i486-linux-gnu/4.2.4/
programs: =/usr/lib/gcc/i486-linux-gnu/4.2.4/:/usr/lib/gcc/i486-linux-gnu/4.2.4/:/usr/lib/gcc/i486-linux-gnu/:/usr/lib/gcc/i486-linux-gnu/4.2.4/:/usr/lib/gcc/i486-linux-gnu/:/usr/libexec/gcc/i486-linux-gnu/4.2.4/:/usr/libexec/gcc/i486-linux-gnu/:/usr/lib/gcc/i486-linux-gnu/4.2.4/:/usr/lib/gcc/i486-linux-gnu/:/usr/lib/gcc/i486-linux-gnu/4.2.4/../../../../i486-linux-gnu/bin/i486-linux-gnu/4.2.4/:/usr/lib/gcc/i486-linux-gnu/4.2.4/../../../../i486-linux-gnu/bin/
libraries: =/usr/lib/gcc/i486-linux-gnu/4.2.4/:/usr/lib/gcc/i486-linux-gnu/4.2.4/:/usr/lib/gcc/i486-linux-gnu/4.2.4/../../../../i486-linux-gnu/lib/i486-linux-gnu/4.2.4/:/usr/lib/gcc/i486-linux-gnu/4.2.4/../../../../i486-linux-gnu/lib/../lib/:/usr/lib/gcc/i486-linux-gnu/4.2.4/../../../i486-linux-gnu/4.2.4/:/usr/lib/gcc/i486-linux-gnu/4.2.4/../../../../lib/:/lib/i486-linux-gnu/4.2.4/:/lib/../lib/:/usr/lib/i486-linux-gnu/4.2.4/:/usr/lib/../lib/:/usr/lib/gcc/i486-linux-gnu/4.2.4/../../../../i486-linux-gnu/lib/:/usr/lib/gcc/i486-linux-gnu/4.2.4/../../../:/lib/:/usr/lib/

查看编译gcc的选项:
gcc -v
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.2 --program-suffix=-4.2 --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-targets=all --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu
Thread model: posix
gcc version 4.2.4 (Ubuntu 4.2.4-1ubuntu4)
相关阅读 更多 +
排行榜 更多 +
空中跑酷汉化版

空中跑酷汉化版

赛车竞速 下载
修仙传说

修仙传说

角色扮演 下载
魔界零之迷宫

魔界零之迷宫

冒险解谜 下载