X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTarget%2FELFTargetAsmInfo.cpp;h=752f4757dddb67919f307bac4363608235d536f1;hb=a61a4f669bbbacb5d52c0a5f3f9f3dd7fa8319bf;hp=9ca9709293eca348af8e96b965bb62f38d41090e;hpb=debe34bd8df7c6bb3d85f836374a1c7763576a63;p=oota-llvm.git diff --git a/lib/Target/ELFTargetAsmInfo.cpp b/lib/Target/ELFTargetAsmInfo.cpp index 9ca9709293e..752f4757ddd 100644 --- a/lib/Target/ELFTargetAsmInfo.cpp +++ b/lib/Target/ELFTargetAsmInfo.cpp @@ -17,25 +17,56 @@ #include "llvm/Function.h" #include "llvm/GlobalVariable.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/CodeGen/MachineConstantPool.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Target/ELFTargetAsmInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetData.h" using namespace llvm; -ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM) { - ETM = &TM; +ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM) + : TargetAsmInfo(TM) { - TextSection_ = getUnnamedSection("\t.text", SectionFlags::Code); - DataSection_ = getUnnamedSection("\t.data", SectionFlags::Writeable); BSSSection_ = getUnnamedSection("\t.bss", SectionFlags::Writeable | SectionFlags::BSS); - ReadOnlySection_ = getNamedSection("\t.rodata", SectionFlags::None); - TLSDataSection_ = getNamedSection("\t.tdata", - SectionFlags::Writeable | SectionFlags::TLS); - TLSBSSSection_ = getNamedSection("\t.tbss", + ReadOnlySection = getNamedSection("\t.rodata", SectionFlags::None); + TLSDataSection = getNamedSection("\t.tdata", + SectionFlags::Writeable | SectionFlags::TLS); + TLSBSSSection = getNamedSection("\t.tbss", SectionFlags::Writeable | SectionFlags::TLS | SectionFlags::BSS); + DataRelSection = getNamedSection("\t.data.rel", SectionFlags::Writeable); + DataRelLocalSection = getNamedSection("\t.data.rel.local", + SectionFlags::Writeable); + DataRelROSection = getNamedSection("\t.data.rel.ro", + SectionFlags::Writeable); + DataRelROLocalSection = getNamedSection("\t.data.rel.ro.local", + SectionFlags::Writeable); +} + +SectionKind::Kind +ELFTargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const { + SectionKind::Kind Kind = TargetAsmInfo::SectionKindForGlobal(GV); + + if (Kind != SectionKind::Data) + return Kind; + + // Decide, whether we need data.rel stuff + const GlobalVariable* GVar = dyn_cast(GV); + if (GVar->hasInitializer()) { + Constant *C = GVar->getInitializer(); + bool isConstant = GVar->isConstant(); + unsigned Reloc = RelocBehaviour(); + if (Reloc != Reloc::None && C->ContainsRelocations(Reloc)) + return (C->ContainsRelocations(Reloc::Global) ? + (isConstant ? + SectionKind::DataRelRO : SectionKind::DataRel) : + (isConstant ? + SectionKind::DataRelROLocal : SectionKind::DataRelLocal)); + } + + return Kind; } const Section* @@ -44,13 +75,16 @@ ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { if (const Function *F = dyn_cast(GV)) { switch (F->getLinkage()) { - default: assert(0 && "Unknown linkage type!"); + default: llvm_unreachable("Unknown linkage type!"); + case Function::PrivateLinkage: case Function::InternalLinkage: case Function::DLLExportLinkage: case Function::ExternalLinkage: - return getTextSection_(); - case Function::WeakLinkage: - case Function::LinkOnceLinkage: + return TextSection; + case Function::WeakAnyLinkage: + case Function::WeakODRLinkage: + case Function::LinkOnceAnyLinkage: + case Function::LinkOnceODRLinkage: std::string Name = UniqueSectionForGlobal(GV, Kind); unsigned Flags = SectionFlagsForGlobal(GV, Name.c_str()); return getNamedSection(Name.c_str(), Flags); @@ -63,39 +97,62 @@ ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const { } else { switch (Kind) { case SectionKind::Data: - return getDataSection_(); + case SectionKind::SmallData: + return DataSection; + case SectionKind::DataRel: + return DataRelSection; + case SectionKind::DataRelLocal: + return DataRelLocalSection; + case SectionKind::DataRelRO: + return DataRelROSection; + case SectionKind::DataRelROLocal: + return DataRelROLocalSection; case SectionKind::BSS: + case SectionKind::SmallBSS: // ELF targets usually have BSS sections return getBSSSection_(); case SectionKind::ROData: - return getReadOnlySection_(); + case SectionKind::SmallROData: + return getReadOnlySection(); case SectionKind::RODataMergeStr: return MergeableStringSection(GVar); case SectionKind::RODataMergeConst: return MergeableConstSection(GVar); case SectionKind::ThreadData: // ELF targets usually support TLS stuff - return getTLSDataSection_(); + return TLSDataSection; case SectionKind::ThreadBSS: - return getTLSBSSSection_(); + return TLSBSSSection; default: - assert(0 && "Unsuported section kind for global"); + llvm_unreachable("Unsuported section kind for global"); } } } else - assert(0 && "Unsupported global"); + llvm_unreachable("Unsupported global"); + + return NULL; +} + +const Section* +ELFTargetAsmInfo::SelectSectionForMachineConst(const Type *Ty) const { + // FIXME: Support data.rel stuff someday + return MergeableConstSection(Ty); } const Section* ELFTargetAsmInfo::MergeableConstSection(const GlobalVariable *GV) const { - const TargetData *TD = ETM->getTargetData(); - Constant *C = cast(GV)->getInitializer(); - const Type *Type = C->getType(); + Constant *C = GV->getInitializer(); + return MergeableConstSection(C->getType()); +} + +inline const Section* +ELFTargetAsmInfo::MergeableConstSection(const Type *Ty) const { + const TargetData *TD = TM.getTargetData(); // FIXME: string here is temporary, until stuff will fully land in. // We cannot use {Four,Eight,Sixteen}ByteConstantSection here, since it's // currently directly used by asmprinter. - unsigned Size = TD->getABITypeSize(Type); + unsigned Size = TD->getTypeAllocSize(Ty); if (Size == 4 || Size == 8 || Size == 16) { std::string Name = ".rodata.cst" + utostr(Size); @@ -104,21 +161,21 @@ ELFTargetAsmInfo::MergeableConstSection(const GlobalVariable *GV) const { Size)); } - return getReadOnlySection_(); + return getReadOnlySection(); } const Section* ELFTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const { - const TargetData *TD = ETM->getTargetData(); + const TargetData *TD = TM.getTargetData(); Constant *C = cast(GV)->getInitializer(); - const ConstantArray *CVA = cast(C); - const Type *Type = CVA->getType()->getElementType(); + const Type *Ty = cast(C->getType())->getElementType(); - unsigned Size = TD->getABITypeSize(Type); + unsigned Size = TD->getTypeAllocSize(Ty); if (Size <= 16) { + assert(getCStringSection() && "Should have string section prefix"); + // We also need alignment here - const TargetData *TD = ETM->getTargetData(); - unsigned Align = TD->getPreferredAlignment(GV); + unsigned Align = TD->getPrefTypeAlignment(Ty); if (Align < Size) Align = Size; @@ -129,10 +186,10 @@ ELFTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const { return getNamedSection(Name.c_str(), Flags); } - return getReadOnlySection_(); + return getReadOnlySection(); } -std::string ELFTargetAsmInfo::PrintSectionFlags(unsigned flags) const { +std::string ELFTargetAsmInfo::printSectionFlags(unsigned flags) const { std::string Flags = ",\""; if (!(flags & SectionFlags::Debug)) @@ -147,18 +204,25 @@ std::string ELFTargetAsmInfo::PrintSectionFlags(unsigned flags) const { Flags += 'S'; if (flags & SectionFlags::TLS) Flags += 'T'; + if (flags & SectionFlags::Small) + Flags += 's'; - Flags += "\""; + Flags += "\","; + + // If comment string is '@', e.g. as on ARM - use '%' instead + if (strcmp(CommentString, "@") == 0) + Flags += '%'; + else + Flags += '@'; // FIXME: There can be exceptions here if (flags & SectionFlags::BSS) - Flags += ",@nobits"; + Flags += "nobits"; else - Flags += ",@progbits"; + Flags += "progbits"; if (unsigned entitySize = SectionFlags::getEntitySize(flags)) Flags += "," + utostr(entitySize); return Flags; } -