GCC C编译器中的cswtch生成

3

我对gcc编译器中的目标代码生成有疑问。

在我的程序中,objdump显示生成了CSWTCH节。

  1. 你能解释一下C代码中需要生成CSWTCH节的标准吗?

  2. CSWTCH部分的分配输出区域是否为.rodata

  3. 在什么情况下会将小的rodata分配为CSWTCH的输出区域?


1
根据此错误报告所述,当编译器决定将switch语句映射到查找表并最终存储在.data中时,这些错误会被生成。 - Matteo Italia
您有一个问题,而不是怀疑 :-) 请参考 https://english.stackexchange.com/questions/2429/can-doubt-sometimes-mean-question - torek
1个回答

2
答案是:(1)没有这样的标准:这只是一个编译器生成值表的技术;(2)由编译器、汇编器和链接器决定;以及(3)由编译器、汇编器和链接器决定。至少在x86上,GCC(至少gcc版本5)发出了.section.type指令。
$ cat cswitch.c
int sw_2 (char x)
{
    switch(x) 
    { 
        case '0': return -1;
        case '1': return  2;
        case '2': return  3;
        case '3': return  5;
        case '4': return  7;
        case '5': return 11;
        case '6': return 13;
        case '7': return 17;
        case '8': return 19;
        case '9': return 23;
        case 'a':return 29;
        case 'A':return 29;
    }

    return -1;
}
$ gcc -Os -S cswitch.c
$ cat cswitch.s
        .file   "cswitch.c"
[mass snippage]
        .section        .rodata
        .align 32
        .type   CSWTCH.1, @object
        .size   CSWTCH.1, 49
CSWTCH.1:

我发现在x86上生成查找表需要使用-Os开关。使用-O会得到一个更典型的跳转表。
在这种情况下,.section指令最终将表应用并放置在.rodata部分中。但这只是某个系统实现方法 - 编译器没有硬性要求。
请注意,您可以进行源代码转换,从而可能使编译器在只读数据段中发出表:
int sw_3(char x)
{
    const char table['a' - '1'] = {
        '1' - '1': 2,
        '2' - '1': 3,
        '3' - '1': 5,
        /* ... fill in the remainder as needed */
    };
    if (x >= '1' && x <= 'A') return table[x - '1'];
    return -1;
}

(这种转换假设系统使用ASCII或UTF-8或类似的编码方式。)然而,即使在这种情况下,只要编译器生成的结果符合适用的标准要求,它就可以生成任意的机器码。


非常感谢您的帮助。我在我的源代码中遇到了问题,但我只有目标代码。我可以看到查找表已经生成,但是应用于此查找表的.section是.srodata。因此,我正在尝试找出如何将.srodata应用于这些.section。另外,在上面的示例中,如果在case语句中使用某些const变量而不是预定义字符,则可能会出现.srodata。如果上述陈述不清楚,请纠正我。 - user210463
1
在GNU链接器脚本中,您可以捕获任何您喜欢的部分并以任何您喜欢的方式处理它。.srodata部分旨在作为“小型只读数据”:通常的想法是将所有小节收集在一起,并设置它们以使用短偏移寻址指令进行寻址,因此您应编写一个链接器脚本来执行此操作(或使用提供的执行此操作的脚本)。 - torek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接