2009-08-13 13:07:35 +08:00
|
|
|
//===- 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.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2017-02-14 08:33:36 +08:00
|
|
|
#include "llvm/ADT/Triple.h"
|
2010-01-14 05:21:29 +08:00
|
|
|
#include "llvm/MC/MCAsmInfo.h"
|
2013-04-18 05:18:16 +08:00
|
|
|
#include "llvm/MC/MCExpr.h"
|
2017-02-14 08:33:36 +08:00
|
|
|
#include "llvm/MC/MCSectionELF.h"
|
2011-01-23 12:28:49 +08:00
|
|
|
#include "llvm/Support/ELF.h"
|
2017-03-10 16:22:13 +08:00
|
|
|
#include "llvm/Support/ErrorHandling.h"
|
2009-08-13 13:07:35 +08:00
|
|
|
#include "llvm/Support/raw_ostream.h"
|
2017-02-14 08:33:36 +08:00
|
|
|
#include <cassert>
|
2011-01-23 12:28:49 +08:00
|
|
|
|
2009-08-13 13:07:35 +08:00
|
|
|
using namespace llvm;
|
|
|
|
|
2017-02-14 08:33:36 +08:00
|
|
|
MCSectionELF::~MCSectionELF() = default; // anchor.
|
2009-08-13 13:07:35 +08:00
|
|
|
|
2014-10-10 05:23:39 +08:00
|
|
|
// Decides whether a '.section' directive
|
|
|
|
// should be printed before the section name.
|
2010-01-23 02:21:23 +08:00
|
|
|
bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name,
|
2010-01-14 05:21:29 +08:00
|
|
|
const MCAsmInfo &MAI) const {
|
2015-04-05 02:02:01 +08:00
|
|
|
if (isUnique())
|
2015-02-18 04:48:01 +08:00
|
|
|
return false;
|
|
|
|
|
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-26 05:41:14 +08:00
|
|
|
return MAI.shouldOmitSectionDirective(Name);
|
2009-08-13 13:07:35 +08:00
|
|
|
}
|
|
|
|
|
2013-11-13 22:01:59 +08:00
|
|
|
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 << '"';
|
|
|
|
}
|
|
|
|
|
2017-01-30 23:38:43 +08:00
|
|
|
void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
|
2013-04-18 05:18:16 +08:00
|
|
|
raw_ostream &OS,
|
|
|
|
const MCExpr *Subsection) const {
|
2010-01-23 02:21:23 +08:00
|
|
|
if (ShouldOmitSectionDirective(SectionName, MAI)) {
|
2013-04-18 05:18:16 +08:00
|
|
|
OS << '\t' << getSectionName();
|
2015-06-09 08:31:39 +08:00
|
|
|
if (Subsection) {
|
|
|
|
OS << '\t';
|
|
|
|
Subsection->print(OS, &MAI);
|
|
|
|
}
|
2013-04-18 05:18:16 +08:00
|
|
|
OS << '\n';
|
2009-08-13 13:07:35 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2013-11-13 22:01:59 +08:00
|
|
|
OS << "\t.section\t";
|
|
|
|
printName(OS, getSectionName());
|
2011-03-04 06:31:08 +08:00
|
|
|
|
2009-08-13 13:07:35 +08:00
|
|
|
// Handle the weird solaris syntax if desired.
|
2012-05-11 09:41:30 +08:00
|
|
|
if (MAI.usesSunStyleELFSectionSwitchSyntax() &&
|
2011-01-23 12:43:11 +08:00
|
|
|
!(Flags & ELF::SHF_MERGE)) {
|
|
|
|
if (Flags & ELF::SHF_ALLOC)
|
2009-08-13 13:07:35 +08:00
|
|
|
OS << ",#alloc";
|
2011-01-23 12:43:11 +08:00
|
|
|
if (Flags & ELF::SHF_EXECINSTR)
|
2009-08-13 13:07:35 +08:00
|
|
|
OS << ",#execinstr";
|
2011-01-23 12:43:11 +08:00
|
|
|
if (Flags & ELF::SHF_WRITE)
|
2009-08-13 13:07:35 +08:00
|
|
|
OS << ",#write";
|
2013-09-16 03:53:20 +08:00
|
|
|
if (Flags & ELF::SHF_EXCLUDE)
|
|
|
|
OS << ",#exclude";
|
2011-01-23 12:43:11 +08:00
|
|
|
if (Flags & ELF::SHF_TLS)
|
2009-08-13 13:07:35 +08:00
|
|
|
OS << ",#tls";
|
2010-04-09 05:26:26 +08:00
|
|
|
OS << '\n';
|
|
|
|
return;
|
|
|
|
}
|
2012-05-11 09:41:30 +08:00
|
|
|
|
2010-04-09 05:26:26 +08:00
|
|
|
OS << ",\"";
|
2011-01-23 12:43:11 +08:00
|
|
|
if (Flags & ELF::SHF_ALLOC)
|
2010-04-09 05:26:26 +08:00
|
|
|
OS << 'a';
|
2013-09-16 03:53:20 +08:00
|
|
|
if (Flags & ELF::SHF_EXCLUDE)
|
|
|
|
OS << 'e';
|
2011-01-23 12:43:11 +08:00
|
|
|
if (Flags & ELF::SHF_EXECINSTR)
|
2010-04-09 05:26:26 +08:00
|
|
|
OS << 'x';
|
2011-02-15 06:23:49 +08:00
|
|
|
if (Flags & ELF::SHF_GROUP)
|
|
|
|
OS << 'G';
|
2011-01-23 12:43:11 +08:00
|
|
|
if (Flags & ELF::SHF_WRITE)
|
2010-04-09 05:26:26 +08:00
|
|
|
OS << 'w';
|
2011-01-23 12:43:11 +08:00
|
|
|
if (Flags & ELF::SHF_MERGE)
|
2010-04-09 05:26:26 +08:00
|
|
|
OS << 'M';
|
2011-01-23 12:43:11 +08:00
|
|
|
if (Flags & ELF::SHF_STRINGS)
|
2010-04-09 05:26:26 +08:00
|
|
|
OS << 'S';
|
2011-01-23 12:43:11 +08:00
|
|
|
if (Flags & ELF::SHF_TLS)
|
2010-04-09 05:26:26 +08:00
|
|
|
OS << 'T';
|
2017-03-15 03:28:51 +08:00
|
|
|
if (Flags & ELF::SHF_LINK_ORDER)
|
2017-04-05 06:35:08 +08:00
|
|
|
OS << 'o';
|
2012-05-11 09:41:30 +08:00
|
|
|
|
2010-04-09 05:26:26 +08:00
|
|
|
// If there are target-specific flags, print them.
|
2017-01-30 23:38:43 +08:00
|
|
|
Triple::ArchType Arch = T.getArch();
|
|
|
|
if (Arch == Triple::xcore) {
|
|
|
|
if (Flags & ELF::XCORE_SHF_CP_SECTION)
|
|
|
|
OS << 'c';
|
|
|
|
if (Flags & ELF::XCORE_SHF_DP_SECTION)
|
|
|
|
OS << 'd';
|
|
|
|
} else if (Arch == Triple::arm || Arch == Triple::armeb ||
|
|
|
|
Arch == Triple::thumb || Arch == Triple::thumbeb) {
|
|
|
|
if (Flags & ELF::SHF_ARM_PURECODE)
|
|
|
|
OS << 'y';
|
|
|
|
}
|
2012-05-11 09:41:30 +08:00
|
|
|
|
2010-04-09 05:26:26 +08:00
|
|
|
OS << '"';
|
2009-08-13 13:07:35 +08:00
|
|
|
|
2010-11-10 07:42:07 +08:00
|
|
|
OS << ',';
|
|
|
|
|
|
|
|
// If comment string is '@', e.g. as on ARM - use '%' instead
|
|
|
|
if (MAI.getCommentString()[0] == '@')
|
|
|
|
OS << '%';
|
|
|
|
else
|
|
|
|
OS << '@';
|
|
|
|
|
2011-01-23 12:28:49 +08:00
|
|
|
if (Type == ELF::SHT_INIT_ARRAY)
|
2010-11-10 07:42:07 +08:00
|
|
|
OS << "init_array";
|
2011-01-23 12:28:49 +08:00
|
|
|
else if (Type == ELF::SHT_FINI_ARRAY)
|
2010-11-10 07:42:07 +08:00
|
|
|
OS << "fini_array";
|
2011-01-23 12:28:49 +08:00
|
|
|
else if (Type == ELF::SHT_PREINIT_ARRAY)
|
2010-11-10 07:42:07 +08:00
|
|
|
OS << "preinit_array";
|
2011-01-23 12:28:49 +08:00
|
|
|
else if (Type == ELF::SHT_NOBITS)
|
2010-11-10 07:42:07 +08:00
|
|
|
OS << "nobits";
|
2011-01-23 12:28:49 +08:00
|
|
|
else if (Type == ELF::SHT_NOTE)
|
2010-12-27 05:30:59 +08:00
|
|
|
OS << "note";
|
2011-01-23 12:28:49 +08:00
|
|
|
else if (Type == ELF::SHT_PROGBITS)
|
2010-11-10 07:42:07 +08:00
|
|
|
OS << "progbits";
|
2015-11-06 23:30:45 +08:00
|
|
|
else if (Type == ELF::SHT_X86_64_UNWIND)
|
|
|
|
OS << "unwind";
|
2017-03-10 16:22:20 +08:00
|
|
|
else if (Type == ELF::SHT_MIPS_DWARF)
|
|
|
|
// Print hex value of the flag while we do not have
|
|
|
|
// any standard symbolic representation of the flag.
|
|
|
|
OS << "0x7000001e";
|
2017-03-10 16:22:13 +08:00
|
|
|
else
|
|
|
|
report_fatal_error("unsupported type 0x" + Twine::utohexstr(Type) +
|
|
|
|
" for section " + getSectionName());
|
2010-11-10 07:42:07 +08:00
|
|
|
|
|
|
|
if (EntrySize) {
|
2011-01-23 12:43:11 +08:00
|
|
|
assert(Flags & ELF::SHF_MERGE);
|
2010-11-10 07:42:07 +08:00
|
|
|
OS << "," << EntrySize;
|
2009-08-13 13:07:35 +08:00
|
|
|
}
|
2010-11-10 07:42:07 +08:00
|
|
|
|
2013-11-13 22:01:59 +08:00
|
|
|
if (Flags & ELF::SHF_GROUP) {
|
|
|
|
OS << ",";
|
|
|
|
printName(OS, Group->getName());
|
|
|
|
OS << ",comdat";
|
|
|
|
}
|
2015-02-18 04:48:01 +08:00
|
|
|
|
2017-03-15 03:28:51 +08:00
|
|
|
if (Flags & ELF::SHF_LINK_ORDER) {
|
|
|
|
assert(AssociatedSymbol);
|
|
|
|
OS << ",";
|
|
|
|
printName(OS, AssociatedSymbol->getName());
|
|
|
|
}
|
|
|
|
|
2015-04-05 02:02:01 +08:00
|
|
|
if (isUnique())
|
2015-04-07 00:34:41 +08:00
|
|
|
OS << ",unique," << UniqueID;
|
2015-02-18 04:48:01 +08:00
|
|
|
|
2009-08-13 13:07:35 +08:00
|
|
|
OS << '\n';
|
2013-04-18 05:18:16 +08:00
|
|
|
|
2015-06-09 08:31:39 +08:00
|
|
|
if (Subsection) {
|
|
|
|
OS << "\t.subsection\t";
|
|
|
|
Subsection->print(OS, &MAI);
|
|
|
|
OS << '\n';
|
|
|
|
}
|
2009-08-13 13:07:35 +08:00
|
|
|
}
|
|
|
|
|
2010-10-05 01:32:41 +08:00
|
|
|
bool MCSectionELF::UseCodeAlign() const {
|
2011-01-23 12:43:11 +08:00
|
|
|
return getFlags() & ELF::SHF_EXECINSTR;
|
2010-10-05 01:32:41 +08:00
|
|
|
}
|
|
|
|
|
2010-11-18 04:03:54 +08:00
|
|
|
bool MCSectionELF::isVirtualSection() const {
|
2011-01-23 12:28:49 +08:00
|
|
|
return getType() == ELF::SHT_NOBITS;
|
2010-11-18 04:03:54 +08:00
|
|
|
}
|