4541|17

222

帖子

2

TA的资源

一粒金砂(高级)

楼主
 

arm-linux-gcc存在漏洞 [复制链接]

以前看国嵌视频讲课的老师说“编译内核时候常常出现不兼容问题,不要试图自己去处理,有些问题是编译器固有的,更换编译器就可以了,但是寻找一款好的编译器不是那么容易,记得3.x.x的交叉编译器就有很大的问题”我只记得他说是“3”打头的版本,子版本没太在意

我是用的交叉编译器正是3.4.5的arm-linux-gcc,天嵌公司附带光盘里的,今天为了读取IO端口状态死活读取不到,查看反汇编发现  if  里面居然没有任何跳转指令。
下面是两个分别在arm-linux-gcc.3.4.5和vs2008编译的函数,
运行结果然人蛋疼,死得很有节奏感
void On_VS2008()
{
        unsigned int rGPFDAT = 1;
        if(0x1 == rGPFDAT & 0x03) {
                printf("1:if(0x1 == rGPFDAT & 0x03) \n");
        }
        if(0x1 == (rGPFDAT & 0x03)) {
                printf("2:if(0x1 == rGPFDAT & 0x03) \n");
        }
        if(rGPFDAT & 0x03 == 0x1) {
                printf("3:if(rGPFDAT & 0x03 == 0x1) \n");
        }
        
        if((rGPFDAT & 0x03) == 0x1) {
                printf("4:if((rGPFDAT & 0x03) == 0x1)\n");
        }
}
输出
1:if(0x1 == rGPFDAT & 0x03)
2:if(0x1 == rGPFDAT & 0x03)
4:if((rGPFDAT & 0x03) == 0x1)

void On_arm_linux_gcc_3_4_5()
{
        if(0x1 == rGPFDAT & 0x03) {
                Uart_SendByte('1');
                Uart_SendByte('\n');
        }

        if(0x1 == (rGPFDAT & 0x03)) {
                Uart_SendByte('2');
                Uart_SendByte('\n');
        }
        if(rGPFDAT & 0x03 == 0x1) {
                Uart_SendByte('3');
                Uart_SendByte('\n');
        }
        
        if((rGPFDAT & 0x03) == 0x1) {
                Uart_SendByte('4');
                Uart_SendByte('\n');
        }
}
输出
2
4


此帖出自ARM技术论坛

最新回复

旁观的千万别乱,看见好的要学,看见问题要想,比如他的代码现在有问题了,所以你应该琢磨琢磨看自己能不能想明白为什么会有这种现象。   详情 回复 发表于 2014-8-21 16:56
点赞 关注
 

回复
举报

222

帖子

2

TA的资源

一粒金砂(高级)

沙发
 
arm-linux-objdump反汇编内容是这样的
if(0x1 == rGPFDAT & 0x03) {
300011a0:        e3a03456         mov        r3, #1442840576        ; 0x56000000
300011a4:        e2833054         add        r3, r3, #84        ; 0x54
300011a8:        e5933000         ldr        r3, [r3]
300011ac:        e3530001         cmp        r3, #1        ; 0x1
300011b0:        1a000003         bne        300011c4

                        Uart_SendByte('1');
300011b4:        e3a00031         mov        r0, #49        ; 0x31
300011b8:        ebffff21         bl        30000e44
                        Uart_SendByte('\n');
300011bc:        e3a0000a         mov        r0, #10        ; 0xa
300011c0:        ebffff1f         bl        30000e44
                }
                if(0x1 == (rGPFDAT & 0x03)) {
300011c4:        e3a03456         mov        r3, #1442840576        ; 0x56000000
300011c8:        e2833054         add        r3, r3, #84        ; 0x54
300011cc:        e5933000         ldr        r3, [r3]
300011d0:        e2033003         and        r3, r3, #3        ; 0x3
300011d4:        e3530001         cmp        r3, #1        ; 0x1
300011d8:        1a000003         bne        300011ec

                        Uart_SendByte('2');
300011dc:        e3a00032         mov        r0, #50        ; 0x32
300011e0:        ebffff17         bl        30000e44
                        Uart_SendByte('\n');
300011e4:        e3a0000a         mov        r0, #10        ; 0xa
300011e8:        ebffff15         bl        30000e44
                }
                if(rGPFDAT & 0x03 == 0x1) {
300011ec:        e3a03456         mov        r3, #1442840576        ; 0x56000000
300011f0:        e2833054         add        r3, r3, #84        ; 0x54
300011f4:        e5933000         ldr        r3, [r3]
                        Uart_SendByte('3');                                      ;这些就不被编译进去
                        Uart_SendByte('\n');

                }
               
                if((rGPFDAT & 0x03) == 0x1) {
300011f8:        e3a03456         mov        r3, #1442840576        ; 0x56000000
300011fc:        e2833054         add        r3, r3, #84        ; 0x54
30001200:        e5933000         ldr        r3, [r3]
30001204:        e2033003         and        r3, r3, #3        ; 0x3
30001208:        e3530001         cmp        r3, #1        ; 0x1
3000120c:        1a000003         bne        30001220

                        Uart_SendByte('4');
30001210:        e3a00034         mov        r0, #52        ; 0x34
30001214:        ebffff0a         bl        30000e44
                        Uart_SendByte('\n');
30001218:        e3a0000a         mov        r0, #10        ; 0xa
3000121c:        ebffff08         bl        30000e44
                }
