Skip to content

Commit 9d37ea9

Browse files
committed
[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
1 parent 114bc86 commit 9d37ea9

File tree

2 files changed

+5
-5
lines changed

2 files changed

+5
-5
lines changed

lld/ELF/Arch/RISCV.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ static bool relax(InputSection &sec) {
663663
auto &aux = *sec.relaxAux;
664664
bool changed = false;
665665
ArrayRef<SymbolAnchor> sa = ArrayRef(aux.anchors);
666-
uint32_t delta = 0;
666+
uint64_t delta = 0;
667667

668668
std::fill_n(aux.relocTypes.get(), sec.relocs().size(), R_RISCV_NONE);
669669
aux.writes.clear();
@@ -726,8 +726,8 @@ static bool relax(InputSection &sec) {
726726
a.d->value = a.offset - delta;
727727
}
728728
// Inform assignAddresses that the size has changed.
729-
if (!isUInt<16>(delta))
730-
fatal("section size decrease is too large");
729+
if (!isUInt<32>(delta))
730+
fatal("section size decrease is too large: " + Twine(delta));
731731
sec.bytesDropped = delta;
732732
return changed;
733733
}

lld/ELF/InputSection.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ class InputSectionBase : public SectionBase {
137137
// Used by --optimize-bb-jumps and RISC-V linker relaxation temporarily to
138138
// indicate the number of bytes which is not counted in the size. This should
139139
// be reset to zero after uses.
140-
uint16_t bytesDropped = 0;
140+
uint32_t bytesDropped = 0;
141141

142142
mutable bool compressed = false;
143143

@@ -401,7 +401,7 @@ class InputSection : public InputSectionBase {
401401
template <class ELFT> void copyShtGroup(uint8_t *buf);
402402
};
403403

404-
static_assert(sizeof(InputSection) <= 152, "InputSection is too big");
404+
static_assert(sizeof(InputSection) <= 160, "InputSection is too big");
405405

406406
class SyntheticSection : public InputSection {
407407
public:

0 commit comments

Comments
 (0)