summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Writer.cpp7
-rw-r--r--lld/test/ELF/Inputs/relocation-copy-align.s9
-rw-r--r--lld/test/ELF/relocation-copy-align.s31
3 files changed, 44 insertions, 3 deletions
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index ceeca1641cb..27553a32206 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -501,9 +501,10 @@ void Writer<ELFT>::addSharedCopySymbols(
const Elf_Sym &Sym = C->Sym;
const Elf_Shdr *Sec = C->File->getSection(Sym);
uintX_t SecAlign = Sec->sh_addralign;
- uintX_t Align = Sym.st_value % SecAlign;
- if (Align == 0)
- Align = SecAlign;
+ unsigned TrailingZeros =
+ std::min(countTrailingZeros(SecAlign),
+ countTrailingZeros((uintX_t)Sym.st_value));
+ uintX_t Align = 1 << TrailingZeros;
Out<ELFT>::Bss->updateAlign(Align);
Off = RoundUpToAlignment(Off, Align);
C->OffsetInBSS = Off;
diff --git a/lld/test/ELF/Inputs/relocation-copy-align.s b/lld/test/ELF/Inputs/relocation-copy-align.s
new file mode 100644
index 00000000000..83dedc7218d
--- /dev/null
+++ b/lld/test/ELF/Inputs/relocation-copy-align.s
@@ -0,0 +1,9 @@
+.data
+ .balign 16
+ .zero 12
+
+ .type x,@object
+ .globl x
+x:
+ .long 0
+ .size x, 4
diff --git a/lld/test/ELF/relocation-copy-align.s b/lld/test/ELF/relocation-copy-align.s
new file mode 100644
index 00000000000..07ae6636e14
--- /dev/null
+++ b/lld/test/ELF/relocation-copy-align.s
@@ -0,0 +1,31 @@
+// REQUIRES: x86
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+// RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/relocation-copy-align.s -o %t2.o
+// RUN: ld.lld -shared %t2.o -o %t.so
+// RUN: ld.lld %t.o %t.so -o %t3
+// RUN: llvm-readobj -s -r --expand-relocs %t3 | FileCheck %s
+
+.global _start
+_start:
+movl $5, x
+
+// CHECK: Name: .bss
+// CHECK-NEXT: Type: SHT_NOBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT: SHF_ALLOC
+// CHECK-NEXT: SHF_WRITE
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address:
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 4
+// CHECK-NEXT: Link:
+// CHECK-NEXT: Info:
+// CHECK-NEXT: AddressAlignment: 4
+// CHECK-NEXT: EntrySize:
+
+// CHECK: Relocation {
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Type: R_X86_64_COPY
+// CHECK-NEXT: Symbol: x
+// CHECK-NEXT: Addend: 0x0
+// CHECK-NEXT: }
OpenPOWER on IntegriCloud