gcc/ld:允许代码放置和删除未使用的功能 [英] gcc/ld: Allow Code Placement And Removal of Unused Functions

查看:231
本文介绍了gcc/ld:允许代码放置和删除未使用的功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图允许在不放弃ld的垃圾回收功能的情况下,在输出二进制文件中指定特定符号的位置.例如:如果我在MyInclude.h

I am trying to allow specifying the location of particular symbols in my output binary without giving up the garbage collection feature of ld. For example: if I have in MyInclude.h

#ifndef MY_INCLUDE_H_
#define MY_INCLUDE_H_

void CalledFunc(void);
void UncalledFunc(void);

#endif

和一个主程序:

#include "MyInclude.h"
int main(void)
{
    CalledFunc();
    return 0;
}

在gcc中使用ffunction-sections -fdata-sections进行编译,并与--gc-sections链接,这在映射文件中显示.text.UncalledFunc已被删除.

compiling with gcc with ffunction-sections -fdata-sections and linking with --gc-sections shows in the map file that .text.UncalledFunc has been removed.

我现在需要在某些部分中放置某些功能.在此示例中,如果确实调用了UncalledFunc(),我希望它位于特殊的部分.我有一个链接器参数文件,看起来像:

I now have a need where I have to place certain functions in different sections. In this example if UncalledFunc() did happen to be called, I want it to be in a special section. I have a linker parameter file that looks something like:

MEMORY
{
    FLASH (rx) : ORIGIN = 0x10000000, LENGTH = 512K
}

SECTIONS
{
    .text.myregion ORIGIN(FLASH):
    {
        *(.text.myregion)
        *(.text.myregion*)
    } >FLASH
    ASSERT ( . <= 0x10010000, "Too much stuff in myregion!")
    .text :
    {
        *(.text)
        *(.text*)
    } >FLASH
}

以及UncalledFunc()CalledFunc()定义为:

void CalledFunc(void) __attribute__ ((section (".text.myregion")))
{
    /* ... */
}
void UncalledFunc(void) __attribute__ ((section (".text.myregion")))
{
    /* ... */
}

在这种情况下,似乎函数属性覆盖了发送到GCC的每个函数部分参数.这样,由于两个功能都在同一个输入部分中,因此它们都出现在输出图像中.有没有一种方法可以告诉链接程序将UncalledFunc()放置在.text.myregion中,如果未调用,仍然将其删除?如上所示,myregion的空间有限,最好不要在该处放置不必要的东西.

In this case, it seems the function attribute overrides the per function section parameter sent to GCC. As such since both functions are in the same input section, they both appear in the output image. Is there a way to tell the linker to place UncalledFunc() in .text.myregion if it is called but still remove it if it is not? As shown above, myregion has limited space and it would optimal to not place anything there that wasn't necessary.

推荐答案

编译器正在按照所告诉的内容进行操作;您要求它将该功能放在该部分中,那么它还应该做什么?

The compiler is just doing what it's told; you asked it to put that function in that section, so what else should it do?

链接器然后在一个部分中看到所有功能,因此垃圾回收不是很有帮助.

The linker then sees all the functions in one section, and so garbage collection is not very helpful.

我还没有尝试过,但是我想简单地为每个功能分配不同手动名称就可以解决问题:

I've not tried this, but I would imagine that simply assigning different manual names to each function will solve the problem:

void CalledFunc(void) __attribute__ ((section (".text.myregion.CalledFunc")))
{
    /* ... */
}
void UncalledFunc(void) __attribute__ ((section (".text.myregion.UncalledFunc")))
{
    /* ... */
}

但是,如果要进行大量输入(或者如果您使用宏来应用属性),则可能会像这样更好:

However, if that's a lot of typing (or if you use a macro to apply the attribute), then it might be better like this:

#define STRINGIFY(S) #S
#define TOSTRING(S) STRINGIFY(S)
#define NAME __FILE__ "." TOSTRING(__LINE__)
void CalledFunc(void) __attribute__ ((section (".text.myregion." NAME)))
{
    /* ... */
}

这样一来,您就可以进行搜索和替换操作,并且每个函数仍具有唯一的节名称. (必须使用宏,因为__LINE__是整数值,但是我们在这里需要一个字符串,并且#"stringify"运算符仅在宏内部可用.显然,无意义的间接层会导致__LINE__变为被评估为实际的行号.)

That way you can do it with search-and-replace and still have each function have a unique section name. (It is necessary to use the macro because __LINE__ is an integer value, but we need a string here, and the # "stringify" operator is only available inside macros. The apparently pointless levels of indirection cause __LINE__ to be evaluated into the actual line number.)

也许__FUNCTION__宏可以工作,但是我不确定这是在函数体之外.

It might be that the __FUNCTION__ macro works, but I'm not confident given that this is outside the function body.

这篇关于gcc/ld:允许代码放置和删除未使用的功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