GCC错误“<变量>导致节类型冲突“ [英] GCC error "<variable> causes a section type conflict"

查看:465
本文介绍了GCC错误“<变量>导致节类型冲突“的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



问题

为什么当试图将两个(RAM)变量(它们只是初始化值不同)发生编译器错误时, h3>

C源代码:

  int __attribute __((section(。in_my_data )))_foo = 1; 
int __attribute __((section(。in_my_data)))_bar = 0; (相关)GCC编译器输出:





  mcve / main.c:75:45:error:_bar会导致节类型冲突

链接器脚本在 SECTIONS 定义中包含以下行,但(致命)错误来自编译器,而不是链接器。 p>

  .my_data:{*(。in_my_data)}>数据



更多信息



更改C允许编译器使用两个部分的源允许编译通过,但如果两个输入部分映射到同一个输出部分,则链接器会生成一个错误。



C源代码:

  int __attribute __((section(。in_my_data_nonzero)))_foo = 1; 
int __attribute __((section(。in_my_data_zero)))_bar = 0;

链接器脚本:

  .my_data:{*(。in_my_data *)}>数据

(相关)链接器输出:

 链接错误:输入节'.in_my_data_nonzero'的属性与输出节'.my_data'冲突

交换C源代码行的顺序只会改变哪一部分(出现在C源代码中的那一部分)出错。



问题



GCC编译器要求一个段的变量初始化为零,而不是一个这是初始化为非零,反之亦然?



编译器是否尝试将变量初始化为零置于 .bss中部分,而不是初始化数据的 .data 部分?还是有另一部分数据被初始化为零?



相关问题



在内存类型(ROM与RAM)之间存在冲突:



...或将初始化 const NOLOAD输出部分中的数据:



...或者仍然是原因的谜,可能是相关:



以上所有内容似乎都没有可以应用于此问题的答案,只要我可以告诉。

解决方案

警告:此答案可能只适用于Microchip XC16编译器。



研究



编译器将属性赋值给C变量,以便将它们分配给特定部分,如下所示(请参见< 注意下面的XC16特定信息1 code> - 分配给 .data

  • int b = 0; - 分配给 .bss

  • int c; - 分配给 .bss

  • ul>

    第一个和最后一个有意义: .data 用于初始化数据,。 bss 用于未初始化的数据。但是,通过ANSI C启动( Note 2 ), .bss 数据也被设置为零。



    Answer



    看起来编译器包含 初始化的变量,但其值等于 .bss 部分中的所有第0位以及所有未初始化的部分。

    根据 wikipedia


    实现还可以将静态分配的变量和常量初始化为一个仅包含零值位的值到BSS段。



    解决方法



    GCC有一个选项 -fno-zero-initialized-in-bss 用于将所有初始化为0的变量强制到 .data 部分中,如这回答呃。这可以应用在每个源文件的基础上,但不适用于单个变量。



    如意算盘



    如果有一个 __属性__((** doload **))可以用来强制编译器将一个零初始化变量放在 .data 而不是 .bss



    注意

    注意1:XC16编译器可以使用 .ndata .nbss __属性__((noload)标记一个变量<$ c $>以指示接近地址0x8000以下的数据。

    ))
    会导致变量被排除在 .bss 部分之外。 XC16生成一个特定的输出部分,每个变量都标有一个(GUID?)唯一名称。


    Why is there a compiler error when attempting to place two (RAM) variables, which only differ by their initialisation values, into the same section?

    Problem

    The C source:

    int __attribute__((section(".in_my_data"))) _foo = 1;
    int __attribute__((section(".in_my_data"))) _bar = 0;
    

    The (relevant) GCC compiler output:

    mcve/main.c:75:45: error: _bar causes a section type conflict
    

    The linker script contains the following line in the SECTIONS definition, but the (fatal) error is from the compiler, not the linker.

    .my_data : { *(.in_my_data) } > data
    

    Further Information

    Changing the C source to permit the compiler to use two sections allows the compile to pass, but the linker then generates an error if the two input sections are mapped into the same output section.

    The C source:

    int __attribute__((section(".in_my_data_nonzero"))) _foo = 1;
    int __attribute__((section(".in_my_data_zero"))) _bar = 0;
    

    The linker script:

    .my_data : { *(.in_my_data*) } > data
    

    The (relevant) linker output:

    Link Error: attributes for input section '.in_my_data_nonzero' conflict
    with output section '.my_data'
    

    Swapping the order of the lines in the C source only changes which section (the second to appear in the C source) is in error.

    Question

    What attribute(s) does the GCC compiler require of a section for a variable that is initialised with zero that it doesn't for one that is initialised with non-zero, or vice versa?

    Is the compiler trying to place the variables that are initialised to zero in the .bss section, rather than the .data section for initialised data? Or is there another section for data that is initialised to zero?

    Related questions

    Similar questions appear cover issues with conflicts between memory types (ROM vs. RAM):

    ... or putting initialised const data in NOLOAD output sections:

    ... or remain a mystery as to the cause and may be related:

    None of the above appear to have an answer that I can apply to issue in this question, as far as I can tell.

    解决方案

    Caveat: This answer may only apply to the Microchip XC16 compiler.

    Research

    The compiler assigns attributes to C variables so that they are allocated to specific sections as follows (see Note 1 below for XC16 specific information).

    • int a = 1; - is assigned to .data.
    • int b = 0; - is assigned to .bss.
    • int c; - is assigned to .bss.

    The first and last of these make sense: .data is used for initialised data and .bss is used for uninitialised data. However, .bss data is also set to zero by the ANSI C start up (see Note 2).

    Answer

    It would appear that the compiler is including variables that are initialised, but with a value that equates to all bits 0 in the .bss section as well as all those which are not initialised at all.

    According to wikipedia:

    An implementation may also assign statically-allocated variables and constants initialized with a value consisting solely of zero-valued bits to the BSS section.

    Workaround

    GCC has an option -fno-zero-initialized-in-bss which can be used to force all variables that are initialised with zero into the .data section, as stated in this answer. This can be applied on a per-source file basis, but not on individual variables.

    Wishful Thinking

    It would be nice if there were an __attribute__((**doload**)) that could be applied to force the compiler to place a zero-initialised variable in .data instead of .bss.

    Notes

    Note 1: The XC16 compiler may use .ndata and .nbss to indicate near data below address 0x8000.

    Note 2: Marking a variable with __attribute__((noload)) will result in the variable being excluded from the .bss section. XC16 generates a specific output section, with a (GUID?) unique name for each variable marked as such.

    这篇关于GCC错误“&lt;变量&gt;导致节类型冲突“的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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