此帖出自ARM技术论坛
 
 
 

回复

222

帖子

2

TA的资源

一粒金砂(高级)

板凳
 
Makefile没有加任何优化选项
%.o : %.c
        @echo compile $^
        @-$(CC) -g -c $^
此帖出自ARM技术论坛
 
 
 

回复

1119

帖子

0

TA的资源

一粒金砂(中级)

4
 
过来看看~~看得懵
此帖出自ARM技术论坛
 
 
 

回复

774

帖子

2

TA的资源

纯净的硅(中级)

5
 
linux内核和gcc是相辅相成的
内核的一些新特性也只有在较新的编译器才能编译通过
用3xx的编译器编译新的内核不出问题才是不正常的
此帖出自ARM技术论坛
 
 
 

回复

222

帖子

2

TA的资源

一粒金砂(高级)

6
 
airqj 发表于 2014-8-20 15:05
linux内核和gcc是相辅相成的
内核的一些新特性也只有在较新的编译器才能编译通过
用3xx的编译器编译新的 ...

我是在写裸机程序,不是写linux上的设备驱动或应用程序,没使用到linux内核的库或头文件。
我不是讨论gcc与linux的关系
而是3.xx版本gcc的语法问题
此帖出自ARM技术论坛
 
 
 

回复

603

帖子

1

TA的资源

纯净的硅(中级)

7
 
不知道楼主想表达什么,看编译结果没有问题
此帖出自ARM技术论坛
 
 
 

回复

222

帖子

2

TA的资源

一粒金砂(高级)

8
 
sjtitr 发表于 2014-8-20 15:20
不知道楼主想表达什么,看编译结果没有问题

你看看同样的语法用VS2008和arm-linux-gcc.3.4.5编译的输出是不同的
VS2008的编译器能识别例子里的3段语句,
arm-linux-gcc只能识别2
同样的语句我用gcc.4.7.3编译linux系统x86平台程序,运行结果和VS2008的一样
此帖出自ARM技术论坛
 
 
 

回复

603

帖子

1

TA的资源

纯净的硅(中级)

9
 
lzwml 发表于 2014-8-20 15:25
你看看同样的语法用VS2008和arm-linux-gcc.3.4.5编译的输出是不同的
VS2008的编译器能识别例子里的3段语 ...

千万别过早下结论,关于2008那个,我建议你把最前面的变量赋值为0x81,然后再运行,我觉得就和下面一样了,

在我看来,不一样是因为在交叉编译以后运行,实际上那个值不是你想像中的1,进而导致和2008里你赋值成1的运行结果不同了。

此帖出自ARM技术论坛
 
 
 

回复

603

帖子

1

TA的资源

纯净的硅(中级)

10
 
另外,关于对国嵌视频讲课的老师说的那句话,我觉得应该劝你忘了他吧,他说得看起来也没错,不过容易误人子弟。

我通常在教育时用的说法是,发生问题一定要首先在自身找原因,如果起先就怀疑是工具的问题、是库的问题,那就没办法调查了,会令自己的错误无限延续下去,翻来覆去就是解决不了根本问题。

当然我也承认关于兼容的问题,但是怀疑的前提是你还没有开始参与写代码。
此帖出自ARM技术论坛
 
 
 

回复

222

帖子

2

TA的资源

一粒金砂(高级)

11
 
sjtitr 发表于 2014-8-20 15:49
另外,关于对国嵌视频讲课的老师说的那句话,我觉得应该劝你忘了他吧,他说得看起来也没错,不过容易误人子 ...

