diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index 7707d3d583c5..62906be84c76 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -58,10 +58,21 @@ static typename ELFT::uint getSymVA(const SymbolBody &Body, int64_t &Addend) { return D.Value; uintX_t Offset = D.Value; + + // An object in an SHF_MERGE section might be referenced via a + // section symbol (as a hack for reducing the number of local + // symbols). + // We must incorporate the addend into the section offset (and + // zero out the addend for later processing) so that we find the + // right object in the section. + // Note that for an ordinary symbol we do not perform this + // adjustment and thus effectively assume that the addend cannot + // cross the boundaries of mergeable objects. if (D.isSection()) { Offset += Addend; Addend = 0; } + const OutputSection *OutSec = IS->getOutputSection(); uintX_t VA = (OutSec ? OutSec->Addr : 0) + IS->getOffset(Offset); if (D.isTls() && !Config->Relocatable) {