diff options
Diffstat (limited to 'lib/Target/ELFTargetAsmInfo.cpp')
-rw-r--r-- | lib/Target/ELFTargetAsmInfo.cpp | 199 |
1 files changed, 106 insertions, 93 deletions
diff --git a/lib/Target/ELFTargetAsmInfo.cpp b/lib/Target/ELFTargetAsmInfo.cpp index dbb2ce30ca..556b494185 100644 --- a/lib/Target/ELFTargetAsmInfo.cpp +++ b/lib/Target/ELFTargetAsmInfo.cpp @@ -12,16 +12,8 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" -#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" +#include "llvm/ADT/SmallVector.h" using namespace llvm; ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM) @@ -53,72 +45,6 @@ ELFTargetAsmInfo::ELFTargetAsmInfo(const TargetMachine &TM) SectionKind::MergeableConst16); } - -const Section* -ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV, - SectionKind Kind) const { - if (Kind.isText()) return TextSection; - if (Kind.isMergeableCString()) { - const TargetData *TD = TM.getTargetData(); - Constant *C = cast<GlobalVariable>(GV)->getInitializer(); - const Type *Ty = cast<ArrayType>(C->getType())->getElementType(); - - unsigned Size = TD->getTypeAllocSize(Ty); - if (Size <= 16) { - assert(getCStringSection() && "Should have string section prefix"); - - // We also need alignment here. - // FIXME: this is getting the alignment of the character, not the - // alignment of the string!! - unsigned Align = TD->getPrefTypeAlignment(Ty); - if (Align < Size) - Align = Size; - - std::string Name = getCStringSection() + utostr(Size) + '.' + - utostr(Align); - return getOrCreateSection(Name.c_str(), false, - SectionKind::MergeableCString); - } - - return getReadOnlySection(); - } - - if (Kind.isMergeableConst()) { - if (Kind.isMergeableConst4()) - return MergeableConst4Section; - if (Kind.isMergeableConst8()) - return MergeableConst8Section; - if (Kind.isMergeableConst16()) - return MergeableConst16Section; - return ReadOnlySection; // .const - } - - if (Kind.isReadOnly()) return getReadOnlySection(); - - - if (Kind.isThreadData()) return TLSDataSection; - if (Kind.isThreadBSS()) return TLSBSSSection; - - if (Kind.isBSS()) return getBSSSection_(); - - - if (Kind.isDataNoRel()) return DataSection; - if (Kind.isDataRelLocal()) return DataRelLocalSection; - if (Kind.isDataRel()) return DataRelSection; - if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection; - - assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); - return DataRelROSection; -} - -/// getSectionForMergeableConstant - Given a Mergeable constant with the -/// specified size and relocation information, return a section that it -/// should be placed in. -const Section * -ELFTargetAsmInfo::getSectionForMergeableConstant(SectionKind Kind) const { - return SelectSectionForGlobal(0, Kind); -} - /// getFlagsForNamedSection - If this target wants to be able to infer /// section flags based on the name of the section specified for a global /// variable, it can implement this. @@ -148,24 +74,6 @@ SectionKind::Kind ELFTargetAsmInfo::getKindForNamedSection(const char *Name, return K; } -const char * -ELFTargetAsmInfo::getSectionPrefixForUniqueGlobal(SectionKind Kind) const{ - if (Kind.isText()) return ".gnu.linkonce.t."; - if (Kind.isReadOnly()) return ".gnu.linkonce.r."; - - if (Kind.isThreadData()) return ".gnu.linkonce.td."; - if (Kind.isThreadBSS()) return ".gnu.linkonce.tb."; - - if (Kind.isBSS()) return ".gnu.linkonce.b."; - if (Kind.isDataNoRel()) return ".gnu.linkonce.d."; - if (Kind.isDataRelLocal()) return ".gnu.linkonce.d.rel.local."; - if (Kind.isDataRel()) return ".gnu.linkonce.d.rel."; - if (Kind.isReadOnlyWithRelLocal()) return ".gnu.linkonce.d.rel.ro.local."; - - assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); - return ".gnu.linkonce.d.rel.ro."; -} - void ELFTargetAsmInfo::getSectionFlagsAsString(SectionKind Kind, SmallVectorImpl<char> &Str) const { @@ -219,3 +127,108 @@ void ELFTargetAsmInfo::getSectionFlagsAsString(SectionKind Kind, Str.push_back('6'); } } + + + +//===----------------------------------------------------------------------===// +// Move to AsmPrinter (mangler access). +//===----------------------------------------------------------------------===// + +#include "llvm/DerivedTypes.h" +#include "llvm/GlobalVariable.h" +#include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/ADT/StringExtras.h" + +static const char *getSectionPrefixForUniqueGlobal(SectionKind Kind) { + if (Kind.isText()) return ".gnu.linkonce.t."; + if (Kind.isReadOnly()) return ".gnu.linkonce.r."; + + if (Kind.isThreadData()) return ".gnu.linkonce.td."; + if (Kind.isThreadBSS()) return ".gnu.linkonce.tb."; + + if (Kind.isBSS()) return ".gnu.linkonce.b."; + if (Kind.isDataNoRel()) return ".gnu.linkonce.d."; + if (Kind.isDataRelLocal()) return ".gnu.linkonce.d.rel.local."; + if (Kind.isDataRel()) return ".gnu.linkonce.d.rel."; + if (Kind.isReadOnlyWithRelLocal()) return ".gnu.linkonce.d.rel.ro.local."; + + assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); + return ".gnu.linkonce.d.rel.ro."; +} + +const Section* +ELFTargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV, + SectionKind Kind) const { + + // If this global is linkonce/weak and the target handles this by emitting it + // into a 'uniqued' section name, create and return the section now. + if (Kind.isWeak()) { + const char *Prefix = getSectionPrefixForUniqueGlobal(Kind); + // FIXME: Use mangler interface (PR4584). + std::string Name = Prefix+GV->getNameStr(); + return getOrCreateSection(Name.c_str(), false, Kind.getKind()); + } + + if (Kind.isText()) return TextSection; + if (Kind.isMergeableCString()) { + const TargetData *TD = TM.getTargetData(); + Constant *C = cast<GlobalVariable>(GV)->getInitializer(); + const Type *Ty = cast<ArrayType>(C->getType())->getElementType(); + + unsigned Size = TD->getTypeAllocSize(Ty); + if (Size <= 16) { + assert(getCStringSection() && "Should have string section prefix"); + + // We also need alignment here. + // FIXME: this is getting the alignment of the character, not the + // alignment of the string!! + unsigned Align = TD->getPrefTypeAlignment(Ty); + if (Align < Size) + Align = Size; + + std::string Name = getCStringSection() + utostr(Size) + '.' + + utostr(Align); + return getOrCreateSection(Name.c_str(), false, + SectionKind::MergeableCString); + } + + return getReadOnlySection(); + } + + if (Kind.isMergeableConst()) { + if (Kind.isMergeableConst4()) + return MergeableConst4Section; + if (Kind.isMergeableConst8()) + return MergeableConst8Section; + if (Kind.isMergeableConst16()) + return MergeableConst16Section; + return ReadOnlySection; // .const + } + + if (Kind.isReadOnly()) return getReadOnlySection(); + + + if (Kind.isThreadData()) return TLSDataSection; + if (Kind.isThreadBSS()) return TLSBSSSection; + + if (Kind.isBSS()) return getBSSSection_(); + + + if (Kind.isDataNoRel()) return DataSection; + if (Kind.isDataRelLocal()) return DataRelLocalSection; + if (Kind.isDataRel()) return DataRelSection; + if (Kind.isReadOnlyWithRelLocal()) return DataRelROLocalSection; + + assert(Kind.isReadOnlyWithRel() && "Unknown section kind"); + return DataRelROSection; +} + +/// getSectionForMergeableConstant - Given a Mergeable constant with the +/// specified size and relocation information, return a section that it +/// should be placed in. +const Section * +ELFTargetAsmInfo::getSectionForMergeableConstant(SectionKind Kind) const { + return SelectSectionForGlobal(0, Kind); +} + |