LLVM API Documentation

MCSectionELF.cpp
Go to the documentation of this file.
00001 //===- lib/MC/MCSectionELF.cpp - ELF Code Section Representation ----------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "llvm/MC/MCSectionELF.h"
00011 #include "llvm/MC/MCAsmInfo.h"
00012 #include "llvm/MC/MCContext.h"
00013 #include "llvm/MC/MCExpr.h"
00014 #include "llvm/MC/MCSymbol.h"
00015 #include "llvm/Support/ELF.h"
00016 #include "llvm/Support/raw_ostream.h"
00017 
00018 using namespace llvm;
00019 
00020 MCSectionELF::~MCSectionELF() {} // anchor.
00021 
00022 // ShouldOmitSectionDirective - Decides whether a '.section' directive
00023 // should be printed before the section name
00024 bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name,
00025                                               const MCAsmInfo &MAI) const {
00026 
00027   // FIXME: Does .section .bss/.data/.text work everywhere??
00028   if (Name == ".text" || Name == ".data" ||
00029       (Name == ".bss" && !MAI.usesELFSectionDirectiveForBSS()))
00030     return true;
00031 
00032   return false;
00033 }
00034 
00035 static void printName(raw_ostream &OS, StringRef Name) {
00036   if (Name.find_first_not_of("0123456789_."
00037                              "abcdefghijklmnopqrstuvwxyz"
00038                              "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == Name.npos) {
00039     OS << Name;
00040     return;
00041   }
00042   OS << '"';
00043   for (const char *B = Name.begin(), *E = Name.end(); B < E; ++B) {
00044     if (*B == '"') // Unquoted "
00045       OS << "\\\"";
00046     else if (*B != '\\') // Neither " or backslash
00047       OS << *B;
00048     else if (B + 1 == E) // Trailing backslash
00049       OS << "\\\\";
00050     else {
00051       OS << B[0] << B[1]; // Quoted character
00052       ++B;
00053     }
00054   }
00055   OS << '"';
00056 }
00057 
00058 void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
00059                                         raw_ostream &OS,
00060                                         const MCExpr *Subsection) const {
00061 
00062   if (ShouldOmitSectionDirective(SectionName, MAI)) {
00063     OS << '\t' << getSectionName();
00064     if (Subsection)
00065       OS << '\t' << *Subsection;
00066     OS << '\n';
00067     return;
00068   }
00069 
00070   OS << "\t.section\t";
00071   printName(OS, getSectionName());
00072 
00073   // Handle the weird solaris syntax if desired.
00074   if (MAI.usesSunStyleELFSectionSwitchSyntax() &&
00075       !(Flags & ELF::SHF_MERGE)) {
00076     if (Flags & ELF::SHF_ALLOC)
00077       OS << ",#alloc";
00078     if (Flags & ELF::SHF_EXECINSTR)
00079       OS << ",#execinstr";
00080     if (Flags & ELF::SHF_WRITE)
00081       OS << ",#write";
00082     if (Flags & ELF::SHF_EXCLUDE)
00083       OS << ",#exclude";
00084     if (Flags & ELF::SHF_TLS)
00085       OS << ",#tls";
00086     OS << '\n';
00087     return;
00088   }
00089 
00090   OS << ",\"";
00091   if (Flags & ELF::SHF_ALLOC)
00092     OS << 'a';
00093   if (Flags & ELF::SHF_EXCLUDE)
00094     OS << 'e';
00095   if (Flags & ELF::SHF_EXECINSTR)
00096     OS << 'x';
00097   if (Flags & ELF::SHF_GROUP)
00098     OS << 'G';
00099   if (Flags & ELF::SHF_WRITE)
00100     OS << 'w';
00101   if (Flags & ELF::SHF_MERGE)
00102     OS << 'M';
00103   if (Flags & ELF::SHF_STRINGS)
00104     OS << 'S';
00105   if (Flags & ELF::SHF_TLS)
00106     OS << 'T';
00107 
00108   // If there are target-specific flags, print them.
00109   if (Flags & ELF::XCORE_SHF_CP_SECTION)
00110     OS << 'c';
00111   if (Flags & ELF::XCORE_SHF_DP_SECTION)
00112     OS << 'd';
00113 
00114   OS << '"';
00115 
00116   OS << ',';
00117 
00118   // If comment string is '@', e.g. as on ARM - use '%' instead
00119   if (MAI.getCommentString()[0] == '@')
00120     OS << '%';
00121   else
00122     OS << '@';
00123 
00124   if (Type == ELF::SHT_INIT_ARRAY)
00125     OS << "init_array";
00126   else if (Type == ELF::SHT_FINI_ARRAY)
00127     OS << "fini_array";
00128   else if (Type == ELF::SHT_PREINIT_ARRAY)
00129     OS << "preinit_array";
00130   else if (Type == ELF::SHT_NOBITS)
00131     OS << "nobits";
00132   else if (Type == ELF::SHT_NOTE)
00133     OS << "note";
00134   else if (Type == ELF::SHT_PROGBITS)
00135     OS << "progbits";
00136 
00137   if (EntrySize) {
00138     assert(Flags & ELF::SHF_MERGE);
00139     OS << "," << EntrySize;
00140   }
00141 
00142   if (Flags & ELF::SHF_GROUP) {
00143     OS << ",";
00144     printName(OS, Group->getName());
00145     OS << ",comdat";
00146   }
00147   OS << '\n';
00148 
00149   if (Subsection)
00150     OS << "\t.subsection\t" << *Subsection << '\n';
00151 }
00152 
00153 bool MCSectionELF::UseCodeAlign() const {
00154   return getFlags() & ELF::SHF_EXECINSTR;
00155 }
00156 
00157 bool MCSectionELF::isVirtualSection() const {
00158   return getType() == ELF::SHT_NOBITS;
00159 }
00160 
00161 unsigned MCSectionELF::DetermineEntrySize(SectionKind Kind) {
00162   if (Kind.isMergeable1ByteCString()) return 1;
00163   if (Kind.isMergeable2ByteCString()) return 2;
00164   if (Kind.isMergeable4ByteCString()) return 4;
00165   if (Kind.isMergeableConst4())       return 4;
00166   if (Kind.isMergeableConst8())       return 8;
00167   if (Kind.isMergeableConst16())      return 16;
00168   return 0;
00169 }