1f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner//===- lib/MC/MCSectionMachO.cpp - MachO Code Section Representation ------===//
2f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner//
3f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner//                     The LLVM Compiler Infrastructure
4f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner//
5f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner// This file is distributed under the University of Illinois Open Source
6f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner// License. See LICENSE.TXT for details.
7f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner//
8f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner//===----------------------------------------------------------------------===//
9f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
10f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#include "llvm/MC/MCSectionMachO.h"
11f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#include "llvm/MC/MCContext.h"
12f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#include "llvm/Support/raw_ostream.h"
13476b242fe7a61e5f9ac6214b0bc5c680d24f152eNick Lewycky#include <cctype>
14f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattnerusing namespace llvm;
15f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
16f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner/// SectionTypeDescriptors - These are strings that describe the various section
17f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner/// types.  This *must* be kept in order with and stay synchronized with the
18f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner/// section type list.
19f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattnerstatic const struct {
20f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  const char *AssemblerName, *EnumName;
21f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner} SectionTypeDescriptors[MCSectionMachO::LAST_KNOWN_SECTION_TYPE+1] = {
22f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { "regular",                  "S_REGULAR" },                    // 0x00
23f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { 0,                          "S_ZEROFILL" },                   // 0x01
24f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { "cstring_literals",         "S_CSTRING_LITERALS" },           // 0x02
25f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { "4byte_literals",           "S_4BYTE_LITERALS" },             // 0x03
26f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { "8byte_literals",           "S_8BYTE_LITERALS" },             // 0x04
27f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { "literal_pointers",         "S_LITERAL_POINTERS" },           // 0x05
28f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { "non_lazy_symbol_pointers", "S_NON_LAZY_SYMBOL_POINTERS" },   // 0x06
29f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { "lazy_symbol_pointers",     "S_LAZY_SYMBOL_POINTERS" },       // 0x07
30f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { "symbol_stubs",             "S_SYMBOL_STUBS" },               // 0x08
31f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { "mod_init_funcs",           "S_MOD_INIT_FUNC_POINTERS" },     // 0x09
32f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { "mod_term_funcs",           "S_MOD_TERM_FUNC_POINTERS" },     // 0x0A
33f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { "coalesced",                "S_COALESCED" },                  // 0x0B
34f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { 0, /*FIXME??*/              "S_GB_ZEROFILL" },                // 0x0C
35f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { "interposing",              "S_INTERPOSING" },                // 0x0D
36f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { "16byte_literals",          "S_16BYTE_LITERALS" },            // 0x0E
37f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { 0, /*FIXME??*/              "S_DTRACE_DOF" },                 // 0x0F
38423c9e3e589a79be757842d421600590c68d5b43Eric Christopher  { 0, /*FIXME??*/              "S_LAZY_DYLIB_SYMBOL_POINTERS" }, // 0x10
39423c9e3e589a79be757842d421600590c68d5b43Eric Christopher  { "thread_local_regular",     "S_THREAD_LOCAL_REGULAR" },       // 0x11
409b00685bb66ad8237dc1e40bcaee10e9b9232beeEric Christopher  { "thread_local_zerofill",    "S_THREAD_LOCAL_ZEROFILL" },      // 0x12
41423c9e3e589a79be757842d421600590c68d5b43Eric Christopher  { "thread_local_variables",   "S_THREAD_LOCAL_VARIABLES" },     // 0x13
42423c9e3e589a79be757842d421600590c68d5b43Eric Christopher  { "thread_local_variable_pointers",
43423c9e3e589a79be757842d421600590c68d5b43Eric Christopher    "S_THREAD_LOCAL_VARIABLE_POINTERS" },                         // 0x14
44423c9e3e589a79be757842d421600590c68d5b43Eric Christopher  { "thread_local_init_function_pointers",
45423c9e3e589a79be757842d421600590c68d5b43Eric Christopher    "S_THREAD_LOCAL_INIT_FUNCTION_POINTERS"},                     // 0x15
46f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner};
47f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
48f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
49f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner/// SectionAttrDescriptors - This is an array of descriptors for section
50f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner/// attributes.  Unlike the SectionTypeDescriptors, this is not directly indexed
515440f6309d6b714475a631b12307432c719cd066Kevin Enderby/// by attribute, instead it is searched.  The last entry has an AttrFlagEnd
525440f6309d6b714475a631b12307432c719cd066Kevin Enderby/// AttrFlag value.
53f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattnerstatic const struct {
54f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  unsigned AttrFlag;
55f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  const char *AssemblerName, *EnumName;
56f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner} SectionAttrDescriptors[] = {
57f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#define ENTRY(ASMNAME, ENUM) \
58f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { MCSectionMachO::ENUM, ASMNAME, #ENUM },
59f9bdeddb96043559c61f176f8077e3b91a0c544fChris LattnerENTRY("pure_instructions",   S_ATTR_PURE_INSTRUCTIONS)
60f9bdeddb96043559c61f176f8077e3b91a0c544fChris LattnerENTRY("no_toc",              S_ATTR_NO_TOC)
61f9bdeddb96043559c61f176f8077e3b91a0c544fChris LattnerENTRY("strip_static_syms",   S_ATTR_STRIP_STATIC_SYMS)
62f9bdeddb96043559c61f176f8077e3b91a0c544fChris LattnerENTRY("no_dead_strip",       S_ATTR_NO_DEAD_STRIP)
63f9bdeddb96043559c61f176f8077e3b91a0c544fChris LattnerENTRY("live_support",        S_ATTR_LIVE_SUPPORT)
64f9bdeddb96043559c61f176f8077e3b91a0c544fChris LattnerENTRY("self_modifying_code", S_ATTR_SELF_MODIFYING_CODE)
65f9bdeddb96043559c61f176f8077e3b91a0c544fChris LattnerENTRY("debug",               S_ATTR_DEBUG)
66f9bdeddb96043559c61f176f8077e3b91a0c544fChris LattnerENTRY(0 /*FIXME*/,           S_ATTR_SOME_INSTRUCTIONS)
67f9bdeddb96043559c61f176f8077e3b91a0c544fChris LattnerENTRY(0 /*FIXME*/,           S_ATTR_EXT_RELOC)
68f9bdeddb96043559c61f176f8077e3b91a0c544fChris LattnerENTRY(0 /*FIXME*/,           S_ATTR_LOC_RELOC)
69f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#undef ENTRY
705440f6309d6b714475a631b12307432c719cd066Kevin Enderby  { 0, "none", 0 }, // used if section has no attributes but has a stub size
715440f6309d6b714475a631b12307432c719cd066Kevin Enderby#define AttrFlagEnd 0xffffffff // non legal value, multiple attribute bits set
725440f6309d6b714475a631b12307432c719cd066Kevin Enderby  { AttrFlagEnd, 0, 0 }
73f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner};
74f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
7574aae4726a66733c5872588287535a984f9a94c7Chris LattnerMCSectionMachO::MCSectionMachO(StringRef Segment, StringRef Section,
7674aae4726a66733c5872588287535a984f9a94c7Chris Lattner                               unsigned TAA, unsigned reserved2, SectionKind K)
779a744e38607bc3046dffea56efec0b2dfc51d5e4Daniel Dunbar  : MCSection(SV_MachO, K), TypeAndAttributes(TAA), Reserved2(reserved2) {
7874aae4726a66733c5872588287535a984f9a94c7Chris Lattner  assert(Segment.size() <= 16 && Section.size() <= 16 &&
7974aae4726a66733c5872588287535a984f9a94c7Chris Lattner         "Segment or section string too long");
8074aae4726a66733c5872588287535a984f9a94c7Chris Lattner  for (unsigned i = 0; i != 16; ++i) {
8174aae4726a66733c5872588287535a984f9a94c7Chris Lattner    if (i < Segment.size())
8274aae4726a66733c5872588287535a984f9a94c7Chris Lattner      SegmentName[i] = Segment[i];
8374aae4726a66733c5872588287535a984f9a94c7Chris Lattner    else
8474aae4726a66733c5872588287535a984f9a94c7Chris Lattner      SegmentName[i] = 0;
85fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
8674aae4726a66733c5872588287535a984f9a94c7Chris Lattner    if (i < Section.size())
8774aae4726a66733c5872588287535a984f9a94c7Chris Lattner      SectionName[i] = Section[i];
8874aae4726a66733c5872588287535a984f9a94c7Chris Lattner    else
8974aae4726a66733c5872588287535a984f9a94c7Chris Lattner      SectionName[i] = 0;
90fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach  }
91f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner}
92f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
9333adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattnervoid MCSectionMachO::PrintSwitchToSection(const MCAsmInfo &MAI,
94f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner                                          raw_ostream &OS) const {
95f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  OS << "\t.section\t" << getSegmentName() << ',' << getSectionName();
96fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
97f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Get the section type and attributes.
98f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  unsigned TAA = getTypeAndAttributes();
99f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  if (TAA == 0) {
100f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    OS << '\n';
101f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    return;
102f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  }
103f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
104f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  unsigned SectionType = TAA & MCSectionMachO::SECTION_TYPE;
105f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  assert(SectionType <= MCSectionMachO::LAST_KNOWN_SECTION_TYPE &&
106f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner         "Invalid SectionType specified!");
107f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
1086ad82d81cc3061a000799ad8751f018c1301906bStuart Hastings  if (SectionTypeDescriptors[SectionType].AssemblerName) {
1096ad82d81cc3061a000799ad8751f018c1301906bStuart Hastings    OS << ',';
110f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    OS << SectionTypeDescriptors[SectionType].AssemblerName;
11137c79c59420763ab78aaaef0b54ac6a702325c3eStuart Hastings  } else {
1126ad82d81cc3061a000799ad8751f018c1301906bStuart Hastings    // If we have no name for the attribute, stop here.
11337c79c59420763ab78aaaef0b54ac6a702325c3eStuart Hastings    OS << '\n';
1146ad82d81cc3061a000799ad8751f018c1301906bStuart Hastings    return;
11537c79c59420763ab78aaaef0b54ac6a702325c3eStuart Hastings  }
116fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
117f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // If we don't have any attributes, we're done.
118f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  unsigned SectionAttrs = TAA & MCSectionMachO::SECTION_ATTRIBUTES;
119f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  if (SectionAttrs == 0) {
120f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    // If we have a S_SYMBOL_STUBS size specified, print it along with 'none' as
121f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    // the attribute specifier.
122f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    if (Reserved2 != 0)
123f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner      OS << ",none," << Reserved2;
124f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    OS << '\n';
125f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    return;
126f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  }
127f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
128f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Check each attribute to see if we have it.
129f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  char Separator = ',';
1306ad82d81cc3061a000799ad8751f018c1301906bStuart Hastings  for (unsigned i = 0;
1316ad82d81cc3061a000799ad8751f018c1301906bStuart Hastings       SectionAttrs != 0 && SectionAttrDescriptors[i].AttrFlag;
1326ad82d81cc3061a000799ad8751f018c1301906bStuart Hastings       ++i) {
133f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    // Check to see if we have this attribute.
134f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    if ((SectionAttrDescriptors[i].AttrFlag & SectionAttrs) == 0)
135f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner      continue;
136fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
137f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    // Yep, clear it and print it.
138f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    SectionAttrs &= ~SectionAttrDescriptors[i].AttrFlag;
139fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
140f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    OS << Separator;
141f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    if (SectionAttrDescriptors[i].AssemblerName)
142f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner      OS << SectionAttrDescriptors[i].AssemblerName;
143f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    else
144f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner      OS << "<<" << SectionAttrDescriptors[i].EnumName << ">>";
145f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    Separator = '+';
146f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  }
147fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
148f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  assert(SectionAttrs == 0 && "Unknown section attributes!");
149fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
150f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // If we have a S_SYMBOL_STUBS size specified, print it.
151f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  if (Reserved2 != 0)
152f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    OS << ',' << Reserved2;
153f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  OS << '\n';
154f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner}
155f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
156083cf1574facc9ce468fba1735c794bd7e520108Jan Wen Voungbool MCSectionMachO::UseCodeAlign() const {
157083cf1574facc9ce468fba1735c794bd7e520108Jan Wen Voung  return hasAttribute(MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS);
158083cf1574facc9ce468fba1735c794bd7e520108Jan Wen Voung}
159083cf1574facc9ce468fba1735c794bd7e520108Jan Wen Voung
160f2dc4aa562e2478a73fe5aeeeec16b1e496a0642Rafael Espindolabool MCSectionMachO::isVirtualSection() const {
161f2dc4aa562e2478a73fe5aeeeec16b1e496a0642Rafael Espindola  return (getType() == MCSectionMachO::S_ZEROFILL ||
162f2dc4aa562e2478a73fe5aeeeec16b1e496a0642Rafael Espindola          getType() == MCSectionMachO::S_GB_ZEROFILL ||
163f2dc4aa562e2478a73fe5aeeeec16b1e496a0642Rafael Espindola          getType() == MCSectionMachO::S_THREAD_LOCAL_ZEROFILL);
164f2dc4aa562e2478a73fe5aeeeec16b1e496a0642Rafael Espindola}
165f2dc4aa562e2478a73fe5aeeeec16b1e496a0642Rafael Espindola
166f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner/// StripSpaces - This removes leading and trailing spaces from the StringRef.
167f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattnerstatic void StripSpaces(StringRef &Str) {
168f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  while (!Str.empty() && isspace(Str[0]))
169f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    Str = Str.substr(1);
170f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  while (!Str.empty() && isspace(Str.back()))
171f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    Str = Str.substr(0, Str.size()-1);
172f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner}
173f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
174f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner/// ParseSectionSpecifier - Parse the section specifier indicated by "Spec".
175f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner/// This is a string that can appear after a .section directive in a mach-o
176f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner/// flavored .s file.  If successful, this fills in the specified Out
177f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner/// parameters and returns an empty string.  When an invalid section
178f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner/// specifier is present, this returns a string indicating the problem.
179f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattnerstd::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec,        // In.
180f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner                                                  StringRef &Segment,    // Out.
181f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner                                                  StringRef &Section,    // Out.
182f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner                                                  unsigned  &TAA,        // Out.
18365c8bca78854712ab2bf135c2008ed455ef0c9b7Stuart Hastings                                                  bool      &TAAParsed,  // Out.
184f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner                                                  unsigned  &StubSize) { // Out.
18565c8bca78854712ab2bf135c2008ed455ef0c9b7Stuart Hastings  TAAParsed = false;
186f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Find the first comma.
187f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  std::pair<StringRef, StringRef> Comma = Spec.split(',');
188fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
189f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // If there is no comma, we fail.
190f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  if (Comma.second.empty())
191f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    return "mach-o section specifier requires a segment and section "
192f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner           "separated by a comma";
193fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
194f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Capture segment, remove leading and trailing whitespace.
195f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  Segment = Comma.first;
196f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  StripSpaces(Segment);
197f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
198f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Verify that the segment is present and not too long.
199f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  if (Segment.empty() || Segment.size() > 16)
200f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    return "mach-o section specifier requires a segment whose length is "
201f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner           "between 1 and 16 characters";
202fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
203f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Split the section name off from any attributes if present.
204f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  Comma = Comma.second.split(',');
205f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
206f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Capture section, remove leading and trailing whitespace.
207f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  Section = Comma.first;
208f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  StripSpaces(Section);
209fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
210f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Verify that the section is present and not too long.
211f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  if (Section.empty() || Section.size() > 16)
212f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    return "mach-o section specifier requires a section whose length is "
213f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner           "between 1 and 16 characters";
214f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
215f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // If there is no comma after the section, we're done.
21665c8bca78854712ab2bf135c2008ed455ef0c9b7Stuart Hastings  TAA = 0;
217f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  StubSize = 0;
218f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  if (Comma.second.empty())
219f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    return "";
220fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
221f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Otherwise, we need to parse the section type and attributes.
222f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  Comma = Comma.second.split(',');
223fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
224f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Get the section type.
225f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  StringRef SectionType = Comma.first;
226f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  StripSpaces(SectionType);
227fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
228f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Figure out which section type it is.
229f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  unsigned TypeID;
230f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  for (TypeID = 0; TypeID !=MCSectionMachO::LAST_KNOWN_SECTION_TYPE+1; ++TypeID)
231f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    if (SectionTypeDescriptors[TypeID].AssemblerName &&
232f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner        SectionType == SectionTypeDescriptors[TypeID].AssemblerName)
233f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner      break;
234fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
235f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // If we didn't find the section type, reject it.
236f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  if (TypeID > MCSectionMachO::LAST_KNOWN_SECTION_TYPE)
237f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    return "mach-o section specifier uses an unknown section type";
238fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
239f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Remember the TypeID.
240f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  TAA = TypeID;
24165c8bca78854712ab2bf135c2008ed455ef0c9b7Stuart Hastings  TAAParsed = true;
242f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
243f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // If we have no comma after the section type, there are no attributes.
244f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  if (Comma.second.empty()) {
245f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    // S_SYMBOL_STUBS always require a symbol stub size specifier.
246f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    if (TAA == MCSectionMachO::S_SYMBOL_STUBS)
247f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner      return "mach-o section specifier of type 'symbol_stubs' requires a size "
248f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner             "specifier";
249f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    return "";
250f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  }
251f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
252f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Otherwise, we do have some attributes.  Split off the size specifier if
253f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // present.
254f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  Comma = Comma.second.split(',');
255f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  StringRef Attrs = Comma.first;
256fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
257f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // The attribute list is a '+' separated list of attributes.
258f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  std::pair<StringRef, StringRef> Plus = Attrs.split('+');
259fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
260f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  while (1) {
261f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    StringRef Attr = Plus.first;
262f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    StripSpaces(Attr);
263f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
264f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    // Look up the attribute.
265f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    for (unsigned i = 0; ; ++i) {
2665440f6309d6b714475a631b12307432c719cd066Kevin Enderby      if (SectionAttrDescriptors[i].AttrFlag == AttrFlagEnd)
267f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner        return "mach-o section specifier has invalid attribute";
268fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
269f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner      if (SectionAttrDescriptors[i].AssemblerName &&
270f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner          Attr == SectionAttrDescriptors[i].AssemblerName) {
271f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner        TAA |= SectionAttrDescriptors[i].AttrFlag;
272f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner        break;
273f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner      }
274f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    }
275fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
276f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    if (Plus.second.empty()) break;
277f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    Plus = Plus.second.split('+');
278f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  };
279f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
280f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Okay, we've parsed the section attributes, see if we have a stub size spec.
281f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  if (Comma.second.empty()) {
282f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    // S_SYMBOL_STUBS always require a symbol stub size specifier.
283f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    if (TAA == MCSectionMachO::S_SYMBOL_STUBS)
284f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner      return "mach-o section specifier of type 'symbol_stubs' requires a size "
285f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner      "specifier";
286f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    return "";
287f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  }
288f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
289f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // If we have a stub size spec, we must have a sectiontype of S_SYMBOL_STUBS.
290f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  if ((TAA & MCSectionMachO::SECTION_TYPE) != MCSectionMachO::S_SYMBOL_STUBS)
291f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    return "mach-o section specifier cannot have a stub size specified because "
292f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner           "it does not have type 'symbol_stubs'";
293fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
294f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Okay, if we do, it must be a number.
295f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  StringRef StubSizeStr = Comma.second;
296f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  StripSpaces(StubSizeStr);
297fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
298d9221d75f02a81eec9c22473b4f2a809d83bf60aChris Lattner  // Convert the stub size from a string to an integer.
299d9221d75f02a81eec9c22473b4f2a809d83bf60aChris Lattner  if (StubSizeStr.getAsInteger(0, StubSize))
300f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    return "mach-o section specifier has a malformed stub size";
301fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
302f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  return "";
303f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner}
304