Home | History | Annotate | Download | only in MC
      1 //===- lib/MC/MCSectionELF.cpp - ELF Code Section Representation ----------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "llvm/MC/MCSectionELF.h"
     11 #include "llvm/MC/MCAsmInfo.h"
     12 #include "llvm/MC/MCContext.h"
     13 #include "llvm/MC/MCExpr.h"
     14 #include "llvm/MC/MCSymbol.h"
     15 #include "llvm/Support/ELF.h"
     16 #include "llvm/Support/raw_ostream.h"
     17 
     18 using namespace llvm;
     19 
     20 MCSectionELF::~MCSectionELF() {} // anchor.
     21 
     22 // Decides whether a '.section' directive
     23 // should be printed before the section name.
     24 bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name,
     25                                               const MCAsmInfo &MAI) const {
     26 
     27   if (isUnique())
     28     return false;
     29 
     30   return MAI.shouldOmitSectionDirective(Name);
     31 }
     32 
     33 static void printName(raw_ostream &OS, StringRef Name) {
     34   if (Name.find_first_not_of("0123456789_."
     35                              "abcdefghijklmnopqrstuvwxyz"
     36                              "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == Name.npos) {
     37     OS << Name;
     38     return;
     39   }
     40   OS << '"';
     41   for (const char *B = Name.begin(), *E = Name.end(); B < E; ++B) {
     42     if (*B == '"') // Unquoted "
     43       OS << "\\\"";
     44     else if (*B != '\\') // Neither " or backslash
     45       OS << *B;
     46     else if (B + 1 == E) // Trailing backslash
     47       OS << "\\\\";
     48     else {
     49       OS << B[0] << B[1]; // Quoted character
     50       ++B;
     51     }
     52   }
     53   OS << '"';
     54 }
     55 
     56 void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
     57                                         raw_ostream &OS,
     58                                         const MCExpr *Subsection) const {
     59 
     60   if (ShouldOmitSectionDirective(SectionName, MAI)) {
     61     OS << '\t' << getSectionName();
     62     if (Subsection) {
     63       OS << '\t';
     64       Subsection->print(OS, &MAI);
     65     }
     66     OS << '\n';
     67     return;
     68   }
     69 
     70   OS << "\t.section\t";
     71   printName(OS, getSectionName());
     72 
     73   // Handle the weird solaris syntax if desired.
     74   if (MAI.usesSunStyleELFSectionSwitchSyntax() &&
     75       !(Flags & ELF::SHF_MERGE)) {
     76     if (Flags & ELF::SHF_ALLOC)
     77       OS << ",#alloc";
     78     if (Flags & ELF::SHF_EXECINSTR)
     79       OS << ",#execinstr";
     80     if (Flags & ELF::SHF_WRITE)
     81       OS << ",#write";
     82     if (Flags & ELF::SHF_EXCLUDE)
     83       OS << ",#exclude";
     84     if (Flags & ELF::SHF_TLS)
     85       OS << ",#tls";
     86     OS << '\n';
     87     return;
     88   }
     89 
     90   OS << ",\"";
     91   if (Flags & ELF::SHF_ALLOC)
     92     OS << 'a';
     93   if (Flags & ELF::SHF_EXCLUDE)
     94     OS << 'e';
     95   if (Flags & ELF::SHF_EXECINSTR)
     96     OS << 'x';
     97   if (Flags & ELF::SHF_GROUP)
     98     OS << 'G';
     99   if (Flags & ELF::SHF_WRITE)
    100     OS << 'w';
    101   if (Flags & ELF::SHF_MERGE)
    102     OS << 'M';
    103   if (Flags & ELF::SHF_STRINGS)
    104     OS << 'S';
    105   if (Flags & ELF::SHF_TLS)
    106     OS << 'T';
    107 
    108   // If there are target-specific flags, print them.
    109   if (Flags & ELF::XCORE_SHF_CP_SECTION)
    110     OS << 'c';
    111   if (Flags & ELF::XCORE_SHF_DP_SECTION)
    112     OS << 'd';
    113 
    114   OS << '"';
    115 
    116   OS << ',';
    117 
    118   // If comment string is '@', e.g. as on ARM - use '%' instead
    119   if (MAI.getCommentString()[0] == '@')
    120     OS << '%';
    121   else
    122     OS << '@';
    123 
    124   if (Type == ELF::SHT_INIT_ARRAY)
    125     OS << "init_array";
    126   else if (Type == ELF::SHT_FINI_ARRAY)
    127     OS << "fini_array";
    128   else if (Type == ELF::SHT_PREINIT_ARRAY)
    129     OS << "preinit_array";
    130   else if (Type == ELF::SHT_NOBITS)
    131     OS << "nobits";
    132   else if (Type == ELF::SHT_NOTE)
    133     OS << "note";
    134   else if (Type == ELF::SHT_PROGBITS)
    135     OS << "progbits";
    136   else if (Type == ELF::SHT_X86_64_UNWIND)
    137     OS << "unwind";
    138 
    139   if (EntrySize) {
    140     assert(Flags & ELF::SHF_MERGE);
    141     OS << "," << EntrySize;
    142   }
    143 
    144   if (Flags & ELF::SHF_GROUP) {
    145     OS << ",";
    146     printName(OS, Group->getName());
    147     OS << ",comdat";
    148   }
    149 
    150   if (isUnique())
    151     OS << ",unique," << UniqueID;
    152 
    153   OS << '\n';
    154 
    155   if (Subsection) {
    156     OS << "\t.subsection\t";
    157     Subsection->print(OS, &MAI);
    158     OS << '\n';
    159   }
    160 }
    161 
    162 bool MCSectionELF::UseCodeAlign() const {
    163   return getFlags() & ELF::SHF_EXECINSTR;
    164 }
    165 
    166 bool MCSectionELF::isVirtualSection() const {
    167   return getType() == ELF::SHT_NOBITS;
    168 }
    169