From 98843087cbc8cc4a26782a5ddf8a14c07d201fb0 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Tue, 24 May 2016 02:37:40 +0000 Subject: [PATCH] Reject zero-sized symbols when creating copy relocations. Copy relocations are relocations to copy data from DSOs to executable's .bss segment at runtime. It doesn't make sense to create such relocations for zero-sized symbols. GNU linkers don't agree with each other. ld rejects such relocation/symbol pair. gold don't reject that but do not create copy relocations as well. I took the former approach because I don't think the latter is what user wants. llvm-svn: 270525 --- lld/ELF/Writer.cpp | 7 ++++++- lld/test/ELF/Inputs/copy-in-shared.s | 1 + lld/test/ELF/Inputs/copy-rel-corrupted.s | 4 ++++ lld/test/ELF/Inputs/mips-dynamic.s | 2 ++ lld/test/ELF/copy-rel-corrupted.s | 10 ++++++++++ lld/test/ELF/mips-got-and-copy.s | 4 ++-- 6 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 lld/test/ELF/Inputs/copy-rel-corrupted.s create mode 100644 lld/test/ELF/copy-rel-corrupted.s diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 0ee7a46d68f4..26c49696696b 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1055,10 +1055,15 @@ template static uint32_t getAlignment(SharedSymbol *SS) { // Reserve space in .bss for copy relocation. template void Writer::addCopyRelSymbol(SharedSymbol *SS) { + // Copy relocation against zero-sized symbol doesn't make sense. + uintX_t SymSize = SS->template getSize(); + if (SymSize == 0) + fatal("cannot create a copy relocation for " + SS->getName()); + ensureBss(); uintX_t Align = getAlignment(SS); uintX_t Off = alignTo(Out::Bss->getSize(), Align); - Out::Bss->setSize(Off + SS->template getSize()); + Out::Bss->setSize(Off + SymSize); Out::Bss->updateAlign(Align); uintX_t Shndx = SS->Sym.st_shndx; uintX_t Value = SS->Sym.st_value; diff --git a/lld/test/ELF/Inputs/copy-in-shared.s b/lld/test/ELF/Inputs/copy-in-shared.s index a4f257979e0f..52e99c6707a7 100644 --- a/lld/test/ELF/Inputs/copy-in-shared.s +++ b/lld/test/ELF/Inputs/copy-in-shared.s @@ -1,3 +1,4 @@ .type foo, @object .global foo foo: +.size foo, 4 diff --git a/lld/test/ELF/Inputs/copy-rel-corrupted.s b/lld/test/ELF/Inputs/copy-rel-corrupted.s new file mode 100644 index 000000000000..b8d1b1aa04c4 --- /dev/null +++ b/lld/test/ELF/Inputs/copy-rel-corrupted.s @@ -0,0 +1,4 @@ +.type x,@object +.globl x +x: +.size x, 0 diff --git a/lld/test/ELF/Inputs/mips-dynamic.s b/lld/test/ELF/Inputs/mips-dynamic.s index 63bdb5ff0790..6f15cf334d9d 100644 --- a/lld/test/ELF/Inputs/mips-dynamic.s +++ b/lld/test/ELF/Inputs/mips-dynamic.s @@ -17,10 +17,12 @@ foo1: .data .globl data0 .type data0, @object + .size data0, 4 data0: .word 0 .globl data1 .type data1, @object + .size data1, 4 data1: .word 0 diff --git a/lld/test/ELF/copy-rel-corrupted.s b/lld/test/ELF/copy-rel-corrupted.s new file mode 100644 index 000000000000..a3f72f71c1da --- /dev/null +++ b/lld/test/ELF/copy-rel-corrupted.s @@ -0,0 +1,10 @@ +// RUN: llvm-mc %s -o %t.o -filetype=obj -triple=x86_64-pc-linux +// RUN: llvm-mc %p/Inputs/copy-rel-corrupted.s -o %t2.o -filetype=obj -triple=x86_64-pc-linux +// RUN: ld.lld %t2.o -o %t2.so -shared +// RUN: not ld.lld %t.o %t2.so -o %t.exe 2>&1 | FileCheck %s + +// CHECK: cannot create a copy relocation for x + +.global _start +_start: + call x diff --git a/lld/test/ELF/mips-got-and-copy.s b/lld/test/ELF/mips-got-and-copy.s index 846bc245bc08..14cf7ac1594f 100644 --- a/lld/test/ELF/mips-got-and-copy.s +++ b/lld/test/ELF/mips-got-and-copy.s @@ -33,8 +33,8 @@ # CHECK-NEXT: Entry { # CHECK-NEXT: Address: 0x3000C # CHECK-NEXT: Access: -32740 -# CHECK-NEXT: Initial: 0x40010 -# CHECK-NEXT: Value: 0x40010 +# CHECK-NEXT: Initial: 0x40014 +# CHECK-NEXT: Value: 0x40014 # CHECK-NEXT: Type: Object (0x1) # CHECK-NEXT: Section: .bss (0xC) # CHECK-NEXT: Name: data1@ (7)