X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FMC%2FMCSectionMachO.cpp;h=870451313bb1725e53bbaf6040c033e9838c1f32;hb=6079f00035e029f12e4be0281aa2cbfbb4817141;hp=5615398737c7d399ab8fd9c971ae6209c4a48c05;hpb=af76e592c7f9deff0e55c13dbb4a34f07f1c7f64;p=oota-llvm.git diff --git a/lib/MC/MCSectionMachO.cpp b/lib/MC/MCSectionMachO.cpp index 5615398737c..870451313bb 100644 --- a/lib/MC/MCSectionMachO.cpp +++ b/lib/MC/MCSectionMachO.cpp @@ -10,6 +10,7 @@ #include "llvm/MC/MCSectionMachO.h" #include "llvm/MC/MCContext.h" #include "llvm/Support/raw_ostream.h" +#include using namespace llvm; /// SectionTypeDescriptors - These are strings that describe the various section @@ -34,14 +35,21 @@ static const struct { { "interposing", "S_INTERPOSING" }, // 0x0D { "16byte_literals", "S_16BYTE_LITERALS" }, // 0x0E { 0, /*FIXME??*/ "S_DTRACE_DOF" }, // 0x0F - { 0, /*FIXME??*/ "S_LAZY_DYLIB_SYMBOL_POINTERS" } // 0x10 + { 0, /*FIXME??*/ "S_LAZY_DYLIB_SYMBOL_POINTERS" }, // 0x10 + { "thread_local_regular", "S_THREAD_LOCAL_REGULAR" }, // 0x11 + { "thread_local_zerofill", "S_THREAD_LOCAL_ZEROFILL" }, // 0x12 + { "thread_local_variables", "S_THREAD_LOCAL_VARIABLES" }, // 0x13 + { "thread_local_variable_pointers", + "S_THREAD_LOCAL_VARIABLE_POINTERS" }, // 0x14 + { "thread_local_init_function_pointers", + "S_THREAD_LOCAL_INIT_FUNCTION_POINTERS"}, // 0x15 }; /// SectionAttrDescriptors - This is an array of descriptors for section /// attributes. Unlike the SectionTypeDescriptors, this is not directly indexed -/// by attribute, instead it is searched. The last entry has a zero AttrFlag -/// value. +/// by attribute, instead it is searched. The last entry has an AttrFlagEnd +/// AttrFlag value. static const struct { unsigned AttrFlag; const char *AssemblerName, *EnumName; @@ -59,23 +67,34 @@ ENTRY(0 /*FIXME*/, S_ATTR_SOME_INSTRUCTIONS) ENTRY(0 /*FIXME*/, S_ATTR_EXT_RELOC) ENTRY(0 /*FIXME*/, S_ATTR_LOC_RELOC) #undef ENTRY - { 0, "none", 0 } + { 0, "none", 0 }, // used if section has no attributes but has a stub size +#define AttrFlagEnd 0xffffffff // non legal value, multiple attribute bits set + { AttrFlagEnd, 0, 0 } }; +MCSectionMachO::MCSectionMachO(StringRef Segment, StringRef Section, + unsigned TAA, unsigned reserved2, SectionKind K) + : MCSection(SV_MachO, K), TypeAndAttributes(TAA), Reserved2(reserved2) { + assert(Segment.size() <= 16 && Section.size() <= 16 && + "Segment or section string too long"); + for (unsigned i = 0; i != 16; ++i) { + if (i < Segment.size()) + SegmentName[i] = Segment[i]; + else + SegmentName[i] = 0; -MCSectionMachO *MCSectionMachO:: -Create(const StringRef &Segment, const StringRef &Section, - unsigned TypeAndAttributes, unsigned Reserved2, - SectionKind K, MCContext &Ctx) { - // S_SYMBOL_STUBS must be set for Reserved2 to be non-zero. - return new (Ctx) MCSectionMachO(Segment, Section, TypeAndAttributes, - Reserved2, K); + if (i < Section.size()) + SectionName[i] = Section[i]; + else + SectionName[i] = 0; + } } -void MCSectionMachO::PrintSwitchToSection(const MCAsmInfo &TAI, - raw_ostream &OS) const { +void MCSectionMachO::PrintSwitchToSection(const MCAsmInfo &MAI, + raw_ostream &OS, + const MCExpr *Subsection) const { OS << "\t.section\t" << getSegmentName() << ',' << getSectionName(); - + // Get the section type and attributes. unsigned TAA = getTypeAndAttributes(); if (TAA == 0) { @@ -83,17 +102,19 @@ void MCSectionMachO::PrintSwitchToSection(const MCAsmInfo &TAI, return; } - OS << ','; - unsigned SectionType = TAA & MCSectionMachO::SECTION_TYPE; assert(SectionType <= MCSectionMachO::LAST_KNOWN_SECTION_TYPE && "Invalid SectionType specified!"); - if (SectionTypeDescriptors[SectionType].AssemblerName) + if (SectionTypeDescriptors[SectionType].AssemblerName) { + OS << ','; OS << SectionTypeDescriptors[SectionType].AssemblerName; - else - OS << "<<" << SectionTypeDescriptors[SectionType].EnumName << ">>"; - + } else { + // If we have no name for the attribute, stop here. + OS << '\n'; + return; + } + // If we don't have any attributes, we're done. unsigned SectionAttrs = TAA & MCSectionMachO::SECTION_ATTRIBUTES; if (SectionAttrs == 0) { @@ -107,14 +128,16 @@ void MCSectionMachO::PrintSwitchToSection(const MCAsmInfo &TAI, // Check each attribute to see if we have it. char Separator = ','; - for (unsigned i = 0; SectionAttrDescriptors[i].AttrFlag; ++i) { + for (unsigned i = 0; + SectionAttrs != 0 && SectionAttrDescriptors[i].AttrFlag; + ++i) { // Check to see if we have this attribute. if ((SectionAttrDescriptors[i].AttrFlag & SectionAttrs) == 0) continue; - + // Yep, clear it and print it. SectionAttrs &= ~SectionAttrDescriptors[i].AttrFlag; - + OS << Separator; if (SectionAttrDescriptors[i].AssemblerName) OS << SectionAttrDescriptors[i].AssemblerName; @@ -122,20 +145,30 @@ void MCSectionMachO::PrintSwitchToSection(const MCAsmInfo &TAI, OS << "<<" << SectionAttrDescriptors[i].EnumName << ">>"; Separator = '+'; } - + assert(SectionAttrs == 0 && "Unknown section attributes!"); - + // If we have a S_SYMBOL_STUBS size specified, print it. if (Reserved2 != 0) OS << ',' << Reserved2; OS << '\n'; } +bool MCSectionMachO::UseCodeAlign() const { + return hasAttribute(MCSectionMachO::S_ATTR_PURE_INSTRUCTIONS); +} + +bool MCSectionMachO::isVirtualSection() const { + return (getType() == MCSectionMachO::S_ZEROFILL || + getType() == MCSectionMachO::S_GB_ZEROFILL || + getType() == MCSectionMachO::S_THREAD_LOCAL_ZEROFILL); +} + /// StripSpaces - This removes leading and trailing spaces from the StringRef. static void StripSpaces(StringRef &Str) { - while (!Str.empty() && isspace(Str[0])) + while (!Str.empty() && isspace(static_cast(Str[0]))) Str = Str.substr(1); - while (!Str.empty() && isspace(Str.back())) + while (!Str.empty() && isspace(static_cast(Str.back()))) Str = Str.substr(0, Str.size()-1); } @@ -148,15 +181,17 @@ std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In. StringRef &Segment, // Out. StringRef &Section, // Out. unsigned &TAA, // Out. + bool &TAAParsed, // Out. unsigned &StubSize) { // Out. + TAAParsed = false; // Find the first comma. std::pair Comma = Spec.split(','); - + // If there is no comma, we fail. if (Comma.second.empty()) return "mach-o section specifier requires a segment and section " "separated by a comma"; - + // Capture segment, remove leading and trailing whitespace. Segment = Comma.first; StripSpaces(Segment); @@ -165,14 +200,14 @@ std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In. if (Segment.empty() || Segment.size() > 16) return "mach-o section specifier requires a segment whose length is " "between 1 and 16 characters"; - + // Split the section name off from any attributes if present. Comma = Comma.second.split(','); // Capture section, remove leading and trailing whitespace. Section = Comma.first; StripSpaces(Section); - + // Verify that the section is present and not too long. if (Section.empty() || Section.size() > 16) return "mach-o section specifier requires a section whose length is " @@ -183,27 +218,28 @@ std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In. StubSize = 0; if (Comma.second.empty()) return ""; - + // Otherwise, we need to parse the section type and attributes. Comma = Comma.second.split(','); - + // Get the section type. StringRef SectionType = Comma.first; StripSpaces(SectionType); - + // Figure out which section type it is. unsigned TypeID; for (TypeID = 0; TypeID !=MCSectionMachO::LAST_KNOWN_SECTION_TYPE+1; ++TypeID) if (SectionTypeDescriptors[TypeID].AssemblerName && SectionType == SectionTypeDescriptors[TypeID].AssemblerName) break; - + // If we didn't find the section type, reject it. if (TypeID > MCSectionMachO::LAST_KNOWN_SECTION_TYPE) return "mach-o section specifier uses an unknown section type"; - + // Remember the TypeID. TAA = TypeID; + TAAParsed = true; // If we have no comma after the section type, there are no attributes. if (Comma.second.empty()) { @@ -218,26 +254,26 @@ std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In. // present. Comma = Comma.second.split(','); StringRef Attrs = Comma.first; - + // The attribute list is a '+' separated list of attributes. std::pair Plus = Attrs.split('+'); - + while (1) { StringRef Attr = Plus.first; StripSpaces(Attr); // Look up the attribute. for (unsigned i = 0; ; ++i) { - if (SectionAttrDescriptors[i].AttrFlag == 0) + if (SectionAttrDescriptors[i].AttrFlag == AttrFlagEnd) return "mach-o section specifier has invalid attribute"; - + if (SectionAttrDescriptors[i].AssemblerName && Attr == SectionAttrDescriptors[i].AssemblerName) { TAA |= SectionAttrDescriptors[i].AttrFlag; break; } } - + if (Plus.second.empty()) break; Plus = Plus.second.split('+'); }; @@ -255,25 +291,14 @@ std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In. if ((TAA & MCSectionMachO::SECTION_TYPE) != MCSectionMachO::S_SYMBOL_STUBS) return "mach-o section specifier cannot have a stub size specified because " "it does not have type 'symbol_stubs'"; - + // Okay, if we do, it must be a number. StringRef StubSizeStr = Comma.second; StripSpaces(StubSizeStr); - - // Convert the a null terminated buffer for strtoul. - char TmpBuffer[32]; - if (StubSizeStr.size() >= 32) - return"mach-o section specifier has a stub size specifier that is too long"; - - memcpy(TmpBuffer, StubSizeStr.data(), StubSizeStr.size()); - TmpBuffer[StubSizeStr.size()] = 0; - - char *EndPtr; - StubSize = strtoul(TmpBuffer, &EndPtr, 0); - - if (EndPtr[0] != 0) + + // Convert the stub size from a string to an integer. + if (StubSizeStr.getAsInteger(0, StubSize)) return "mach-o section specifier has a malformed stub size"; - + return ""; } -