Line data Source code
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/ADT/Triple.h"
12 : #include "llvm/BinaryFormat/ELF.h"
13 : #include "llvm/MC/MCAsmInfo.h"
14 : #include "llvm/MC/MCExpr.h"
15 : #include "llvm/Support/ErrorHandling.h"
16 : #include "llvm/Support/raw_ostream.h"
17 : #include <cassert>
18 :
19 : using namespace llvm;
20 :
21 : MCSectionELF::~MCSectionELF() = default; // anchor.
22 :
23 : // Decides whether a '.section' directive
24 : // should be printed before the section name.
25 149302 : bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name,
26 : const MCAsmInfo &MAI) const {
27 149302 : if (isUnique())
28 : return false;
29 :
30 149158 : return MAI.shouldOmitSectionDirective(Name);
31 : }
32 :
33 82533 : static void printName(raw_ostream &OS, StringRef Name) {
34 82533 : if (Name.find_first_not_of("0123456789_."
35 : "abcdefghijklmnopqrstuvwxyz"
36 : "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == Name.npos) {
37 66620 : OS << Name;
38 66620 : return;
39 : }
40 : OS << '"';
41 255420 : for (const char *B = Name.begin(), *E = Name.end(); B < E; ++B) {
42 239507 : if (*B == '"') // Unquoted "
43 4 : OS << "\\\"";
44 239503 : else if (*B != '\\') // Neither " or backslash
45 : OS << *B;
46 1 : else if (B + 1 == E) // Trailing backslash
47 0 : OS << "\\\\";
48 : else {
49 1 : OS << B[0] << B[1]; // Quoted character
50 : ++B;
51 : }
52 : }
53 : OS << '"';
54 : }
55 :
56 149302 : void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
57 : raw_ostream &OS,
58 : const MCExpr *Subsection) const {
59 149302 : if (ShouldOmitSectionDirective(SectionName, MAI)) {
60 67078 : OS << '\t' << getSectionName();
61 67078 : if (Subsection) {
62 : OS << '\t';
63 0 : Subsection->print(OS, &MAI);
64 : }
65 : OS << '\n';
66 67078 : return;
67 : }
68 :
69 82224 : OS << "\t.section\t";
70 82224 : printName(OS, getSectionName());
71 :
72 : // Handle the weird solaris syntax if desired.
73 82224 : if (MAI.usesSunStyleELFSectionSwitchSyntax() &&
74 43152 : !(Flags & ELF::SHF_MERGE)) {
75 43073 : if (Flags & ELF::SHF_ALLOC)
76 73 : OS << ",#alloc";
77 43073 : if (Flags & ELF::SHF_EXECINSTR)
78 0 : OS << ",#execinstr";
79 43073 : if (Flags & ELF::SHF_WRITE)
80 27 : OS << ",#write";
81 43073 : if (Flags & ELF::SHF_EXCLUDE)
82 0 : OS << ",#exclude";
83 43073 : if (Flags & ELF::SHF_TLS)
84 6 : OS << ",#tls";
85 : OS << '\n';
86 43073 : return;
87 : }
88 :
89 39151 : OS << ",\"";
90 39151 : if (Flags & ELF::SHF_ALLOC)
91 : OS << 'a';
92 39151 : if (Flags & ELF::SHF_EXCLUDE)
93 : OS << 'e';
94 39151 : if (Flags & ELF::SHF_EXECINSTR)
95 : OS << 'x';
96 39151 : if (Flags & ELF::SHF_GROUP)
97 : OS << 'G';
98 39151 : if (Flags & ELF::SHF_WRITE)
99 : OS << 'w';
100 39151 : if (Flags & ELF::SHF_MERGE)
101 : OS << 'M';
102 39151 : if (Flags & ELF::SHF_STRINGS)
103 : OS << 'S';
104 39151 : if (Flags & ELF::SHF_TLS)
105 : OS << 'T';
106 39151 : if (Flags & ELF::SHF_LINK_ORDER)
107 : OS << 'o';
108 :
109 : // If there are target-specific flags, print them.
110 39151 : Triple::ArchType Arch = T.getArch();
111 39151 : if (Arch == Triple::xcore) {
112 139 : if (Flags & ELF::XCORE_SHF_CP_SECTION)
113 : OS << 'c';
114 139 : if (Flags & ELF::XCORE_SHF_DP_SECTION)
115 : OS << 'd';
116 : } else if (T.isARM() || T.isThumb()) {
117 2534 : if (Flags & ELF::SHF_ARM_PURECODE)
118 : OS << 'y';
119 : }
120 :
121 : OS << '"';
122 :
123 : OS << ',';
124 :
125 : // If comment string is '@', e.g. as on ARM - use '%' instead
126 39151 : if (MAI.getCommentString()[0] == '@')
127 : OS << '%';
128 : else
129 : OS << '@';
130 :
131 39151 : if (Type == ELF::SHT_INIT_ARRAY)
132 28 : OS << "init_array";
133 39123 : else if (Type == ELF::SHT_FINI_ARRAY)
134 3 : OS << "fini_array";
135 39120 : else if (Type == ELF::SHT_PREINIT_ARRAY)
136 1 : OS << "preinit_array";
137 39119 : else if (Type == ELF::SHT_NOBITS)
138 312 : OS << "nobits";
139 38807 : else if (Type == ELF::SHT_NOTE)
140 7 : OS << "note";
141 38800 : else if (Type == ELF::SHT_PROGBITS)
142 38711 : OS << "progbits";
143 89 : else if (Type == ELF::SHT_X86_64_UNWIND)
144 5 : OS << "unwind";
145 84 : else if (Type == ELF::SHT_MIPS_DWARF)
146 : // Print hex value of the flag while we do not have
147 : // any standard symbolic representation of the flag.
148 78 : OS << "0x7000001e";
149 6 : else if (Type == ELF::SHT_LLVM_ODRTAB)
150 1 : OS << "llvm_odrtab";
151 5 : else if (Type == ELF::SHT_LLVM_LINKER_OPTIONS)
152 4 : OS << "llvm_linker_options";
153 1 : else if (Type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE)
154 0 : OS << "llvm_call_graph_profile";
155 : else
156 2 : report_fatal_error("unsupported type 0x" + Twine::utohexstr(Type) +
157 1 : " for section " + getSectionName());
158 :
159 39150 : if (EntrySize) {
160 : assert(Flags & ELF::SHF_MERGE);
161 14230 : OS << "," << EntrySize;
162 : }
163 :
164 39150 : if (Flags & ELF::SHF_GROUP) {
165 181 : OS << ",";
166 362 : printName(OS, Group->getName());
167 181 : OS << ",comdat";
168 : }
169 :
170 39150 : if (Flags & ELF::SHF_LINK_ORDER) {
171 : assert(AssociatedSymbol);
172 128 : OS << ",";
173 256 : printName(OS, AssociatedSymbol->getName());
174 : }
175 :
176 39150 : if (isUnique())
177 144 : OS << ",unique," << UniqueID;
178 :
179 : OS << '\n';
180 :
181 39150 : if (Subsection) {
182 0 : OS << "\t.subsection\t";
183 0 : Subsection->print(OS, &MAI);
184 : OS << '\n';
185 : }
186 : }
187 :
188 2025 : bool MCSectionELF::UseCodeAlign() const {
189 2025 : return getFlags() & ELF::SHF_EXECINSTR;
190 : }
191 :
192 2082499 : bool MCSectionELF::isVirtualSection() const {
193 2082499 : return getType() == ELF::SHT_NOBITS;
194 : }
|