Path: blob/main/contrib/llvm-project/llvm/lib/MC/MCSectionELF.cpp
35233 views
//===- lib/MC/MCSectionELF.cpp - ELF Code Section Representation ----------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//78#include "llvm/MC/MCSectionELF.h"9#include "llvm/BinaryFormat/ELF.h"10#include "llvm/MC/MCAsmInfo.h"11#include "llvm/MC/MCExpr.h"12#include "llvm/Support/ErrorHandling.h"13#include "llvm/Support/raw_ostream.h"14#include "llvm/TargetParser/Triple.h"15#include <cassert>1617using namespace llvm;1819// Decides whether a '.section' directive20// should be printed before the section name.21bool MCSectionELF::shouldOmitSectionDirective(StringRef Name,22const MCAsmInfo &MAI) const {23if (isUnique())24return false;2526return MAI.shouldOmitSectionDirective(Name);27}2829static void printName(raw_ostream &OS, StringRef Name) {30if (Name.find_first_not_of("0123456789_."31"abcdefghijklmnopqrstuvwxyz"32"ABCDEFGHIJKLMNOPQRSTUVWXYZ") == Name.npos) {33OS << Name;34return;35}36OS << '"';37for (const char *B = Name.begin(), *E = Name.end(); B < E; ++B) {38if (*B == '"') // Unquoted "39OS << "\\\"";40else if (*B != '\\') // Neither " or backslash41OS << *B;42else if (B + 1 == E) // Trailing backslash43OS << "\\\\";44else {45OS << B[0] << B[1]; // Quoted character46++B;47}48}49OS << '"';50}5152void MCSectionELF::printSwitchToSection(const MCAsmInfo &MAI, const Triple &T,53raw_ostream &OS,54uint32_t Subsection) const {55if (shouldOmitSectionDirective(getName(), MAI)) {56OS << '\t' << getName();57if (Subsection)58OS << '\t' << Subsection;59OS << '\n';60return;61}6263OS << "\t.section\t";64printName(OS, getName());6566// Handle the weird solaris syntax if desired.67if (MAI.usesSunStyleELFSectionSwitchSyntax() &&68!(Flags & ELF::SHF_MERGE)) {69if (Flags & ELF::SHF_ALLOC)70OS << ",#alloc";71if (Flags & ELF::SHF_EXECINSTR)72OS << ",#execinstr";73if (Flags & ELF::SHF_WRITE)74OS << ",#write";75if (Flags & ELF::SHF_EXCLUDE)76OS << ",#exclude";77if (Flags & ELF::SHF_TLS)78OS << ",#tls";79OS << '\n';80return;81}8283OS << ",\"";84if (Flags & ELF::SHF_ALLOC)85OS << 'a';86if (Flags & ELF::SHF_EXCLUDE)87OS << 'e';88if (Flags & ELF::SHF_EXECINSTR)89OS << 'x';90if (Flags & ELF::SHF_WRITE)91OS << 'w';92if (Flags & ELF::SHF_MERGE)93OS << 'M';94if (Flags & ELF::SHF_STRINGS)95OS << 'S';96if (Flags & ELF::SHF_TLS)97OS << 'T';98if (Flags & ELF::SHF_LINK_ORDER)99OS << 'o';100if (Flags & ELF::SHF_GROUP)101OS << 'G';102if (Flags & ELF::SHF_GNU_RETAIN)103OS << 'R';104105// If there are os-specific flags, print them.106if (T.isOSSolaris())107if (Flags & ELF::SHF_SUNW_NODISCARD)108OS << 'R';109110// If there are target-specific flags, print them.111Triple::ArchType Arch = T.getArch();112if (Arch == Triple::xcore) {113if (Flags & ELF::XCORE_SHF_CP_SECTION)114OS << 'c';115if (Flags & ELF::XCORE_SHF_DP_SECTION)116OS << 'd';117} else if (T.isARM() || T.isThumb()) {118if (Flags & ELF::SHF_ARM_PURECODE)119OS << 'y';120} else if (Arch == Triple::hexagon) {121if (Flags & ELF::SHF_HEX_GPREL)122OS << 's';123} else if (Arch == Triple::x86_64) {124if (Flags & ELF::SHF_X86_64_LARGE)125OS << 'l';126}127128OS << '"';129130OS << ',';131132// If comment string is '@', e.g. as on ARM - use '%' instead133if (MAI.getCommentString()[0] == '@')134OS << '%';135else136OS << '@';137138if (Type == ELF::SHT_INIT_ARRAY)139OS << "init_array";140else if (Type == ELF::SHT_FINI_ARRAY)141OS << "fini_array";142else if (Type == ELF::SHT_PREINIT_ARRAY)143OS << "preinit_array";144else if (Type == ELF::SHT_NOBITS)145OS << "nobits";146else if (Type == ELF::SHT_NOTE)147OS << "note";148else if (Type == ELF::SHT_PROGBITS)149OS << "progbits";150else if (Type == ELF::SHT_X86_64_UNWIND)151OS << "unwind";152else if (Type == ELF::SHT_MIPS_DWARF)153// Print hex value of the flag while we do not have154// any standard symbolic representation of the flag.155OS << "0x7000001e";156else if (Type == ELF::SHT_LLVM_ODRTAB)157OS << "llvm_odrtab";158else if (Type == ELF::SHT_LLVM_LINKER_OPTIONS)159OS << "llvm_linker_options";160else if (Type == ELF::SHT_LLVM_CALL_GRAPH_PROFILE)161OS << "llvm_call_graph_profile";162else if (Type == ELF::SHT_LLVM_DEPENDENT_LIBRARIES)163OS << "llvm_dependent_libraries";164else if (Type == ELF::SHT_LLVM_SYMPART)165OS << "llvm_sympart";166else if (Type == ELF::SHT_LLVM_BB_ADDR_MAP)167OS << "llvm_bb_addr_map";168else if (Type == ELF::SHT_LLVM_BB_ADDR_MAP_V0)169OS << "llvm_bb_addr_map_v0";170else if (Type == ELF::SHT_LLVM_OFFLOADING)171OS << "llvm_offloading";172else if (Type == ELF::SHT_LLVM_LTO)173OS << "llvm_lto";174else175OS << "0x" << Twine::utohexstr(Type);176177if (EntrySize) {178assert(Flags & ELF::SHF_MERGE);179OS << "," << EntrySize;180}181182if (Flags & ELF::SHF_LINK_ORDER) {183OS << ",";184if (LinkedToSym)185printName(OS, LinkedToSym->getName());186else187OS << '0';188}189190if (Flags & ELF::SHF_GROUP) {191OS << ",";192printName(OS, Group.getPointer()->getName());193if (isComdat())194OS << ",comdat";195}196197if (isUnique())198OS << ",unique," << UniqueID;199200OS << '\n';201202if (Subsection) {203OS << "\t.subsection\t" << Subsection;204OS << '\n';205}206}207208bool MCSectionELF::useCodeAlign() const {209return getFlags() & ELF::SHF_EXECINSTR;210}211212StringRef MCSectionELF::getVirtualSectionKind() const { return "SHT_NOBITS"; }213214215