1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-25 04:02:41 +01:00

Support #pragma clang section directives on MachO targets

rdar://59560986

Differential Revision: https://reviews.llvm.org/D97233
This commit is contained in:
Jon Roelofs 2021-02-23 08:01:27 -08:00
parent 0d01ba504c
commit d535e65db9
6 changed files with 77 additions and 56 deletions

View File

@ -59,14 +59,14 @@ public:
/// appear after a .section directive in a mach-o flavored .s file. If /// appear after a .section directive in a mach-o flavored .s file. If
/// successful, this fills in the specified Out parameters and returns an /// successful, this fills in the specified Out parameters and returns an
/// empty string. When an invalid section specifier is present, this returns /// 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. /// and TAAWasSet becomes false.
static std::string ParseSectionSpecifier(StringRef Spec, // In. static Error ParseSectionSpecifier(StringRef Spec, // In.
StringRef &Segment, // Out. StringRef &Segment, // Out.
StringRef &Section, // Out. StringRef &Section, // Out.
unsigned &TAA, // Out. unsigned &TAA, // Out.
bool &TAAParsed, // Out. bool &TAAParsed, // Out.
unsigned &StubSize); // Out. unsigned &StubSize); // Out.
void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T, void PrintSwitchToSection(const MCAsmInfo &MAI, const Triple &T,
raw_ostream &OS, raw_ostream &OS,

View File

@ -1129,13 +1129,12 @@ void TargetLoweringObjectFileMachO::emitModuleMetadata(MCStreamer &Streamer,
StringRef Segment, Section; StringRef Segment, Section;
unsigned TAA = 0, StubSize = 0; unsigned TAA = 0, StubSize = 0;
bool TAAParsed; bool TAAParsed;
std::string ErrorCode = if (Error E = MCSectionMachO::ParseSectionSpecifier(
MCSectionMachO::ParseSectionSpecifier(SectionVal, Segment, Section, SectionVal, Segment, Section, TAA, TAAParsed, StubSize)) {
TAA, TAAParsed, StubSize);
if (!ErrorCode.empty())
// If invalid, report the error with report_fatal_error. // If invalid, report the error with report_fatal_error.
report_fatal_error("Invalid section specifier '" + Section + "': " + report_fatal_error("Invalid section specifier '" + Section +
ErrorCode + "."); "': " + toString(std::move(E)) + ".");
}
// Get the section. // Get the section.
MCSectionMachO *S = getContext().getMachOSection( MCSectionMachO *S = getContext().getMachOSection(
@ -1159,6 +1158,14 @@ static void checkMachOComdat(const GlobalValue *GV) {
MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal( MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal(
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
StringRef SectionName = GO->getSection();
const Function *F = dyn_cast<Function>(GO);
if (F && F->hasFnAttribute("implicit-section-name")) {
SectionName = F->getFnAttribute("implicit-section-name").getValueAsString();
}
// Parse the section specifier and create it if valid. // Parse the section specifier and create it if valid.
StringRef Segment, Section; StringRef Segment, Section;
unsigned TAA = 0, StubSize = 0; unsigned TAA = 0, StubSize = 0;
@ -1166,14 +1173,12 @@ MCSection *TargetLoweringObjectFileMachO::getExplicitSectionGlobal(
checkMachOComdat(GO); checkMachOComdat(GO);
std::string ErrorCode = if (Error E = MCSectionMachO::ParseSectionSpecifier(
MCSectionMachO::ParseSectionSpecifier(GO->getSection(), Segment, Section, SectionName, Segment, Section, TAA, TAAParsed, StubSize)) {
TAA, TAAParsed, StubSize);
if (!ErrorCode.empty()) {
// If invalid, report the error with report_fatal_error. // If invalid, report the error with report_fatal_error.
report_fatal_error("Global variable '" + GO->getName() + report_fatal_error("Global variable '" + GO->getName() +
"' has an invalid section specifier '" + "' has an invalid section specifier '" +
GO->getSection() + "': " + ErrorCode + "."); GO->getSection() + "': " + toString(std::move(E)) + ".");
} }
// Get the section. // Get the section.

View File

@ -23,6 +23,7 @@
#include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCSymbol.h"
#include "llvm/MC/SectionKind.h" #include "llvm/MC/SectionKind.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h" #include "llvm/Support/FileSystem.h"
#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SMLoc.h" #include "llvm/Support/SMLoc.h"
@ -689,12 +690,9 @@ bool DarwinAsmParser::parseDirectiveSection(StringRef, SMLoc) {
unsigned StubSize; unsigned StubSize;
unsigned TAA; unsigned TAA;
bool TAAParsed; bool TAAParsed;
std::string ErrorStr = if (class Error E = MCSectionMachO::ParseSectionSpecifier(
MCSectionMachO::ParseSectionSpecifier(SectionSpec, Segment, Section, SectionSpec, Segment, Section, TAA, TAAParsed, StubSize))
TAA, TAAParsed, StubSize); return Error(Loc, toString(std::move(E)));
if (!ErrorStr.empty())
return Error(Loc, ErrorStr);
// Issue a warning if the target is not powerpc and Section is a *coal* section. // Issue a warning if the target is not powerpc and Section is a *coal* section.
Triple TT = getParser().getContext().getObjectFileInfo()->getTargetTriple(); Triple TT = getParser().getContext().getObjectFileInfo()->getTargetTriple();

View File

@ -174,12 +174,12 @@ bool MCSectionMachO::isVirtualSection() const {
/// flavored .s file. If successful, this fills in the specified Out /// flavored .s file. If successful, this fills in the specified Out
/// parameters and returns an empty string. When an invalid section /// parameters and returns an empty string. When an invalid section
/// specifier is present, this returns a string indicating the problem. /// specifier is present, this returns a string indicating the problem.
std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In. Error MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In.
StringRef &Segment, // Out. StringRef &Segment, // Out.
StringRef &Section, // Out. StringRef &Section, // Out.
unsigned &TAA, // Out. unsigned &TAA, // Out.
bool &TAAParsed, // Out. bool &TAAParsed, // Out.
unsigned &StubSize) { // Out. unsigned &StubSize) { // Out.
TAAParsed = false; TAAParsed = false;
SmallVector<StringRef, 5> SplitSpec; SmallVector<StringRef, 5> SplitSpec;
@ -194,25 +194,23 @@ std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In.
StringRef Attrs = GetEmptyOrTrim(3); StringRef Attrs = GetEmptyOrTrim(3);
StringRef StubSizeStr = GetEmptyOrTrim(4); StringRef StubSizeStr = GetEmptyOrTrim(4);
// Verify that the segment is present and not too long. // Verify that the section is present.
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.
if (Section.empty()) if (Section.empty())
return "mach-o section specifier requires a segment and section " return createStringError(inconvertibleErrorCode(),
"separated by a comma"; "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) if (Section.size() > 16)
return "mach-o section specifier requires a section whose length is " return createStringError(inconvertibleErrorCode(),
"between 1 and 16 characters"; "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. // If there is no comma after the section, we're done.
TAA = 0; TAA = 0;
StubSize = 0; StubSize = 0;
if (SectionType.empty()) if (SectionType.empty())
return ""; return Error::success();
// Figure out which section type it is. // Figure out which section type it is.
auto TypeDescriptor = auto TypeDescriptor =
@ -223,7 +221,9 @@ std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In.
// If we didn't find the section type, reject it. // If we didn't find the section type, reject it.
if (TypeDescriptor == std::end(SectionTypeDescriptors)) 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. // Remember the TypeID.
TAA = TypeDescriptor - std::begin(SectionTypeDescriptors); TAA = TypeDescriptor - std::begin(SectionTypeDescriptors);
@ -233,9 +233,10 @@ std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In.
if (Attrs.empty()) { if (Attrs.empty()) {
// S_SYMBOL_STUBS always require a symbol stub size specifier. // S_SYMBOL_STUBS always require a symbol stub size specifier.
if (TAA == MachO::S_SYMBOL_STUBS) if (TAA == MachO::S_SYMBOL_STUBS)
return "mach-o section specifier of type 'symbol_stubs' requires a size " return createStringError(inconvertibleErrorCode(),
"specifier"; "mach-o section specifier of type "
return ""; "'symbol_stubs' requires a size specifier");
return Error::success();
} }
// The attribute list is a '+' separated list of attributes. // 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; return SectionAttr.trim() == Descriptor.AssemblerName;
}); });
if (AttrDescriptorI == std::end(SectionAttrDescriptors)) 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; TAA |= AttrDescriptorI->AttrFlag;
} }
@ -258,19 +261,24 @@ std::string MCSectionMachO::ParseSectionSpecifier(StringRef Spec, // In.
if (StubSizeStr.empty()) { if (StubSizeStr.empty()) {
// S_SYMBOL_STUBS always require a symbol stub size specifier. // S_SYMBOL_STUBS always require a symbol stub size specifier.
if (TAA == MachO::S_SYMBOL_STUBS) if (TAA == MachO::S_SYMBOL_STUBS)
return "mach-o section specifier of type 'symbol_stubs' requires a size " return createStringError(inconvertibleErrorCode(),
"specifier"; "mach-o section specifier of type "
return ""; "'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 we have a stub size spec, we must have a sectiontype of S_SYMBOL_STUBS.
if ((TAA & MachO::SECTION_TYPE) != MachO::S_SYMBOL_STUBS) if ((TAA & MachO::SECTION_TYPE) != MachO::S_SYMBOL_STUBS)
return "mach-o section specifier cannot have a stub size specified because " return createStringError(inconvertibleErrorCode(),
"it does not have type 'symbol_stubs'"; "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. // Convert the stub size from a string to an integer.
if (StubSizeStr.getAsInteger(0, StubSize)) 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();
} }

View File

@ -1919,9 +1919,8 @@ bool ModuleAddressSanitizer::shouldInstrumentGlobal(GlobalVariable *G) const {
StringRef ParsedSegment, ParsedSection; StringRef ParsedSegment, ParsedSection;
unsigned TAA = 0, StubSize = 0; unsigned TAA = 0, StubSize = 0;
bool TAAParsed; bool TAAParsed;
std::string ErrorCode = MCSectionMachO::ParseSectionSpecifier( cantFail(MCSectionMachO::ParseSectionSpecifier(
Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize); Section, ParsedSegment, ParsedSection, TAA, TAAParsed, StubSize));
assert(ErrorCode.empty() && "Invalid section specifier.");
// Ignore the globals from the __OBJC section. The ObjC runtime assumes // 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 // those conform to /usr/lib/objc/runtime.h, so we can't add redzones to

View File

@ -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