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
17using namespace llvm;
18
19MCSectionELF::~MCSectionELF() {} // anchor.
20
21// ShouldOmitSectionDirective - Decides whether a '.section' directive
22// should be printed before the section name
23bool 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
34void 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
134bool MCSectionELF::UseCodeAlign() const {
135  return getFlags() & ELF::SHF_EXECINSTR;
136}
137
138bool MCSectionELF::isVirtualSection() const {
139  return getType() == ELF::SHT_NOBITS;
140}
141
142unsigned 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