Other Parts Discussed in Thread: MSP430FR5994
Thread 中讨论的其他器件:MSP430FR5994
工具/软件:
为简单起见、考虑以下代码片段、名为`x.c`:
#include <stdint.h>
static int src_local_a;
static int src_local_b;
int funct(int a,int b)
{
src_local_a = b + src_local_a;
src_local_b = src_local_b + 2*a;
return (3*src_local_a + src_local_b);
}
如果使用`m sp430-elf-gcc -Fdata-SECTIONS`进行编译、然后使用`m sp430-elf-ld -r|--relocatable`进行部分链接、则合并两个.bss 段 (.bss.src_local_a 和.bss.src_local_b ) 后的最终重定位会在输出对象中产生无效重定位:
根据`reí a adelf`á:
Relocation section '.rela.text' at offset 0x188 contains 4 entries: Offset Info Type Sym.Value Sym. Name + Addend 00000002 0000020f R_MSP430X_ABS16 00000000 .bss + 0 00000006 0000020f R_MSP430X_ABS16 00000000 .bss + 0 0000000c 0000020f R_MSP430X_ABS16 00000000 .bss + 0 00000012 0000020f R_MSP430X_ABS16 00000000 .bss + 0
当然、程序/代码并没有执行应有的操作、因为 src_local_a 和 src_local_b 都被读取/写入到地址[0]加上 bss 偏移。 此外、编译后的目标/文本代码不包含加数 (+2):
00000000 <funct>: 0: 1d 52 00 00 add &0x0000,r13 ;0x0000 4: 82 4d 00 00 mov r13, &0x0000 ; 8: 5c 02 rlam #1, r12 ; a: 1e 42 00 00 mov &0x0000,r14 ;0x0000 e: 0e 5c add r12, r14 ; 10: 82 4e 00 00 mov r14, &0x0000 ; 14: 0c 4d mov r13, r12 ; 16: 5c 02 rlam #1, r12 ; 18: 0c 5d add r13, r12 ; 1a: 0c 5e add r14, r12 ; 1c: 10 01 reta ;
上述代码片段使用另一个 GCC 工具链(如 ARM)进行测试。 其中、重定位表不包含加数(如上所示)、但偏移量包含在目标/文本代码中。 这里不存在 Rela 条目的加数、编译后的对象/文本代码中也不存在加数。
如果省略了变量的“静态“声明或省略了-Fdata-sections、则可以重定位。 如果省略` tatic `s、则加数将按预期显示在 Rela 条目中:
Relocation section '.rela.text' at offset 0x188 contains 4 entries: Offset Info Type Sym.Value Sym. Name + Addend 00000002 0000020f R_MSP430X_ABS16 00000000 .bss + 2 00000006 0000020f R_MSP430X_ABS16 00000000 .bss + 2 0000000c 0000020f R_MSP430X_ABS16 00000000 .bss + 0 00000012 0000020f R_MSP430X_ABS16 00000000 .bss + 0
或者、如果省略了-fdata-sections、则 Rela 条目会引用变量名称而不是合并的 bss 段+偏移量:
Relocation section '.rela.text' at offset 0x188 contains 4 entries: Offset Info Type Sym.Value Sym. Name + Addend 00000002 0000070f R_MSP430X_ABS16 00000002 src_local_a + 0 00000006 0000070f R_MSP430X_ABS16 00000002 src_local_a + 0 0000000c 0000090f R_MSP430X_ABS16 00000000 src_local_b + 0 00000012 0000090f R_MSP430X_ABS16 00000000 src_local_b + 0
当然、该计划的工作原理也是一样的。 rodata 段也是如此(即具有额外的“const"声明“声明且声明且不写入变量)。 此外、-Fdata-sections + static 变量在直接链接到最终 elf 时提供良好的重定位、即跳过此部分链接阶段(当然,还有包含 main() 和其他必要部分的附加对象)。
GCC/LD 的完整命令行参数是:
msp430-elf-gcc -D__MSP430FR5994__ -mmcu=MSP430FR5994 -D__LARGE_DATA_MODEL__ -D__LARGE__ -mlarge -mcode-region=upper -Os -c x.c msp430-elf-ld -r -T ./test.ld --gc-sections --entry funct -o x-partial.o x.o
链接器脚本 (./test.ld) 为:
ENTRY(init)
SECTIONS
{
.text :
{ *(.upper.text.* .upper.text .lower.text.* .lower.text .text.* .text)
}
.bss :
{ *(.bss.* .upper.bss.* .lower.bss.* .upper.bss .lower.bss .bss)
}
.rodata :
{ *(.rodata.* .upper.rodata.* .lower.rodata.* .upper.rodata .lower.rodata .rodata)
}
.data :
{ *(.data.* .upper.data.* .lower.data.* .upper.data .lower.data .data)
}
}
由于它是 TI 网页上发布的最新 MSP430-elf-gcc 工具链、因此问题是:如何报告此问题以及如何解决此问题? 可以看到、从 ELF 文件的分析中可以看出错误的行为、但当然、如果需要、可以在实际硬件上复制错误的行为(如在 MSP430FR5994 Launchpad 上)。 如果需要、我可以提供完整的示例。