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