From 8c7c5361e01cbe7334d445159240b82e13c2879e Mon Sep 17 00:00:00 2001 From: Fangrui Song Date: Thu, 15 May 2025 21:43:17 -0700 Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?= =?UTF-8?q?l=20version?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Created using spr 1.3.5-bogner --- lld/ELF/Writer.cpp | 32 +++++++++++++------ lld/test/ELF/linkerscript/out-of-order.s | 12 +++++++ lld/test/ELF/linkerscript/section-align2.test | 2 +- lld/test/ELF/sectionstart.s | 17 +++++++--- 4 files changed, 49 insertions(+), 14 deletions(-) diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 6a0552e808c7b..ea11841731d27 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1615,17 +1615,31 @@ template void Writer::finalizeAddressDependentContent() { sec->addr = 0; // If addrExpr is set, the address may not be a multiple of the alignment. - // Warn because this is error-prone. - for (SectionCommand *cmd : ctx.script->sectionCommands) - if (auto *osd = dyn_cast(cmd)) { - OutputSection *osec = &osd->osec; - if (osec->addr % osec->addralign != 0) - Warn(ctx) << "address (0x" << Twine::utohexstr(osec->addr) - << ") of section " << osec->name - << " is not a multiple of alignment (" << osec->addralign - << ")"; + // Warn because this is error-prone. In addition, warn if the address + // is smaller than the image base when SECTIONS is absent (e.g. when -Ttext + // is specified and smaller than the default target image base for no-pie). + uint64_t imageBase = ctx.script->hasSectionsCommand || ctx.arg.relocatable + ? 0 + : ctx.target->getImageBase(); + for (SectionCommand *cmd : ctx.script->sectionCommands) { + auto *osd = dyn_cast(cmd); + if (!osd) + continue; + OutputSection *osec = &osd->osec; + if (osec->addr < imageBase && (osec->flags & SHF_ALLOC)) { + Warn(ctx) << "section '" << osec->name << "' address (0x" + << Twine::utohexstr(osec->addr) + << ") is smaller than image base (0x" + << Twine::utohexstr(imageBase) << "); specify --image-base"; } + if (osec->addr % osec->addralign != 0) + Warn(ctx) << "address (0x" << Twine::utohexstr(osec->addr) + << ") of section " << osec->name + << " is not a multiple of alignment (" << osec->addralign + << ")"; + } + // Sizes are no longer allowed to grow, so all allowable spills have been // taken. Remove any leftover potential spills. ctx.script->erasePotentialSpillSections(); diff --git a/lld/test/ELF/linkerscript/out-of-order.s b/lld/test/ELF/linkerscript/out-of-order.s index 9b834cf712038..2f990e0205f0e 100644 --- a/lld/test/ELF/linkerscript/out-of-order.s +++ b/lld/test/ELF/linkerscript/out-of-order.s @@ -31,6 +31,18 @@ # CHECK-NEXT: 5 .hash 00000010 000000000000201c # CHECK-NEXT: 6 .text 00000008 000000000000202c +# RUN: ld.lld -e 0 -o %t --script %t.script %t.o --fatal-warnings +# RUN: llvm-readelf -Sl %t | FileCheck %s --check-prefix=CHECK1 + +# CHECK1: Name Type Address Off Size ES Flg Lk Inf Al +# CHECK1-NEXT: NULL 0000000000000000 000000 000000 00 0 0 0 +# CHECK1-NEXT: .text PROGBITS 0000000000000000 001000 000008 00 AX 0 0 4 +# CHECK1-NEXT: .data PROGBITS 0000000000004000 002000 000008 00 WA 0 0 1 +# CHECK1: Program Headers: +# CHECK1-NEXT: Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align +# CHECK1-NEXT: LOAD 0x001000 0x0000000000000000 0x0000000000000000 0x000008 0x000008 R E 0x1000 +# CHECK1-NEXT: LOAD 0x002000 0x0000000000004000 0x0000000000004000 0x000008 0x000008 RW 0x1000 + .quad 0 .data .quad 0 diff --git a/lld/test/ELF/linkerscript/section-align2.test b/lld/test/ELF/linkerscript/section-align2.test index 3eb42cadc059e..3269633b92930 100644 --- a/lld/test/ELF/linkerscript/section-align2.test +++ b/lld/test/ELF/linkerscript/section-align2.test @@ -10,7 +10,7 @@ # RUN: llvm-readelf -S %t | FileCheck %s ## Check we don't warn in the absence of SECTIONS. -# RUN: ld.lld --fatal-warnings -Ttext=0x10000 %t.o -o /dev/null +# RUN: ld.lld --fatal-warnings -Ttext=0x10000 --image-base=0x10000 %t.o -o /dev/null # WARN: warning: address (0x10004) of section .data.rel.ro is not a multiple of alignment (16) # WARN: warning: address (0x20001) of section .data2 is not a multiple of alignment (8) diff --git a/lld/test/ELF/sectionstart.s b/lld/test/ELF/sectionstart.s index d694c9375fd80..a1202bc185a70 100644 --- a/lld/test/ELF/sectionstart.s +++ b/lld/test/ELF/sectionstart.s @@ -1,9 +1,13 @@ # REQUIRES: x86 # RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o # RUN: ld.lld %t.o --section-start .text=0x100000 \ -# RUN: --section-start=.data=0x110000 --section-start .bss=0x200000 -o %t +# RUN: --section-start=.data=0x110000 --section-start .bss=0x200000 -o %t 2>&1 | \ +# RUN: FileCheck %s --check-prefix=LINK --implicit-check-not=warning: # RUN: llvm-objdump --section-headers %t | FileCheck %s +# LINK: warning: section '.text' address (0x100000) is smaller than image base (0x200000); specify --image-base +# LINK-NEXT: warning: section '.data' address (0x110000) is smaller than image base (0x200000); specify --image-base + # CHECK: Sections: # CHECK-NEXT: Idx Name Size VMA Type # CHECK-NEXT: 0 00000000 0000000000000000 @@ -11,9 +15,14 @@ # CHECK-NEXT: 2 .data 00000004 0000000000110000 DATA # CHECK-NEXT: 3 .bss 00000004 0000000000200000 BSS -## The same, but dropped "0x" prefix. -# RUN: ld.lld %t.o --section-start .text=100000 \ -# RUN: --section-start .data=110000 --section-start .bss=0x200000 -o %t1 +## The warnings go away when the image base is 0. +# RUN: ld.lld %t.o -pie --section-start .text=0x100000 \ +# RUN: --section-start=.data=0x110000 --section-start .bss=0x200000 -o %t --noinhibit-exec +# RUN: llvm-objdump --section-headers %t | FileCheck %s + +## The same, but dropped "0x" prefix. Specify a smaller --image-base to suppress warnings. +# RUN: ld.lld %t.o --image-base=0x90000 --section-start .text=100000 \ +# RUN: --section-start .data=110000 --section-start .bss=0x200000 -o %t1 --noinhibit-exec # RUN: llvm-objdump --section-headers %t1 | FileCheck %s ## Use -Ttext, -Tdata, -Tbss as replacement for --section-start: