xref: /llvm-project/llvm/lib/MC/MCSectionELF.cpp (revision f0bab7875e78e01c149d12302dcc4b6d4c43e25c)
1 //===- lib/MC/MCSectionELF.cpp - ELF Code Section Representation ----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "llvm/MC/MCSectionELF.h"
10 #include "llvm/ADT/Triple.h"
11 #include "llvm/ADT/Twine.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 // 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   if (isUnique())
26     return false;
27 
28   return MAI.shouldOmitSectionDirective(Name);
29 }
30 
31 static void printName(raw_ostream &OS, StringRef Name) {
32   if (Name.find_first_not_of("0123456789_."
33                              "abcdefghijklmnopqrstuvwxyz"
34                              "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == Name.npos) {
35     OS << Name;
36     return;
37   }
38   OS << '"';
39   for (const char *B = Name.begin(), *E = Name.end(); B < E; ++B) {
40     if (*B == '"') // Unquoted "
41       OS << "\\\"";
42     else if (*B != '\\') // Neither " or backslash
43       OS << *B;
44     else if (B + 1 == E) // Trailing backslash
45       OS << "\\\\";
46     else {
47       OS << B[0] << B[1]; // Quoted character
48       ++B;
49     }
50   }
51   OS << '"';
52 }
53 
54 void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
55                                         raw_ostream &OS,
56                                         const MCExpr *Subsection) const {
57   if (ShouldOmitSectionDirective(getName(), MAI)) {
58     OS << '\t' << getName();
59     if (Subsection) {
60       OS << '\t';
61       Subsection->print(OS, &MAI);
62     }
63     OS << '\n';
64     return;
65   }
66 
67   OS << "\t.section\t";
68   printName(OS, getName());
69 
70   // Handle the weird solaris syntax if desired.
71   if (MAI.usesSunStyleELFSectionSwitchSyntax() &&
72       !(Flags & ELF::SHF_MERGE)) {
73     if (Flags & ELF::SHF_ALLOC)
74       OS << ",#alloc";
75     if (Flags & ELF::SHF_EXECINSTR)
76       OS << ",#execinstr";
77     if (Flags & ELF::SHF_WRITE)
78       OS << ",#write";
79     if (Flags & ELF::SHF_EXCLUDE)
80       OS << ",#exclude";
81     if (Flags & ELF::SHF_TLS)
82       OS << ",#tls";
83     OS << '\n';
84     return;
85   }
86 
87   OS << ",\"";
88   if (Flags & ELF::SHF_ALLOC)
89     OS << 'a';
90   if (Flags & ELF::SHF_EXCLUDE)
91     OS << 'e';
92   if (Flags & ELF::SHF_EXECINSTR)
93     OS << 'x';
94   if (Flags & ELF::SHF_GROUP)
95     OS << 'G';
96   if (Flags & ELF::SHF_WRITE)
97     OS << 'w';
98   if (Flags & ELF::SHF_MERGE)
99     OS << 'M';
100   if (Flags & ELF::SHF_STRINGS)
101     OS << 'S';
102   if (Flags & ELF::SHF_TLS)
103     OS << 'T';
104   if (Flags & ELF::SHF_LINK_ORDER)
105     OS << 'o';
106 
107   // If there are target-specific flags, print them.
108   Triple::ArchType Arch = T.getArch();
109   if (Arch == Triple::xcore) {
110     if (Flags & ELF::XCORE_SHF_CP_SECTION)
111       OS << 'c';
112     if (Flags & ELF::XCORE_SHF_DP_SECTION)
113       OS << 'd';
114   } else if (T.isARM() || T.isThumb()) {
115     if (Flags & ELF::SHF_ARM_PURECODE)
116       OS << 'y';
117   } else if (Arch == Triple::hexagon) {
118     if (Flags & ELF::SHF_HEX_GPREL)
119       OS << 's';
120   }
121 
122   OS << '"';
123 
124   OS << ',';
125 
126   // If comment string is '@', e.g. as on ARM - use '%' instead
127   if (MAI.getCommentString()[0] == '@')
128     OS << '%';
129   else
130     OS << '@';
131 
132   if (Type == ELF::SHT_INIT_ARRAY)
133     OS << "init_array";
134   else if (Type == ELF::SHT_FINI_ARRAY)
135     OS << "fini_array";
136   else if (Type == ELF::SHT_PREINIT_ARRAY)
137     OS << "preinit_array";
138   else if (Type == ELF::SHT_NOBITS)
139     OS << "nobits";
140   else if (Type == ELF::SHT_NOTE)
141     OS << "note";
142   else if (Type == ELF::SHT_PROGBITS)
143     OS << "progbits";
144   else if (Type == ELF::SHT_X86_64_UNWIND)
145     OS << "unwind";
146   else if (Type == ELF::SHT_MIPS_DWARF)
147     // Print hex value of the flag while we do not have
148     // any standard symbolic representation of the flag.
149     OS << "0x7000001e";
150   else if (Type == ELF::SHT_LLVM_ODRTAB)
151     OS << "llvm_odrtab";
152   else if (Type == ELF::SHT_LLVM_LINKER_OPTIONS)
153     OS << "llvm_linker_options";
154   else if (Type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE)
155     OS << "llvm_call_graph_profile";
156   else if (Type == ELF::SHT_LLVM_DEPENDENT_LIBRARIES)
157     OS << "llvm_dependent_libraries";
158   else if (Type == ELF::SHT_LLVM_SYMPART)
159     OS << "llvm_sympart";
160   else
161     report_fatal_error("unsupported type 0x" + Twine::utohexstr(Type) +
162                        " for section " + getName());
163 
164   if (EntrySize) {
165     assert(Flags & ELF::SHF_MERGE);
166     OS << "," << EntrySize;
167   }
168 
169   if (Flags & ELF::SHF_GROUP) {
170     OS << ",";
171     printName(OS, Group->getName());
172     OS << ",comdat";
173   }
174 
175   if (Flags & ELF::SHF_LINK_ORDER) {
176     assert(LinkedToSym);
177     OS << ",";
178     printName(OS, LinkedToSym->getName());
179   }
180 
181   if (isUnique())
182     OS << ",unique," << UniqueID;
183 
184   OS << '\n';
185 
186   if (Subsection) {
187     OS << "\t.subsection\t";
188     Subsection->print(OS, &MAI);
189     OS << '\n';
190   }
191 }
192 
193 bool MCSectionELF::UseCodeAlign() const {
194   return getFlags() & ELF::SHF_EXECINSTR;
195 }
196 
197 bool MCSectionELF::isVirtualSection() const {
198   return getType() == ELF::SHT_NOBITS;
199 }
200 
201 StringRef MCSectionELF::getVirtualSectionKind() const { return "SHT_NOBITS"; }
202