C 如何将函数的可用性限制在其自己的部分内
我正在处理一个嵌入式项目,该项目的程序内存有限且不相交 我遇到了一个问题,优化器有时会为case语句创建跳转表,它会调用C 如何将函数的可用性限制在其自己的部分内,c,gcc,optimization,ld,C,Gcc,Optimization,Ld,我正在处理一个嵌入式项目,该项目的程序内存有限且不相交 我遇到了一个问题,优化器有时会为case语句创建跳转表,它会调用\uu开关,并在调用后放置一个偏移表 其思想是一个\u开关计算表中的偏移量,将其添加到其地址,并执行一个简短的相对jmp 问题在于,调用\u switch函数的case语句可能位于0x600xxxxx,而\u switch位于0x80xxxxx,因此创建的短相对jmp无法返回0x600xxxxx 我可以编写脚本来检测这种情况并使构建失败,我们可以使用if语句而不是case语句来
\uu开关
,并在调用后放置一个偏移表
其思想是一个\u开关
计算表中的偏移量,将其添加到其地址,并执行一个简短的相对jmp
问题在于,调用\u switch
函数的case语句可能位于0x600xxxxx,而\u switch位于0x80xxxxx,因此创建的短相对jmp无法返回0x600xxxxx
我可以编写脚本来检测这种情况并使构建失败,我们可以使用if语句而不是case语句来解决问题
我想要的是一种方法,告诉链接器如果距离较远,不要使用\u开关
,即不要从code2::xx
调用code::\u开关
专有编译器基于gnu gcc 4.7.3
有什么想法吗
备选答案可能是在两个部分中生成一个给定函数的副本(\uu switch
),并使优化器选择最接近的函数
更新 我发现
--fno jump tables
选项听起来是一个很好的解决方法。
编译器理解它,但它对生成的代码没有影响。
我正在使用LTO,所以可能链接器需要理解它,但ld只是退出,将其视为未知选项
另外,
-fno树开关转换
,更改了大量生成的代码,但并没有消除我的问题。所以。。。你的编译器会生成错误的代码?我想是的,但可以理解的是,跨越这样一个代码空间的嵌入式代码肯定非常罕见。在代码空间之外,我们将节塞进我们能找到的任何[data]空间代码>-->near_foo(){far_foo();}。。。案例123:near_foo()代码>像手动蹦床。。。我认为它会跳转到case语句的主体,从而避免比较要执行哪个case语句,它不会跳转到工作代码。所以它仍然无法回到身体。