1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
//===- 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/MCSymbol.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
MCSectionELF::~MCSectionELF() {} // anchor.
// ShouldOmitSectionDirective - Decides whether a '.section' directive
// should be printed before the section name
bool MCSectionELF::ShouldOmitSectionDirective(StringRef Name,
const MCAsmInfo &MAI) const {
// FIXME: Does .section .bss/.data/.text work everywhere??
if (Name == ".text" || Name == ".data" ||
(Name == ".bss" && !MAI.usesELFSectionDirectiveForBSS()))
return true;
return false;
}
void MCSectionELF::PrintSwitchToSection(const MCAsmInfo &MAI,
raw_ostream &OS) const {
if (ShouldOmitSectionDirective(SectionName, MAI)) {
OS << '\t' << getSectionName() << '\n';
return;
}
OS << "\t.section\t" << 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_TLS)
OS << ",#tls";
OS << '\n';
return;
}
OS << ",\"";
if (Flags & ELF::SHF_ALLOC)
OS << 'a';
if (Flags & ELF::SHF_EXECINSTR)
OS << 'x';
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;
}
OS << '\n';
}
bool MCSectionELF::UseCodeAlign() const {
return getFlags() & ELF::SHF_EXECINSTR;
}
bool MCSectionELF::isVirtualSection() const {
return getType() == ELF::SHT_NOBITS;
}
unsigned MCSectionELF::DetermineEntrySize(SectionKind Kind) {
if (Kind.isMergeable1ByteCString()) return 1;
if (Kind.isMergeable2ByteCString()) return 2;
if (Kind.isMergeable4ByteCString()) return 4;
if (Kind.isMergeableConst4()) return 4;
if (Kind.isMergeableConst8()) return 8;
if (Kind.isMergeableConst16()) return 16;
return 0;
}
|