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