Skip to content

Commit

Permalink
[ELF] - Check that output sections fit in address space.
Browse files Browse the repository at this point in the history
Added checks to test that we do not produce
output where VA of sections overruns the address
space available.

Differential revision: https://reviews.llvm.org/D43820

llvm-svn: 329063
  • Loading branch information
George Rimar committed Apr 3, 2018
1 parent 8fcd04b commit 1fc9f39
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 7 deletions.
20 changes: 14 additions & 6 deletions lld/ELF/Writer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2063,17 +2063,25 @@ static void checkOverlap(StringRef Name, std::vector<SectionOffset> &Sections) {
}
}

// Check for overlapping sections
// Check for overlapping sections and address overflows.
//
// In this function we check that none of the output sections have overlapping
// file offsets. For SHF_ALLOC sections we also check that the load address
// ranges and the virtual address ranges don't overlap
template <class ELFT> void Writer<ELFT>::checkSectionOverlap() {
// First check for overlapping file offsets. In this case we need to skip
// any section marked as SHT_NOBITS. These sections don't actually occupy
// space in the file so Sec->Offset + Sec->Size can overlap with others.
// If --oformat binary is specified only add SHF_ALLOC sections are added to
// the output file so we skip any non-allocated sections in that case.
// First, check that section's VAs fit in available address space for target.
for (OutputSection *OS : OutputSections)
if ((OS->Addr + OS->Size < OS->Addr) ||
(!ELFT::Is64Bits && OS->Addr + OS->Size > UINT32_MAX))
errorOrWarn("section " + OS->Name + " at 0x" + utohexstr(OS->Addr) +
" of size 0x" + utohexstr(OS->Size) +
" exceeds available address space");

// Check for overlapping file offsets. In this case we need to skip any
// section marked as SHT_NOBITS. These sections don't actually occupy space in
// the file so Sec->Offset + Sec->Size can overlap with others. If --oformat
// binary is specified only add SHF_ALLOC sections are added to the output
// file so we skip any non-allocated sections in that case.
std::vector<SectionOffset> FileOffs;
for (OutputSection *Sec : OutputSections)
if (0 < Sec->Size && Sec->Type != SHT_NOBITS &&
Expand Down
13 changes: 13 additions & 0 deletions lld/test/ELF/linkerscript/i386-sections-max-va-overflow.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux %s -o %t.o

# RUN: echo "SECTIONS { . = 0xfffffff1;" > %t.script
# RUN: echo " .bar : { *(.bar*) } }" >> %t.script
# RUN: not ld.lld -o %t.so --script %t.script %t.o 2>&1 | FileCheck %s -check-prefix=ERR

## .bar section has data in [0xfffffff1, 0xfffffff1 + 0x10] == [0xffffff1, 0x1].
## Check we can catch this overflow.
# ERR: error: section .bar at 0xFFFFFFF1 of size 0x10 exceeds available address space

.section .bar,"ax",@progbits
.zero 0x10
2 changes: 1 addition & 1 deletion lld/test/ELF/linkerscript/output-too-large.s
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=i686-unknown-linux %s -o %t.o
# RUN: echo "SECTIONS { .text : { . = 0xffffffff; *(.text*); } }" > %t.script
# RUN: not ld.lld --script %t.script %t.o -o %t 2>&1 | FileCheck %s
# RUN: not ld.lld --no-check-sections --script %t.script %t.o -o %t 2>&1 | FileCheck %s
# CHECK: error: output file too large

.global _start
Expand Down
13 changes: 13 additions & 0 deletions lld/test/ELF/linkerscript/sections-max-va-overflow.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# REQUIRES: x86
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o

# RUN: echo "SECTIONS { . = 0xfffffffffffffff1;" > %t.script
# RUN: echo " .bar : { *(.bar*) } }" >> %t.script
# RUN: not ld.lld -o %t.so --script %t.script %t.o 2>&1 | FileCheck %s -check-prefix=ERR

## .bar section has data in [0xfffffffffffffff1, 0xfffffffffffffff1 + 0x10] ==
## [0xfffffffffffffff1, 0x1]. Check we can catch this overflow.
# ERR: error: section .bar at 0xFFFFFFFFFFFFFFF1 of size 0x10 exceeds available address space

.section .bar,"ax",@progbits
.zero 0x10

0 comments on commit 1fc9f39

Please sign in to comment.