Skip to content

Commit

Permalink
MIR Serialization: Serialize the frame information's stack protector …
Browse files Browse the repository at this point in the history
…index.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245372 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
hyp committed Aug 18, 2015
1 parent 0a39c58 commit 07c6bd8
Show file tree
Hide file tree
Showing 8 changed files with 199 additions and 3 deletions.
5 changes: 4 additions & 1 deletion include/llvm/CodeGen/MIRYamlMapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,8 @@ struct MachineFrameInfo {
unsigned MaxAlignment = 0;
bool AdjustsStack = false;
bool HasCalls = false;
// TODO: Serialize StackProtectorIdx and FunctionContextIdx
StringValue StackProtector;
// TODO: Serialize FunctionContextIdx
unsigned MaxCallFrameSize = 0;
bool HasOpaqueSPAdjustment = false;
bool HasVAStart = false;
Expand All @@ -357,6 +358,8 @@ template <> struct MappingTraits<MachineFrameInfo> {
YamlIO.mapOptional("maxAlignment", MFI.MaxAlignment);
YamlIO.mapOptional("adjustsStack", MFI.AdjustsStack);
YamlIO.mapOptional("hasCalls", MFI.HasCalls);
YamlIO.mapOptional("stackProtector", MFI.StackProtector,
StringValue()); // Don't print it out when it's empty.
YamlIO.mapOptional("maxCallFrameSize", MFI.MaxCallFrameSize);
YamlIO.mapOptional("hasOpaqueSPAdjustment", MFI.HasOpaqueSPAdjustment);
YamlIO.mapOptional("hasVAStart", MFI.HasVAStart);
Expand Down
1 change: 1 addition & 0 deletions include/llvm/CodeGen/MachineFrameInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ class MachineFrameInfo {
/// Return the index for the stack protector object.
int getStackProtectorIndex() const { return StackProtectorIdx; }
void setStackProtectorIndex(int I) { StackProtectorIdx = I; }
bool hasStackProtectorIndex() const { return StackProtectorIdx != -1; }

/// Return the index for the function context object.
/// This object is used for SjLj exceptions.
Expand Down
21 changes: 21 additions & 0 deletions lib/CodeGen/MIRParser/MIParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ class MIParser {
bool parseStandaloneMBB(MachineBasicBlock *&MBB);
bool parseStandaloneNamedRegister(unsigned &Reg);
bool parseStandaloneVirtualRegister(unsigned &Reg);
bool parseStandaloneStackObject(int &FI);

bool
parseBasicBlockDefinition(DenseMap<unsigned, MachineBasicBlock *> &MBBSlots);
Expand Down Expand Up @@ -655,6 +656,17 @@ bool MIParser::parseStandaloneVirtualRegister(unsigned &Reg) {
return false;
}

bool MIParser::parseStandaloneStackObject(int &FI) {
lex();
if (Token.isNot(MIToken::StackObject))
return error("expected a stack object");
if (parseStackFrameIndex(FI))
return true;
if (Token.isNot(MIToken::Eof))
return error("expected end of string after the stack object reference");
return false;
}

static const char *printImplicitRegisterFlag(const MachineOperand &MO) {
assert(MO.isImplicit());
return MO.isDef() ? "implicit-def" : "implicit";
Expand Down Expand Up @@ -1794,3 +1806,12 @@ bool llvm::parseVirtualRegisterReference(unsigned &Reg, SourceMgr &SM,
return MIParser(SM, MF, Error, Src, PFS, IRSlots)
.parseStandaloneVirtualRegister(Reg);
}

bool llvm::parseStackObjectReference(int &FI, SourceMgr &SM,
MachineFunction &MF, StringRef Src,
const PerFunctionMIParsingState &PFS,
const SlotMapping &IRSlots,
SMDiagnostic &Error) {
return MIParser(SM, MF, Error, Src, PFS, IRSlots)
.parseStandaloneStackObject(FI);
}
5 changes: 5 additions & 0 deletions lib/CodeGen/MIRParser/MIParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ bool parseVirtualRegisterReference(unsigned &Reg, SourceMgr &SM,
const SlotMapping &IRSlots,
SMDiagnostic &Error);

bool parseStackObjectReference(int &FI, SourceMgr &SM, MachineFunction &MF,
StringRef Src,
const PerFunctionMIParsingState &PFS,
const SlotMapping &IRSlots, SMDiagnostic &Error);

} // end namespace llvm

#endif
11 changes: 11 additions & 0 deletions lib/CodeGen/MIRParser/MIRParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,17 @@ bool MIRParserImpl::initializeFrameInfo(MachineFunction &MF,
MFI.setCalleeSavedInfo(CSIInfo);
if (!CSIInfo.empty())
MFI.setCalleeSavedInfoValid(true);

// Initialize the various stack object references after initializing the
// stack objects.
if (!YamlMFI.StackProtector.Value.empty()) {
SMDiagnostic Error;
int FI;
if (parseStackObjectReference(FI, SM, MF, YamlMFI.StackProtector.Value, PFS,
IRSlots, Error))
return error(Error, YamlMFI.StackProtector.SourceRange);
MFI.setStackProtectorIndex(FI);
}
return false;
}

Expand Down
13 changes: 11 additions & 2 deletions lib/CodeGen/MIRPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class MIRPrinter {
void convert(ModuleSlotTracker &MST, yaml::MachineJumpTable &YamlJTI,
const MachineJumpTableInfo &JTI);
void convertStackObjects(yaml::MachineFunction &MF,
const MachineFrameInfo &MFI,
const MachineFrameInfo &MFI, ModuleSlotTracker &MST,
const TargetRegisterInfo *TRI);

private:
Expand Down Expand Up @@ -171,7 +171,7 @@ void MIRPrinter::print(const MachineFunction &MF) {
ModuleSlotTracker MST(MF.getFunction()->getParent());
MST.incorporateFunction(*MF.getFunction());
convert(MST, YamlMF.FrameInfo, *MF.getFrameInfo());
convertStackObjects(YamlMF, *MF.getFrameInfo(),
convertStackObjects(YamlMF, *MF.getFrameInfo(), MST,
MF.getSubtarget().getRegisterInfo());
if (const auto *ConstantPool = MF.getConstantPool())
convert(YamlMF, *ConstantPool);
Expand Down Expand Up @@ -265,6 +265,7 @@ void MIRPrinter::convert(ModuleSlotTracker &MST,

void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
const MachineFrameInfo &MFI,
ModuleSlotTracker &MST,
const TargetRegisterInfo *TRI) {
// Process fixed stack objects.
unsigned ID = 0;
Expand Down Expand Up @@ -333,6 +334,14 @@ void MIRPrinter::convertStackObjects(yaml::MachineFunction &MF,
assert(!StackObject.IsFixed && "Expected a locally mapped stack object");
MF.StackObjects[StackObject.ID].LocalOffset = LocalObject.second;
}

// Print the stack object references in the frame information class after
// converting the stack objects.
if (MFI.hasStackProtectorIndex()) {
raw_string_ostream StrOS(MF.FrameInfo.StackProtector.Value);
MIPrinter(StrOS, MST, RegisterMaskIds, StackObjectOperandMapping)
.printStackObjectReference(MFI.getStackProtectorIndex());
}
}

void MIRPrinter::convert(yaml::MachineFunction &MF,
Expand Down
67 changes: 67 additions & 0 deletions test/CodeGen/MIR/X86/expected-stack-object.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# RUN: not llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s 2>&1 | FileCheck %s


--- |
@.str = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1
@__stack_chk_guard = external global i8*

define i32 @test() #0 {
entry:
%StackGuardSlot = alloca i8*
%StackGuard = load i8*, i8** @__stack_chk_guard
call void @llvm.stackprotector(i8* %StackGuard, i8** %StackGuardSlot)
%test = alloca i8*, align 8
%a = alloca i8, i64 5
store i8* %a, i8** %test, align 8
%b = load i8*, i8** %test, align 8
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %b)
call void @llvm.stackprotectorcheck(i8** @__stack_chk_guard)
ret i32 %call
}

declare i32 @printf(i8*, ...)

declare void @llvm.stackprotector(i8*, i8**) #1

declare void @llvm.stackprotectorcheck(i8**) #2

attributes #0 = { ssp "stack-protector-buffer-size"="5" }
attributes #1 = { nounwind }
attributes #2 = { nounwind argmemonly }
...
---
name: test
alignment: 4
tracksRegLiveness: true
frameInfo:
stackSize: 40
maxAlignment: 8
adjustsStack: true
hasCalls: true
# CHECK: [[@LINE+1]]:21: expected a stack object
stackProtector: '0'
fixedStack:
- { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16,
callee-saved-register: '%rbx' }
stack:
- { id: 0, name: StackGuardSlot, offset: -24, size: 8, alignment: 8 }
- { id: 1, name: test, offset: -40, size: 8, alignment: 8 }
- { id: 2, name: a, offset: -29, size: 5, alignment: 1 }
body: |
bb.0.entry:
liveins: %rbx, %rbx
frame-setup PUSH64r killed %rbx, implicit-def %rsp, implicit %rsp
%rsp = frame-setup SUB64ri8 %rsp, 32, implicit-def dead %eflags
%rbx = LOAD_STACK_GUARD :: (invariant load 8 from %ir.__stack_chk_guard)
MOV64mr %rsp, 1, _, 24, _, %rbx
%rsi = LEA64r %rsp, 1, _, 19, _
MOV64mr %rsp, 1, _, 8, _, %rsi
%rdi = LEA64r %rip, 1, _, @.str, _
dead %eax = MOV32r0 implicit-def dead %eflags, implicit-def %al
CALL64pcrel32 @printf, csr_64, implicit %rsp, implicit %rdi, implicit %rsi, implicit %al, implicit-def %rsp, implicit-def %eax
CMP64rm killed %rbx, %rsp, 1, _, 24, _, implicit-def %eflags
%rsp = ADD64ri8 %rsp, 32, implicit-def dead %eflags
%rbx = POP64r implicit-def %rsp, implicit %rsp
RETQ %eax
...
79 changes: 79 additions & 0 deletions test/CodeGen/MIR/X86/frame-info-stack-references.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# RUN: llc -march=x86-64 -start-after branch-folder -stop-after branch-folder -o /dev/null %s | FileCheck %s
# This test ensures that the MIR parser parses the stack protector stack
# object reference in the machine frame info correctly.

--- |
@.str = private unnamed_addr constant [4 x i8] c"%s\0A\00", align 1
@__stack_chk_guard = external global i8*

define i32 @test() #0 {
entry:
%StackGuardSlot = alloca i8*
%StackGuard = load i8*, i8** @__stack_chk_guard
call void @llvm.stackprotector(i8* %StackGuard, i8** %StackGuardSlot)
%test = alloca i8*, align 8
%a = alloca i8, i64 5
store i8* %a, i8** %test, align 8
%b = load i8*, i8** %test, align 8
%call = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i32 0, i32 0), i8* %b)
call void @llvm.stackprotectorcheck(i8** @__stack_chk_guard)
ret i32 %call
}

declare i32 @printf(i8*, ...)

declare void @llvm.stackprotector(i8*, i8**) #1

declare void @llvm.stackprotectorcheck(i8**) #2

attributes #0 = { ssp "stack-protector-buffer-size"="5" }
attributes #1 = { nounwind }
attributes #2 = { nounwind argmemonly }
...
---
name: test
alignment: 4
tracksRegLiveness: true
frameInfo:
stackSize: 40
maxAlignment: 8
adjustsStack: true
hasCalls: true
# CHECK-LABEL: name: test
# CHECK: frameInfo
# CHECK: stackProtector: '%stack.0.StackGuardSlot'
stackProtector: '%stack.0.StackGuardSlot'
fixedStack:
- { id: 0, type: spill-slot, offset: -16, size: 8, alignment: 16,
callee-saved-register: '%rbx' }
stack:
- { id: 0, name: StackGuardSlot, offset: -24, size: 8, alignment: 8 }
- { id: 1, name: test, offset: -40, size: 8, alignment: 8 }
- { id: 2, name: a, offset: -29, size: 5, alignment: 1 }
body: |
bb.0.entry:
successors: %bb.1.entry, %bb.2.entry
liveins: %rbx, %rbx
frame-setup PUSH64r killed %rbx, implicit-def %rsp, implicit %rsp
%rsp = frame-setup SUB64ri8 %rsp, 32, implicit-def dead %eflags
%rbx = LOAD_STACK_GUARD :: (invariant load 8 from %ir.__stack_chk_guard)
MOV64mr %rsp, 1, _, 24, _, %rbx
%rsi = LEA64r %rsp, 1, _, 19, _
MOV64mr %rsp, 1, _, 8, _, %rsi
%rdi = LEA64r %rip, 1, _, @.str, _
dead %eax = MOV32r0 implicit-def dead %eflags, implicit-def %al
CALL64pcrel32 @printf, csr_64, implicit %rsp, implicit %rdi, implicit %rsi, implicit %al, implicit-def %rsp, implicit-def %eax
CMP64rm killed %rbx, %rsp, 1, _, 24, _, implicit-def %eflags
JNE_1 %bb.2.entry, implicit %eflags
bb.1.entry:
liveins: %eax
%rsp = ADD64ri8 %rsp, 32, implicit-def dead %eflags
%rbx = POP64r implicit-def %rsp, implicit %rsp
RETQ %eax
bb.2.entry:
CALL64pcrel32 $__stack_chk_fail, csr_64, implicit %rsp, implicit-def %rsp
...

0 comments on commit 07c6bd8

Please sign in to comment.