Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 23 additions & 9 deletions lld/ELF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1615,17 +1615,31 @@ template <class ELFT> void Writer<ELFT>::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<OutputDesc>(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, error 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<OutputDesc>(cmd);
if (!osd)
continue;
OutputSection *osec = &osd->osec;
if (osec->addr < imageBase && (osec->flags & SHF_ALLOC)) {
Err(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();
Expand Down
12 changes: 12 additions & 0 deletions lld/test/ELF/linkerscript/out-of-order.s
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lld/test/ELF/linkerscript/section-align2.test
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
25 changes: 18 additions & 7 deletions lld/test/ELF/sectionstart.s
Original file line number Diff line number Diff line change
@@ -1,31 +1,42 @@
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
# RUN: not ld.lld %t.o --section-start .text=0x100000 \
# RUN: --section-start=.data=0x110000 --section-start .bss=0x200000
# 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 --noinhibit-exec -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
# CHECK-NEXT: 1 .text 00000001 0000000000100000 TEXT
# 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 errors 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:
# RUN: ld.lld %t.o -Ttext=0x100000 -Tdata=0x110000 -Tbss=0x200000 -o %t4
# RUN: ld.lld %t.o --image-base=0x90000 -Ttext=0x100000 -Tdata=0x110000 -Tbss=0x200000 -o %t4
# RUN: llvm-objdump --section-headers %t4 | FileCheck %s

## The same, but dropped "0x" prefix.
# RUN: ld.lld %t.o -Ttext=100000 -Tdata=110000 -Tbss=200000 -o %t5
# RUN: ld.lld %t.o --image-base=0x90000 -Ttext=100000 -Tdata=110000 -Tbss=200000 -o %t5
# RUN: llvm-objdump --section-headers %t5 | FileCheck %s

## Check form without assignment:
# RUN: ld.lld %t.o -Ttext 0x100000 -Tdata 0x110000 -Tbss 0x200000 -o %t4
# RUN: ld.lld %t.o --image-base=0x90000 -Ttext 0x100000 -Tdata 0x110000 -Tbss 0x200000 -o %t4
# RUN: llvm-objdump --section-headers %t4 | FileCheck %s

## Errors:
Expand Down
4 changes: 3 additions & 1 deletion lld/test/ELF/ttext-tdata-tbss.s
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
## If -Ttext is smaller than the image base (which defaults to 0x200000 for -no-pie),
## the headers will still be allocated, but mapped at a higher address,
## which may look strange.
# RUN: ld.lld -Ttext 0x0 -Tdata 0x4000 -Tbss 0x8000 %t.o -o %t2
# RUN: ld.lld -Ttext 0x0 -Tdata 0x4000 -Tbss 0x8000 %t.o --noinhibit-exec -o %t2 2>&1 | FileCheck %s --check-prefix=LINK1
# RUN: llvm-readelf -S -l %t2 | FileCheck %s --check-prefix=USER1
# LINK1: warning: section '.text' address (0x0) is smaller than image base (0x200000); specify --image-base
# LINK1-NEXT: warning: section '.data' address (0x4000) is smaller than image base (0x200000); specify --image-base
# USER1: .text PROGBITS 0000000000000000 001000 000001
# USER1-NEXT: .data PROGBITS 0000000000004000 002000 000008
# USER1-NEXT: .bss NOBITS 0000000000008000 002008 000008
Expand Down
Loading