我知道遇到问题是要解决,对于个人成长是必须的。而且交叉编译器是不是可以自己定制,用gcc+glibc????我一直都是用开发板附带的编译器,自己定制不成功。。。。
https://bbs.eeworld.com.cn/thread-445643-1-1.html
但是站在开发和产品的调节上,减缓开发周期才是硬道理。至于用什么编译器在他看来属于小事情,为了定制编译器花几天时间不值得。万万没想到——“忘掉这些细节”
此帖出自ARM技术论坛
 
 
 

回复

222

帖子

2

TA的资源

一粒金砂(高级)

12
 
sjtitr 发表于 2014-8-20 15:49
另外,关于对国嵌视频讲课的老师说的那句话,我觉得应该劝你忘了他吧,他说得看起来也没错,不过容易误人子 ...

问题已经解决了。我不该用rGPFDAT这个IO寄存器做实验,应该用重新定义一个内存变量,由于我最初IO属性初始化写错了才出现这种问题,这个IO刚开始电平是不稳定的,也就导致只输出2、4而没有1。现在IO初始化正确就没有问题了,运行结果和VS2008的一样。

可以结贴了
此帖出自ARM技术论坛
 
 
 

回复

603

帖子

1

TA的资源

纯净的硅(中级)

13
 
lzwml 发表于 2014-8-20 19:23
问题已经解决了。我不该用rGPFDAT这个IO寄存器做实验,应该用重新定义一个内存变量,由于我最初IO属性初 ...

发现自己的问题是好事。

不过,还没有发现根本问题,还不能结贴,你还得再继续琢磨。
此帖出自ARM技术论坛
 
 
 

回复

603

帖子

1

TA的资源

纯净的硅(中级)

14
 
一个重要的情报,为什么——
                        Uart_SendByte('3');                                      ;这些就不被编译进去
                        Uart_SendByte('\n');
此帖出自ARM技术论坛
 
 
 

回复

222

帖子

2

TA的资源

一粒金砂(高级)

15
 
本帖最后由 lzwml 于 2014-8-21 06:54 编辑
sjtitr 发表于 2014-8-20 20:46
一个重要的情报,为什么——
                        Uart_SendByte('3');                              ...


以前我用其他开发环境(Keil ARM STM32、凌阳61IDE开发环境)加断点也看到过某些代码没反汇编的情况,大多都是编译器优化的结果,可能和我初始化IO有关。例如下面:
void _O3()
{

    int tmp = 3;        //红色部分存在汇编
    int b;
    if(tmp == 3) {
        b = 3;
    }

    else if(tmp == 1) {    //这些地方没法加断点
        b = 1;
    }
    else if(tmp == 10) {
        b = 10;
    }

}
tmp初始化为3,编译器认为他是可以预知的,所以后面两个  if  语句不被编译进去,现象:在线调试时那些没有汇编的C代码不能加入断点如果编译器聪明些或许优化后得下面的代码,要是聪明甚是疯狂认为_O3没有实际用途,将里面内容清空也说不定,编译器太聪明未必是好事,编译器自作聪明把Delay循环当做没实际用途清空处理就完蛋了。
void _O3()
{

    int tmp = 3,b;
    b = tmp;
}
如果代码这么编写,可以保证全部代码都存在汇编,tmp参数由输入a觉得,编译器无法预知
void _O3(int a)
{
    int tmp = a;
    int b;
    if(tmp == 3) {
        b = 3;
    }
    else if(tmp == 1) {
        b = 1;
    }
    else if(tmp == 10) {
        b = 10;
    }
}
此帖出自ARM技术论坛
 
 
 

回复

603

帖子

1

TA的资源

纯净的硅(中级)

16
 
lzwml 发表于 2014-8-21 06:48
以前我用其他开发环境(Keil ARM STM32、凌阳61IDE开发环境)加断点也看到过某些代码没反汇编的情况, ...

嗯对,所以需要检查你的代码,为什么被优化掉了。
此帖出自ARM技术论坛
 
 
 

回复

705

帖子

0

TA的资源

纯净的硅(中级)

17
 
楼上都是高手,小白都看懵了。。。
此帖出自ARM技术论坛
 
 
 

回复

603

帖子

1

TA的资源

纯净的硅(中级)

18
 
awarenessxie 发表于 2014-8-21 16:03
楼上都是高手,小白都看懵了。。。

旁观的千万别乱,看见好的要学,看见问题要想,比如他的代码现在有问题了,所以你应该琢磨琢磨看自己能不能想明白为什么会有这种现象。


此帖出自ARM技术论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表