236 lines · cpp
1//===- MCAsmInfoELF.cpp - ELF asm properties ------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines target asm properties related what form asm statements10// should take in general on ELF-based targets11//12//===----------------------------------------------------------------------===//13 14#include "llvm/MC/MCAsmInfoELF.h"15#include "llvm/ADT/Twine.h"16#include "llvm/BinaryFormat/ELF.h"17#include "llvm/MC/MCAsmInfo.h"18#include "llvm/MC/MCContext.h"19#include "llvm/MC/MCExpr.h"20#include "llvm/MC/MCSectionELF.h"21#include "llvm/Support/ErrorHandling.h"22#include "llvm/Support/raw_ostream.h"23#include "llvm/TargetParser/Triple.h"24#include <cassert>25 26using namespace llvm;27 28void MCAsmInfoELF::anchor() {}29 30MCSection *MCAsmInfoELF::getStackSection(MCContext &Ctx, bool Exec) const {31 // Solaris doesn't know/doesn't care about .note.GNU-stack sections, so32 // don't emit them.33 if (Ctx.getTargetTriple().isOSSolaris())34 return nullptr;35 return Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS,36 Exec ? ELF::SHF_EXECINSTR : 0U);37}38 39bool MCAsmInfoELF::useCodeAlign(const MCSection &Sec) const {40 return static_cast<const MCSectionELF &>(Sec).getFlags() & ELF::SHF_EXECINSTR;41}42 43MCAsmInfoELF::MCAsmInfoELF() {44 HasIdentDirective = true;45 WeakRefDirective = "\t.weak\t";46 PrivateGlobalPrefix = ".L";47 PrivateLabelPrefix = ".L";48}49 50static void printName(raw_ostream &OS, StringRef Name) {51 if (Name.find_first_not_of("0123456789_."52 "abcdefghijklmnopqrstuvwxyz"53 "ABCDEFGHIJKLMNOPQRSTUVWXYZ") == Name.npos) {54 OS << Name;55 return;56 }57 OS << '"';58 for (const char *B = Name.begin(), *E = Name.end(); B < E; ++B) {59 if (*B == '"') // Unquoted "60 OS << "\\\"";61 else if (*B != '\\') // Neither " or backslash62 OS << *B;63 else if (B + 1 == E) // Trailing backslash64 OS << "\\\\";65 else {66 OS << B[0] << B[1]; // Quoted character67 ++B;68 }69 }70 OS << '"';71}72 73void MCAsmInfoELF::printSwitchToSection(const MCSection &Section,74 uint32_t Subsection, const Triple &T,75 raw_ostream &OS) const {76 auto &Sec = static_cast<const MCSectionELF &>(Section);77 if (!Sec.isUnique() && shouldOmitSectionDirective(Sec.getName())) {78 OS << '\t' << Sec.getName();79 if (Subsection)80 OS << '\t' << Subsection;81 OS << '\n';82 return;83 }84 85 OS << "\t.section\t";86 printName(OS, Sec.getName());87 88 // Handle the weird solaris syntax if desired.89 if (usesSunStyleELFSectionSwitchSyntax() && !(Sec.Flags & ELF::SHF_MERGE)) {90 if (Sec.Flags & ELF::SHF_ALLOC)91 OS << ",#alloc";92 if (Sec.Flags & ELF::SHF_EXECINSTR)93 OS << ",#execinstr";94 if (Sec.Flags & ELF::SHF_WRITE)95 OS << ",#write";96 if (Sec.Flags & ELF::SHF_EXCLUDE)97 OS << ",#exclude";98 if (Sec.Flags & ELF::SHF_TLS)99 OS << ",#tls";100 OS << '\n';101 return;102 }103 104 OS << ",\"";105 if (Sec.Flags & ELF::SHF_ALLOC)106 OS << 'a';107 if (Sec.Flags & ELF::SHF_EXCLUDE)108 OS << 'e';109 if (Sec.Flags & ELF::SHF_EXECINSTR)110 OS << 'x';111 if (Sec.Flags & ELF::SHF_WRITE)112 OS << 'w';113 if (Sec.Flags & ELF::SHF_MERGE)114 OS << 'M';115 if (Sec.Flags & ELF::SHF_STRINGS)116 OS << 'S';117 if (Sec.Flags & ELF::SHF_TLS)118 OS << 'T';119 if (Sec.Flags & ELF::SHF_LINK_ORDER)120 OS << 'o';121 if (Sec.Flags & ELF::SHF_GROUP)122 OS << 'G';123 if (Sec.Flags & ELF::SHF_GNU_RETAIN)124 OS << 'R';125 126 // If there are os-specific flags, print them.127 if (T.isOSSolaris())128 if (Sec.Flags & ELF::SHF_SUNW_NODISCARD)129 OS << 'R';130 131 // If there are tarSec.get-specific flags, print them.132 Triple::ArchType Arch = T.getArch();133 if (Arch == Triple::xcore) {134 if (Sec.Flags & ELF::XCORE_SHF_CP_SECTION)135 OS << 'c';136 if (Sec.Flags & ELF::XCORE_SHF_DP_SECTION)137 OS << 'd';138 } else if (T.isARM() || T.isThumb()) {139 if (Sec.Flags & ELF::SHF_ARM_PURECODE)140 OS << 'y';141 } else if (T.isAArch64()) {142 if (Sec.Flags & ELF::SHF_AARCH64_PURECODE)143 OS << 'y';144 } else if (Arch == Triple::hexagon) {145 if (Sec.Flags & ELF::SHF_HEX_GPREL)146 OS << 's';147 } else if (Arch == Triple::x86_64) {148 if (Sec.Flags & ELF::SHF_X86_64_LARGE)149 OS << 'l';150 }151 152 OS << '"';153 154 OS << ',';155 156 // If comment string is '@', e.g. as on ARM - use '%' instead157 if (getCommentString()[0] == '@')158 OS << '%';159 else160 OS << '@';161 162 if (Sec.Type == ELF::SHT_INIT_ARRAY)163 OS << "init_array";164 else if (Sec.Type == ELF::SHT_FINI_ARRAY)165 OS << "fini_array";166 else if (Sec.Type == ELF::SHT_PREINIT_ARRAY)167 OS << "preinit_array";168 else if (Sec.Type == ELF::SHT_NOBITS)169 OS << "nobits";170 else if (Sec.Type == ELF::SHT_NOTE)171 OS << "note";172 else if (Sec.Type == ELF::SHT_PROGBITS)173 OS << "progbits";174 else if (Sec.Type == ELF::SHT_X86_64_UNWIND)175 OS << "unwind";176 else if (Sec.Type == ELF::SHT_MIPS_DWARF)177 // Print hex value of the flag while we do not have178 // any standard symbolic representation of the flag.179 OS << "0x7000001e";180 else if (Sec.Type == ELF::SHT_LLVM_ODRTAB)181 OS << "llvm_odrtab";182 else if (Sec.Type == ELF::SHT_LLVM_LINKER_OPTIONS)183 OS << "llvm_linker_options";184 else if (Sec.Type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE)185 OS << "llvm_call_graph_profile";186 else if (Sec.Type == ELF::SHT_LLVM_DEPENDENT_LIBRARIES)187 OS << "llvm_dependent_libraries";188 else if (Sec.Type == ELF::SHT_LLVM_SYMPART)189 OS << "llvm_sympart";190 else if (Sec.Type == ELF::SHT_LLVM_BB_ADDR_MAP)191 OS << "llvm_bb_addr_map";192 else if (Sec.Type == ELF::SHT_LLVM_OFFLOADING)193 OS << "llvm_offloading";194 else if (Sec.Type == ELF::SHT_LLVM_LTO)195 OS << "llvm_lto";196 else if (Sec.Type == ELF::SHT_LLVM_JT_SIZES)197 OS << "llvm_jt_sizes";198 else if (Sec.Type == ELF::SHT_LLVM_CFI_JUMP_TABLE)199 OS << "llvm_cfi_jump_table";200 else if (Sec.Type == ELF::SHT_LLVM_CALL_GRAPH)201 OS << "llvm_call_graph";202 else203 OS << "0x" << Twine::utohexstr(Sec.Type);204 205 if (Sec.EntrySize) {206 assert((Sec.Flags & ELF::SHF_MERGE) ||207 Sec.Type == ELF::SHT_LLVM_CFI_JUMP_TABLE);208 OS << "," << Sec.EntrySize;209 }210 211 if (Sec.Flags & ELF::SHF_LINK_ORDER) {212 OS << ",";213 if (Sec.LinkedToSym)214 printName(OS, Sec.LinkedToSym->getName());215 else216 OS << '0';217 }218 219 if (Sec.Flags & ELF::SHF_GROUP) {220 OS << ",";221 printName(OS, Sec.Group.getPointer()->getName());222 if (Sec.isComdat())223 OS << ",comdat";224 }225 226 if (Sec.isUnique())227 OS << ",unique," << Sec.UniqueID;228 229 OS << '\n';230 231 if (Subsection) {232 OS << "\t.subsection\t" << Subsection;233 OS << '\n';234 }235}236