我有一个链接描述文件:
SECTIONS
{
.text 0x42000:
{
*(.text*)
}
aligned_dot = ALIGN(0x10 * 1024);
.data aligned_dot :
{
*(.data*)
}
}
如果我使用它链接一个(非常简单的)文件,它会给出我期望的结果:
Sections:
Idx Name Size Address Type
0 00000000 0000000000000000
1 .text 00000008 0000000000042000 TEXT DATA
2 .data 00000000 0000000000044000 TEXT BSS
aligned_dot
是:
00044000 A aligned_dot
但是,我想使用这样的MEMORY
命令:
MEMORY
{
ram (wxa) : ORIGIN = 0x42000, LENGTH = 0x100000
}
SECTIONS
{
.text :
{
*(.text*)
}
aligned_dot = ALIGN(0x10 * 1024);
.data aligned_dot :
{
*(.data*)
}
}
当我使用此脚本进行链接时,似乎忽略了.data
部分的地址!
Sections:
Idx Name Size Address Type
0 00000000 0000000000000000
1 .text 00000008 0000000000042000 TEXT DATA
2 .data 00000000 0000000000042008 TEXT BSS
尽管aligned_dot
仍在:
00044000 A aligned_dot
这很奇怪吧?到底是怎么回事?这是使用Clang的LLD。
答案 0 :(得分:0)
我认为这可能是LLVM中的一个错误。在LinkerScript.cpp
我们有:
void LinkerScript::assignOffsets(OutputSection *Sec) {
if (!(Sec->Flags & SHF_ALLOC))
Dot = 0;
else if (Sec->AddrExpr)
setDot(Sec->AddrExpr, Sec->Location, false);
Ctx->MemRegion = Sec->MemRegion;
Ctx->LMARegion = Sec->LMARegion;
if (Ctx->MemRegion)
Dot = Ctx->MemRegion->CurPos;
如果设置AddrExpr
,我认为它会忽略MemRegion
。如果我将倒数第二行更改为此,那么它可以正常工作:
if (Ctx->MemRegion && !Sec->AddrExpr)
编辑:如果手动地址之后有部分,这似乎是不够的。你需要这样的东西,虽然我对此更不确定:
void LinkerScript::assignOffsets(OutputSection *Sec) {
if (!(Sec->Flags & SHF_ALLOC))
Dot = 0;
else if (Sec->AddrExpr)
setDot(Sec->AddrExpr, Sec->Location, false);
Ctx->MemRegion = Sec->MemRegion;
Ctx->LMARegion = Sec->LMARegion;
if (Ctx->MemRegion && !Sec->AddrExpr)
Dot = Ctx->MemRegion->CurPos;
switchTo(Sec);
if (Ctx->MemRegion && Sec->AddrExpr) {
if (Ctx->MemRegion->CurPos < Dot) {
expandMemoryRegions(Dot - Ctx->MemRegion->CurPos);
}
}