#include "llvm/Module.h"
#include "llvm/Type.h"
#include "llvm/Target/TargetAsmInfo.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Dwarf.h"
#include <cctype>
#include <cstring>
-
using namespace llvm;
-void TargetAsmInfo::fillDefaultValues() {
+TargetAsmInfo::TargetAsmInfo(const TargetMachine &tm)
+: TM(tm) {
BSSSection = "\t.bss";
BSSSection_ = 0;
ReadOnlySection = 0;
InlineAsmEnd = "#NO_APP";
AssemblerDialect = 0;
StringConstantPrefix = ".str";
+ AllowQuotesInName = false;
ZeroDirective = "\t.zero\t";
ZeroDirectiveSuffix = 0;
AsciiDirective = "\t.ascii\t";
SupportsDebugInformation = false;
SupportsExceptionHandling = false;
DwarfRequiresFrameSection = true;
- SupportsMacInfoSection = true;
+ DwarfUsesInlineInfoSection = false;
NonLocalEHFrameLabel = false;
GlobalEHDirective = 0;
SupportsWeakOmittedEHFrame = true;
DwarfFrameSection = ".debug_frame";
DwarfPubNamesSection = ".debug_pubnames";
DwarfPubTypesSection = ".debug_pubtypes";
+ DwarfDebugInlineSection = ".debug_inlined";
DwarfStrSection = ".debug_str";
DwarfLocSection = ".debug_loc";
DwarfARangesSection = ".debug_aranges";
DwarfRangesSection = ".debug_ranges";
- DwarfMacInfoSection = ".debug_macinfo";
+ DwarfMacroInfoSection = ".debug_macinfo";
DwarfEHFrameSection = ".eh_frame";
DwarfExceptionSection = ".gcc_except_table";
AsmTransCBE = 0;
DataSection = getUnnamedSection("\t.data", SectionFlags::Writeable);
}
-TargetAsmInfo::TargetAsmInfo(const TargetMachine &tm)
- : TM(tm) {
- fillDefaultValues();
-}
-
TargetAsmInfo::~TargetAsmInfo() {
}
return false;
}
+unsigned TargetAsmInfo::RelocBehaviour() const {
+ // By default - all relocations in PIC mode would force symbol to be
+ // placed in r/w section.
+ return (TM.getRelocationModel() != Reloc::Static ?
+ Reloc::LocalOrGlobal : Reloc::None);
+}
SectionKind::Kind
TargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const {
// check its initializer to decide, which section to output it into. Also
// note, there is no thread-local r/o section.
Constant *C = GVar->getInitializer();
- if (C->ContainsRelocations())
- return SectionKind::ROData;
- else {
+ if (C->ContainsRelocations(Reloc::LocalOrGlobal)) {
+ // Decide, whether it is still possible to put symbol into r/o section.
+ unsigned Reloc = RelocBehaviour();
+
+ // We already did a query for 'all' relocs, thus - early exits.
+ if (Reloc == Reloc::LocalOrGlobal)
+ return SectionKind::Data;
+ else if (Reloc == Reloc::None)
+ return SectionKind::ROData;
+ else {
+ // Ok, target wants something funny. Honour it.
+ return (C->ContainsRelocations(Reloc) ?
+ SectionKind::Data : SectionKind::ROData);
+ }
+ } else {
// Check, if initializer is a null-terminated string
if (isConstantString(C))
return SectionKind::RODataMergeStr;
}
}
- // Variable is not constant or thread-local - emit to generic data section.
+ // Variable either is not constant or thread-local - output to data section.
return (isThreadLocal ? SectionKind::ThreadData : SectionKind::Data);
}
Flags |= SectionFlags::TLS;
// FALLS THROUGH
case SectionKind::Data:
+ case SectionKind::DataRel:
+ case SectionKind::DataRelLocal:
+ case SectionKind::DataRelRO:
+ case SectionKind::DataRelROLocal:
case SectionKind::BSS:
Flags |= SectionFlags::Writeable;
break;
assert(0 && "Unexpected section kind!");
}
- if (GV->mayBeOverridden())
+ if (GV->isWeakForLinker())
Flags |= SectionFlags::Linkonce;
}
TargetAsmInfo::SelectSectionForGlobal(const GlobalValue *GV) const {
SectionKind::Kind Kind = SectionKindForGlobal(GV);
- if (GV->mayBeOverridden()) {
+ if (GV->isWeakForLinker()) {
std::string Name = UniqueSectionForGlobal(GV, Kind);
unsigned Flags = SectionFlagsForGlobal(GV, Name.c_str());
return getNamedSection(Name.c_str(), Flags);
return ".gnu.linkonce.t." + GV->getName();
case SectionKind::Data:
return ".gnu.linkonce.d." + GV->getName();
+ case SectionKind::DataRel:
+ return ".gnu.linkonce.d.rel" + GV->getName();
+ case SectionKind::DataRelLocal:
+ return ".gnu.linkonce.d.rel.local" + GV->getName();
+ case SectionKind::DataRelRO:
+ return ".gnu.linkonce.d.rel.ro" + GV->getName();
+ case SectionKind::DataRelROLocal:
+ return ".gnu.linkonce.d.rel.ro.local" + GV->getName();
case SectionKind::SmallData:
return ".gnu.linkonce.s." + GV->getName();
case SectionKind::BSS: