-/// PreferredEHDataFormat - This hook allows the target to select data
-/// format used for encoding pointers in exception handling data. Reason is
-/// 0 for data, 1 for code labels, 2 for function pointers. Global is true
-/// if the symbol can be relocated.
-unsigned X86TargetAsmInfo::PreferredEHDataFormat(DwarfEncoding::Target Reason,
- bool Global) const {
- const X86Subtarget *Subtarget = &X86TM->getSubtarget<X86Subtarget>();
-
- switch (Subtarget->TargetType) {
- case X86Subtarget::isDarwin:
- if (Reason == DwarfEncoding::Functions && Global)
- return (DW_EH_PE_pcrel | DW_EH_PE_indirect | DW_EH_PE_sdata4);
- else if (Reason == DwarfEncoding::CodeLabels || !Global)
- return DW_EH_PE_pcrel;
- else
- return DW_EH_PE_absptr;
-
- case X86Subtarget::isELF:
- case X86Subtarget::isCygwin:
- case X86Subtarget::isMingw: {
- CodeModel::Model CM = X86TM->getCodeModel();
-
- if (X86TM->getRelocationModel() == Reloc::PIC_) {
- unsigned Format = 0;
-
- if (!Subtarget->is64Bit())
- // 32 bit targets always encode pointers as 4 bytes
- Format = DW_EH_PE_sdata4;
- else {
- // 64 bit targets encode pointers in 4 bytes iff:
- // - code model is small OR
- // - code model is medium and we're emitting externally visible symbols
- // or any code symbols
- if (CM == CodeModel::Small ||
- (CM == CodeModel::Medium && (Global ||
- Reason != DwarfEncoding::Data)))
- Format = DW_EH_PE_sdata4;
- else
- Format = DW_EH_PE_sdata8;
- }
-
- if (Global)
- Format |= DW_EH_PE_indirect;
-
- return (Format | DW_EH_PE_pcrel);
- } else {
- if (Subtarget->is64Bit() &&
- (CM == CodeModel::Small ||
- (CM == CodeModel::Medium && Reason != DwarfEncoding::Data)))
- return DW_EH_PE_udata4;
- else
- return DW_EH_PE_absptr;
- }
- }
-
- default:
- return TargetAsmInfo::PreferredEHDataFormat(Reason, Global);
- }
-}
-
-std::string X86TargetAsmInfo::UniqueSectionForGlobal(const GlobalValue* GV,
- SectionKind::Kind kind) const {
- const X86Subtarget *Subtarget = &X86TM->getSubtarget<X86Subtarget>();
-
- switch (Subtarget->TargetType) {
- case X86Subtarget::isDarwin:
- if (kind == SectionKind::Text)
- return "__TEXT,__textcoal_nt,coalesced,pure_instructions";
- else
- return "__DATA,__datacoal_nt,coalesced";
- case X86Subtarget::isCygwin:
- case X86Subtarget::isMingw:
- switch (kind) {
- case SectionKind::Text:
- return ".text$linkonce" + GV->getName();
- case SectionKind::Data:
- case SectionKind::BSS:
- case SectionKind::ThreadData:
- case SectionKind::ThreadBSS:
- return ".data$linkonce" + GV->getName();
- case SectionKind::ROData:
- case SectionKind::RODataMergeConst:
- case SectionKind::RODataMergeStr:
- return ".rdata$linkonce" + GV->getName();
- default:
- assert(0 && "Unknown section kind");
- }
- case X86Subtarget::isELF:
- return TargetAsmInfo::UniqueSectionForGlobal(GV, kind);
- default:
- return "";
- }
-}
-
-
-std::string X86TargetAsmInfo::SectionForGlobal(const GlobalValue *GV) const {
- SectionKind::Kind kind = SectionKindForGlobal(GV);
- unsigned flags = SectionFlagsForGlobal(GV, GV->getSection().c_str());
- std::string Name;
-
- // FIXME: Should we use some hashing based on section name and just check
- // flags?
- // FIXME: It seems, that Darwin uses much more sections.
-
- // Select section name
- if (GV->hasSection()) {
- // Honour section already set, if any
- Name = GV->getSection();
- } else {
- // Use default section depending on the 'type' of global
- if (const Function *F = dyn_cast<Function>(GV)) {
- switch (F->getLinkage()) {
- default: assert(0 && "Unknown linkage type!");
- case Function::InternalLinkage:
- case Function::DLLExportLinkage:
- case Function::ExternalLinkage:
- Name = TextSection;
- break;
- case Function::WeakLinkage:
- case Function::LinkOnceLinkage:
- Name = UniqueSectionForGlobal(F, kind);
- break;
- }
- } else if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV)) {
- if (GVar->hasCommonLinkage() ||
- GVar->hasLinkOnceLinkage() ||
- GVar->hasWeakLinkage())
- Name = UniqueSectionForGlobal(GVar, kind);
- else {
- switch (kind) {
- case SectionKind::Data:
- Name = DataSection;
- break;
- case SectionKind::BSS:
- Name = (BSSSection ? BSSSection : DataSection);
- break;
- case SectionKind::ROData:
- case SectionKind::RODataMergeStr:
- case SectionKind::RODataMergeConst:
- // FIXME: Temporary
- Name = DataSection;
- break;
- case SectionKind::ThreadData:
- Name = (TLSDataSection ? TLSDataSection : DataSection);
- break;
- case SectionKind::ThreadBSS:
- Name = (TLSBSSSection ? TLSBSSSection : DataSection);
- default:
- assert(0 && "Unsuported section kind for global");
- }
- }
- } else
- assert(0 && "Unsupported global");
- }
-
- Name += PrintSectionFlags(flags);
- return Name;
-}
-
-std::string X86TargetAsmInfo::PrintSectionFlags(unsigned flags) const {
- const X86Subtarget *Subtarget = &X86TM->getSubtarget<X86Subtarget>();
-
- std::string Flags = "";
-
- // Add all special flags, etc
- switch (Subtarget->TargetType) {
- case X86Subtarget::isELF:
- Flags += ",\"";
-
- if (!(flags & SectionFlags::Debug))
- Flags += 'a';
- if (flags & SectionFlags::Code)
- Flags += 'x';
- if (flags & SectionFlags::Writeable)
- Flags += 'w';
- if (flags & SectionFlags::Mergeable)
- Flags += 'M';
- if (flags & SectionFlags::Strings)
- Flags += 'S';
- if (flags & SectionFlags::TLS)
- Flags += 'T';
-
- Flags += "\"";
-
- // FIXME: There can be exceptions here
- if (flags & SectionFlags::BSS)
- Flags += ",@nobits";
- else
- Flags += ",@progbits";
-
- // FIXME: entity size for mergeable sections
- break;
- case X86Subtarget::isCygwin:
- case X86Subtarget::isMingw:
- Flags += ",\"";
-
- if (flags & SectionFlags::Code)
- Flags += 'x';
- if (flags & SectionFlags::Writeable)
- Flags += 'w';
-
- Flags += "\"";
-
- break;
- case X86Subtarget::isDarwin:
- // Darwin does not use any special flags
- default:
- break;
- }
-
- return Flags;
-}