Skip to content

Commit

Permalink
[ELF] Do not try to assign a memory region to a non-allocatable section
Browse files Browse the repository at this point in the history
Non-allocatable sections are not part of the memory image of the
program, so there is no need to find memory regions for them either
matching properties or handling explicit assignments. The early test
and return help to simplify LinkerScript::findMemoryRegion() a bit.

Differential Revision: https://reviews.llvm.org/D113768
  • Loading branch information
igorkudrin committed Nov 15, 2021
1 parent 7cf887b commit 66691de
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 4 deletions.
15 changes: 11 additions & 4 deletions lld/ELF/LinkerScript.cpp
Expand Up @@ -887,6 +887,14 @@ void LinkerScript::switchTo(OutputSection *sec) {
// subsequent call of this method.
std::pair<MemoryRegion *, MemoryRegion *>
LinkerScript::findMemoryRegion(OutputSection *sec, MemoryRegion *hint) {
// Non-allocatable sections are not part of the process image.
if (!(sec->flags & SHF_ALLOC)) {
if (!sec->memoryRegionName.empty())
warn("ignoring memory region assignment for non-allocatable section '" +
sec->name + "'");
return {nullptr, nullptr};
}

// If a memory region name was specified in the output section command,
// then try to find that region first.
if (!sec->memoryRegionName.empty()) {
Expand All @@ -902,8 +910,8 @@ LinkerScript::findMemoryRegion(OutputSection *sec, MemoryRegion *hint) {
if (memoryRegions.empty())
return {nullptr, nullptr};

// An allocatable orphan section should continue the previous memory region.
if (sec->sectionIndex == UINT32_MAX && (sec->flags & SHF_ALLOC) && hint)
// An orphan section should continue the previous memory region.
if (sec->sectionIndex == UINT32_MAX && hint)
return {hint, hint};

// See if a region can be found by matching section flags.
Expand All @@ -914,8 +922,7 @@ LinkerScript::findMemoryRegion(OutputSection *sec, MemoryRegion *hint) {
}

// Otherwise, no suitable region was found.
if (sec->flags & SHF_ALLOC)
error("no memory region specified for section '" + sec->name + "'");
error("no memory region specified for section '" + sec->name + "'");
return {nullptr, nullptr};
}

Expand Down
48 changes: 48 additions & 0 deletions lld/test/ELF/linkerscript/memory-nonalloc.test
@@ -0,0 +1,48 @@
REQUIRES: x86

RUN: split-file %s %ts
RUN: llvm-mc -filetype=obj -triple=x86_64 %ts/s -o %t.o

## Check that a non-allocatable section is not assigned to a memory region by
## matching the section/region properties. Previously, that could lead to an
## "error: section '.nonalloc' will not fit in region 'RAM'".

RUN: ld.lld %t.o -T %ts/t --fatal-warnings -o /dev/null

## Check that an explicit assignment is ignored for a non-allocatable section.
## Previously, that also could lead to the same error.

RUN: ld.lld %t.o -T %ts/t2 -o /dev/null 2>&1 | FileCheck %s --check-prefix=WARN

WARN: warning: ignoring memory region assignment for non-allocatable section '.nonalloc'

#--- s
.global _start
_start:

## Note: a "writable" section is used because lld does not fully support
## memory region attribute "r" at the moment.
.section .nonalloc,"w"
.zero 0x1000

#--- t
MEMORY
{
RAM (rwx) : ORIGIN = 0x8000, LENGTH = 0x100
}

SECTIONS
{
.nonalloc : { *(.nonalloc) }
}

#--- t2
MEMORY
{
RAM (rwx) : ORIGIN = 0x8000, LENGTH = 0x100
}

SECTIONS
{
.nonalloc : { *(.nonalloc) } > RAM
}

0 comments on commit 66691de

Please sign in to comment.