[all-commits] [llvm/llvm-project] b498d9: [ELF] Start a new PT_LOAD if LMA region is different

Fangrui Song via All-commits all-commits at lists.llvm.org
Wed Feb 12 08:21:20 PST 2020


  Branch: refs/heads/master
  Home:   https://github.com/llvm/llvm-project
  Commit: b498d99338f868bcab3384b4e58f8a4d764fa48b
      https://github.com/llvm/llvm-project/commit/b498d99338f868bcab3384b4e58f8a4d764fa48b
  Author: Fangrui Song <maskray at google.com>
  Date:   2020-02-12 (Wed, 12 Feb 2020)

  Changed paths:
    M lld/ELF/LinkerScript.cpp
    M lld/ELF/Writer.cpp
    M lld/test/ELF/linkerscript/Inputs/at2.s
    M lld/test/ELF/linkerscript/at2.test
    M lld/test/ELF/linkerscript/at8.test
    M lld/test/ELF/linkerscript/lma-align.test

  Log Message:
  -----------
  [ELF] Start a new PT_LOAD if LMA region is different

GNU ld has a counterintuitive lang_propagate_lma_regions rule.

```
// .foo's LMA region is propagated to .bar because their VMA region is the same,
// and .bar does not have an explicit output section address (addr_tree).
.foo : { *(.foo) } >RAM AT> FLASH
.bar : { *(.bar) } >RAM

// An explicit output section address disables propagation.
.foo : { *(.foo) } >RAM AT> FLASH
.bar . : { *(.bar) } >RAM
```

In both cases, lld thinks .foo's LMA region is propagated and
places .bar in the same PT_LOAD, so lld diverges from GNU ld w.r.t. the
second case (lma-align.test).

This patch changes Writer<ELFT>::createPhdrs to disable propagation
(start a new PT_LOAD). A user of the first case can make linker scripts
portable by explicitly specifying `AT>`. By contrast, there was no
workaround for the old behavior.

This change uncovers another LMA related bug in assignOffsets() where
`ctx->lmaOffset = 0;` was omitted. It caused a spurious "load address
range overlaps" error for at2.test

The new PT_LOAD rule is complex. For convenience, I listed the origins of some subexpressions:

* rL323449: `sec->memRegion == load->firstSec->memRegion`; linkerscript/at3.test
* D43284: `load->lastSec == Out::programHeaders` (don't start a new PT_LOAD after program headers); linkerscript/at4.test
* D58892: `sec != relroEnd` (start a new PT_LOAD after PT_GNU_RELRO)

Reviewed By: psmith

Differential Revision: https://reviews.llvm.org/D74297




More information about the All-commits mailing list