aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2019-02-05 11:15:26 +0000
committerHans Wennborg <hans@hanshq.net>2019-02-05 11:15:26 +0000
commitca26c44df0122e65a56661bef56c9a63901eb699 (patch)
treeb00a280eb83e2780ec9a8e6c036e634d5534a0ad
parent44c793021d5746a3860aaa241e7f0756a48df744 (diff)
downloadllvm-ca26c44df0122e65a56661bef56c9a63901eb699.zip
llvm-ca26c44df0122e65a56661bef56c9a63901eb699.tar.gz
llvm-ca26c44df0122e65a56661bef56c9a63901eb699.tar.bz2
Merging r352928:
------------------------------------------------------------------------ r352928 | mstorsjo | 2019-02-01 23:08:03 +0100 (Fri, 01 Feb 2019) | 9 lines [COFF] Fix crashes when writing a PDB after adding thunks. When writing a PDB, the OutputSection of all chunks need to be set. The thunks are added directly to OutputSection after the normal machinery that sets it for all other chunks. This fixes part of PR40467. Differential Revision: https://reviews.llvm.org/D57574 ------------------------------------------------------------------------ llvm-svn: 353157
-rw-r--r--lld/COFF/Writer.cpp11
-rw-r--r--lld/test/COFF/arm-thumb-thunks-pdb.s18
2 files changed, 24 insertions, 5 deletions
diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp
index 258796e..71c24f6 100644
--- a/lld/COFF/Writer.cpp
+++ b/lld/COFF/Writer.cpp
@@ -344,14 +344,14 @@ getThunk(DenseMap<uint64_t, Defined *> &LastThunks, Defined *Target, uint64_t P,
// After adding thunks, we verify that all relocations are in range (with
// no extra margin requirements). If this failed, we restart (throwing away
// the previously created thunks) and retry with a wider margin.
-static bool createThunks(std::vector<Chunk *> &Chunks, int Margin) {
+static bool createThunks(OutputSection *OS, int Margin) {
bool AddressesChanged = false;
DenseMap<uint64_t, Defined *> LastThunks;
size_t ThunksSize = 0;
// Recheck Chunks.size() each iteration, since we can insert more
// elements into it.
- for (size_t I = 0; I != Chunks.size(); ++I) {
- SectionChunk *SC = dyn_cast_or_null<SectionChunk>(Chunks[I]);
+ for (size_t I = 0; I != OS->Chunks.size(); ++I) {
+ SectionChunk *SC = dyn_cast_or_null<SectionChunk>(OS->Chunks[I]);
if (!SC)
continue;
size_t ThunkInsertionSpot = I + 1;
@@ -388,7 +388,8 @@ static bool createThunks(std::vector<Chunk *> &Chunks, int Margin) {
Chunk *ThunkChunk = Thunk->getChunk();
ThunkChunk->setRVA(
ThunkInsertionRVA); // Estimate of where it will be located.
- Chunks.insert(Chunks.begin() + ThunkInsertionSpot, ThunkChunk);
+ ThunkChunk->setOutputSection(OS);
+ OS->Chunks.insert(OS->Chunks.begin() + ThunkInsertionSpot, ThunkChunk);
ThunkInsertionSpot++;
ThunksSize += ThunkChunk->getSize();
ThunkInsertionRVA += ThunkChunk->getSize();
@@ -477,7 +478,7 @@ void Writer::finalizeAddresses() {
// to avoid things going out of range due to the added thunks.
bool AddressesChanged = false;
for (OutputSection *Sec : OutputSections)
- AddressesChanged |= createThunks(Sec->Chunks, Margin);
+ AddressesChanged |= createThunks(Sec, Margin);
// If the verification above thought we needed thunks, we should have
// added some.
assert(AddressesChanged);
diff --git a/lld/test/COFF/arm-thumb-thunks-pdb.s b/lld/test/COFF/arm-thumb-thunks-pdb.s
new file mode 100644
index 0000000..9e972a7
--- /dev/null
+++ b/lld/test/COFF/arm-thumb-thunks-pdb.s
@@ -0,0 +1,18 @@
+// REQUIRES: arm
+// RUN: llvm-mc -filetype=obj -triple=thumbv7-windows %s -o %t.obj
+// RUN: lld-link -entry:main -subsystem:console %t.obj -out:%t.exe -debug -pdb:%t.pdb -verbose 2>&1 | FileCheck %s --check-prefix=VERBOSE
+
+// VERBOSE: Added 1 thunks with margin {{.*}} in {{.*}} passes
+
+ .syntax unified
+ .globl main
+ .globl func1
+ .text
+main:
+ bne func1
+ bx lr
+ .section .text$a, "xr"
+ .space 0x100000
+ .section .text$b, "xr"
+func1:
+ bx lr