diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index 86b2f33196ec9..b3da9c7881bef 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2182,8 +2182,6 @@ static BssSection *getCommonSec(Symbol *sym) { } static uint32_t getSymSectionIndex(Symbol *sym) { - if (getCommonSec(sym)) - return SHN_COMMON; assert(!(sym->needsCopy && sym->isObject())); if (!isa(sym) || sym->needsCopy) return SHN_UNDEF; @@ -2205,10 +2203,10 @@ template void SymbolTableSection::writeTo(uint8_t *buf) { Symbol *sym = ent.sym; bool isDefinedHere = type == SHT_SYMTAB || sym->partition == partition; - // Set st_info and st_other. - eSym->st_other = 0; + // Set st_name, st_info and st_other. + eSym->st_name = ent.strTabOffset; eSym->setBindingAndType(sym->binding, sym->type); - eSym->setVisibility(sym->visibility); + eSym->st_other = sym->visibility; // The 3 most significant bits of st_other are used by OpenPOWER ABI. // See getPPC64GlobalEntryToLocalEntryOffset() for more details. @@ -2219,30 +2217,29 @@ template void SymbolTableSection::writeTo(uint8_t *buf) { else if (config->emachine == EM_AARCH64) eSym->st_other |= sym->stOther & STO_AARCH64_VARIANT_PCS; - eSym->st_name = ent.strTabOffset; - if (isDefinedHere) - eSym->st_shndx = getSymSectionIndex(ent.sym); - else - eSym->st_shndx = 0; - - // Copy symbol size if it is a defined symbol. st_size is not significant - // for undefined symbols, so whether copying it or not is up to us if that's - // the case. We'll leave it as zero because by not setting a value, we can - // get the exact same outputs for two sets of input files that differ only - // in undefined symbol size in DSOs. - if (eSym->st_shndx == SHN_UNDEF || !isDefinedHere) - eSym->st_size = 0; - else - eSym->st_size = sym->getSize(); - - // st_value is usually an address of a symbol, but that has a special - // meaning for uninstantiated common symbols (--no-define-common). - if (BssSection *commonSec = getCommonSec(ent.sym)) + if (BssSection *commonSec = getCommonSec(sym)) { + // st_value is usually an address of a symbol, but that has a special + // meaning for uninstantiated common symbols (--no-define-common). + eSym->st_shndx = SHN_COMMON; eSym->st_value = commonSec->alignment; - else if (isDefinedHere) - eSym->st_value = sym->getVA(); - else - eSym->st_value = 0; + eSym->st_size = cast(sym)->size; + } else { + const uint32_t shndx = getSymSectionIndex(sym); + if (isDefinedHere) { + eSym->st_shndx = shndx; + eSym->st_value = sym->getVA(); + // Copy symbol size if it is a defined symbol. st_size is not + // significant for undefined symbols, so whether copying it or not is up + // to us if that's the case. We'll leave it as zero because by not + // setting a value, we can get the exact same outputs for two sets of + // input files that differ only in undefined symbol size in DSOs. + eSym->st_size = shndx != SHN_UNDEF ? cast(sym)->size : 0; + } else { + eSym->st_shndx = 0; + eSym->st_value = 0; + eSym->st_size = 0; + } + } ++eSym; } @@ -2293,7 +2290,7 @@ void SymtabShndxSection::writeTo(uint8_t *buf) { // we need to write actual index, otherwise, we must write SHN_UNDEF(0). buf += 4; // Ignore .symtab[0] entry. for (const SymbolTableEntry &entry : in.symTab->getSymbols()) { - if (getSymSectionIndex(entry.sym) == SHN_XINDEX) + if (!getCommonSec(entry.sym) && getSymSectionIndex(entry.sym) == SHN_XINDEX) write32(buf, entry.sym->getOutputSection()->sectionIndex); buf += 4; }