xref: /openbsd/gnu/llvm/llvm/lib/MC/MCSectionELF.cpp (revision d415bd75)
109467b48Spatrick //===- lib/MC/MCSectionELF.cpp - ELF Code Section Representation ----------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick 
909467b48Spatrick #include "llvm/MC/MCSectionELF.h"
1009467b48Spatrick #include "llvm/ADT/Triple.h"
1109467b48Spatrick #include "llvm/BinaryFormat/ELF.h"
1209467b48Spatrick #include "llvm/MC/MCAsmInfo.h"
1309467b48Spatrick #include "llvm/MC/MCExpr.h"
1409467b48Spatrick #include "llvm/Support/ErrorHandling.h"
1509467b48Spatrick #include "llvm/Support/raw_ostream.h"
1609467b48Spatrick #include <cassert>
1709467b48Spatrick 
1809467b48Spatrick using namespace llvm;
1909467b48Spatrick 
2009467b48Spatrick // Decides whether a '.section' directive
2109467b48Spatrick // should be printed before the section name.
shouldOmitSectionDirective(StringRef Name,const MCAsmInfo & MAI) const22*d415bd75Srobert bool MCSectionELF::shouldOmitSectionDirective(StringRef Name,
2309467b48Spatrick                                               const MCAsmInfo &MAI) const {
2409467b48Spatrick   if (isUnique())
2509467b48Spatrick     return false;
2609467b48Spatrick 
2709467b48Spatrick   return MAI.shouldOmitSectionDirective(Name);
2809467b48Spatrick }
2909467b48Spatrick 
printName(raw_ostream & OS,StringRef Name)3009467b48Spatrick static void printName(raw_ostream &OS, StringRef Name) {
3109467b48Spatrick   if (Name.find_first_not_of("0123456789_."
3209467b48Spatrick                              "abcdefghijklmnopqrstuvwxyz"
3309467b48Spatrick                              "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == Name.npos) {
3409467b48Spatrick     OS << Name;
3509467b48Spatrick     return;
3609467b48Spatrick   }
3709467b48Spatrick   OS << '"';
3809467b48Spatrick   for (const char *B = Name.begin(), *E = Name.end(); B < E; ++B) {
3909467b48Spatrick     if (*B == '"') // Unquoted "
4009467b48Spatrick       OS << "\\\"";
4109467b48Spatrick     else if (*B != '\\') // Neither " or backslash
4209467b48Spatrick       OS << *B;
4309467b48Spatrick     else if (B + 1 == E) // Trailing backslash
4409467b48Spatrick       OS << "\\\\";
4509467b48Spatrick     else {
4609467b48Spatrick       OS << B[0] << B[1]; // Quoted character
4709467b48Spatrick       ++B;
4809467b48Spatrick     }
4909467b48Spatrick   }
5009467b48Spatrick   OS << '"';
5109467b48Spatrick }
5209467b48Spatrick 
printSwitchToSection(const MCAsmInfo & MAI,const Triple & T,raw_ostream & OS,const MCExpr * Subsection) const53*d415bd75Srobert void MCSectionELF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
5409467b48Spatrick                                         raw_ostream &OS,
5509467b48Spatrick                                         const MCExpr *Subsection) const {
56*d415bd75Srobert   if (shouldOmitSectionDirective(getName(), MAI)) {
57097a140dSpatrick     OS << '\t' << getName();
5809467b48Spatrick     if (Subsection) {
5909467b48Spatrick       OS << '\t';
6009467b48Spatrick       Subsection->print(OS, &MAI);
6109467b48Spatrick     }
6209467b48Spatrick     OS << '\n';
6309467b48Spatrick     return;
6409467b48Spatrick   }
6509467b48Spatrick 
6609467b48Spatrick   OS << "\t.section\t";
67097a140dSpatrick   printName(OS, getName());
6809467b48Spatrick 
6909467b48Spatrick   // Handle the weird solaris syntax if desired.
7009467b48Spatrick   if (MAI.usesSunStyleELFSectionSwitchSyntax() &&
7109467b48Spatrick       !(Flags & ELF::SHF_MERGE)) {
7209467b48Spatrick     if (Flags & ELF::SHF_ALLOC)
7309467b48Spatrick       OS << ",#alloc";
7409467b48Spatrick     if (Flags & ELF::SHF_EXECINSTR)
7509467b48Spatrick       OS << ",#execinstr";
7609467b48Spatrick     if (Flags & ELF::SHF_WRITE)
7709467b48Spatrick       OS << ",#write";
7809467b48Spatrick     if (Flags & ELF::SHF_EXCLUDE)
7909467b48Spatrick       OS << ",#exclude";
8009467b48Spatrick     if (Flags & ELF::SHF_TLS)
8109467b48Spatrick       OS << ",#tls";
8209467b48Spatrick     OS << '\n';
8309467b48Spatrick     return;
8409467b48Spatrick   }
8509467b48Spatrick 
8609467b48Spatrick   OS << ",\"";
8709467b48Spatrick   if (Flags & ELF::SHF_ALLOC)
8809467b48Spatrick     OS << 'a';
8909467b48Spatrick   if (Flags & ELF::SHF_EXCLUDE)
9009467b48Spatrick     OS << 'e';
9109467b48Spatrick   if (Flags & ELF::SHF_EXECINSTR)
9209467b48Spatrick     OS << 'x';
9309467b48Spatrick   if (Flags & ELF::SHF_GROUP)
9409467b48Spatrick     OS << 'G';
9509467b48Spatrick   if (Flags & ELF::SHF_WRITE)
9609467b48Spatrick     OS << 'w';
9709467b48Spatrick   if (Flags & ELF::SHF_MERGE)
9809467b48Spatrick     OS << 'M';
9909467b48Spatrick   if (Flags & ELF::SHF_STRINGS)
10009467b48Spatrick     OS << 'S';
10109467b48Spatrick   if (Flags & ELF::SHF_TLS)
10209467b48Spatrick     OS << 'T';
10309467b48Spatrick   if (Flags & ELF::SHF_LINK_ORDER)
10409467b48Spatrick     OS << 'o';
10573471bf0Spatrick   if (Flags & ELF::SHF_GNU_RETAIN)
10673471bf0Spatrick     OS << 'R';
10709467b48Spatrick 
108*d415bd75Srobert   // If there are os-specific flags, print them.
109*d415bd75Srobert   if (T.isOSSolaris())
110*d415bd75Srobert     if (Flags & ELF::SHF_SUNW_NODISCARD)
111*d415bd75Srobert       OS << 'R';
112*d415bd75Srobert 
11309467b48Spatrick   // If there are target-specific flags, print them.
11409467b48Spatrick   Triple::ArchType Arch = T.getArch();
11509467b48Spatrick   if (Arch == Triple::xcore) {
11609467b48Spatrick     if (Flags & ELF::XCORE_SHF_CP_SECTION)
11709467b48Spatrick       OS << 'c';
11809467b48Spatrick     if (Flags & ELF::XCORE_SHF_DP_SECTION)
11909467b48Spatrick       OS << 'd';
12009467b48Spatrick   } else if (T.isARM() || T.isThumb()) {
12109467b48Spatrick     if (Flags & ELF::SHF_ARM_PURECODE)
12209467b48Spatrick       OS << 'y';
12309467b48Spatrick   } else if (Arch == Triple::hexagon) {
12409467b48Spatrick     if (Flags & ELF::SHF_HEX_GPREL)
12509467b48Spatrick       OS << 's';
12609467b48Spatrick   }
12709467b48Spatrick 
12809467b48Spatrick   OS << '"';
12909467b48Spatrick 
13009467b48Spatrick   OS << ',';
13109467b48Spatrick 
13209467b48Spatrick   // If comment string is '@', e.g. as on ARM - use '%' instead
13309467b48Spatrick   if (MAI.getCommentString()[0] == '@')
13409467b48Spatrick     OS << '%';
13509467b48Spatrick   else
13609467b48Spatrick     OS << '@';
13709467b48Spatrick 
13809467b48Spatrick   if (Type == ELF::SHT_INIT_ARRAY)
13909467b48Spatrick     OS << "init_array";
14009467b48Spatrick   else if (Type == ELF::SHT_FINI_ARRAY)
14109467b48Spatrick     OS << "fini_array";
14209467b48Spatrick   else if (Type == ELF::SHT_PREINIT_ARRAY)
14309467b48Spatrick     OS << "preinit_array";
14409467b48Spatrick   else if (Type == ELF::SHT_NOBITS)
14509467b48Spatrick     OS << "nobits";
14609467b48Spatrick   else if (Type == ELF::SHT_NOTE)
14709467b48Spatrick     OS << "note";
14809467b48Spatrick   else if (Type == ELF::SHT_PROGBITS)
14909467b48Spatrick     OS << "progbits";
15009467b48Spatrick   else if (Type == ELF::SHT_X86_64_UNWIND)
15109467b48Spatrick     OS << "unwind";
15209467b48Spatrick   else if (Type == ELF::SHT_MIPS_DWARF)
15309467b48Spatrick     // Print hex value of the flag while we do not have
15409467b48Spatrick     // any standard symbolic representation of the flag.
15509467b48Spatrick     OS << "0x7000001e";
15609467b48Spatrick   else if (Type == ELF::SHT_LLVM_ODRTAB)
15709467b48Spatrick     OS << "llvm_odrtab";
15809467b48Spatrick   else if (Type == ELF::SHT_LLVM_LINKER_OPTIONS)
15909467b48Spatrick     OS << "llvm_linker_options";
16009467b48Spatrick   else if (Type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE)
16109467b48Spatrick     OS << "llvm_call_graph_profile";
16209467b48Spatrick   else if (Type == ELF::SHT_LLVM_DEPENDENT_LIBRARIES)
16309467b48Spatrick     OS << "llvm_dependent_libraries";
16409467b48Spatrick   else if (Type == ELF::SHT_LLVM_SYMPART)
16509467b48Spatrick     OS << "llvm_sympart";
16673471bf0Spatrick   else if (Type == ELF::SHT_LLVM_BB_ADDR_MAP)
16773471bf0Spatrick     OS << "llvm_bb_addr_map";
168*d415bd75Srobert   else if (Type == ELF::SHT_LLVM_BB_ADDR_MAP_V0)
169*d415bd75Srobert     OS << "llvm_bb_addr_map_v0";
170*d415bd75Srobert   else if (Type == ELF::SHT_LLVM_OFFLOADING)
171*d415bd75Srobert     OS << "llvm_offloading";
17209467b48Spatrick   else
17309467b48Spatrick     report_fatal_error("unsupported type 0x" + Twine::utohexstr(Type) +
174097a140dSpatrick                        " for section " + getName());
17509467b48Spatrick 
17609467b48Spatrick   if (EntrySize) {
17709467b48Spatrick     assert(Flags & ELF::SHF_MERGE);
17809467b48Spatrick     OS << "," << EntrySize;
17909467b48Spatrick   }
18009467b48Spatrick 
18109467b48Spatrick   if (Flags & ELF::SHF_GROUP) {
18209467b48Spatrick     OS << ",";
18373471bf0Spatrick     printName(OS, Group.getPointer()->getName());
18473471bf0Spatrick     if (isComdat())
18509467b48Spatrick       OS << ",comdat";
18609467b48Spatrick   }
18709467b48Spatrick 
18809467b48Spatrick   if (Flags & ELF::SHF_LINK_ORDER) {
18909467b48Spatrick     OS << ",";
19073471bf0Spatrick     if (LinkedToSym)
191097a140dSpatrick       printName(OS, LinkedToSym->getName());
19273471bf0Spatrick     else
19373471bf0Spatrick       OS << '0';
19409467b48Spatrick   }
19509467b48Spatrick 
19609467b48Spatrick   if (isUnique())
19709467b48Spatrick     OS << ",unique," << UniqueID;
19809467b48Spatrick 
19909467b48Spatrick   OS << '\n';
20009467b48Spatrick 
20109467b48Spatrick   if (Subsection) {
20209467b48Spatrick     OS << "\t.subsection\t";
20309467b48Spatrick     Subsection->print(OS, &MAI);
20409467b48Spatrick     OS << '\n';
20509467b48Spatrick   }
20609467b48Spatrick }
20709467b48Spatrick 
useCodeAlign() const208*d415bd75Srobert bool MCSectionELF::useCodeAlign() const {
20909467b48Spatrick   return getFlags() & ELF::SHF_EXECINSTR;
21009467b48Spatrick }
21109467b48Spatrick 
isVirtualSection() const21209467b48Spatrick bool MCSectionELF::isVirtualSection() const {
21309467b48Spatrick   return getType() == ELF::SHT_NOBITS;
21409467b48Spatrick }
215097a140dSpatrick 
getVirtualSectionKind() const216097a140dSpatrick StringRef MCSectionELF::getVirtualSectionKind() const { return "SHT_NOBITS"; }
217