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;
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} SectionTypeDescriptors[MachO::LAST_KNOWN_SECTION_TYPE+1] = {
22f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { "regular",                  "S_REGULAR" },                    // 0x00
23dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  { nullptr,                    "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
34dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  { nullptr, /*FIXME??*/        "S_GB_ZEROFILL" },                // 0x0C
35f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { "interposing",              "S_INTERPOSING" },                // 0x0D
36f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  { "16byte_literals",          "S_16BYTE_LITERALS" },            // 0x0E
37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  { nullptr, /*FIXME??*/        "S_DTRACE_DOF" },                 // 0x0F
38dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  { nullptr, /*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
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// by attribute, instead it is searched.
52f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattnerstatic const struct {
53f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  unsigned AttrFlag;
54f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  const char *AssemblerName, *EnumName;
55f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner} SectionAttrDescriptors[] = {
56f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#define ENTRY(ASMNAME, ENUM) \
5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  { MachO::ENUM, ASMNAME, #ENUM },
58f9bdeddb96043559c61f176f8077e3b91a0c544fChris LattnerENTRY("pure_instructions",   S_ATTR_PURE_INSTRUCTIONS)
59f9bdeddb96043559c61f176f8077e3b91a0c544fChris LattnerENTRY("no_toc",              S_ATTR_NO_TOC)
60f9bdeddb96043559c61f176f8077e3b91a0c544fChris LattnerENTRY("strip_static_syms",   S_ATTR_STRIP_STATIC_SYMS)
61f9bdeddb96043559c61f176f8077e3b91a0c544fChris LattnerENTRY("no_dead_strip",       S_ATTR_NO_DEAD_STRIP)
62f9bdeddb96043559c61f176f8077e3b91a0c544fChris LattnerENTRY("live_support",        S_ATTR_LIVE_SUPPORT)
63f9bdeddb96043559c61f176f8077e3b91a0c544fChris LattnerENTRY("self_modifying_code", S_ATTR_SELF_MODIFYING_CODE)
64f9bdeddb96043559c61f176f8077e3b91a0c544fChris LattnerENTRY("debug",               S_ATTR_DEBUG)
65dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesENTRY(nullptr /*FIXME*/,     S_ATTR_SOME_INSTRUCTIONS)
66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesENTRY(nullptr /*FIXME*/,     S_ATTR_EXT_RELOC)
67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesENTRY(nullptr /*FIXME*/,     S_ATTR_LOC_RELOC)
68f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner#undef ENTRY
69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  { 0, "none", nullptr }, // used if section has no attributes but has a stub size
70f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner};
71f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
7274aae4726a66733c5872588287535a984f9a94c7Chris LattnerMCSectionMachO::MCSectionMachO(StringRef Segment, StringRef Section,
734c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                               unsigned TAA, unsigned reserved2, SectionKind K,
744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar                               MCSymbol *Begin)
754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    : MCSection(SV_MachO, K, Begin), TypeAndAttributes(TAA),
764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      Reserved2(reserved2) {
7774aae4726a66733c5872588287535a984f9a94c7Chris Lattner  assert(Segment.size() <= 16 && Section.size() <= 16 &&
7874aae4726a66733c5872588287535a984f9a94c7Chris Lattner         "Segment or section string too long");
7974aae4726a66733c5872588287535a984f9a94c7Chris Lattner  for (unsigned i = 0; i != 16; ++i) {
8074aae4726a66733c5872588287535a984f9a94c7Chris Lattner    if (i < Segment.size())
8174aae4726a66733c5872588287535a984f9a94c7Chris Lattner      SegmentName[i] = Segment[i];
8274aae4726a66733c5872588287535a984f9a94c7Chris Lattner    else
8374aae4726a66733c5872588287535a984f9a94c7Chris Lattner      SegmentName[i] = 0;
84fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
8574aae4726a66733c5872588287535a984f9a94c7Chris Lattner    if (i < Section.size())
8674aae4726a66733c5872588287535a984f9a94c7Chris Lattner      SectionName[i] = Section[i];
8774aae4726a66733c5872588287535a984f9a94c7Chris Lattner    else
8874aae4726a66733c5872588287535a984f9a94c7Chris Lattner      SectionName[i] = 0;
89fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach  }
90f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner}
91f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
9233adcfb4d217f5f23d9bde8ba02b8e48f9605fc5Chris Lattnervoid MCSectionMachO::PrintSwitchToSection(const MCAsmInfo &MAI,
93df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne                                          raw_ostream &OS,
94df39be6cb4eb44011db3d3e86f8fe463f81ce127Peter Collingbourne                                          const MCExpr *Subsection) 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
10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MachO::SectionType SectionType = getType();
10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(SectionType <= MachO::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.
11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned SectionAttrs = TAA & MachO::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 {
15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return hasAttribute(MachO::S_ATTR_PURE_INSTRUCTIONS);
158083cf1574facc9ce468fba1735c794bd7e520108Jan Wen Voung}
159083cf1574facc9ce468fba1735c794bd7e520108Jan Wen Voung
160f2dc4aa562e2478a73fe5aeeeec16b1e496a0642Rafael Espindolabool MCSectionMachO::isVirtualSection() const {
16136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return (getType() == MachO::S_ZEROFILL ||
16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          getType() == MachO::S_GB_ZEROFILL ||
16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          getType() == MachO::S_THREAD_LOCAL_ZEROFILL);
164f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner}
165f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
166f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner/// ParseSectionSpecifier - Parse the section specifier indicated by "Spec".
167f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner/// This is a string that can appear after a .section directive in a mach-o
168f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner/// flavored .s file.  If successful, this fills in the specified Out
169f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner/// parameters and returns an empty string.  When an invalid section
170f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner/// specifier is present, this returns a string indicating the problem.
171f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattnerstd::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec,        // In.
172f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner                                                  StringRef &Segment,    // Out.
173f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner                                                  StringRef &Section,    // Out.
174f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner                                                  unsigned  &TAA,        // Out.
17565c8bca78854712ab2bf135c2008ed455ef0c9b7Stuart Hastings                                                  bool      &TAAParsed,  // Out.
176f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner                                                  unsigned  &StubSize) { // Out.
17765c8bca78854712ab2bf135c2008ed455ef0c9b7Stuart Hastings  TAAParsed = false;
178fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallVector<StringRef, 5> SplitSpec;
180f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Spec.split(SplitSpec, ',');
18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Remove leading and trailing whitespace.
18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  auto GetEmptyOrTrim = [&SplitSpec](size_t Idx) -> StringRef {
18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return SplitSpec.size() > Idx ? SplitSpec[Idx].trim() : StringRef();
18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  };
18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Segment = GetEmptyOrTrim(0);
18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Section = GetEmptyOrTrim(1);
18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StringRef SectionType = GetEmptyOrTrim(2);
18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StringRef Attrs = GetEmptyOrTrim(3);
18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StringRef StubSizeStr = GetEmptyOrTrim(4);
190f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
191f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Verify that the segment is present and not too long.
192f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  if (Segment.empty() || Segment.size() > 16)
193f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    return "mach-o section specifier requires a segment whose length is "
194f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner           "between 1 and 16 characters";
195fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
196f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Verify that the section is present and not too long.
19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Section.empty())
19836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return "mach-o section specifier requires a segment and section "
19936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           "separated by a comma";
20036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
20136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Section.size() > 16)
202f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    return "mach-o section specifier requires a section whose length is "
203f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner           "between 1 and 16 characters";
204f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
205f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // If there is no comma after the section, we're done.
20665c8bca78854712ab2bf135c2008ed455ef0c9b7Stuart Hastings  TAA = 0;
207f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  StubSize = 0;
20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (SectionType.empty())
209f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    return "";
210fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
211f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Figure out which section type it is.
21236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  auto TypeDescriptor = std::find_if(
21336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      std::begin(SectionTypeDescriptors), std::end(SectionTypeDescriptors),
21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      [&](decltype(*SectionTypeDescriptors) &Descriptor) {
21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return Descriptor.AssemblerName &&
21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines               SectionType == Descriptor.AssemblerName;
21736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      });
218fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
219f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // If we didn't find the section type, reject it.
22036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (TypeDescriptor == std::end(SectionTypeDescriptors))
221f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    return "mach-o section specifier uses an unknown section type";
222fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
223f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Remember the TypeID.
22436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  TAA = TypeDescriptor - std::begin(SectionTypeDescriptors);
22565c8bca78854712ab2bf135c2008ed455ef0c9b7Stuart Hastings  TAAParsed = true;
226f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
227f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // If we have no comma after the section type, there are no attributes.
22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Attrs.empty()) {
229f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    // S_SYMBOL_STUBS always require a symbol stub size specifier.
23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (TAA == MachO::S_SYMBOL_STUBS)
231f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner      return "mach-o section specifier of type 'symbol_stubs' requires a size "
232f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner             "specifier";
233f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    return "";
234f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  }
235f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
236f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // The attribute list is a '+' separated list of attributes.
23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SmallVector<StringRef, 1> SectionAttrs;
238f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Attrs.split(SectionAttrs, '+', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  for (StringRef &SectionAttr : SectionAttrs) {
24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    auto AttrDescriptorI = std::find_if(
24236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        std::begin(SectionAttrDescriptors), std::end(SectionAttrDescriptors),
24336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        [&](decltype(*SectionAttrDescriptors) &Descriptor) {
24436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          return Descriptor.AssemblerName &&
24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                 SectionAttr.trim() == Descriptor.AssemblerName;
24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        });
24736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (AttrDescriptorI == std::end(SectionAttrDescriptors))
24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return "mach-o section specifier has invalid attribute";
24936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    TAA |= AttrDescriptorI->AttrFlag;
25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
252f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
253f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // Okay, we've parsed the section attributes, see if we have a stub size spec.
25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (StubSizeStr.empty()) {
255f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    // S_SYMBOL_STUBS always require a symbol stub size specifier.
25636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (TAA == MachO::S_SYMBOL_STUBS)
257f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner      return "mach-o section specifier of type 'symbol_stubs' requires a size "
258f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner      "specifier";
259f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    return "";
260f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  }
261f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner
262f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  // If we have a stub size spec, we must have a sectiontype of S_SYMBOL_STUBS.
26336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((TAA & MachO::SECTION_TYPE) != MachO::S_SYMBOL_STUBS)
264f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    return "mach-o section specifier cannot have a stub size specified because "
265f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner           "it does not have type 'symbol_stubs'";
266fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
267d9221d75f02a81eec9c22473b4f2a809d83bf60aChris Lattner  // Convert the stub size from a string to an integer.
268d9221d75f02a81eec9c22473b4f2a809d83bf60aChris Lattner  if (StubSizeStr.getAsInteger(0, StubSize))
269f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner    return "mach-o section specifier has a malformed stub size";
270fe40f9551cab75c4576ee03e6a994fe4fb4530d9Jim Grosbach
271f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner  return "";
272f9bdeddb96043559c61f176f8077e3b91a0c544fChris Lattner}
273