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 // ShouldOmitSectionDirective - 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   // FIXME: Does .section .bss/.data/.text work everywhere??
     28   if (Name == ".text" || Name == ".data" ||
     29       (Name == ".bss" && !MAI.usesELFSectionDirectiveForBSS()))
     30     return true;
     31 
     32   return false;
     33 }
     34 
     35 static void printName(raw_ostream &OS, StringRef Name) {
     36   if (Name.find_first_not_of("0123456789_."
     37                              "abcdefghijklmnopqrstuvwxyz"
     38                              "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == Name.npos) {
     39     OS << Name;
     40     return;
     41   }
     42   OS << '"';
     43   for (const char *B = Name.begin(), *E = Name.end(); B < E; ++B) {
     44     if (*B == '"') // Unquoted "
     45       OS << "\\\"";
     46     else if (*B != '\\') // Neither " or backslash
     47       OS << *B;
     48     else if (B + 1 == E) // Trailing backslash
     49       OS << "\\\\";
     50     else {
     51       OS << B[0] << B[1]; // Quoted character
     52       ++B;
     53     }
     54   }
     55   OS << '"';
     56 }
     57 
     58 void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
     59                                         raw_ostream &OS,
     60                                         const MCExpr *Subsection) const {
     61 
     62   if (ShouldOmitSectionDirective(SectionName, MAI)) {
     63     OS << '\t' << getSectionName();
     64     if (Subsection)
     65       OS << '\t' << *Subsection;
     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 
    137   if (EntrySize) {
    138     assert(Flags & ELF::SHF_MERGE);
    139     OS << "," << EntrySize;
    140   }
    141 
    142   if (Flags & ELF::SHF_GROUP) {
    143     OS << ",";
    144     printName(OS, Group->getName());
    145     OS << ",comdat";
    146   }
    147   OS << '\n';
    148 
    149   if (Subsection)
    150     OS << "\t.subsection\t" << *Subsection << '\n';
    151 }
    152 
    153 bool MCSectionELF::UseCodeAlign() const {
    154   return getFlags() & ELF::SHF_EXECINSTR;
    155 }
    156 
    157 bool MCSectionELF::isVirtualSection() const {
    158   return getType() == ELF::SHT_NOBITS;
    159 }
    160 
    161 unsigned MCSectionELF::DetermineEntrySize(SectionKind Kind) {
    162   if (Kind.isMergeable1ByteCString()) return 1;
    163   if (Kind.isMergeable2ByteCString()) return 2;
    164   if (Kind.isMergeable4ByteCString()) return 4;
    165   if (Kind.isMergeableConst4())       return 4;
    166   if (Kind.isMergeableConst8())       return 8;
    167   if (Kind.isMergeableConst16())      return 16;
    168   return 0;
    169 }
    170