diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 1810d8acaa568d..415afef45a69f6 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -887,6 +887,14 @@ void LinkerScript::switchTo(OutputSection *sec) { // subsequent call of this method. std::pair 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()) { @@ -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. @@ -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}; } diff --git a/lld/test/ELF/linkerscript/memory-nonalloc.test b/lld/test/ELF/linkerscript/memory-nonalloc.test new file mode 100644 index 00000000000000..ed9e2c3a017503 --- /dev/null +++ b/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 +}