MCSectionELF *MCContext::createELFSectionImpl(StringRef Section, unsigned Type, unsigned Flags, SectionKind K, unsigned EntrySize, const MCSymbolELF *Group, unsigned UniqueID, const MCSymbolELF *Associated) { MCSymbolELF *R; MCSymbol *&Sym = Symbols[Section]; // A section symbol can not redefine regular symbols. There may be multiple // sections with the same name, in which case the first such section wins. if (Sym && Sym->isDefined() && (!Sym->isInSection() || Sym->getSection().getBeginSymbol() != Sym)) reportError(SMLoc(), "invalid symbol redefinition"); if (Sym && Sym->isUndefined()) { R = cast<MCSymbolELF>(Sym); } else { auto NameIter = UsedNames.insert(std::make_pair(Section, false)).first; R = new (&*NameIter, *this) MCSymbolELF(&*NameIter, /*isTemporary*/ false); if (!Sym) Sym = R; } R->setBinding(ELF::STB_LOCAL); R->setType(ELF::STT_SECTION); auto *Ret = new (ELFAllocator.Allocate()) MCSectionELF( Section, Type, Flags, K, EntrySize, Group, UniqueID, R, Associated); auto *F = new MCDataFragment(); Ret->getFragmentList().insert(Ret->begin(), F); F->setParent(Ret); R->setFragment(F); return Ret; }
void AMDGPUTargetELFStreamer::EmitAMDGPUHsaProgramScopeGlobal( StringRef GlobalName) { MCSymbolELF *Symbol = cast<MCSymbolELF>( getStreamer().getContext().getOrCreateSymbol(GlobalName)); Symbol->setType(ELF::STT_OBJECT); Symbol->setBinding(ELF::STB_GLOBAL); }
bool ELFObjectWriter::isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol, bool Used, bool Renamed) { if (Symbol.isVariable()) { const MCExpr *Expr = Symbol.getVariableValue(); if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) { if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF) return false; } } if (Used) return true; if (Renamed) return false; if (Symbol.isVariable() && Symbol.isUndefined()) { // FIXME: this is here just to diagnose the case of a var = commmon_sym. Layout.getBaseSymbol(Symbol); return false; } if (Symbol.isUndefined() && !Symbol.isBindingSet()) return false; if (Symbol.isTemporary()) return false; if (Symbol.getType() == ELF::STT_SECTION) return false; return true; }
// True if the assembler knows nothing about the final value of the symbol. // This doesn't cover the comdat issues, since in those cases the assembler // can at least know that all symbols in the section will move together. static bool isWeak(const MCSymbolELF &Sym) { if (Sym.getType() == ELF::STT_GNU_IFUNC) return true; switch (Sym.getBinding()) { default: llvm_unreachable("Unknown binding"); case ELF::STB_LOCAL: return false; case ELF::STB_GLOBAL: return false; case ELF::STB_WEAK: case ELF::STB_GNU_UNIQUE: return true; } }
void TargetLoweringObjectFileELF::emitPersonalityValue( MCStreamer &Streamer, const DataLayout &DL, const MCSymbol *Sym) const { SmallString<64> NameData("DW.ref."); NameData += Sym->getName(); MCSymbolELF *Label = cast<MCSymbolELF>(getContext().getOrCreateSymbol(NameData)); Streamer.EmitSymbolAttribute(Label, MCSA_Hidden); Streamer.EmitSymbolAttribute(Label, MCSA_Weak); unsigned Flags = ELF::SHF_ALLOC | ELF::SHF_WRITE | ELF::SHF_GROUP; MCSection *Sec = getContext().getELFNamedSection(".data", Label->getName(), ELF::SHT_PROGBITS, Flags, 0); unsigned Size = DL.getPointerSize(); Streamer.SwitchSection(Sec); Streamer.EmitValueToAlignment(DL.getPointerABIAlignment()); Streamer.EmitSymbolAttribute(Label, MCSA_ELF_TypeObject); const MCExpr *E = MCConstantExpr::create(Size, getContext()); Streamer.emitELFSize(Label, E); Streamer.EmitLabel(Label); Streamer.EmitSymbolValue(Sym, Size); }
void AMDGPUTargetELFStreamer::EmitAmdhsaKernelDescriptor( const MCSubtargetInfo &STI, StringRef KernelName, const amdhsa::kernel_descriptor_t &KernelDescriptor, uint64_t NextVGPR, uint64_t NextSGPR, bool ReserveVCC, bool ReserveFlatScr, bool ReserveXNACK) { auto &Streamer = getStreamer(); auto &Context = Streamer.getContext(); MCSymbolELF *KernelDescriptorSymbol = cast<MCSymbolELF>( Context.getOrCreateSymbol(Twine(KernelName) + Twine(".kd"))); KernelDescriptorSymbol->setBinding(ELF::STB_GLOBAL); KernelDescriptorSymbol->setType(ELF::STT_OBJECT); KernelDescriptorSymbol->setSize( MCConstantExpr::create(sizeof(KernelDescriptor), Context)); MCSymbolELF *KernelCodeSymbol = cast<MCSymbolELF>( Context.getOrCreateSymbol(Twine(KernelName))); KernelCodeSymbol->setBinding(ELF::STB_LOCAL); Streamer.EmitLabel(KernelDescriptorSymbol); Streamer.EmitBytes(StringRef( (const char*)&(KernelDescriptor), offsetof(amdhsa::kernel_descriptor_t, kernel_code_entry_byte_offset))); // FIXME: Remove the use of VK_AMDGPU_REL64 in the expression below. The // expression being created is: // (start of kernel code) - (start of kernel descriptor) // It implies R_AMDGPU_REL64, but ends up being R_AMDGPU_ABS64. Streamer.EmitValue(MCBinaryExpr::createSub( MCSymbolRefExpr::create( KernelCodeSymbol, MCSymbolRefExpr::VK_AMDGPU_REL64, Context), MCSymbolRefExpr::create( KernelDescriptorSymbol, MCSymbolRefExpr::VK_None, Context), Context), sizeof(KernelDescriptor.kernel_code_entry_byte_offset)); Streamer.EmitBytes(StringRef( (const char*)&(KernelDescriptor) + offsetof(amdhsa::kernel_descriptor_t, kernel_code_entry_byte_offset) + sizeof(KernelDescriptor.kernel_code_entry_byte_offset), sizeof(KernelDescriptor) - offsetof(amdhsa::kernel_descriptor_t, kernel_code_entry_byte_offset) - sizeof(KernelDescriptor.kernel_code_entry_byte_offset))); }
void AMDGPUTargetELFStreamer::EmitAmdhsaKernelDescriptor( const MCSubtargetInfo &STI, StringRef KernelName, const amdhsa::kernel_descriptor_t &KernelDescriptor, uint64_t NextVGPR, uint64_t NextSGPR, bool ReserveVCC, bool ReserveFlatScr, bool ReserveXNACK) { auto &Streamer = getStreamer(); auto &Context = Streamer.getContext(); MCSymbolELF *KernelCodeSymbol = cast<MCSymbolELF>( Context.getOrCreateSymbol(Twine(KernelName))); MCSymbolELF *KernelDescriptorSymbol = cast<MCSymbolELF>( Context.getOrCreateSymbol(Twine(KernelName) + Twine(".kd"))); // Copy kernel descriptor symbol's binding, other and visibility from the // kernel code symbol. KernelDescriptorSymbol->setBinding(KernelCodeSymbol->getBinding()); KernelDescriptorSymbol->setOther(KernelCodeSymbol->getOther()); KernelDescriptorSymbol->setVisibility(KernelCodeSymbol->getVisibility()); // Kernel descriptor symbol's type and size are fixed. KernelDescriptorSymbol->setType(ELF::STT_OBJECT); KernelDescriptorSymbol->setSize( MCConstantExpr::create(sizeof(KernelDescriptor), Context)); // The visibility of the kernel code symbol must be protected or less to allow // static relocations from the kernel descriptor to be used. if (KernelCodeSymbol->getVisibility() == ELF::STV_DEFAULT) KernelCodeSymbol->setVisibility(ELF::STV_PROTECTED); Streamer.EmitLabel(KernelDescriptorSymbol); Streamer.EmitBytes(StringRef( (const char*)&(KernelDescriptor), offsetof(amdhsa::kernel_descriptor_t, kernel_code_entry_byte_offset))); // FIXME: Remove the use of VK_AMDGPU_REL64 in the expression below. The // expression being created is: // (start of kernel code) - (start of kernel descriptor) // It implies R_AMDGPU_REL64, but ends up being R_AMDGPU_ABS64. Streamer.EmitValue(MCBinaryExpr::createSub( MCSymbolRefExpr::create( KernelCodeSymbol, MCSymbolRefExpr::VK_AMDGPU_REL64, Context), MCSymbolRefExpr::create( KernelDescriptorSymbol, MCSymbolRefExpr::VK_None, Context), Context), sizeof(KernelDescriptor.kernel_code_entry_byte_offset)); Streamer.EmitBytes(StringRef( (const char*)&(KernelDescriptor) + offsetof(amdhsa::kernel_descriptor_t, kernel_code_entry_byte_offset) + sizeof(KernelDescriptor.kernel_code_entry_byte_offset), sizeof(KernelDescriptor) - offsetof(amdhsa::kernel_descriptor_t, kernel_code_entry_byte_offset) - sizeof(KernelDescriptor.kernel_code_entry_byte_offset))); }
void AMDGPUTargetELFStreamer::EmitAMDGPUSymbolType(StringRef SymbolName, unsigned Type) { MCSymbolELF *Symbol = cast<MCSymbolELF>( getStreamer().getContext().getOrCreateSymbol(SymbolName)); Symbol->setType(Type); }