xref: /freebsd/contrib/llvm-project/llvm/lib/MC/MCSectionELF.cpp (revision d54a7d337331d991e039e4f42f6b4dc64aedce08)
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/BinaryFormat/ELF.h"
12  #include "llvm/MC/MCAsmInfo.h"
13  #include "llvm/MC/MCExpr.h"
14  #include "llvm/Support/ErrorHandling.h"
15  #include "llvm/Support/raw_ostream.h"
16  #include <cassert>
17  
18  using namespace llvm;
19  
20  // Decides whether a '.section' directive
21  // should be printed before the section name.
22  bool MCSectionELF::shouldOmitSectionDirective(StringRef Name,
23                                                const MCAsmInfo &MAI) const {
24    if (isUnique())
25      return false;
26  
27    return MAI.shouldOmitSectionDirective(Name);
28  }
29  
30  static void printName(raw_ostream &OS, StringRef Name) {
31    if (Name.find_first_not_of("0123456789_."
32                               "abcdefghijklmnopqrstuvwxyz"
33                               "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == Name.npos) {
34      OS << Name;
35      return;
36    }
37    OS << '"';
38    for (const char *B = Name.begin(), *E = Name.end(); B < E; ++B) {
39      if (*B == '"') // Unquoted "
40        OS << "\\\"";
41      else if (*B != '\\') // Neither " or backslash
42        OS << *B;
43      else if (B + 1 == E) // Trailing backslash
44        OS << "\\\\";
45      else {
46        OS << B[0] << B[1]; // Quoted character
47        ++B;
48      }
49    }
50    OS << '"';
51  }
52  
53  void MCSectionELF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
54                                          raw_ostream &OS,
55                                          const MCExpr *Subsection) const {
56    if (shouldOmitSectionDirective(getName(), MAI)) {
57      OS << '\t' << getName();
58      if (Subsection) {
59        OS << '\t';
60        Subsection->print(OS, &MAI);
61      }
62      OS << '\n';
63      return;
64    }
65  
66    OS << "\t.section\t";
67    printName(OS, getName());
68  
69    // Handle the weird solaris syntax if desired.
70    if (MAI.usesSunStyleELFSectionSwitchSyntax() &&
71        !(Flags & ELF::SHF_MERGE)) {
72      if (Flags & ELF::SHF_ALLOC)
73        OS << ",#alloc";
74      if (Flags & ELF::SHF_EXECINSTR)
75        OS << ",#execinstr";
76      if (Flags & ELF::SHF_WRITE)
77        OS << ",#write";
78      if (Flags & ELF::SHF_EXCLUDE)
79        OS << ",#exclude";
80      if (Flags & ELF::SHF_TLS)
81        OS << ",#tls";
82      OS << '\n';
83      return;
84    }
85  
86    OS << ",\"";
87    if (Flags & ELF::SHF_ALLOC)
88      OS << 'a';
89    if (Flags & ELF::SHF_EXCLUDE)
90      OS << 'e';
91    if (Flags & ELF::SHF_EXECINSTR)
92      OS << 'x';
93    if (Flags & ELF::SHF_GROUP)
94      OS << 'G';
95    if (Flags & ELF::SHF_WRITE)
96      OS << 'w';
97    if (Flags & ELF::SHF_MERGE)
98      OS << 'M';
99    if (Flags & ELF::SHF_STRINGS)
100      OS << 'S';
101    if (Flags & ELF::SHF_TLS)
102      OS << 'T';
103    if (Flags & ELF::SHF_LINK_ORDER)
104      OS << 'o';
105    if (Flags & ELF::SHF_GNU_RETAIN)
106      OS << 'R';
107  
108    // If there are os-specific flags, print them.
109    if (T.isOSSolaris())
110      if (Flags & ELF::SHF_SUNW_NODISCARD)
111        OS << 'R';
112  
113    // If there are target-specific flags, print them.
114    Triple::ArchType Arch = T.getArch();
115    if (Arch == Triple::xcore) {
116      if (Flags & ELF::XCORE_SHF_CP_SECTION)
117        OS << 'c';
118      if (Flags & ELF::XCORE_SHF_DP_SECTION)
119        OS << 'd';
120    } else if (T.isARM() || T.isThumb()) {
121      if (Flags & ELF::SHF_ARM_PURECODE)
122        OS << 'y';
123    } else if (Arch == Triple::hexagon) {
124      if (Flags & ELF::SHF_HEX_GPREL)
125        OS << 's';
126    }
127  
128    OS << '"';
129  
130    OS << ',';
131  
132    // If comment string is '@', e.g. as on ARM - use '%' instead
133    if (MAI.getCommentString()[0] == '@')
134      OS << '%';
135    else
136      OS << '@';
137  
138    if (Type == ELF::SHT_INIT_ARRAY)
139      OS << "init_array";
140    else if (Type == ELF::SHT_FINI_ARRAY)
141      OS << "fini_array";
142    else if (Type == ELF::SHT_PREINIT_ARRAY)
143      OS << "preinit_array";
144    else if (Type == ELF::SHT_NOBITS)
145      OS << "nobits";
146    else if (Type == ELF::SHT_NOTE)
147      OS << "note";
148    else if (Type == ELF::SHT_PROGBITS)
149      OS << "progbits";
150    else if (Type == ELF::SHT_X86_64_UNWIND)
151      OS << "unwind";
152    else if (Type == ELF::SHT_MIPS_DWARF)
153      // Print hex value of the flag while we do not have
154      // any standard symbolic representation of the flag.
155      OS << "0x7000001e";
156    else if (Type == ELF::SHT_LLVM_ODRTAB)
157      OS << "llvm_odrtab";
158    else if (Type == ELF::SHT_LLVM_LINKER_OPTIONS)
159      OS << "llvm_linker_options";
160    else if (Type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE)
161      OS << "llvm_call_graph_profile";
162    else if (Type == ELF::SHT_LLVM_DEPENDENT_LIBRARIES)
163      OS << "llvm_dependent_libraries";
164    else if (Type == ELF::SHT_LLVM_SYMPART)
165      OS << "llvm_sympart";
166    else if (Type == ELF::SHT_LLVM_BB_ADDR_MAP)
167      OS << "llvm_bb_addr_map";
168    else if (Type == ELF::SHT_LLVM_BB_ADDR_MAP_V0)
169      OS << "llvm_bb_addr_map_v0";
170    else if (Type == ELF::SHT_LLVM_OFFLOADING)
171      OS << "llvm_offloading";
172    else
173      report_fatal_error("unsupported type 0x" + Twine::utohexstr(Type) +
174                         " for section " + getName());
175  
176    if (EntrySize) {
177      assert(Flags & ELF::SHF_MERGE);
178      OS << "," << EntrySize;
179    }
180  
181    if (Flags & ELF::SHF_GROUP) {
182      OS << ",";
183      printName(OS, Group.getPointer()->getName());
184      if (isComdat())
185        OS << ",comdat";
186    }
187  
188    if (Flags & ELF::SHF_LINK_ORDER) {
189      OS << ",";
190      if (LinkedToSym)
191        printName(OS, LinkedToSym->getName());
192      else
193        OS << '0';
194    }
195  
196    if (isUnique())
197      OS << ",unique," << UniqueID;
198  
199    OS << '\n';
200  
201    if (Subsection) {
202      OS << "\t.subsection\t";
203      Subsection->print(OS, &MAI);
204      OS << '\n';
205    }
206  }
207  
208  bool MCSectionELF::useCodeAlign() const {
209    return getFlags() & ELF::SHF_EXECINSTR;
210  }
211  
212  bool MCSectionELF::isVirtualSection() const {
213    return getType() == ELF::SHT_NOBITS;
214  }
215  
216  StringRef MCSectionELF::getVirtualSectionKind() const { return "SHT_NOBITS"; }
217