aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHan Shen <shenhan@google.com>2018-06-06 21:43:34 +0000
committerHan Shen <shenhan@google.com>2018-06-06 21:43:34 +0000
commit0eace3a392ae2da8c0310926b0504480cf7c4f25 (patch)
tree400b8d3e99fe68aa9b719806fcd9cf2a3190c754
parentce0e3863ca5a4046db1b64c0b9afe97d3cd8827f (diff)
Correct aligment computation for shared object symbols.
The original computation for shared object symbol alignment is wrong when st_value equals 0. It is very unusual for dso symbols to have st_value equal 0. But when it happens, it causes obscure run time bugs. Differential Revision: https://reviews.llvm.org/D47602 git-svn-id: https://llvm.org/svn/llvm-project/lld/trunk@334135 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--ELF/InputFiles.cpp8
-rw-r--r--ELF/Relocations.cpp2
-rw-r--r--test/ELF/Inputs/copy-relocation-zero-abs-addr.s7
-rw-r--r--test/ELF/Inputs/copy-relocation-zero-nonabs-addr.s7
-rw-r--r--test/ELF/Inputs/copy-relocation-zero-nonabs-addr.script3
-rw-r--r--test/ELF/copy-relocation-zero-abs-addr.s44
-rw-r--r--test/ELF/copy-relocation-zero-nonabs-addr.s29
7 files changed, 93 insertions, 7 deletions
diff --git a/ELF/InputFiles.cpp b/ELF/InputFiles.cpp
index 853e20f77..5f1ec5118 100644
--- a/ELF/InputFiles.cpp
+++ b/ELF/InputFiles.cpp
@@ -900,16 +900,12 @@ std::vector<const typename ELFT::Verdef *> SharedFile<ELFT>::parseVerdefs() {
template <class ELFT>
uint32_t SharedFile<ELFT>::getAlignment(ArrayRef<Elf_Shdr> Sections,
const Elf_Sym &Sym) {
- uint64_t Ret = 1;
+ uint64_t Ret = UINT64_MAX;
if (Sym.st_value)
Ret = 1ULL << countTrailingZeros((uint64_t)Sym.st_value);
if (0 < Sym.st_shndx && Sym.st_shndx < Sections.size())
Ret = std::min<uint64_t>(Ret, Sections[Sym.st_shndx].sh_addralign);
-
- if (Ret > UINT32_MAX)
- error(toString(this) + ": alignment too large: " +
- CHECK(Sym.getName(this->StringTable), this));
- return Ret;
+ return (Ret > UINT32_MAX) ? 0 : Ret;
}
// Fully parse the shared object file. This must be called after parseSoName().
diff --git a/ELF/Relocations.cpp b/ELF/Relocations.cpp
index 5c4a797a1..2e3d4f192 100644
--- a/ELF/Relocations.cpp
+++ b/ELF/Relocations.cpp
@@ -528,7 +528,7 @@ static void replaceWithDefined(Symbol &Sym, SectionBase *Sec, uint64_t Value,
template <class ELFT> static void addCopyRelSymbol(SharedSymbol &SS) {
// Copy relocation against zero-sized symbol doesn't make sense.
uint64_t SymSize = SS.getSize();
- if (SymSize == 0)
+ if (SymSize == 0 || SS.Alignment == 0)
fatal("cannot create a copy relocation for symbol " + toString(SS));
// See if this symbol is in a read-only segment. If so, preserve the symbol's
diff --git a/test/ELF/Inputs/copy-relocation-zero-abs-addr.s b/test/ELF/Inputs/copy-relocation-zero-abs-addr.s
new file mode 100644
index 000000000..da81e0372
--- /dev/null
+++ b/test/ELF/Inputs/copy-relocation-zero-abs-addr.s
@@ -0,0 +1,7 @@
+.globl ver1
+.globl ver2
+ ver1 = 0x0
+ ver2 = 0x0
+
+.type foo,@object
+.comm foo,16,16
diff --git a/test/ELF/Inputs/copy-relocation-zero-nonabs-addr.s b/test/ELF/Inputs/copy-relocation-zero-nonabs-addr.s
new file mode 100644
index 000000000..26ac7bed1
--- /dev/null
+++ b/test/ELF/Inputs/copy-relocation-zero-nonabs-addr.s
@@ -0,0 +1,7 @@
+.balign 1024
+.type foo,@object
+.globl foo
+goo:
+foo:
+ .long 0
+ .size foo,4
diff --git a/test/ELF/Inputs/copy-relocation-zero-nonabs-addr.script b/test/ELF/Inputs/copy-relocation-zero-nonabs-addr.script
new file mode 100644
index 000000000..a5807231a
--- /dev/null
+++ b/test/ELF/Inputs/copy-relocation-zero-nonabs-addr.script
@@ -0,0 +1,3 @@
+SECTIONS {
+ goo = 0;
+};
diff --git a/test/ELF/copy-relocation-zero-abs-addr.s b/test/ELF/copy-relocation-zero-abs-addr.s
new file mode 100644
index 000000000..fae963e9b
--- /dev/null
+++ b/test/ELF/copy-relocation-zero-abs-addr.s
@@ -0,0 +1,44 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/copy-relocation-zero-abs-addr.s -o %t.o
+// RUN: ld.lld -shared -o %t2.so %t.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t3.o
+// RUN: ld.lld %t2.so %t3.o -o %t4
+// RUN: llvm-readobj -symbols %t2.so | FileCheck -check-prefix=ABSADDR %s
+// RUN: llvm-readobj -s -r --expand-relocs %t4 | FileCheck %s
+
+// This tests that symbols with absolute addresses are properly
+// handled. Normal DSO symbols are handled as usual.
+
+.text
+.globl _start
+_start:
+ movl $5, foo
+
+// ABSADDR: Name: ver1
+// ABSADDR-NEXT: Value: 0x0
+// ABSADDR-NEXT: Size: 0
+// ABSADDR-NEXT: Binding: Global
+// ABSADDR-NEXT: Type: None
+// ABSADDR-NEXT: Other: 0
+// ABSADDR-NEXT: Section: Absolute (0xFFF1)
+// ABSADDR-NEXT: }
+// ABSADDR-NEXT: Symbol {
+// ABSADDR-NEXT: Name: ver2
+// ABSADDR-NEXT: Value: 0x0
+// ABSADDR-NEXT: Size: 0
+// ABSADDR-NEXT: Binding: Global
+// ABSADDR-NEXT: Type: None
+// ABSADDR-NEXT: Other: 0
+// ABSADDR-NEXT: Section: Absolute (0xFFF1)
+// ABSADDR-NEXT: }
+
+// CHECK: Relocations [
+// CHECK-NEXT: Section (5) .rela.dyn {
+// CHECK-NEXT: Relocation {
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Type: R_X86_64_COPY
+// CHECK-NEXT: Symbol: foo
+// CHECK-NEXT: Addend:
+// CHECK-NEXT: }
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
diff --git a/test/ELF/copy-relocation-zero-nonabs-addr.s b/test/ELF/copy-relocation-zero-nonabs-addr.s
new file mode 100644
index 000000000..50876056b
--- /dev/null
+++ b/test/ELF/copy-relocation-zero-nonabs-addr.s
@@ -0,0 +1,29 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/copy-relocation-zero-nonabs-addr.s -o %t1.o
+// RUN: ld.lld -Ttext=0 -o %t2.so --script=%p/Inputs/copy-relocation-zero-nonabs-addr.script %t1.o -shared
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t3.o
+// RUN: ld.lld %t2.so %t3.o -o %t4
+// RUN: llvm-readobj --symbols %t2.so | FileCheck --check-prefix=CHECKSO %s
+// RUN: llvm-readobj --symbols %t4 | FileCheck %s
+
+.text
+.globl _start
+_start:
+ movl $5, foo
+
+// Make sure foo has st_value == 0.
+// CHECKSO: Name: foo
+// CHECKSO-NEXT: Value: 0x0
+// CHECKSO-NEXT: Size: 4
+// CHECKSO-NEXT: Binding: Global
+// CHECKSO-NEXT: Type: Object
+// CHECKSO-NEXT: Other: 0
+// CHECKSO-NEXT: Section: .text
+
+// When foo has st_value == 0, it carries the section alignment.
+// In this case, section alignment is 2^10, 0x202400 meets the requirement.
+// CHECK: Name: foo
+// CHECK-NEXT: Value: 0x202400
+// CHECK-NEXT: Size: 4
+// CHECK-NEXT: Binding: Global
+// CHECK-NEXT: Type: Object