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