aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-05-03 20:26:46 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-05-03 20:26:46 +0000
commitd803cda42997f42649910309ac18170d2d6f2214 (patch)
tree7bb26c9b927f1a3a4ee50d7773cc29fa7a4eb188
parent274c9ff5404582ff22769d9599ab10ed216ceec3 (diff)
downloadsrc-d803cda42997f42649910309ac18170d2d6f2214.tar.gz
src-d803cda42997f42649910309ac18170d2d6f2214.zip
Vendor import of lld trunk r302069:vendor/lld/lld-trunk-r302069
Notes
Notes: svn path=/vendor/lld/dist/; revision=317767 svn path=/vendor/lld/lld-trunk-r302069/; revision=317768; tag=vendor/lld/lld-trunk-r302069
-rw-r--r--COFF/PDB.cpp2
-rw-r--r--ELF/Driver.h2
-rw-r--r--ELF/InputFiles.cpp2
-rw-r--r--ELF/LTO.cpp5
-rw-r--r--ELF/LinkerScript.cpp23
-rw-r--r--ELF/SymbolTable.cpp5
-rw-r--r--ELF/Target.cpp28
-rw-r--r--ELF/Writer.cpp2
-rw-r--r--test/ELF/Inputs/weak-and-strong-undef.s1
-rw-r--r--test/ELF/gdb-index-ranges.s66
-rw-r--r--test/ELF/sectionstart-noallochdr.s23
-rw-r--r--test/ELF/weak-and-strong-undef.s12
12 files changed, 134 insertions, 37 deletions
diff --git a/COFF/PDB.cpp b/COFF/PDB.cpp
index e32bcd20a541..20411a703e24 100644
--- a/COFF/PDB.cpp
+++ b/COFF/PDB.cpp
@@ -28,8 +28,8 @@
#include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
#include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h"
+#include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
#include "llvm/DebugInfo/PDB/Native/PDBTypeServerHandler.h"
-#include "llvm/DebugInfo/PDB/Native/StringTableBuilder.h"
#include "llvm/DebugInfo/PDB/Native/TpiStream.h"
#include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h"
#include "llvm/Object/COFF.h"
diff --git a/ELF/Driver.h b/ELF/Driver.h
index 58bd2ab52195..af88341632f4 100644
--- a/ELF/Driver.h
+++ b/ELF/Driver.h
@@ -64,8 +64,6 @@ enum {
};
void printHelp(const char *Argv0);
-std::vector<uint8_t> parseHexstring(StringRef S);
-
std::string createResponseFile(const llvm::opt::InputArgList &Args);
llvm::Optional<std::string> findFromSearchPaths(StringRef Path);
diff --git a/ELF/InputFiles.cpp b/ELF/InputFiles.cpp
index 12867bbd071c..260a78ebbf8e 100644
--- a/ELF/InputFiles.cpp
+++ b/ELF/InputFiles.cpp
@@ -410,7 +410,7 @@ elf::ObjectFile<ELFT>::createInputSection(const Elf_Shdr &Sec,
// Mergeable sections with relocations are tricky because relocations
// need to be taken into account when comparing section contents for
- // merging. It doesn't worth supporting such mergeable sections because
+ // merging. It's not worth supporting such mergeable sections because
// they are rare and it'd complicates the internal design (we usually
// have to determine if two sections are mergeable early in the link
// process much before applying relocations). We simply handle mergeable
diff --git a/ELF/LTO.cpp b/ELF/LTO.cpp
index de0d45bea1c4..dd435173101a 100644
--- a/ELF/LTO.cpp
+++ b/ELF/LTO.cpp
@@ -105,11 +105,6 @@ BitcodeCompiler::~BitcodeCompiler() = default;
static void undefine(Symbol *S) {
replaceBody<Undefined>(S, S->body()->getName(), /*IsLocal=*/false,
STV_DEFAULT, S->body()->Type, nullptr);
- // It shouldn't normally matter what the binding is, but if a bug in the LTO
- // implementation causes it to fail to provide a definition for a symbol,
- // setting the binding to STB_GLOBAL will cause the linker to report an
- // undefined symbol error, even if the definition was weak.
- S->Binding = STB_GLOBAL;
}
void BitcodeCompiler::add(BitcodeFile &F) {
diff --git a/ELF/LinkerScript.cpp b/ELF/LinkerScript.cpp
index 22a5b639469b..3f872c65897f 100644
--- a/ELF/LinkerScript.cpp
+++ b/ELF/LinkerScript.cpp
@@ -428,13 +428,12 @@ void LinkerScript::fabricateDefaultCommands(bool AllocateHeader) {
if (AllocateHeader)
StartAddr += elf::getHeaderSize();
- // The Sections with -T<section> are sorted in order of ascending address
- // we must use this if it is lower than StartAddr as calls to setDot() must
- // be monotonically increasing
- if (!Config->SectionStartMap.empty()) {
- uint64_t LowestSecStart = Config->SectionStartMap.begin()->second;
- StartAddr = std::min(StartAddr, LowestSecStart);
- }
+ // The Sections with -T<section> have been sorted in order of ascending
+ // address. We must lower StartAddr if the lowest -T<section address> as
+ // calls to setDot() must be monotonically increasing.
+ for (auto& KV : Config->SectionStartMap)
+ StartAddr = std::min(StartAddr, KV.second);
+
Commands.push_back(
make<SymbolAssignment>(".", [=] { return StartAddr; }, ""));
@@ -444,17 +443,19 @@ void LinkerScript::fabricateDefaultCommands(bool AllocateHeader) {
if (!(Sec->Flags & SHF_ALLOC))
continue;
+ auto *OSCmd = make<OutputSectionCommand>(Sec->Name);
+ OSCmd->Sec = Sec;
+
+ // Prefer user supplied address over additional alignment constraint
auto I = Config->SectionStartMap.find(Sec->Name);
if (I != Config->SectionStartMap.end())
Commands.push_back(
make<SymbolAssignment>(".", [=] { return I->second; }, ""));
-
- auto *OSCmd = make<OutputSectionCommand>(Sec->Name);
- OSCmd->Sec = Sec;
- if (Sec->PageAlign)
+ else if (Sec->PageAlign)
OSCmd->AddrExpr = [=] {
return alignTo(Script->getDot(), Config->MaxPageSize);
};
+
Commands.push_back(OSCmd);
if (Sec->Sections.size()) {
auto *ISD = make<InputSectionDescription>("");
diff --git a/ELF/SymbolTable.cpp b/ELF/SymbolTable.cpp
index 541fc1bf6479..30f1c3653f50 100644
--- a/ELF/SymbolTable.cpp
+++ b/ELF/SymbolTable.cpp
@@ -279,9 +279,10 @@ Symbol *SymbolTable<ELFT>::addUndefined(StringRef Name, bool IsLocal,
return S;
}
if (Binding != STB_WEAK) {
- if (S->body()->isShared() || S->body()->isLazy())
+ SymbolBody *B = S->body();
+ if (B->isShared() || B->isLazy() || B->isUndefined())
S->Binding = Binding;
- if (auto *SS = dyn_cast<SharedSymbol>(S->body()))
+ if (auto *SS = dyn_cast<SharedSymbol>(B))
cast<SharedFile<ELFT>>(SS->File)->IsUsed = true;
}
if (auto *L = dyn_cast<Lazy>(S->body())) {
diff --git a/ELF/Target.cpp b/ELF/Target.cpp
index 7bc29e3d3de2..921505ae4b61 100644
--- a/ELF/Target.cpp
+++ b/ELF/Target.cpp
@@ -1324,8 +1324,8 @@ RelExpr AArch64TargetInfo::getRelExpr(uint32_t Type, const SymbolBody &S,
return R_ABS;
case R_AARCH64_TLSDESC_ADR_PAGE21:
return R_TLSDESC_PAGE;
- case R_AARCH64_TLSDESC_LD64_LO12_NC:
- case R_AARCH64_TLSDESC_ADD_LO12_NC:
+ case R_AARCH64_TLSDESC_LD64_LO12:
+ case R_AARCH64_TLSDESC_ADD_LO12:
return R_TLSDESC;
case R_AARCH64_TLSDESC_CALL:
return R_TLSDESC_CALL;
@@ -1376,8 +1376,8 @@ bool AArch64TargetInfo::usesOnlyLowPageBits(uint32_t Type) const {
case R_AARCH64_LDST32_ABS_LO12_NC:
case R_AARCH64_LDST64_ABS_LO12_NC:
case R_AARCH64_LDST8_ABS_LO12_NC:
- case R_AARCH64_TLSDESC_ADD_LO12_NC:
- case R_AARCH64_TLSDESC_LD64_LO12_NC:
+ case R_AARCH64_TLSDESC_ADD_LO12:
+ case R_AARCH64_TLSDESC_LD64_LO12:
case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
return true;
}
@@ -1503,7 +1503,7 @@ void AArch64TargetInfo::relocateOne(uint8_t *Loc, uint32_t Type,
break;
case R_AARCH64_LD64_GOT_LO12_NC:
case R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC:
- case R_AARCH64_TLSDESC_LD64_LO12_NC:
+ case R_AARCH64_TLSDESC_LD64_LO12:
checkAlignment<8>(Loc, Val, Type);
or32le(Loc, (Val & 0xFF8) << 7);
break;
@@ -1543,7 +1543,7 @@ void AArch64TargetInfo::relocateOne(uint8_t *Loc, uint32_t Type,
or32AArch64Imm(Loc, Val >> 12);
break;
case R_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
- case R_AARCH64_TLSDESC_ADD_LO12_NC:
+ case R_AARCH64_TLSDESC_ADD_LO12:
or32AArch64Imm(Loc, Val);
break;
default:
@@ -1555,8 +1555,8 @@ void AArch64TargetInfo::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type,
uint64_t Val) const {
// TLSDESC Global-Dynamic relocation are in the form:
// adrp x0, :tlsdesc:v [R_AARCH64_TLSDESC_ADR_PAGE21]
- // ldr x1, [x0, #:tlsdesc_lo12:v [R_AARCH64_TLSDESC_LD64_LO12_NC]
- // add x0, x0, :tlsdesc_los:v [_AARCH64_TLSDESC_ADD_LO12_NC]
+ // ldr x1, [x0, #:tlsdesc_lo12:v [R_AARCH64_TLSDESC_LD64_LO12]
+ // add x0, x0, :tlsdesc_los:v [R_AARCH64_TLSDESC_ADD_LO12]
// .tlsdesccall [R_AARCH64_TLSDESC_CALL]
// blr x1
// And it can optimized to:
@@ -1567,14 +1567,14 @@ void AArch64TargetInfo::relaxTlsGdToLe(uint8_t *Loc, uint32_t Type,
checkUInt<32>(Loc, Val, Type);
switch (Type) {
- case R_AARCH64_TLSDESC_ADD_LO12_NC:
+ case R_AARCH64_TLSDESC_ADD_LO12:
case R_AARCH64_TLSDESC_CALL:
write32le(Loc, 0xd503201f); // nop
return;
case R_AARCH64_TLSDESC_ADR_PAGE21:
write32le(Loc, 0xd2a00000 | (((Val >> 16) & 0xffff) << 5)); // movz
return;
- case R_AARCH64_TLSDESC_LD64_LO12_NC:
+ case R_AARCH64_TLSDESC_LD64_LO12:
write32le(Loc, 0xf2800000 | ((Val & 0xffff) << 5)); // movk
return;
default:
@@ -1586,8 +1586,8 @@ void AArch64TargetInfo::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type,
uint64_t Val) const {
// TLSDESC Global-Dynamic relocation are in the form:
// adrp x0, :tlsdesc:v [R_AARCH64_TLSDESC_ADR_PAGE21]
- // ldr x1, [x0, #:tlsdesc_lo12:v [R_AARCH64_TLSDESC_LD64_LO12_NC]
- // add x0, x0, :tlsdesc_los:v [_AARCH64_TLSDESC_ADD_LO12_NC]
+ // ldr x1, [x0, #:tlsdesc_lo12:v [R_AARCH64_TLSDESC_LD64_LO12]
+ // add x0, x0, :tlsdesc_los:v [R_AARCH64_TLSDESC_ADD_LO12]
// .tlsdesccall [R_AARCH64_TLSDESC_CALL]
// blr x1
// And it can optimized to:
@@ -1597,7 +1597,7 @@ void AArch64TargetInfo::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type,
// nop
switch (Type) {
- case R_AARCH64_TLSDESC_ADD_LO12_NC:
+ case R_AARCH64_TLSDESC_ADD_LO12:
case R_AARCH64_TLSDESC_CALL:
write32le(Loc, 0xd503201f); // nop
break;
@@ -1605,7 +1605,7 @@ void AArch64TargetInfo::relaxTlsGdToIe(uint8_t *Loc, uint32_t Type,
write32le(Loc, 0x90000000); // adrp
relocateOne(Loc, R_AARCH64_TLSIE_ADR_GOTTPREL_PAGE21, Val);
break;
- case R_AARCH64_TLSDESC_LD64_LO12_NC:
+ case R_AARCH64_TLSDESC_LD64_LO12:
write32le(Loc, 0xf9400000); // ldr
relocateOne(Loc, R_AARCH64_TLSIE_LD64_GOTTPREL_LO12_NC, Val);
break;
diff --git a/ELF/Writer.cpp b/ELF/Writer.cpp
index e2ab48433a52..3de2596af27c 100644
--- a/ELF/Writer.cpp
+++ b/ELF/Writer.cpp
@@ -252,7 +252,7 @@ template <class ELFT> void Writer<ELFT>::run() {
} else {
if (!Script->Opt.HasSections) {
fixSectionAlignments();
- Script->fabricateDefaultCommands(Config->MaxPageSize);
+ Script->fabricateDefaultCommands(AllocateHeader);
}
Script->synchronize();
Script->assignAddresses(Phdrs);
diff --git a/test/ELF/Inputs/weak-and-strong-undef.s b/test/ELF/Inputs/weak-and-strong-undef.s
new file mode 100644
index 000000000000..a5e476d43160
--- /dev/null
+++ b/test/ELF/Inputs/weak-and-strong-undef.s
@@ -0,0 +1 @@
+ .weak foo
diff --git a/test/ELF/gdb-index-ranges.s b/test/ELF/gdb-index-ranges.s
new file mode 100644
index 000000000000..2dd158ee4a0a
--- /dev/null
+++ b/test/ELF/gdb-index-ranges.s
@@ -0,0 +1,66 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o
+# RUN: ld.lld --gdb-index -e main %t.o -o %t
+# RUN: llvm-dwarfdump -debug-dump=gdb_index %t | FileCheck %s
+
+# CHECK: .gnu_index contents:
+# CHECK: Address area offset = 0x28, has 2 entries:
+# CHECK-NEXT: Low/High address = [0x201000, 0x201001) (Size: 0x1), CU id = 0
+# CHECK-NEXT: Low/High address = [0x201001, 0x201003) (Size: 0x2), CU id = 0
+
+.section .text.foo1,"ax",@progbits
+.Lfunc_begin0:
+ nop
+.Lfunc_end0:
+
+.section .text.foo2,"ax",@progbits
+.Lfunc_begin1:
+ nop
+ nop
+.Lfunc_end1:
+
+.section .debug_abbrev,"",@progbits
+.byte 1 # Abbreviation Code
+.byte 17 # DW_TAG_compile_unit
+.byte 0 # DW_CHILDREN_no
+.byte 37 # DW_AT_producer
+.byte 14 # DW_FORM_strp
+.byte 19 # DW_AT_language
+.byte 5 # DW_FORM_data2
+.byte 3 # DW_AT_name
+.byte 14 # DW_FORM_strp
+.byte 16 # DW_AT_stmt_list
+.byte 23 # DW_FORM_sec_offset
+.byte 27 # DW_AT_comp_dir
+.byte 14 # DW_FORM_strp
+.byte 17 # DW_AT_low_pc
+.byte 1 # DW_FORM_addr
+.byte 85 # DW_AT_ranges
+.byte 23 # DW_FORM_sec_offset
+.byte 0 # EOM(1)
+.byte 0 # EOM(2)
+.byte 0 # EOM(3)
+
+.section .debug_info,"",@progbits
+.Lcu_begin0:
+.long 38 # Length of Unit
+.short 4 # DWARF version number
+.long .debug_abbrev # Offset Into Abbrev. Section
+.byte 8 # Address Size (in bytes)
+.byte 1 # Abbrev [1] 0xb:0x1f DW_TAG_compile_unit
+.long 0 # DW_AT_producer
+.short 4 # DW_AT_language
+.long 0 # DW_AT_name
+.long 0 # DW_AT_stmt_list
+.long 0 # DW_AT_comp_dir
+.quad 0 # DW_AT_low_pc
+.long .Ldebug_ranges0 # DW_AT_ranges
+
+.section .debug_ranges,"",@progbits
+.Ldebug_ranges0:
+.quad .Lfunc_begin0
+.quad .Lfunc_end0
+.quad .Lfunc_begin1
+.quad .Lfunc_end1
+.quad 0
+.quad 0
diff --git a/test/ELF/sectionstart-noallochdr.s b/test/ELF/sectionstart-noallochdr.s
new file mode 100644
index 000000000000..e9267a5372a5
--- /dev/null
+++ b/test/ELF/sectionstart-noallochdr.s
@@ -0,0 +1,23 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o --section-start .data=0x20 \
+# RUN: --section-start .bss=0x30 --section-start .text=0x10 -o %t1
+# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
+
+# CHECK: Sections:
+# CHECK-NEXT: Idx Name Size Address Type
+# CHECK-NEXT: 0 00000000 0000000000000000
+# CHECK-NEXT: 1 .text 00000001 0000000000000010 TEXT DATA
+# CHECK-NEXT: 2 .data 00000004 0000000000000020 DATA
+# CHECK-NEXT: 3 .bss 00000004 0000000000000030 BSS
+
+.text
+.globl _start
+_start:
+ nop
+
+.data
+.long 0
+
+.bss
+.zero 4
diff --git a/test/ELF/weak-and-strong-undef.s b/test/ELF/weak-and-strong-undef.s
new file mode 100644
index 000000000000..db93470636df
--- /dev/null
+++ b/test/ELF/weak-and-strong-undef.s
@@ -0,0 +1,12 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t1.o
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %p/Inputs/weak-and-strong-undef.s -o %t2.o
+# RUN: not ld.lld %t1.o %t2.o -o %t 2>&1 | FileCheck %s
+# RUN: not ld.lld %t2.o %t1.o -o %t 2>&1 | FileCheck %s
+
+# CHECK: error: undefined symbol: foo
+
+.long foo
+.globl _start
+_start:
+ret