X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FMC%2FMCSectionELF.cpp;h=09eb3e7829582daf1b1749b492a9f87c8c430144;hb=9e0e56462d1e350290654e880f153d955d35e594;hp=96f8429ad9235371af9c19f13764aabed37b8002;hpb=af76e592c7f9deff0e55c13dbb4a34f07f1c7f64;p=oota-llvm.git diff --git a/lib/MC/MCSectionELF.cpp b/lib/MC/MCSectionELF.cpp index 96f8429ad92..09eb3e78295 100644 --- a/lib/MC/MCSectionELF.cpp +++ b/lib/MC/MCSectionELF.cpp @@ -8,131 +8,162 @@ //===----------------------------------------------------------------------===// #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" -#include "llvm/MC/MCAsmInfo.h" using namespace llvm; -MCSectionELF *MCSectionELF:: -Create(const StringRef &Section, unsigned Type, unsigned Flags, - SectionKind K, bool isExplicit, MCContext &Ctx) { - return new (Ctx) MCSectionELF(Section, Type, Flags, K, isExplicit); -} +MCSectionELF::~MCSectionELF() {} // anchor. // ShouldOmitSectionDirective - Decides whether a '.section' directive // should be printed before the section name -bool MCSectionELF::ShouldOmitSectionDirective(const char *Name, - const MCAsmInfo &TAI) const { - +bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name, + const MCAsmInfo &MAI) const { + // FIXME: Does .section .bss/.data/.text work everywhere?? - if (strcmp(Name, ".text") == 0 || - strcmp(Name, ".data") == 0 || - (strcmp(Name, ".bss") == 0 && - !TAI.usesELFSectionDirectiveForBSS())) + if (Name == ".text" || Name == ".data" || + (Name == ".bss" && !MAI.usesELFSectionDirectiveForBSS())) return true; return false; } -// ShouldPrintSectionType - Only prints the section type if supported -bool MCSectionELF::ShouldPrintSectionType(unsigned Ty) const { - - if (IsExplicit && !(Ty == SHT_NOBITS || Ty == SHT_PROGBITS)) - return false; - - return true; +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 &TAI, - raw_ostream &OS) const { - - if (ShouldOmitSectionDirective(SectionName.c_str(), TAI)) { - OS << '\t' << getSectionName() << '\n'; +void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, + raw_ostream &OS, + const MCExpr *Subsection) const { + + if (ShouldOmitSectionDirective(SectionName, MAI)) { + 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 (TAI.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"; - } else { - OS << ",\""; - if (Flags & MCSectionELF::SHF_ALLOC) - OS << 'a'; - if (Flags & MCSectionELF::SHF_EXECINSTR) - OS << 'x'; - if (Flags & MCSectionELF::SHF_WRITE) - OS << 'w'; - if (Flags & MCSectionELF::SHF_MERGE) - OS << 'M'; - if (Flags & MCSectionELF::SHF_STRINGS) - OS << 'S'; - if (Flags & MCSectionELF::SHF_TLS) - OS << 'T'; - - // If there are target-specific flags, print them. - if (Flags & ~MCSectionELF::TARGET_INDEP_SHF) - PrintTargetSpecificSectionFlags(TAI, OS); - - OS << '"'; - - if (ShouldPrintSectionType(Type)) { - OS << ','; - - // If comment string is '@', e.g. as on ARM - use '%' instead - if (TAI.getCommentString()[0] == '@') - OS << '%'; - else - OS << '@'; - - if (Type == MCSectionELF::SHT_INIT_ARRAY) - OS << "init_array"; - else if (Type == MCSectionELF::SHT_FINI_ARRAY) - OS << "fini_array"; - else if (Type == MCSectionELF::SHT_PREINIT_ARRAY) - OS << "preinit_array"; - else if (Type == MCSectionELF::SHT_NOBITS) - OS << "nobits"; - else if (Type == MCSectionELF::SHT_PROGBITS) - OS << "progbits"; - - if (getKind().isMergeable1ByteCString()) { - OS << ",1"; - } else if (getKind().isMergeable2ByteCString()) { - OS << ",2"; - } else if (getKind().isMergeable4ByteCString() || - getKind().isMergeableConst4()) { - OS << ",4"; - } else if (getKind().isMergeableConst8()) { - OS << ",8"; - } else if (getKind().isMergeableConst16()) { - OS << ",16"; - } - } + OS << '\n'; + return; + } + + OS << ",\""; + if (Flags & ELF::SHF_ALLOC) + OS << 'a'; + if (Flags & ELF::SHF_EXCLUDE) + OS << 'e'; + if (Flags & ELF::SHF_EXECINSTR) + OS << 'x'; + if (Flags & ELF::SHF_GROUP) + OS << 'G'; + if (Flags & ELF::SHF_WRITE) + OS << 'w'; + if (Flags & ELF::SHF_MERGE) + OS << 'M'; + if (Flags & ELF::SHF_STRINGS) + OS << 'S'; + if (Flags & ELF::SHF_TLS) + OS << 'T'; + + // If there are target-specific flags, print them. + if (Flags & ELF::XCORE_SHF_CP_SECTION) + OS << 'c'; + if (Flags & ELF::XCORE_SHF_DP_SECTION) + OS << 'd'; + + OS << '"'; + + OS << ','; + + // If comment string is '@', e.g. as on ARM - use '%' instead + if (MAI.getCommentString()[0] == '@') + OS << '%'; + else + OS << '@'; + + if (Type == ELF::SHT_INIT_ARRAY) + OS << "init_array"; + else if (Type == ELF::SHT_FINI_ARRAY) + OS << "fini_array"; + else if (Type == ELF::SHT_PREINIT_ARRAY) + OS << "preinit_array"; + else if (Type == ELF::SHT_NOBITS) + OS << "nobits"; + else if (Type == ELF::SHT_NOTE) + OS << "note"; + else if (Type == ELF::SHT_PROGBITS) + OS << "progbits"; + + if (EntrySize) { + assert(Flags & ELF::SHF_MERGE); + OS << "," << EntrySize; + } + + if (Flags & ELF::SHF_GROUP) { + OS << ","; + printName(OS, Group->getName()); + OS << ",comdat"; } - OS << '\n'; -} -// 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 (strncmp(SectionName.c_str(), ".gnu.linkonce.", 14) == 0) - return true; + if (Subsection) + OS << "\t.subsection\t" << *Subsection << '\n'; +} - return false; +bool MCSectionELF::UseCodeAlign() const { + return getFlags() & ELF::SHF_EXECINSTR; } +bool MCSectionELF::isVirtualSection() const { + return getType() == ELF::SHT_NOBITS; +} +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; +}