使用MEMORY时忽略节地址

时间:2018-06-18 12:52:53

标签: linker-scripts lld

我有一个链接描述文件:

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。

1 个答案:

答案 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);
    }
  }