X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FMC%2FMCSectionELF.cpp;h=3cd84538425db0cc3970027cdd44265aa3357551;hp=a53489790d28c3143149c4292803fbe30b7b3a4d;hb=e93f977e8d84407de9aec402473487737ad1339b;hpb=98976610d2c8067efe04042f17486a4b6c746b31 diff --git a/lib/MC/MCSectionELF.cpp b/lib/MC/MCSectionELF.cpp index a53489790d2..3cd84538425 100644 --- a/lib/MC/MCSectionELF.cpp +++ b/lib/MC/MCSectionELF.cpp @@ -10,17 +10,23 @@ #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" +#include "llvm/MC/MCExpr.h" #include "llvm/MC/MCSymbol.h" +#include "llvm/Support/ELF.h" #include "llvm/Support/raw_ostream.h" + using namespace llvm; MCSectionELF::~MCSectionELF() {} // anchor. -// ShouldOmitSectionDirective - Decides whether a '.section' directive -// should be printed before the section name +// Decides whether a '.section' directive +// should be printed before the section name. bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name, const MCAsmInfo &MAI) const { - + + if (isUnique()) + return false; + // FIXME: Does .section .bss/.data/.text work everywhere?? if (Name == ".text" || Name == ".data" || (Name == ".bss" && !MAI.usesELFSectionDirectiveForBSS())) @@ -29,51 +35,85 @@ bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name, return false; } +static void printName(raw_ostream &OS, StringRef Name) { + if (Name.find_first_not_of("0123456789_." + "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == Name.npos) { + OS << Name; + return; + } + OS << '"'; + for (const char *B = Name.begin(), *E = Name.end(); B < E; ++B) { + if (*B == '"') // Unquoted " + OS << "\\\""; + else if (*B != '\\') // Neither " or backslash + OS << *B; + else if (B + 1 == E) // Trailing backslash + OS << "\\\\"; + else { + OS << B[0] << B[1]; // Quoted character + ++B; + } + } + OS << '"'; +} + void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, - raw_ostream &OS) const { - + raw_ostream &OS, + const MCExpr *Subsection) const { + if (ShouldOmitSectionDirective(SectionName, MAI)) { - OS << '\t' << getSectionName() << '\n'; + OS << '\t' << getSectionName(); + if (Subsection) + OS << '\t' << *Subsection; + OS << '\n'; return; } - OS << "\t.section\t" << getSectionName(); - + OS << "\t.section\t"; + printName(OS, getSectionName()); + // Handle the weird solaris syntax if desired. - if (MAI.usesSunStyleELFSectionSwitchSyntax() && - !(Flags & MCSectionELF::SHF_MERGE)) { - if (Flags & MCSectionELF::SHF_ALLOC) + if (MAI.usesSunStyleELFSectionSwitchSyntax() && + !(Flags & ELF::SHF_MERGE)) { + if (Flags & ELF::SHF_ALLOC) OS << ",#alloc"; - if (Flags & MCSectionELF::SHF_EXECINSTR) + if (Flags & ELF::SHF_EXECINSTR) OS << ",#execinstr"; - if (Flags & MCSectionELF::SHF_WRITE) + if (Flags & ELF::SHF_WRITE) OS << ",#write"; - if (Flags & MCSectionELF::SHF_TLS) + if (Flags & ELF::SHF_EXCLUDE) + OS << ",#exclude"; + if (Flags & ELF::SHF_TLS) OS << ",#tls"; OS << '\n'; return; } - + OS << ",\""; - if (Flags & MCSectionELF::SHF_ALLOC) + if (Flags & ELF::SHF_ALLOC) OS << 'a'; - if (Flags & MCSectionELF::SHF_EXECINSTR) + if (Flags & ELF::SHF_EXCLUDE) + OS << 'e'; + if (Flags & ELF::SHF_EXECINSTR) OS << 'x'; - if (Flags & MCSectionELF::SHF_WRITE) + if (Flags & ELF::SHF_GROUP) + OS << 'G'; + if (Flags & ELF::SHF_WRITE) OS << 'w'; - if (Flags & MCSectionELF::SHF_MERGE) + if (Flags & ELF::SHF_MERGE) OS << 'M'; - if (Flags & MCSectionELF::SHF_STRINGS) + if (Flags & ELF::SHF_STRINGS) OS << 'S'; - if (Flags & MCSectionELF::SHF_TLS) + if (Flags & ELF::SHF_TLS) OS << 'T'; - + // If there are target-specific flags, print them. - if (Flags & MCSectionELF::XCORE_SHF_CP_SECTION) + if (Flags & ELF::XCORE_SHF_CP_SECTION) OS << 'c'; - if (Flags & MCSectionELF::XCORE_SHF_DP_SECTION) + if (Flags & ELF::XCORE_SHF_DP_SECTION) OS << 'd'; - + OS << '"'; OS << ','; @@ -84,52 +124,43 @@ void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, else OS << '@'; - if (Type == MCSectionELF::SHT_INIT_ARRAY) + if (Type == ELF::SHT_INIT_ARRAY) OS << "init_array"; - else if (Type == MCSectionELF::SHT_FINI_ARRAY) + else if (Type == ELF::SHT_FINI_ARRAY) OS << "fini_array"; - else if (Type == MCSectionELF::SHT_PREINIT_ARRAY) + else if (Type == ELF::SHT_PREINIT_ARRAY) OS << "preinit_array"; - else if (Type == MCSectionELF::SHT_NOBITS) + else if (Type == ELF::SHT_NOBITS) OS << "nobits"; - else if (Type == MCSectionELF::SHT_NOTE) + else if (Type == ELF::SHT_NOTE) OS << "note"; - else if (Type == MCSectionELF::SHT_PROGBITS) + else if (Type == ELF::SHT_PROGBITS) OS << "progbits"; if (EntrySize) { - assert(Flags & MCSectionELF::SHF_MERGE); + assert(Flags & ELF::SHF_MERGE); OS << "," << EntrySize; } + if (Flags & ELF::SHF_GROUP) { + OS << ","; + printName(OS, Group->getName()); + OS << ",comdat"; + } + + if (isUnique()) + OS << ",unique," << UniqueID; + OS << '\n'; + + if (Subsection) + OS << "\t.subsection\t" << *Subsection << '\n'; } bool MCSectionELF::UseCodeAlign() const { - return getFlags() & MCSectionELF::SHF_EXECINSTR; + return getFlags() & ELF::SHF_EXECINSTR; } bool MCSectionELF::isVirtualSection() const { - return getType() == MCSectionELF::SHT_NOBITS; -} - -// HasCommonSymbols - True if this section holds common symbols, this is -// indicated on the ELF object file by a symbol with SHN_COMMON section -// header index. -bool MCSectionELF::HasCommonSymbols() const { - - if (StringRef(SectionName).startswith(".gnu.linkonce.")) - return true; - - return false; -} - -unsigned MCSectionELF::DetermineEntrySize(SectionKind Kind) { - if (Kind.isMergeable1ByteCString()) return 1; - if (Kind.isMergeable2ByteCString()) return 2; - if (Kind.isMergeable4ByteCString()) return 4; - if (Kind.isMergeableConst4()) return 4; - if (Kind.isMergeableConst8()) return 8; - if (Kind.isMergeableConst16()) return 16; - return 0; + return getType() == ELF::SHT_NOBITS; }