diff options
Diffstat (limited to 'contrib/llvm-project/lld/ELF/LinkerScript.cpp')
-rw-r--r-- | contrib/llvm-project/lld/ELF/LinkerScript.cpp | 36 |
1 files changed, 20 insertions, 16 deletions
diff --git a/contrib/llvm-project/lld/ELF/LinkerScript.cpp b/contrib/llvm-project/lld/ELF/LinkerScript.cpp index a938984ad945..01785f39ed75 100644 --- a/contrib/llvm-project/lld/ELF/LinkerScript.cpp +++ b/contrib/llvm-project/lld/ELF/LinkerScript.cpp @@ -849,17 +849,8 @@ void LinkerScript::diagnoseOrphanHandling() const { } uint64_t LinkerScript::advance(uint64_t size, unsigned alignment) { - bool isTbss = - (ctx->outSec->flags & SHF_TLS) && ctx->outSec->type == SHT_NOBITS; - uint64_t start = isTbss ? dot + ctx->threadBssOffset : dot; - start = alignTo(start, alignment); - uint64_t end = start + size; - - if (isTbss) - ctx->threadBssOffset = end - dot; - else - dot = end; - return end; + dot = alignTo(dot, alignment) + size; + return dot; } void LinkerScript::output(InputSection *s) { @@ -931,13 +922,24 @@ static OutputSection *findFirstSection(PhdrEntry *load) { // This function assigns offsets to input sections and an output section // for a single sections command (e.g. ".text { *(.text); }"). void LinkerScript::assignOffsets(OutputSection *sec) { + const bool isTbss = (sec->flags & SHF_TLS) && sec->type == SHT_NOBITS; const bool sameMemRegion = ctx->memRegion == sec->memRegion; const bool prevLMARegionIsDefault = ctx->lmaRegion == nullptr; const uint64_t savedDot = dot; ctx->memRegion = sec->memRegion; ctx->lmaRegion = sec->lmaRegion; - if (sec->flags & SHF_ALLOC) { + if (!(sec->flags & SHF_ALLOC)) { + // Non-SHF_ALLOC sections have zero addresses. + dot = 0; + } else if (isTbss) { + // Allow consecutive SHF_TLS SHT_NOBITS output sections. The address range + // starts from the end address of the previous tbss section. + if (ctx->tbssAddr == 0) + ctx->tbssAddr = dot; + else + dot = ctx->tbssAddr; + } else { if (ctx->memRegion) dot = ctx->memRegion->curPos; if (sec->addrExpr) @@ -950,9 +952,6 @@ void LinkerScript::assignOffsets(OutputSection *sec) { if (ctx->memRegion && ctx->memRegion->curPos < dot) expandMemoryRegion(ctx->memRegion, dot - ctx->memRegion->curPos, ctx->memRegion->name, sec->name); - } else { - // Non-SHF_ALLOC sections have zero addresses. - dot = 0; } switchTo(sec); @@ -1008,8 +1007,13 @@ void LinkerScript::assignOffsets(OutputSection *sec) { // Non-SHF_ALLOC sections do not affect the addresses of other OutputSections // as they are not part of the process image. - if (!(sec->flags & SHF_ALLOC)) + if (!(sec->flags & SHF_ALLOC)) { dot = savedDot; + } else if (isTbss) { + // NOBITS TLS sections are similar. Additionally save the end address. + ctx->tbssAddr = dot; + dot = savedDot; + } } static bool isDiscardable(OutputSection &sec) { |