1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-22 20:43:44 +02:00
llvm-mirror/lib/MC/MCSectionELF.cpp
Tom Stellard b419e6733b MCAsmInfo: Allow targets to specify when the .section directive should be omitted
Summary:
The default behavior is to omit the .section directive for .text, .data,
and sometimes .bss, but some targets may want to omit this directive for
other sections too.

The AMDGPU backend will uses this to emit a simplified syntax for section
switches.  For example if the section directive is not omitted (current
behavior), section switches to .hsatext will be printed like this:

.section .hsatext,#alloc,#execinstr,#write

This is actually wrong, because .hsatext has some custom STT_* flags,
which MC doesn't know how to print or parse.

If the section directive is omitted (made possible by this commit),
section switches will be printed like this:

.hsatext

The motivation for this patch is to make it possible to emit sections
with custom STT_* flags without having to teach MC about all the target
specific STT_* flags.

Reviewers: rafael, grosbach

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D12423

llvm-svn: 248618
2015-09-25 21:41:14 +00:00

167 lines
4.0 KiB
C++

//===- lib/MC/MCSectionELF.cpp - ELF Code Section Representation ----------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
MCSectionELF::~MCSectionELF() {} // anchor.
// Decides whether a '.section' directive
// should be printed before the section name.
bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name,
const MCAsmInfo &MAI) const {
if (isUnique())
return false;
return MAI.shouldOmitSectionDirective(Name);
}
static void printName(raw_ostream &OS, StringRef Name) {
if (Name.find_first_not_of("0123456789_."
"abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ") == Name.npos) {
OS << Name;
return;
}
OS << '"';
for (const char *B = Name.begin(), *E = Name.end(); B < E; ++B) {
if (*B == '"') // Unquoted "
OS << "\\\"";
else if (*B != '\\') // Neither " or backslash
OS << *B;
else if (B + 1 == E) // Trailing backslash
OS << "\\\\";
else {
OS << B[0] << B[1]; // Quoted character
++B;
}
}
OS << '"';
}
void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS,
const MCExpr *Subsection) const {
if (ShouldOmitSectionDirective(SectionName, MAI)) {
OS << '\t' << getSectionName();
if (Subsection) {
OS << '\t';
Subsection->print(OS, &MAI);
}
OS << '\n';
return;
}
OS << "\t.section\t";
printName(OS, getSectionName());
// Handle the weird solaris syntax if desired.
if (MAI.usesSunStyleELFSectionSwitchSyntax() &&
!(Flags & ELF::SHF_MERGE)) {
if (Flags & ELF::SHF_ALLOC)
OS << ",#alloc";
if (Flags & ELF::SHF_EXECINSTR)
OS << ",#execinstr";
if (Flags & ELF::SHF_WRITE)
OS << ",#write";
if (Flags & ELF::SHF_EXCLUDE)
OS << ",#exclude";
if (Flags & ELF::SHF_TLS)
OS << ",#tls";
OS << '\n';
return;
}
OS << ",\"";
if (Flags & ELF::SHF_ALLOC)
OS << 'a';
if (Flags & ELF::SHF_EXCLUDE)
OS << 'e';
if (Flags & ELF::SHF_EXECINSTR)
OS << 'x';
if (Flags & ELF::SHF_GROUP)
OS << 'G';
if (Flags & ELF::SHF_WRITE)
OS << 'w';
if (Flags & ELF::SHF_MERGE)
OS << 'M';
if (Flags & ELF::SHF_STRINGS)
OS << 'S';
if (Flags & ELF::SHF_TLS)
OS << 'T';
// If there are target-specific flags, print them.
if (Flags & ELF::XCORE_SHF_CP_SECTION)
OS << 'c';
if (Flags & ELF::XCORE_SHF_DP_SECTION)
OS << 'd';
OS << '"';
OS << ',';
// If comment string is '@', e.g. as on ARM - use '%' instead
if (MAI.getCommentString()[0] == '@')
OS << '%';
else
OS << '@';
if (Type == ELF::SHT_INIT_ARRAY)
OS << "init_array";
else if (Type == ELF::SHT_FINI_ARRAY)
OS << "fini_array";
else if (Type == ELF::SHT_PREINIT_ARRAY)
OS << "preinit_array";
else if (Type == ELF::SHT_NOBITS)
OS << "nobits";
else if (Type == ELF::SHT_NOTE)
OS << "note";
else if (Type == ELF::SHT_PROGBITS)
OS << "progbits";
if (EntrySize) {
assert(Flags & ELF::SHF_MERGE);
OS << "," << EntrySize;
}
if (Flags & ELF::SHF_GROUP) {
OS << ",";
printName(OS, Group->getName());
OS << ",comdat";
}
if (isUnique())
OS << ",unique," << UniqueID;
OS << '\n';
if (Subsection) {
OS << "\t.subsection\t";
Subsection->print(OS, &MAI);
OS << '\n';
}
}
bool MCSectionELF::UseCodeAlign() const {
return getFlags() & ELF::SHF_EXECINSTR;
}
bool MCSectionELF::isVirtualSection() const {
return getType() == ELF::SHT_NOBITS;
}