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:
parent
0d01ba504c
commit
d535e65db9
@ -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,
|
||||||
|
@ -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.
|
||||||
|
@ -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();
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
11
test/CodeGen/AArch64/clang-section-macho.ll
Normal file
11
test/CodeGen/AArch64/clang-section-macho.ll
Normal 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
|
Loading…
Reference in New Issue
Block a user