免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1766 | 回复: 0
打印 上一主题 下一主题

共享库的全局变量以及gcc相关配置 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-07-02 21:40 |只看该作者 |倒序浏览

                                共享库的全局变量
gcc使用的库版本
编译gcc的配置选项
其他gcc信息dump
1)生成动态链接库libtest.so
---test.h---
#ifndef __TEST_H__
#define __TEST_H__
#include
#include
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
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 :        lea    0x4(%esp),%ecx
0x08048518 :        and    $0xfffffff0,%esp
0x0804851b :        pushl  -0x4(%ecx)
0x0804851e :        push   %ebp
0x0804851f :        mov    %esp,%ebp
0x08048521 :        push   %ecx
0x08048522 :        sub    $0x24,%esp
0x08048525 :        movl   $0x804a018,-0x8(%ebp)
0x0804852c :        call   0x8048418
0x08048531 :        mov    %eax,-0xc(%ebp)
0x08048534 :        mov    -0x8(%ebp),%eax
0x08048537 :        mov    %eax,0x4(%esp)
0x0804853b :        movl   $0x8048630,(%esp)
0x08048542 :        call   0x8048448
0x08048547 :        mov    -0xc(%ebp),%eax
0x0804854a :        mov    %eax,0x4(%esp)
0x0804854e :        movl   $0x8048630,(%esp)
0x08048555 :        call   0x8048448
0x0804855a :        mov    $0x0,%eax
0x0804855f :        add    $0x24,%esp
0x08048562 :        pop    %ecx
0x08048563 :        pop    %ebp
---Type  to continue, or q  to quit---
0x08048564 :        lea    -0x4(%ecx),%esp
0x08048567 :        ret   
End of assembler dump.
(gdb) info symbol 0x804a018
global_test in section .bss
(gdb) disassemble 0x8048418
Dump of assembler code for function
[email=__errno_location@plt:]__errno_location@plt:[/email]
0x08048418 :        jmp    *0x804a000
0x0804841e :        push   $0x0
0x08048423 :        jmp    0x8048408
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.
搜索路径可以用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)
               
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/79526/showart_1984362.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP