summaryrefslogtreecommitdiffstats
path: root/recipes-devtools/clang/clang/0039-lld-RISCV-Handle-relaxation-reductions-of-more-than-.patch
blob: 713cd3a598b41891e2cef7a0e743bb15414e8964 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
From 1405446343007159cdbef39b37427b3cc2e94266 Mon Sep 17 00:00:00 2001
From: Roland McGrath <mcgrathr@google.com>
Date: Tue, 16 May 2023 13:35:35 -0700
Subject: [PATCH] [lld][RISCV] Handle relaxation reductions of more than 65536
 bytes

In a real-world case with functions that have many, many
R_RISCV_CALL_PLT relocations due to asan and ubsan
instrumentation, all these can be relaxed by an instruction and
the net result is more than 65536 bytes of reduction in the
output .text section that totals about 1.2MiB in final size.

This changes InputSection to use a 32-bit field for bytesDropped.
The RISCV relaxation keeps track in a 64-bit field and detects
32-bit overflow as it previously detected 16-bit overflow. It
doesn't seem likely that 32-bit overflow will arise, but it's not
inconceivable and it's cheap enough to detect it.

This unfortunately increases the size of InputSection on 64-bit
hosts by a word, but that seems hard to avoid.

Reviewed By: MaskRay

Differential Revision: https://reviews.llvm.org/D150722

Upstream-Status: Backport [https://github.com/llvm/llvm-project/commit/9d37ea95df1b84cca9b5e954d8964c976a5e303e]
Signed-off-by: Khem Raj <raj.khem@gmail.com>
---
 lld/ELF/Arch/RISCV.cpp | 6 +++---
 lld/ELF/InputSection.h | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp
index 87887b314a5a..80754e37d3ed 100644
--- a/lld/ELF/Arch/RISCV.cpp
+++ b/lld/ELF/Arch/RISCV.cpp
@@ -621,7 +621,7 @@ static bool relax(InputSection &sec) {
   // iteration.
   DenseMap<const Defined *, uint64_t> valueDelta;
   ArrayRef<SymbolAnchor> sa = ArrayRef(aux.anchors);
-  uint32_t delta = 0;
+  uint64_t delta = 0;
   for (auto [i, r] : llvm::enumerate(sec.relocs())) {
     for (; sa.size() && sa[0].offset <= r.offset; sa = sa.slice(1))
       if (!sa[0].end)
@@ -688,8 +688,8 @@ static bool relax(InputSection &sec) {
       a.d->value -= delta - valueDelta.find(a.d)->second;
   }
   // Inform assignAddresses that the size has changed.
-  if (!isUInt<16>(delta))
-    fatal("section size decrease is too large");
+  if (!isUInt<32>(delta))
+    fatal("section size decrease is too large: " + Twine(delta));
   sec.bytesDropped = delta;
   return changed;
 }
diff --git a/lld/ELF/InputSection.h b/lld/ELF/InputSection.h
index 356ccda2d743..143384b3ba7b 100644
--- a/lld/ELF/InputSection.h
+++ b/lld/ELF/InputSection.h
@@ -137,7 +137,7 @@ public:
   // Used by --optimize-bb-jumps and RISC-V linker relaxation temporarily to
   // indicate the number of bytes which is not counted in the size. This should
   // be reset to zero after uses.
-  uint16_t bytesDropped = 0;
+  uint32_t bytesDropped = 0;
 
   mutable bool compressed = false;
 
@@ -401,7 +401,7 @@ private:
   template <class ELFT> void copyShtGroup(uint8_t *buf);
 };
 
-static_assert(sizeof(InputSection) <= 152, "InputSection is too big");
+static_assert(sizeof(InputSection) <= 160, "InputSection is too big");
 
 class SyntheticSection : public InputSection {
 public: