From 28f514acfeec1dd105d663d9c3d269fa46dd002e Mon Sep 17 00:00:00 2001 From: clc5q <clc5q@git.zephyr-software.com> Date: Mon, 11 Jan 2016 16:05:28 +0000 Subject: [PATCH] Detect chains of tail calls that cause return to orphaned code. Former-commit-id: dbfd0f99ba3a6c364d9a639af771b1b143470144 --- include/base/SMPFunction.h | 3 +++ src/base/SMPFunction.cpp | 10 +++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/include/base/SMPFunction.h b/include/base/SMPFunction.h index f4310796..de25c986 100644 --- a/include/base/SMPFunction.h +++ b/include/base/SMPFunction.h @@ -295,6 +295,7 @@ public: inline void SetIsSpeculative(bool IsS) { IsSpeculative = IsS; }; inline void SetIsMutuallyRecursive(void) { MutuallyRecursive = true; }; inline void SetIsCalledFromOrphanedCode(void) { CalledFromOrphanCode = true; }; + inline void SetIsTailCallChainFromOrphanedCode(void) { TailCallChainFromOrphanCode = true; }; inline void SetHasHashingCode(bool Hashes) { HasHashingCode = Hashes; }; void AddCallSource(STARS_ea_t addr); // Add a caller to the list of all callers of this function. bool AddDirectCallTarget(STARS_ea_t addr); // Add a direct call target; return true if new target, false if target already added @@ -384,6 +385,7 @@ public: inline bool IsRegPreserved(std::size_t RegNum) const { return (PreservedRegsBitmap[RegNum] != 0); }; inline bool IsPossibleIndirectCallTarget(void) const { return PossibleIndirectCallTarget; }; inline bool IsCalledFromOrphanedCode(void) const { return CalledFromOrphanCode; }; + inline bool IsTailCallChainFromOrphanedCode(void) const { return TailCallChainFromOrphanCode; }; // Printing methods void Dump(void); // debug dump @@ -465,6 +467,7 @@ private: bool UnsharedChunks; // Does function have noncontiguous fragments that are not shared with other funcs? bool MultipleEntryPoints; // Does function have multiple entry points from other functions? bool CalledFromOrphanCode; // function is called from orphaned code, so program CFG is not complete at this function. + bool TailCallChainFromOrphanCode; // Part of chain orphancode ... func.. tailcallsfunc2 ... which can return to orphaned code bool CallsAlloca; // Does function allocate stack space after initial allocation? NOTE:SMPInstr::IsAllocaCall() excludes immediate value alloca calls bool PushAfterLocalVarAlloc; // Does function push onto the stack after allocating local var space? bool LinkerStub; // Is function just a stub to be filled in by the linker, e.g. a PLT stub? diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp index 1e789c18..724815aa 100644 --- a/src/base/SMPFunction.cpp +++ b/src/base/SMPFunction.cpp @@ -159,6 +159,7 @@ SMPFunction::SMPFunction(STARS_Function_t *Info, SMPProgram* pgm) { this->UnsharedChunks = false; this->MultipleEntryPoints = false; this->CalledFromOrphanCode = false; + this->TailCallChainFromOrphanCode = false; this->CallsAlloca = false; this->PushAfterLocalVarAlloc = false; this->LinkerStub = false; @@ -9227,6 +9228,9 @@ bool SMPFunction::ComputeReturnTargets(bool FirstIteration) { IncompleteCaller = true; UnresolvedCallers.insert(CallingFunc); } + if (CallingFunc->IsCalledFromOrphanedCode() || CallingFunc->IsTailCallChainFromOrphanedCode()) { + this->SetIsTailCallChainFromOrphanedCode(); + } } else if (STARS_LIVEIN_PSEUDO_ID == FallThroughAddr) { // error case; could not find fall-through this->ReturnTargetsComputed = true; @@ -9262,6 +9266,9 @@ bool SMPFunction::ComputeReturnTargets(bool FirstIteration) { IncompleteCaller = true; UnresolvedCallers.insert(CallingFunc); } + if (CallingFunc->IsCalledFromOrphanedCode() || CallingFunc->IsTailCallChainFromOrphanedCode()) { + this->SetIsTailCallChainFromOrphanedCode(); + } } } this->ReturnTargetsComputed = (!IncompleteCaller); @@ -9601,6 +9608,7 @@ void SMPFunction::EmitAnnotations(FILE *AnnotFile, FILE *InfoAnnotFile) { // Emit Indirect Branch Target destinations for return instructions in this func. void SMPFunction::EmitReturnTargetAnnotations(void) { if (!this->ReturnTargets.empty()) { + bool OrphanCodeProblem = (this->IsCalledFromOrphanedCode() || this->IsTailCallChainFromOrphanedCode()); for (size_t BlockIndex = 0; BlockIndex < this->RPOBlocks.size(); ++BlockIndex) { SMPBasicBlock *CurrBlock = this->RPOBlocks[BlockIndex]; if (CurrBlock->HasReturn()) { @@ -9617,7 +9625,7 @@ void SMPFunction::EmitReturnTargetAnnotations(void) { bool TailCallFlag = (this->TailReturnTargets.find(RetTargetAddr) != this->TailReturnTargets.end()); global_STARS_program->PrintReturnInstXref(ReturnInstAddr, RetTargetAddr, RetInstSize, TailCallFlag); } - if (!(this->PossibleIndirectCallTarget || this->MultipleEntryPoints || this->IsCalledFromOrphanedCode())) { + if (!(this->PossibleIndirectCallTarget || this->MultipleEntryPoints || OrphanCodeProblem)) { global_STARS_program->PrintCodeToCodeXrefComplete(ReturnInstAddr, RetInstSize, this->ReturnTargets.size()); } } -- GitLab