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

llvm-svn: 334135
This commit is contained in:
Han Shen 2018-06-06 21:43:34 +00:00
parent 2dab88e652
commit 08d1640535
7 changed files with 93 additions and 7 deletions

View File

@ -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().

View File

@ -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

View File

@ -0,0 +1,7 @@
.globl ver1
.globl ver2
ver1 = 0x0
ver2 = 0x0
.type foo,@object
.comm foo,16,16

View File

@ -0,0 +1,7 @@
.balign 1024
.type foo,@object
.globl foo
goo:
foo:
.long 0
.size foo,4

View File

@ -0,0 +1,3 @@
SECTIONS {
goo = 0;
};

View File

@ -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: ]

View File

@ -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