1*9880d681SAndroid Build Coastguard Worker //===- lib/MC/MCSectionMachO.cpp - MachO Code Section Representation ------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker
10*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSectionMachO.h"
11*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h"
12*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
13*9880d681SAndroid Build Coastguard Worker #include <cctype>
14*9880d681SAndroid Build Coastguard Worker using namespace llvm;
15*9880d681SAndroid Build Coastguard Worker
16*9880d681SAndroid Build Coastguard Worker /// SectionTypeDescriptors - These are strings that describe the various section
17*9880d681SAndroid Build Coastguard Worker /// types. This *must* be kept in order with and stay synchronized with the
18*9880d681SAndroid Build Coastguard Worker /// section type list.
19*9880d681SAndroid Build Coastguard Worker static const struct {
20*9880d681SAndroid Build Coastguard Worker const char *AssemblerName, *EnumName;
21*9880d681SAndroid Build Coastguard Worker } SectionTypeDescriptors[MachO::LAST_KNOWN_SECTION_TYPE+1] = {
22*9880d681SAndroid Build Coastguard Worker { "regular", "S_REGULAR" }, // 0x00
23*9880d681SAndroid Build Coastguard Worker { nullptr, "S_ZEROFILL" }, // 0x01
24*9880d681SAndroid Build Coastguard Worker { "cstring_literals", "S_CSTRING_LITERALS" }, // 0x02
25*9880d681SAndroid Build Coastguard Worker { "4byte_literals", "S_4BYTE_LITERALS" }, // 0x03
26*9880d681SAndroid Build Coastguard Worker { "8byte_literals", "S_8BYTE_LITERALS" }, // 0x04
27*9880d681SAndroid Build Coastguard Worker { "literal_pointers", "S_LITERAL_POINTERS" }, // 0x05
28*9880d681SAndroid Build Coastguard Worker { "non_lazy_symbol_pointers", "S_NON_LAZY_SYMBOL_POINTERS" }, // 0x06
29*9880d681SAndroid Build Coastguard Worker { "lazy_symbol_pointers", "S_LAZY_SYMBOL_POINTERS" }, // 0x07
30*9880d681SAndroid Build Coastguard Worker { "symbol_stubs", "S_SYMBOL_STUBS" }, // 0x08
31*9880d681SAndroid Build Coastguard Worker { "mod_init_funcs", "S_MOD_INIT_FUNC_POINTERS" }, // 0x09
32*9880d681SAndroid Build Coastguard Worker { "mod_term_funcs", "S_MOD_TERM_FUNC_POINTERS" }, // 0x0A
33*9880d681SAndroid Build Coastguard Worker { "coalesced", "S_COALESCED" }, // 0x0B
34*9880d681SAndroid Build Coastguard Worker { nullptr, /*FIXME??*/ "S_GB_ZEROFILL" }, // 0x0C
35*9880d681SAndroid Build Coastguard Worker { "interposing", "S_INTERPOSING" }, // 0x0D
36*9880d681SAndroid Build Coastguard Worker { "16byte_literals", "S_16BYTE_LITERALS" }, // 0x0E
37*9880d681SAndroid Build Coastguard Worker { nullptr, /*FIXME??*/ "S_DTRACE_DOF" }, // 0x0F
38*9880d681SAndroid Build Coastguard Worker { nullptr, /*FIXME??*/ "S_LAZY_DYLIB_SYMBOL_POINTERS" }, // 0x10
39*9880d681SAndroid Build Coastguard Worker { "thread_local_regular", "S_THREAD_LOCAL_REGULAR" }, // 0x11
40*9880d681SAndroid Build Coastguard Worker { "thread_local_zerofill", "S_THREAD_LOCAL_ZEROFILL" }, // 0x12
41*9880d681SAndroid Build Coastguard Worker { "thread_local_variables", "S_THREAD_LOCAL_VARIABLES" }, // 0x13
42*9880d681SAndroid Build Coastguard Worker { "thread_local_variable_pointers",
43*9880d681SAndroid Build Coastguard Worker "S_THREAD_LOCAL_VARIABLE_POINTERS" }, // 0x14
44*9880d681SAndroid Build Coastguard Worker { "thread_local_init_function_pointers",
45*9880d681SAndroid Build Coastguard Worker "S_THREAD_LOCAL_INIT_FUNCTION_POINTERS"}, // 0x15
46*9880d681SAndroid Build Coastguard Worker };
47*9880d681SAndroid Build Coastguard Worker
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker /// SectionAttrDescriptors - This is an array of descriptors for section
50*9880d681SAndroid Build Coastguard Worker /// attributes. Unlike the SectionTypeDescriptors, this is not directly indexed
51*9880d681SAndroid Build Coastguard Worker /// by attribute, instead it is searched.
52*9880d681SAndroid Build Coastguard Worker static const struct {
53*9880d681SAndroid Build Coastguard Worker unsigned AttrFlag;
54*9880d681SAndroid Build Coastguard Worker const char *AssemblerName, *EnumName;
55*9880d681SAndroid Build Coastguard Worker } SectionAttrDescriptors[] = {
56*9880d681SAndroid Build Coastguard Worker #define ENTRY(ASMNAME, ENUM) \
57*9880d681SAndroid Build Coastguard Worker { MachO::ENUM, ASMNAME, #ENUM },
58*9880d681SAndroid Build Coastguard Worker ENTRY("pure_instructions", S_ATTR_PURE_INSTRUCTIONS)
59*9880d681SAndroid Build Coastguard Worker ENTRY("no_toc", S_ATTR_NO_TOC)
60*9880d681SAndroid Build Coastguard Worker ENTRY("strip_static_syms", S_ATTR_STRIP_STATIC_SYMS)
61*9880d681SAndroid Build Coastguard Worker ENTRY("no_dead_strip", S_ATTR_NO_DEAD_STRIP)
62*9880d681SAndroid Build Coastguard Worker ENTRY("live_support", S_ATTR_LIVE_SUPPORT)
63*9880d681SAndroid Build Coastguard Worker ENTRY("self_modifying_code", S_ATTR_SELF_MODIFYING_CODE)
64*9880d681SAndroid Build Coastguard Worker ENTRY("debug", S_ATTR_DEBUG)
65*9880d681SAndroid Build Coastguard Worker ENTRY(nullptr /*FIXME*/, S_ATTR_SOME_INSTRUCTIONS)
66*9880d681SAndroid Build Coastguard Worker ENTRY(nullptr /*FIXME*/, S_ATTR_EXT_RELOC)
67*9880d681SAndroid Build Coastguard Worker ENTRY(nullptr /*FIXME*/, S_ATTR_LOC_RELOC)
68*9880d681SAndroid Build Coastguard Worker #undef ENTRY
69*9880d681SAndroid Build Coastguard Worker { 0, "none", nullptr }, // used if section has no attributes but has a stub size
70*9880d681SAndroid Build Coastguard Worker };
71*9880d681SAndroid Build Coastguard Worker
MCSectionMachO(StringRef Segment,StringRef Section,unsigned TAA,unsigned reserved2,SectionKind K,MCSymbol * Begin)72*9880d681SAndroid Build Coastguard Worker MCSectionMachO::MCSectionMachO(StringRef Segment, StringRef Section,
73*9880d681SAndroid Build Coastguard Worker unsigned TAA, unsigned reserved2, SectionKind K,
74*9880d681SAndroid Build Coastguard Worker MCSymbol *Begin)
75*9880d681SAndroid Build Coastguard Worker : MCSection(SV_MachO, K, Begin), TypeAndAttributes(TAA),
76*9880d681SAndroid Build Coastguard Worker Reserved2(reserved2) {
77*9880d681SAndroid Build Coastguard Worker assert(Segment.size() <= 16 && Section.size() <= 16 &&
78*9880d681SAndroid Build Coastguard Worker "Segment or section string too long");
79*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0; i != 16; ++i) {
80*9880d681SAndroid Build Coastguard Worker if (i < Segment.size())
81*9880d681SAndroid Build Coastguard Worker SegmentName[i] = Segment[i];
82*9880d681SAndroid Build Coastguard Worker else
83*9880d681SAndroid Build Coastguard Worker SegmentName[i] = 0;
84*9880d681SAndroid Build Coastguard Worker
85*9880d681SAndroid Build Coastguard Worker if (i < Section.size())
86*9880d681SAndroid Build Coastguard Worker SectionName[i] = Section[i];
87*9880d681SAndroid Build Coastguard Worker else
88*9880d681SAndroid Build Coastguard Worker SectionName[i] = 0;
89*9880d681SAndroid Build Coastguard Worker }
90*9880d681SAndroid Build Coastguard Worker }
91*9880d681SAndroid Build Coastguard Worker
PrintSwitchToSection(const MCAsmInfo & MAI,raw_ostream & OS,const MCExpr * Subsection) const92*9880d681SAndroid Build Coastguard Worker void MCSectionMachO::PrintSwitchToSection(const MCAsmInfo &MAI,
93*9880d681SAndroid Build Coastguard Worker raw_ostream &OS,
94*9880d681SAndroid Build Coastguard Worker const MCExpr *Subsection) const {
95*9880d681SAndroid Build Coastguard Worker OS << "\t.section\t" << getSegmentName() << ',' << getSectionName();
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker // Get the section type and attributes.
98*9880d681SAndroid Build Coastguard Worker unsigned TAA = getTypeAndAttributes();
99*9880d681SAndroid Build Coastguard Worker if (TAA == 0) {
100*9880d681SAndroid Build Coastguard Worker OS << '\n';
101*9880d681SAndroid Build Coastguard Worker return;
102*9880d681SAndroid Build Coastguard Worker }
103*9880d681SAndroid Build Coastguard Worker
104*9880d681SAndroid Build Coastguard Worker MachO::SectionType SectionType = getType();
105*9880d681SAndroid Build Coastguard Worker assert(SectionType <= MachO::LAST_KNOWN_SECTION_TYPE &&
106*9880d681SAndroid Build Coastguard Worker "Invalid SectionType specified!");
107*9880d681SAndroid Build Coastguard Worker
108*9880d681SAndroid Build Coastguard Worker if (SectionTypeDescriptors[SectionType].AssemblerName) {
109*9880d681SAndroid Build Coastguard Worker OS << ',';
110*9880d681SAndroid Build Coastguard Worker OS << SectionTypeDescriptors[SectionType].AssemblerName;
111*9880d681SAndroid Build Coastguard Worker } else {
112*9880d681SAndroid Build Coastguard Worker // If we have no name for the attribute, stop here.
113*9880d681SAndroid Build Coastguard Worker OS << '\n';
114*9880d681SAndroid Build Coastguard Worker return;
115*9880d681SAndroid Build Coastguard Worker }
116*9880d681SAndroid Build Coastguard Worker
117*9880d681SAndroid Build Coastguard Worker // If we don't have any attributes, we're done.
118*9880d681SAndroid Build Coastguard Worker unsigned SectionAttrs = TAA & MachO::SECTION_ATTRIBUTES;
119*9880d681SAndroid Build Coastguard Worker if (SectionAttrs == 0) {
120*9880d681SAndroid Build Coastguard Worker // If we have a S_SYMBOL_STUBS size specified, print it along with 'none' as
121*9880d681SAndroid Build Coastguard Worker // the attribute specifier.
122*9880d681SAndroid Build Coastguard Worker if (Reserved2 != 0)
123*9880d681SAndroid Build Coastguard Worker OS << ",none," << Reserved2;
124*9880d681SAndroid Build Coastguard Worker OS << '\n';
125*9880d681SAndroid Build Coastguard Worker return;
126*9880d681SAndroid Build Coastguard Worker }
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Worker // Check each attribute to see if we have it.
129*9880d681SAndroid Build Coastguard Worker char Separator = ',';
130*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0;
131*9880d681SAndroid Build Coastguard Worker SectionAttrs != 0 && SectionAttrDescriptors[i].AttrFlag;
132*9880d681SAndroid Build Coastguard Worker ++i) {
133*9880d681SAndroid Build Coastguard Worker // Check to see if we have this attribute.
134*9880d681SAndroid Build Coastguard Worker if ((SectionAttrDescriptors[i].AttrFlag & SectionAttrs) == 0)
135*9880d681SAndroid Build Coastguard Worker continue;
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Worker // Yep, clear it and print it.
138*9880d681SAndroid Build Coastguard Worker SectionAttrs &= ~SectionAttrDescriptors[i].AttrFlag;
139*9880d681SAndroid Build Coastguard Worker
140*9880d681SAndroid Build Coastguard Worker OS << Separator;
141*9880d681SAndroid Build Coastguard Worker if (SectionAttrDescriptors[i].AssemblerName)
142*9880d681SAndroid Build Coastguard Worker OS << SectionAttrDescriptors[i].AssemblerName;
143*9880d681SAndroid Build Coastguard Worker else
144*9880d681SAndroid Build Coastguard Worker OS << "<<" << SectionAttrDescriptors[i].EnumName << ">>";
145*9880d681SAndroid Build Coastguard Worker Separator = '+';
146*9880d681SAndroid Build Coastguard Worker }
147*9880d681SAndroid Build Coastguard Worker
148*9880d681SAndroid Build Coastguard Worker assert(SectionAttrs == 0 && "Unknown section attributes!");
149*9880d681SAndroid Build Coastguard Worker
150*9880d681SAndroid Build Coastguard Worker // If we have a S_SYMBOL_STUBS size specified, print it.
151*9880d681SAndroid Build Coastguard Worker if (Reserved2 != 0)
152*9880d681SAndroid Build Coastguard Worker OS << ',' << Reserved2;
153*9880d681SAndroid Build Coastguard Worker OS << '\n';
154*9880d681SAndroid Build Coastguard Worker }
155*9880d681SAndroid Build Coastguard Worker
UseCodeAlign() const156*9880d681SAndroid Build Coastguard Worker bool MCSectionMachO::UseCodeAlign() const {
157*9880d681SAndroid Build Coastguard Worker return hasAttribute(MachO::S_ATTR_PURE_INSTRUCTIONS);
158*9880d681SAndroid Build Coastguard Worker }
159*9880d681SAndroid Build Coastguard Worker
isVirtualSection() const160*9880d681SAndroid Build Coastguard Worker bool MCSectionMachO::isVirtualSection() const {
161*9880d681SAndroid Build Coastguard Worker return (getType() == MachO::S_ZEROFILL ||
162*9880d681SAndroid Build Coastguard Worker getType() == MachO::S_GB_ZEROFILL ||
163*9880d681SAndroid Build Coastguard Worker getType() == MachO::S_THREAD_LOCAL_ZEROFILL);
164*9880d681SAndroid Build Coastguard Worker }
165*9880d681SAndroid Build Coastguard Worker
166*9880d681SAndroid Build Coastguard Worker /// ParseSectionSpecifier - Parse the section specifier indicated by "Spec".
167*9880d681SAndroid Build Coastguard Worker /// This is a string that can appear after a .section directive in a mach-o
168*9880d681SAndroid Build Coastguard Worker /// flavored .s file. If successful, this fills in the specified Out
169*9880d681SAndroid Build Coastguard Worker /// parameters and returns an empty string. When an invalid section
170*9880d681SAndroid Build Coastguard Worker /// specifier is present, this returns a string indicating the problem.
ParseSectionSpecifier(StringRef Spec,StringRef & Segment,StringRef & Section,unsigned & TAA,bool & TAAParsed,unsigned & StubSize)171*9880d681SAndroid Build Coastguard Worker std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In.
172*9880d681SAndroid Build Coastguard Worker StringRef &Segment, // Out.
173*9880d681SAndroid Build Coastguard Worker StringRef &Section, // Out.
174*9880d681SAndroid Build Coastguard Worker unsigned &TAA, // Out.
175*9880d681SAndroid Build Coastguard Worker bool &TAAParsed, // Out.
176*9880d681SAndroid Build Coastguard Worker unsigned &StubSize) { // Out.
177*9880d681SAndroid Build Coastguard Worker TAAParsed = false;
178*9880d681SAndroid Build Coastguard Worker
179*9880d681SAndroid Build Coastguard Worker SmallVector<StringRef, 5> SplitSpec;
180*9880d681SAndroid Build Coastguard Worker Spec.split(SplitSpec, ',');
181*9880d681SAndroid Build Coastguard Worker // Remove leading and trailing whitespace.
182*9880d681SAndroid Build Coastguard Worker auto GetEmptyOrTrim = [&SplitSpec](size_t Idx) -> StringRef {
183*9880d681SAndroid Build Coastguard Worker return SplitSpec.size() > Idx ? SplitSpec[Idx].trim() : StringRef();
184*9880d681SAndroid Build Coastguard Worker };
185*9880d681SAndroid Build Coastguard Worker Segment = GetEmptyOrTrim(0);
186*9880d681SAndroid Build Coastguard Worker Section = GetEmptyOrTrim(1);
187*9880d681SAndroid Build Coastguard Worker StringRef SectionType = GetEmptyOrTrim(2);
188*9880d681SAndroid Build Coastguard Worker StringRef Attrs = GetEmptyOrTrim(3);
189*9880d681SAndroid Build Coastguard Worker StringRef StubSizeStr = GetEmptyOrTrim(4);
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Worker // Verify that the segment is present and not too long.
192*9880d681SAndroid Build Coastguard Worker if (Segment.empty() || Segment.size() > 16)
193*9880d681SAndroid Build Coastguard Worker return "mach-o section specifier requires a segment whose length is "
194*9880d681SAndroid Build Coastguard Worker "between 1 and 16 characters";
195*9880d681SAndroid Build Coastguard Worker
196*9880d681SAndroid Build Coastguard Worker // Verify that the section is present and not too long.
197*9880d681SAndroid Build Coastguard Worker if (Section.empty())
198*9880d681SAndroid Build Coastguard Worker return "mach-o section specifier requires a segment and section "
199*9880d681SAndroid Build Coastguard Worker "separated by a comma";
200*9880d681SAndroid Build Coastguard Worker
201*9880d681SAndroid Build Coastguard Worker if (Section.size() > 16)
202*9880d681SAndroid Build Coastguard Worker return "mach-o section specifier requires a section whose length is "
203*9880d681SAndroid Build Coastguard Worker "between 1 and 16 characters";
204*9880d681SAndroid Build Coastguard Worker
205*9880d681SAndroid Build Coastguard Worker // If there is no comma after the section, we're done.
206*9880d681SAndroid Build Coastguard Worker TAA = 0;
207*9880d681SAndroid Build Coastguard Worker StubSize = 0;
208*9880d681SAndroid Build Coastguard Worker if (SectionType.empty())
209*9880d681SAndroid Build Coastguard Worker return "";
210*9880d681SAndroid Build Coastguard Worker
211*9880d681SAndroid Build Coastguard Worker // Figure out which section type it is.
212*9880d681SAndroid Build Coastguard Worker auto TypeDescriptor = std::find_if(
213*9880d681SAndroid Build Coastguard Worker std::begin(SectionTypeDescriptors), std::end(SectionTypeDescriptors),
214*9880d681SAndroid Build Coastguard Worker [&](decltype(*SectionTypeDescriptors) &Descriptor) {
215*9880d681SAndroid Build Coastguard Worker return Descriptor.AssemblerName &&
216*9880d681SAndroid Build Coastguard Worker SectionType == Descriptor.AssemblerName;
217*9880d681SAndroid Build Coastguard Worker });
218*9880d681SAndroid Build Coastguard Worker
219*9880d681SAndroid Build Coastguard Worker // If we didn't find the section type, reject it.
220*9880d681SAndroid Build Coastguard Worker if (TypeDescriptor == std::end(SectionTypeDescriptors))
221*9880d681SAndroid Build Coastguard Worker return "mach-o section specifier uses an unknown section type";
222*9880d681SAndroid Build Coastguard Worker
223*9880d681SAndroid Build Coastguard Worker // Remember the TypeID.
224*9880d681SAndroid Build Coastguard Worker TAA = TypeDescriptor - std::begin(SectionTypeDescriptors);
225*9880d681SAndroid Build Coastguard Worker TAAParsed = true;
226*9880d681SAndroid Build Coastguard Worker
227*9880d681SAndroid Build Coastguard Worker // If we have no comma after the section type, there are no attributes.
228*9880d681SAndroid Build Coastguard Worker if (Attrs.empty()) {
229*9880d681SAndroid Build Coastguard Worker // S_SYMBOL_STUBS always require a symbol stub size specifier.
230*9880d681SAndroid Build Coastguard Worker if (TAA == MachO::S_SYMBOL_STUBS)
231*9880d681SAndroid Build Coastguard Worker return "mach-o section specifier of type 'symbol_stubs' requires a size "
232*9880d681SAndroid Build Coastguard Worker "specifier";
233*9880d681SAndroid Build Coastguard Worker return "";
234*9880d681SAndroid Build Coastguard Worker }
235*9880d681SAndroid Build Coastguard Worker
236*9880d681SAndroid Build Coastguard Worker // The attribute list is a '+' separated list of attributes.
237*9880d681SAndroid Build Coastguard Worker SmallVector<StringRef, 1> SectionAttrs;
238*9880d681SAndroid Build Coastguard Worker Attrs.split(SectionAttrs, '+', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
239*9880d681SAndroid Build Coastguard Worker
240*9880d681SAndroid Build Coastguard Worker for (StringRef &SectionAttr : SectionAttrs) {
241*9880d681SAndroid Build Coastguard Worker auto AttrDescriptorI = std::find_if(
242*9880d681SAndroid Build Coastguard Worker std::begin(SectionAttrDescriptors), std::end(SectionAttrDescriptors),
243*9880d681SAndroid Build Coastguard Worker [&](decltype(*SectionAttrDescriptors) &Descriptor) {
244*9880d681SAndroid Build Coastguard Worker return Descriptor.AssemblerName &&
245*9880d681SAndroid Build Coastguard Worker SectionAttr.trim() == Descriptor.AssemblerName;
246*9880d681SAndroid Build Coastguard Worker });
247*9880d681SAndroid Build Coastguard Worker if (AttrDescriptorI == std::end(SectionAttrDescriptors))
248*9880d681SAndroid Build Coastguard Worker return "mach-o section specifier has invalid attribute";
249*9880d681SAndroid Build Coastguard Worker
250*9880d681SAndroid Build Coastguard Worker TAA |= AttrDescriptorI->AttrFlag;
251*9880d681SAndroid Build Coastguard Worker }
252*9880d681SAndroid Build Coastguard Worker
253*9880d681SAndroid Build Coastguard Worker // Okay, we've parsed the section attributes, see if we have a stub size spec.
254*9880d681SAndroid Build Coastguard Worker if (StubSizeStr.empty()) {
255*9880d681SAndroid Build Coastguard Worker // S_SYMBOL_STUBS always require a symbol stub size specifier.
256*9880d681SAndroid Build Coastguard Worker if (TAA == MachO::S_SYMBOL_STUBS)
257*9880d681SAndroid Build Coastguard Worker return "mach-o section specifier of type 'symbol_stubs' requires a size "
258*9880d681SAndroid Build Coastguard Worker "specifier";
259*9880d681SAndroid Build Coastguard Worker return "";
260*9880d681SAndroid Build Coastguard Worker }
261*9880d681SAndroid Build Coastguard Worker
262*9880d681SAndroid Build Coastguard Worker // If we have a stub size spec, we must have a sectiontype of S_SYMBOL_STUBS.
263*9880d681SAndroid Build Coastguard Worker if ((TAA & MachO::SECTION_TYPE) != MachO::S_SYMBOL_STUBS)
264*9880d681SAndroid Build Coastguard Worker return "mach-o section specifier cannot have a stub size specified because "
265*9880d681SAndroid Build Coastguard Worker "it does not have type 'symbol_stubs'";
266*9880d681SAndroid Build Coastguard Worker
267*9880d681SAndroid Build Coastguard Worker // Convert the stub size from a string to an integer.
268*9880d681SAndroid Build Coastguard Worker if (StubSizeStr.getAsInteger(0, StubSize))
269*9880d681SAndroid Build Coastguard Worker return "mach-o section specifier has a malformed stub size";
270*9880d681SAndroid Build Coastguard Worker
271*9880d681SAndroid Build Coastguard Worker return "";
272*9880d681SAndroid Build Coastguard Worker }
273