diff --git a/include/llvm/MC/MCSectionMachO.h b/include/llvm/MC/MCSectionMachO.h index b67558551d9..bf8940524e5 100644 --- a/include/llvm/MC/MCSectionMachO.h +++ b/include/llvm/MC/MCSectionMachO.h @@ -59,14 +59,14 @@ public: /// appear after a .section directive in a mach-o flavored .s file. If /// successful, this fills in the specified Out parameters and returns an /// empty string. When an invalid section specifier is present, this returns - /// a string indicating the problem. If no TAA was parsed, TAA is not altered, + /// an Error indicating the problem. If no TAA was parsed, TAA is not altered, /// and TAAWasSet becomes false. - static std::string ParseSectionSpecifier(StringRef Spec, // In. - StringRef &Segment, // Out. - StringRef &Section, // Out. - unsigned &TAA, // Out. - bool &TAAParsed, // Out. - unsigned &StubSize); // Out. + static Error ParseSectionSpecifier(StringRef Spec, // In. + StringRef &Segment, // Out. + StringRef &Section, // Out. + unsigned &TAA, // Out. + bool &TAAParsed, // Out. + unsigned &StubSize); // Out. void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T, raw_ostream &OS, diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index 2530fdc9037..8f74866187c 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -1129,13 +1129,12 @@ void TargetLoweringObjectFileMachO::emitModuleMetadata(MCStreamer &Streamer, StringRef Segment, Section; unsigned TAA = 0, StubSize = 0; bool TAAParsed; - std::string ErrorCode = - MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section, - TAA, TAAParsed, StubSize); - if (!ErrorCode.empty()) + if (Error E = MCSectionMachO::ParseSectionSpecifier( + SectionVal, Segment, Section, TAA, TAAParsed, StubSize)) { // If invalid, report the error with report_fatal_error. - report_fatal_error("Invalid section specifier '" + Section + "': " + - ErrorCode + "."); + report_fatal_error("Invalid section specifier '" + Section + + "': " + toString(std::move(E)) + "."); + } // Get the section. MCSectionMachO *S = getContext().getMachOSection( @@ -1159,6 +1158,14 @@ static void checkMachOComdat(const GlobalValue *GV) { MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { + + StringRef SectionName = GO->getSection(); + + const Function *F = dyn_cast(GO); + if (F && F->hasFnAttribute("implicit-section-name")) { + SectionName = F->getFnAttribute("implicit-section-name").getValueAsString(); + } + // Parse the section specifier and create it if valid. StringRef Segment, Section; unsigned TAA = 0, StubSize = 0; @@ -1166,14 +1173,12 @@ MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( checkMachOComdat(GO); - std::string ErrorCode = - MCSectionMachO::ParseSectionSpecifier(GO->getSection(), Segment, Section, - TAA, TAAParsed, StubSize); - if (!ErrorCode.empty()) { + if (Error E = MCSectionMachO::ParseSectionSpecifier( + SectionName, Segment, Section, TAA, TAAParsed, StubSize)) { // If invalid, report the error with report_fatal_error. report_fatal_error("Global variable '" + GO->getName() + "' has an invalid section specifier '" + - GO->getSection() + "': " + ErrorCode + "."); + GO->getSection() + "': " + toString(std::move(E)) + "."); } // Get the section. diff --git a/lib/MC/MCParser/DarwinAsmParser.cpp b/lib/MC/MCParser/DarwinAsmParser.cpp index 92648345125..f56013869a6 100644 --- a/lib/MC/MCParser/DarwinAsmParser.cpp +++ b/lib/MC/MCParser/DarwinAsmParser.cpp @@ -23,6 +23,7 @@ #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSymbol.h" #include "llvm/MC/SectionKind.h" +#include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SMLoc.h" @@ -689,12 +690,9 @@ bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) { unsigned StubSize; unsigned TAA; bool TAAParsed; - std::string ErrorStr = - MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section, - TAA, TAAParsed, StubSize); - - if (!ErrorStr.empty()) - return Error(Loc, ErrorStr); + if (class Error E = MCSectionMachO::ParseSectionSpecifier( + SectionSpec, Segment, Section, TAA, TAAParsed, StubSize)) + return Error(Loc, toString(std::move(E))); // Issue a warning if the target is not powerpc and Section is a *coal* section. Triple TT = getParser().getContext().getObjectFileInfo()->getTargetTriple(); diff --git a/lib/MC/MCSectionMachO.cpp b/lib/MC/MCSectionMachO.cpp index 794d2c52d7b..d914e64ca23 100644 --- a/lib/MC/MCSectionMachO.cpp +++ b/lib/MC/MCSectionMachO.cpp @@ -174,12 +174,12 @@ bool MCSectionMachO::isVirtualSection() const { /// flavored .s file. If successful, this fills in the specified Out /// parameters and returns an empty string. When an invalid section /// specifier is present, this returns a string indicating the problem. -std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In. - StringRef &Segment, // Out. - StringRef &Section, // Out. - unsigned &TAA, // Out. - bool &TAAParsed, // Out. - unsigned &StubSize) { // Out. +Error MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In. + StringRef &Segment, // Out. + StringRef &Section, // Out. + unsigned &TAA, // Out. + bool &TAAParsed, // Out. + unsigned &StubSize) { // Out. TAAParsed = false; SmallVector SplitSpec; @@ -194,25 +194,23 @@ std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In. StringRef Attrs = GetEmptyOrTrim(3); StringRef StubSizeStr = GetEmptyOrTrim(4); - // Verify that the segment is present and not too long. - if (Segment.empty() || Segment.size() > 16) - return "mach-o section specifier requires a segment whose length is " - "between 1 and 16 characters"; - - // Verify that the section is present and not too long. + // Verify that the section is present. if (Section.empty()) - return "mach-o section specifier requires a segment and section " - "separated by a comma"; + return createStringError(inconvertibleErrorCode(), + "mach-o section specifier requires a segment " + "and section separated by a comma"); + // Verify that the section is not too long. if (Section.size() > 16) - return "mach-o section specifier requires a section whose length is " - "between 1 and 16 characters"; + return createStringError(inconvertibleErrorCode(), + "mach-o section specifier requires a section " + "whose length is between 1 and 16 characters"); // If there is no comma after the section, we're done. TAA = 0; StubSize = 0; if (SectionType.empty()) - return ""; + return Error::success(); // Figure out which section type it is. auto TypeDescriptor = @@ -223,7 +221,9 @@ std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In. // If we didn't find the section type, reject it. if (TypeDescriptor == std::end(SectionTypeDescriptors)) - return "mach-o section specifier uses an unknown section type"; + return createStringError(inconvertibleErrorCode(), + "mach-o section specifier uses an unknown " + "section type"); // Remember the TypeID. TAA = TypeDescriptor - std::begin(SectionTypeDescriptors); @@ -233,9 +233,10 @@ std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In. if (Attrs.empty()) { // S_SYMBOL_STUBS always require a symbol stub size specifier. if (TAA == MachO::S_SYMBOL_STUBS) - return "mach-o section specifier of type 'symbol_stubs' requires a size " - "specifier"; - return ""; + return createStringError(inconvertibleErrorCode(), + "mach-o section specifier of type " + "'symbol_stubs' requires a size specifier"); + return Error::success(); } // The attribute list is a '+' separated list of attributes. @@ -249,7 +250,9 @@ std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In. return SectionAttr.trim() == Descriptor.AssemblerName; }); if (AttrDescriptorI == std::end(SectionAttrDescriptors)) - return "mach-o section specifier has invalid attribute"; + return createStringError(inconvertibleErrorCode(), + "mach-o section specifier has invalid " + "attribute"); TAA |= AttrDescriptorI->AttrFlag; } @@ -258,19 +261,24 @@ std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In. if (StubSizeStr.empty()) { // S_SYMBOL_STUBS always require a symbol stub size specifier. if (TAA == MachO::S_SYMBOL_STUBS) - return "mach-o section specifier of type 'symbol_stubs' requires a size " - "specifier"; - return ""; + return createStringError(inconvertibleErrorCode(), + "mach-o section specifier of type " + "'symbol_stubs' requires a size specifier"); + return Error::success(); } // If we have a stub size spec, we must have a sectiontype of S_SYMBOL_STUBS. if ((TAA & MachO::SECTION_TYPE) != MachO::S_SYMBOL_STUBS) - return "mach-o section specifier cannot have a stub size specified because " - "it does not have type 'symbol_stubs'"; + return createStringError(inconvertibleErrorCode(), + "mach-o section specifier cannot have a stub " + "size specified because it does not have type " + "'symbol_stubs'"); // 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 createStringError(inconvertibleErrorCode(), + "mach-o section specifier has a malformed " + "stub size"); - return ""; + return Error::success(); } diff --git a/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/lib/Transforms/Instrumentation/AddressSanitizer.cpp index dcfff19de01..551dd7530d8 100644 --- a/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -1919,9 +1919,8 @@ bool ModuleAddressSanitizer::shouldInstrumentGlobal(GlobalVariable *G) const { StringRef ParsedSegment, ParsedSection; unsigned TAA = 0, StubSize = 0; bool TAAParsed; - std::string ErrorCode = MCSectionMachO::ParseSectionSpecifier( - Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize); - assert(ErrorCode.empty() && "Invalid section specifier."); + cantFail(MCSectionMachO::ParseSectionSpecifier( + Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize)); // Ignore the globals from the __OBJC section. The ObjC runtime assumes // those conform to /usr/lib/objc/runtime.h, so we can't add redzones to diff --git a/test/CodeGen/AArch64/clang-section-macho.ll b/test/CodeGen/AArch64/clang-section-macho.ll new file mode 100644 index 00000000000..1c23f4c0a14 --- /dev/null +++ b/test/CodeGen/AArch64/clang-section-macho.ll @@ -0,0 +1,11 @@ +;RUN: llc -mtriple=arm64-apple-ios %s -o - | FileCheck %s + +define dso_local void @foo() #0 { +entry: + ret void +} + +attributes #0 = { "implicit-section-name"="__TEXT,__mytext" } + +; CHECK: .section __TEXT,__mytext +; CHECK-NEXT: .globl _foo