LLVM  3.7.0
MCSectionMachO.cpp
Go to the documentation of this file.
1 //===- lib/MC/MCSectionMachO.cpp - MachO Code Section Representation ------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/MC/MCSectionMachO.h"
11 #include "llvm/MC/MCContext.h"
13 #include <cctype>
14 using namespace llvm;
15 
16 /// SectionTypeDescriptors - These are strings that describe the various section
17 /// types. This *must* be kept in order with and stay synchronized with the
18 /// section type list.
19 static const struct {
20  const char *AssemblerName, *EnumName;
22  { "regular", "S_REGULAR" }, // 0x00
23  { nullptr, "S_ZEROFILL" }, // 0x01
24  { "cstring_literals", "S_CSTRING_LITERALS" }, // 0x02
25  { "4byte_literals", "S_4BYTE_LITERALS" }, // 0x03
26  { "8byte_literals", "S_8BYTE_LITERALS" }, // 0x04
27  { "literal_pointers", "S_LITERAL_POINTERS" }, // 0x05
28  { "non_lazy_symbol_pointers", "S_NON_LAZY_SYMBOL_POINTERS" }, // 0x06
29  { "lazy_symbol_pointers", "S_LAZY_SYMBOL_POINTERS" }, // 0x07
30  { "symbol_stubs", "S_SYMBOL_STUBS" }, // 0x08
31  { "mod_init_funcs", "S_MOD_INIT_FUNC_POINTERS" }, // 0x09
32  { "mod_term_funcs", "S_MOD_TERM_FUNC_POINTERS" }, // 0x0A
33  { "coalesced", "S_COALESCED" }, // 0x0B
34  { nullptr, /*FIXME??*/ "S_GB_ZEROFILL" }, // 0x0C
35  { "interposing", "S_INTERPOSING" }, // 0x0D
36  { "16byte_literals", "S_16BYTE_LITERALS" }, // 0x0E
37  { nullptr, /*FIXME??*/ "S_DTRACE_DOF" }, // 0x0F
38  { nullptr, /*FIXME??*/ "S_LAZY_DYLIB_SYMBOL_POINTERS" }, // 0x10
39  { "thread_local_regular", "S_THREAD_LOCAL_REGULAR" }, // 0x11
40  { "thread_local_zerofill", "S_THREAD_LOCAL_ZEROFILL" }, // 0x12
41  { "thread_local_variables", "S_THREAD_LOCAL_VARIABLES" }, // 0x13
42  { "thread_local_variable_pointers",
43  "S_THREAD_LOCAL_VARIABLE_POINTERS" }, // 0x14
44  { "thread_local_init_function_pointers",
45  "S_THREAD_LOCAL_INIT_FUNCTION_POINTERS"}, // 0x15
46 };
47 
48 
49 /// SectionAttrDescriptors - This is an array of descriptors for section
50 /// attributes. Unlike the SectionTypeDescriptors, this is not directly indexed
51 /// by attribute, instead it is searched.
52 static const struct {
53  unsigned AttrFlag;
54  const char *AssemblerName, *EnumName;
56 #define ENTRY(ASMNAME, ENUM) \
57  { MachO::ENUM, ASMNAME, #ENUM },
58 ENTRY("pure_instructions", S_ATTR_PURE_INSTRUCTIONS)
59 ENTRY("no_toc", S_ATTR_NO_TOC)
60 ENTRY("strip_static_syms", S_ATTR_STRIP_STATIC_SYMS)
61 ENTRY("no_dead_strip", S_ATTR_NO_DEAD_STRIP)
62 ENTRY("live_support", S_ATTR_LIVE_SUPPORT)
63 ENTRY("self_modifying_code", S_ATTR_SELF_MODIFYING_CODE)
64 ENTRY("debug", S_ATTR_DEBUG)
65 ENTRY(nullptr /*FIXME*/, S_ATTR_SOME_INSTRUCTIONS)
66 ENTRY(nullptr /*FIXME*/, S_ATTR_EXT_RELOC)
67 ENTRY(nullptr /*FIXME*/, S_ATTR_LOC_RELOC)
68 #undef ENTRY
69  { 0, "none", nullptr }, // used if section has no attributes but has a stub size
70 };
71 
72 MCSectionMachO::MCSectionMachO(StringRef Segment, StringRef Section,
73  unsigned TAA, unsigned reserved2, SectionKind K,
74  MCSymbol *Begin)
75  : MCSection(SV_MachO, K, Begin), TypeAndAttributes(TAA),
76  Reserved2(reserved2) {
77  assert(Segment.size() <= 16 && Section.size() <= 16 &&
78  "Segment or section string too long");
79  for (unsigned i = 0; i != 16; ++i) {
80  if (i < Segment.size())
81  SegmentName[i] = Segment[i];
82  else
83  SegmentName[i] = 0;
84 
85  if (i < Section.size())
86  SectionName[i] = Section[i];
87  else
88  SectionName[i] = 0;
89  }
90 }
91 
92 void MCSectionMachO::PrintSwitchToSection(const MCAsmInfo &MAI,
93  raw_ostream &OS,
94  const MCExpr *Subsection) const {
95  OS << "\t.section\t" << getSegmentName() << ',' << getSectionName();
96 
97  // Get the section type and attributes.
98  unsigned TAA = getTypeAndAttributes();
99  if (TAA == 0) {
100  OS << '\n';
101  return;
102  }
103 
105  assert(SectionType <= MachO::LAST_KNOWN_SECTION_TYPE &&
106  "Invalid SectionType specified!");
107 
108  if (SectionTypeDescriptors[SectionType].AssemblerName) {
109  OS << ',';
110  OS << SectionTypeDescriptors[SectionType].AssemblerName;
111  } else {
112  // If we have no name for the attribute, stop here.
113  OS << '\n';
114  return;
115  }
116 
117  // If we don't have any attributes, we're done.
118  unsigned SectionAttrs = TAA & MachO::SECTION_ATTRIBUTES;
119  if (SectionAttrs == 0) {
120  // If we have a S_SYMBOL_STUBS size specified, print it along with 'none' as
121  // the attribute specifier.
122  if (Reserved2 != 0)
123  OS << ",none," << Reserved2;
124  OS << '\n';
125  return;
126  }
127 
128  // Check each attribute to see if we have it.
129  char Separator = ',';
130  for (unsigned i = 0;
131  SectionAttrs != 0 && SectionAttrDescriptors[i].AttrFlag;
132  ++i) {
133  // Check to see if we have this attribute.
134  if ((SectionAttrDescriptors[i].AttrFlag & SectionAttrs) == 0)
135  continue;
136 
137  // Yep, clear it and print it.
138  SectionAttrs &= ~SectionAttrDescriptors[i].AttrFlag;
139 
140  OS << Separator;
141  if (SectionAttrDescriptors[i].AssemblerName)
142  OS << SectionAttrDescriptors[i].AssemblerName;
143  else
144  OS << "<<" << SectionAttrDescriptors[i].EnumName << ">>";
145  Separator = '+';
146  }
147 
148  assert(SectionAttrs == 0 && "Unknown section attributes!");
149 
150  // If we have a S_SYMBOL_STUBS size specified, print it.
151  if (Reserved2 != 0)
152  OS << ',' << Reserved2;
153  OS << '\n';
154 }
155 
158 }
159 
161  return (getType() == MachO::S_ZEROFILL ||
164 }
165 
166 /// ParseSectionSpecifier - Parse the section specifier indicated by "Spec".
167 /// This is a string that can appear after a .section directive in a mach-o
168 /// flavored .s file. If successful, this fills in the specified Out
169 /// parameters and returns an empty string. When an invalid section
170 /// specifier is present, this returns a string indicating the problem.
172  StringRef &Segment, // Out.
173  StringRef &Section, // Out.
174  unsigned &TAA, // Out.
175  bool &TAAParsed, // Out.
176  unsigned &StubSize) { // Out.
177  TAAParsed = false;
178 
179  SmallVector<StringRef, 5> SplitSpec;
180  Spec.split(SplitSpec, ",");
181  // Remove leading and trailing whitespace.
182  auto GetEmptyOrTrim = [&SplitSpec](size_t Idx) -> StringRef {
183  return SplitSpec.size() > Idx ? SplitSpec[Idx].trim() : StringRef();
184  };
185  Segment = GetEmptyOrTrim(0);
186  Section = GetEmptyOrTrim(1);
187  StringRef SectionType = GetEmptyOrTrim(2);
188  StringRef Attrs = GetEmptyOrTrim(3);
189  StringRef StubSizeStr = GetEmptyOrTrim(4);
190 
191  // Verify that the segment is present and not too long.
192  if (Segment.empty() || Segment.size() > 16)
193  return "mach-o section specifier requires a segment whose length is "
194  "between 1 and 16 characters";
195 
196  // Verify that the section is present and not too long.
197  if (Section.empty())
198  return "mach-o section specifier requires a segment and section "
199  "separated by a comma";
200 
201  if (Section.size() > 16)
202  return "mach-o section specifier requires a section whose length is "
203  "between 1 and 16 characters";
204 
205  // If there is no comma after the section, we're done.
206  TAA = 0;
207  StubSize = 0;
208  if (SectionType.empty())
209  return "";
210 
211  // Figure out which section type it is.
212  auto TypeDescriptor = std::find_if(
214  [&](decltype(*SectionTypeDescriptors) &Descriptor) {
215  return Descriptor.AssemblerName &&
216  SectionType == Descriptor.AssemblerName;
217  });
218 
219  // If we didn't find the section type, reject it.
220  if (TypeDescriptor == std::end(SectionTypeDescriptors))
221  return "mach-o section specifier uses an unknown section type";
222 
223  // Remember the TypeID.
224  TAA = TypeDescriptor - std::begin(SectionTypeDescriptors);
225  TAAParsed = true;
226 
227  // If we have no comma after the section type, there are no attributes.
228  if (Attrs.empty()) {
229  // S_SYMBOL_STUBS always require a symbol stub size specifier.
230  if (TAA == MachO::S_SYMBOL_STUBS)
231  return "mach-o section specifier of type 'symbol_stubs' requires a size "
232  "specifier";
233  return "";
234  }
235 
236  // The attribute list is a '+' separated list of attributes.
237  SmallVector<StringRef, 1> SectionAttrs;
238  Attrs.split(SectionAttrs, "+", /*MaxSplit=*/-1, /*KeepEmpty=*/false);
239 
240  for (StringRef &SectionAttr : SectionAttrs) {
241  auto AttrDescriptorI = std::find_if(
243  [&](decltype(*SectionAttrDescriptors) &Descriptor) {
244  return Descriptor.AssemblerName &&
245  SectionAttr.trim() == Descriptor.AssemblerName;
246  });
247  if (AttrDescriptorI == std::end(SectionAttrDescriptors))
248  return "mach-o section specifier has invalid attribute";
249 
250  TAA |= AttrDescriptorI->AttrFlag;
251  }
252 
253  // Okay, we've parsed the section attributes, see if we have a stub size spec.
254  if (StubSizeStr.empty()) {
255  // S_SYMBOL_STUBS always require a symbol stub size specifier.
256  if (TAA == MachO::S_SYMBOL_STUBS)
257  return "mach-o section specifier of type 'symbol_stubs' requires a size "
258  "specifier";
259  return "";
260  }
261 
262  // If we have a stub size spec, we must have a sectiontype of S_SYMBOL_STUBS.
264  return "mach-o section specifier cannot have a stub size specified because "
265  "it does not have type 'symbol_stubs'";
266 
267  // Convert the stub size from a string to an integer.
268  if (StubSizeStr.getAsInteger(0, StubSize))
269  return "mach-o section specifier has a malformed stub size";
270 
271  return "";
272 }
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:347
Instances of this class represent a uniqued identifier for a section in the current translation unit...
Definition: MCSection.h:48
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:240
S_SYMBOL_STUBS - Section with symbol stubs, byte size of stub in the Reserved2 field.
size_t size() const
size - Get the string size.
Definition: StringRef.h:113
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:39
S_ATTR_SOME_INSTRUCTIONS - Section contains some machine instructions.
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:450
const_iterator begin(StringRef path)
Get begin iterator over path.
Definition: Path.cpp:232
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:33
#define ENTRY(ASMNAME, ENUM)
StringRef getSectionName() const
S_ATTR_EXT_RELOC - Section has external relocation entries.
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:58
S_ATTR_STRIP_STATIC_SYMS - Ok to strip static symbols in this section in files with the MY_DYLDLINK f...
static std::string ParseSectionSpecifier(StringRef Spec, StringRef &Segment, StringRef &Section, unsigned &TAA, bool &TAAParsed, unsigned &StubSize)
ParseSectionSpecifier - Parse the section specifier indicated by "Spec".
S_ATTR_PURE_INSTRUCTIONS - Section contains only true machine instructions.
S_GB_ZEROFILL - Zero fill on demand section (that can be larger than 4 gigabytes).
const char * EnumName
S_THREAD_LOCAL_ZEROFILL - Thread local zerofill section.
bool hasAttribute(unsigned Value) const
SectionKind - This is a simple POD value that classifies the properties of a section.
Definition: SectionKind.h:28
bool UseCodeAlign() const override
Return true if a .align directive should use "optimized nops" to fill instead of 0s.
S_ATTR_LIVE_SUPPORT - Blocks are live if they reference live blocks.
S_ATTR_NO_DEAD_STRIP - No dead stripping.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
static const struct @220 SectionAttrDescriptors[]
SectionAttrDescriptors - This is an array of descriptors for section attributes.
MachO::SectionType getType() const
S_ATTR_LOC_RELOC - Section has local relocation entries.
StringRef getSegmentName() const
unsigned AttrFlag
S_ATTR_DEBUG - A debug section.
S_ATTR_SELF_MODIFYING_CODE - Used with i386 code stubs written on by dyld.
const char * AssemblerName
bool isVirtualSection() const override
Check whether this section is "virtual", that is has no actual object file contents.
unsigned getTypeAndAttributes() const
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:40
static const struct @219 SectionTypeDescriptors[MachO::LAST_KNOWN_SECTION_TYPE+1]
SectionTypeDescriptors - These are strings that describe the various section types.
S_ZEROFILL - Zero fill on demand section.
SectionType
These are the section type and attributes fields.
S_ATTR_NO_TOC - Section contains coalesced symbols that are not to be in a ranlib table of contents...
bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:110