MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { unsigned Flags = getELFSectionFlags(Kind); // If we have -ffunction-section or -fdata-section then we should emit the // global value to a uniqued section specifically for it. bool EmitUniqueSection = false; if (!(Flags & ELF::SHF_MERGE) && !Kind.isCommon()) { if (Kind.isText()) EmitUniqueSection = TM.getFunctionSections(); else EmitUniqueSection = TM.getDataSections(); } EmitUniqueSection |= GO->hasComdat(); const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM); if (AssociatedSymbol) { EmitUniqueSection = true; Flags |= ELF::SHF_LINK_ORDER; } MCSectionELF *Section = selectELFSectionForGlobal( getContext(), GO, Kind, getMangler(), TM, EmitUniqueSection, Flags, &NextUniqueID, AssociatedSymbol); assert(Section->getAssociatedSymbol() == AssociatedSymbol); return Section; }
MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { StringRef SectionName = GO->getSection(); // Infer section flags from the section name if we can. Kind = getELFKindForNamedSection(SectionName, Kind); StringRef Group = ""; unsigned Flags = getELFSectionFlags(Kind); if (const Comdat *C = getELFComdat(GO)) { Group = C->getName(); Flags |= ELF::SHF_GROUP; } // A section can have at most one associated section. Put each global with // MD_associated in a unique section. unsigned UniqueID = MCContext::GenericSectionID; const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM); if (AssociatedSymbol) { UniqueID = NextUniqueID++; Flags |= ELF::SHF_LINK_ORDER; } MCSectionELF *Section = getContext().getELFSection( SectionName, getELFSectionType(SectionName, Kind), Flags, /*EntrySize=*/0, Group, UniqueID, AssociatedSymbol); // Make sure that we did not get some other section with incompatible sh_link. // This should not be possible due to UniqueID code above. assert(Section->getAssociatedSymbol() == AssociatedSymbol); return Section; }
MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { StringRef SectionName = GO->getSection(); // Check if '#pragma clang section' name is applicable. // Note that pragma directive overrides -ffunction-section, -fdata-section // and so section name is exactly as user specified and not uniqued. const GlobalVariable *GV = dyn_cast<GlobalVariable>(GO); if (GV && GV->hasImplicitSection()) { auto Attrs = GV->getAttributes(); if (Attrs.hasAttribute("bss-section") && Kind.isBSS()) { SectionName = Attrs.getAttribute("bss-section").getValueAsString(); } else if (Attrs.hasAttribute("rodata-section") && Kind.isReadOnly()) { SectionName = Attrs.getAttribute("rodata-section").getValueAsString(); } else if (Attrs.hasAttribute("data-section") && Kind.isData()) { SectionName = Attrs.getAttribute("data-section").getValueAsString(); } } const Function *F = dyn_cast<Function>(GO); if (F && F->hasFnAttribute("implicit-section-name")) { SectionName = F->getFnAttribute("implicit-section-name").getValueAsString(); } // Infer section flags from the section name if we can. Kind = getELFKindForNamedSection(SectionName, Kind); StringRef Group = ""; unsigned Flags = getELFSectionFlags(Kind); if (const Comdat *C = getELFComdat(GO)) { Group = C->getName(); Flags |= ELF::SHF_GROUP; } // A section can have at most one associated section. Put each global with // MD_associated in a unique section. unsigned UniqueID = MCContext::GenericSectionID; const MCSymbolELF *AssociatedSymbol = getAssociatedSymbol(GO, TM); if (AssociatedSymbol) { UniqueID = NextUniqueID++; Flags |= ELF::SHF_LINK_ORDER; } MCSectionELF *Section = getContext().getELFSection( SectionName, getELFSectionType(SectionName, Kind), Flags, /*EntrySize=*/0, Group, UniqueID, AssociatedSymbol); // Make sure that we did not get some other section with incompatible sh_link. // This should not be possible due to UniqueID code above. assert(Section->getAssociatedSymbol() == AssociatedSymbol); return Section; }
void ELFObjectWriter::writeSection(const SectionIndexMapTy &SectionIndexMap, uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size, const MCSectionELF &Section) { uint64_t sh_link = 0; uint64_t sh_info = 0; switch(Section.getType()) { default: // Nothing to do. break; case ELF::SHT_DYNAMIC: llvm_unreachable("SHT_DYNAMIC in a relocatable object"); case ELF::SHT_REL: case ELF::SHT_RELA: { sh_link = SymbolTableIndex; assert(sh_link && ".symtab not found"); const MCSection *InfoSection = Section.getAssociatedSection(); sh_info = SectionIndexMap.lookup(cast<MCSectionELF>(InfoSection)); break; } case ELF::SHT_SYMTAB: case ELF::SHT_DYNSYM: sh_link = StringTableIndex; sh_info = LastLocalSymbolIndex; break; case ELF::SHT_SYMTAB_SHNDX: sh_link = SymbolTableIndex; break; case ELF::SHT_GROUP: sh_link = SymbolTableIndex; sh_info = GroupSymbolIndex; break; } if (Section.getFlags() & ELF::SHF_LINK_ORDER) { const MCSymbol *Sym = Section.getAssociatedSymbol(); const MCSectionELF *Sec = cast<MCSectionELF>(&Sym->getSection()); sh_link = SectionIndexMap.lookup(Sec); } WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getSectionName()), Section.getType(), Section.getFlags(), 0, Offset, Size, sh_link, sh_info, Section.getAlignment(), Section.getEntrySize()); }