Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1810751
  • 博文数量: 241
  • 博客积分: 9862
  • 博客等级: 中将
  • 技术积分: 5206
  • 用 户 组: 普通用户
  • 注册时间: 2005-02-18 23:23
文章分类
文章存档

2011年(14)

2010年(61)

2009年(48)

2008年(118)

我的朋友

分类: LINUX

2009-09-27 10:07:00

上一篇说了交叉编译的构建和使用,那用这个东东搞出来的模块能不能在Linux下面正常用,和Linux下面gcc编出来的有什么区别,下面做个简单的分析。

         对gcc编译生成的客户端主执行文件depagtdcygwin编译生成的相同文件进行简单的分析,论

         证两者可以互换使用。


         使用工具:gcc, readelf, objdump, BC

                Ia32版本:

                 Elf头分析:

                     

                   

         主要不同有两点:

                1、 program headersgcc生成的有7个,cygwin生成的有6个。具体如下:

               

   gcc比cygwin多了一个STACK Segment,在ELF的标准中查询没有这个program header, (http://www.caldera.com/developers/gabi/2003-12-17/ch5.pheader.html)猜测是redhat公司自己的扩展。它的offset,virtaddr,phyaddr,filesize等参数全部为0,而且在Section to Segment mapping中STACK没有映射任何section,所以不管在程序link和load时候这个Segment应该都不起作用。
2、    section headers,gcc生成的有27个,cygwin生成的有31个。具体如下:

cygwin比gcc多了四个section:debug_arranges;debug_info;debug_abbrev;debug_line,从名字来看,全部都是关于调试信息的section,在编译时并没有加-g参数,所以应该是在编译交叉编译器时候的缺省设定导致。反编译之后这几个section信息都是关于crosstool的版本信息。

可以看出,都是关于使用的交叉编译器的gcc,glibc的版本信息及编译交叉编译器工具crosstool信息,对程序的exec和load没有影响。
(背景知识参照:http://www.caldera.com/developers/gabi/2003-12-17/contents.html ;
http://blog.chinaunix.net/u3/94916/showart_1908331.html)

Te

Text段分析:
1、汇编后结果基本相同的例子:


2、汇编后结果有差异的例子:

以下面C语句为例分析差异:
openlog("depagtd", LOG_PID, LOG_DAEMON);
Linux从右向左参数压栈。
gccdump                                                                 cygwindump
push  $0x18                                                        movl  $0x18,0x8(%esp)
push  $0x1                                                         movl  $0x1,0x4(%esp)
push  $0x8056dc0                                                  movl  $0x80576e0 (%esp)
call 8049444                                           call 804949c

从syslog.h查到:
#define LOG_PID            0x01    /* log the pid with each message */
#define LOG_DAEMON    (3<<3)


从elf只读数据段查到:
Contents of section .rodata:                                            Contents of section .rodata:
8056db8 03000000 01000200 64657061 67746400  ........depagtd.       80576c0 03000000 01000200 00000000 00000000  ................
                                                80576d0 00000000 00000000 00000000 00000000  ................
                                            80576e0 64657061 67746400 5b455252 4f525d73  depagtd.[ERROR]s

差别主要在参数压栈的表示形式上不同,编译机上的gcc直接编译的程序,参数压栈时使用push指令,而cygwin中的交叉编译环境的gcc编译的程序,参数压栈时使用movl指令。(因为esp是栈指针)

关键地方的跳转指令和判断指令相同。
结论:可以使用交叉编译器生成的可执行文件代替原有编译器生成的可执行文件。








                        

      


阅读(1260) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~