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 void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
     36                                         raw_ostream &OS,
     37                                         const MCExpr *Subsection) const {
     38 
     39   if (ShouldOmitSectionDirective(SectionName, MAI)) {
     40     OS << '\t' << getSectionName();
     41     if (Subsection)
     42       OS << '\t' << *Subsection;
     43     OS << '\n';
     44     return;
     45   }
     46 
     47   StringRef name = getSectionName();
     48   if (name.find_first_not_of("0123456789_."
     49                              "abcdefghijklmnopqrstuvwxyz"
     50                              "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == name.npos) {
     51     OS << "\t.section\t" << name;
     52   } else {
     53     OS << "\t.section\t\"";
     54     for (const char *b = name.begin(), *e = name.end(); b < e; ++b) {
     55       if (*b == '"') // Unquoted "
     56         OS << "\\\"";
     57       else if (*b != '\\') // Neither " or backslash
     58         OS << *b;
     59       else if (b + 1 == e) // Trailing backslash
     60         OS << "\\\\";
     61       else {
     62         OS << b[0] << b[1]; // Quoted character
     63         ++b;
     64       }
     65     }
     66     OS << '"';
     67   }
     68 
     69   // Handle the weird solaris syntax if desired.
     70   if (MAI.usesSunStyleELFSectionSwitchSyntax() &&
     71       !(Flags & ELF::SHF_MERGE)) {
     72     if (Flags & ELF::SHF_ALLOC)
     73       OS << ",#alloc";
     74     if (Flags & ELF::SHF_EXECINSTR)
     75       OS << ",#execinstr";
     76     if (Flags & ELF::SHF_WRITE)
     77       OS << ",#write";
     78     if (Flags & ELF::SHF_TLS)
     79       OS << ",#tls";
     80     OS << '\n';
     81     return;
     82   }
     83 
     84   OS << ",\"";
     85   if (Flags & ELF::SHF_ALLOC)
     86     OS << 'a';
     87   if (Flags & ELF::SHF_EXECINSTR)
     88     OS << 'x';
     89   if (Flags & ELF::SHF_GROUP)
     90     OS << 'G';
     91   if (Flags & ELF::SHF_WRITE)
     92     OS << 'w';
     93   if (Flags & ELF::SHF_MERGE)
     94     OS << 'M';
     95   if (Flags & ELF::SHF_STRINGS)
     96     OS << 'S';
     97   if (Flags & ELF::SHF_TLS)
     98     OS << 'T';
     99 
    100   // If there are target-specific flags, print them.
    101   if (Flags & ELF::XCORE_SHF_CP_SECTION)
    102     OS << 'c';
    103   if (Flags & ELF::XCORE_SHF_DP_SECTION)
    104     OS << 'd';
    105 
    106   OS << '"';
    107 
    108   OS << ',';
    109 
    110   // If comment string is '@', e.g. as on ARM - use '%' instead
    111   if (MAI.getCommentString()[0] == '@')
    112     OS << '%';
    113   else
    114     OS << '@';
    115 
    116   if (Type == ELF::SHT_INIT_ARRAY)
    117     OS << "init_array";
    118   else if (Type == ELF::SHT_FINI_ARRAY)
    119     OS << "fini_array";
    120   else if (Type == ELF::SHT_PREINIT_ARRAY)
    121     OS << "preinit_array";
    122   else if (Type == ELF::SHT_NOBITS)
    123     OS << "nobits";
    124   else if (Type == ELF::SHT_NOTE)
    125     OS << "note";
    126   else if (Type == ELF::SHT_PROGBITS)
    127     OS << "progbits";
    128 
    129   if (EntrySize) {
    130     assert(Flags & ELF::SHF_MERGE);
    131     OS << "," << EntrySize;
    132   }
    133 
    134   if (Flags & ELF::SHF_GROUP)
    135     OS << "," << Group->getName() << ",comdat";
    136   OS << '\n';
    137 
    138   if (Subsection)
    139     OS << "\t.subsection\t" << *Subsection << '\n';
    140 }
    141 
    142 bool MCSectionELF::UseCodeAlign() const {
    143   return getFlags() & ELF::SHF_EXECINSTR;
    144 }
    145 
    146 bool MCSectionELF::isVirtualSection() const {
    147   return getType() == ELF::SHT_NOBITS;
    148 }
    149 
    150 unsigned MCSectionELF::DetermineEntrySize(SectionKind Kind) {
    151   if (Kind.isMergeable1ByteCString()) return 1;
    152   if (Kind.isMergeable2ByteCString()) return 2;
    153   if (Kind.isMergeable4ByteCString()) return 4;
    154   if (Kind.isMergeableConst4())       return 4;
    155   if (Kind.isMergeableConst8())       return 8;
    156   if (Kind.isMergeableConst16())      return 16;
    157   return 0;
    158 }
    159