diff --git a/include/base/SMPDataFlowAnalysis.h b/include/base/SMPDataFlowAnalysis.h
index 051401340ee1f8ae70db6e918d85ad90434cc936..fc31df263b6ff1ae03be0d85bcb009277bc9157e 100644
--- a/include/base/SMPDataFlowAnalysis.h
+++ b/include/base/SMPDataFlowAnalysis.h
@@ -443,6 +443,9 @@ enum SMPitype {
 	HALT = 256       // execution stops
 };
 
+#define IsBranchOrCall(FlowType) ((FlowType >= JUMP) && (FlowType <= INDIR_CALL))
+#define IsControlFlow(FlowType) ((FlowType >= JUMP) && (FlowType <= RETURN))
+
 // A primary goal of data flow analysis in SMP will be to identify
 //  operands as numeric or pointer type. If an instruction definitely
 //  produces a numeric result, an annotation could inform the mmStrata
diff --git a/include/base/SMPFunction.h b/include/base/SMPFunction.h
index 5b293a5a002b662151f21a5ab4d356c635b4d5d6..f4310796b602cb5e2f835aec9368ab44cb9b4f78 100644
--- a/include/base/SMPFunction.h
+++ b/include/base/SMPFunction.h
@@ -294,6 +294,7 @@ public:
 	inline void SetUnsafeForFastReturns(bool Status, UnsafeFastReturnReason Reason) { UnsafeForFastReturns = Status; FastReturnStatus |= (int) Reason; return; };
 	inline void SetIsSpeculative(bool IsS) { IsSpeculative = IsS; };
 	inline void SetIsMutuallyRecursive(void) { MutuallyRecursive = true; };
+	inline void SetIsCalledFromOrphanedCode(void) { CalledFromOrphanCode = 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
@@ -382,6 +383,7 @@ public:
 	inline bool DoesStackFrameExtendPastStackTop(void) const { return StackFrameExtendsPastStackTop; };
 	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; };
 
 	// Printing methods
 	void Dump(void); // debug dump
@@ -462,6 +464,7 @@ private:
 //	bool SharedChunks; // Does function share a tail chunk with other functions?
 	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 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/include/base/SMPProgram.h b/include/base/SMPProgram.h
index 154a45a59461f89c8e98559e2048d5cfa5c3b8b5..17ecb4bcda6223228fd897e62bcad96627f1e4ec 100644
--- a/include/base/SMPProgram.h
+++ b/include/base/SMPProgram.h
@@ -134,6 +134,7 @@ public:
 	void ProfGranularityFinished(FILE *AnnotFile, FILE *InfoAnnotFile);  // notification from ProfilerInformation
 	bool InsertUnsharedFragment(STARS_ea_t TargetAddr); // Add code fragment starting address to set; return false if already in set, true otherwise
 	bool InsertDataToCodeXref(STARS_ea_t TargetAddr); // Data xref to code TargetAddr has been found; record it
+	void SetFuncAddrCalledFromOrphanedCode(STARS_ea_t TargetAddr); // TargetAddr is called from orphaned code
 	void AddUnreachableBlock(SMPBasicBlock *DeadBlock); // Add unreachable block and its instructions to containers
 	void SetProgramThrowsExceptions(void); // Record detection of __cxa_throw in the binary
 	void AddBlockToRemovalList(SMPBasicBlock *UnreachableBlock); // Add block, e.g. with "call 0" instruction, to later removal list.
@@ -145,6 +146,7 @@ public:
 	bool IsUnsharedFragment(STARS_ea_t InstAddr); // Does InstAddr begin an unshared function fragment?
 	bool IsCodeXrefFromData(STARS_ea_t InstAddr) const; // Does InstAddr have a data xref to it?
 	inline bool ProgramThrowsExceptions(void) const { return ThrowsExceptions; };
+	bool IsFuncAddrCalledFromOrphanedCode(STARS_ea_t InstAddr) const; // Look up in address set of targets from orphaned code
 
 	// Printing methods
 	void Dump(void); // debug dump
@@ -175,6 +177,7 @@ private:
 	std::list<std::pair<STARS_ea_t, SMPFunction *> > FuncList; // FuncMap entries prioritized in desired order for analysis
 	std::set<STARS_ea_t> UnsharedFragments; // Code fragments incorporated into their callers; remove from FuncMaps
 	std::set<STARS_ea_t> DataToCodeXrefTargets; // Code targets of data xrefs; probably will be called indirectly
+	std::set<STARS_ea_t> FuncAddrsCalledFromOrphanedCode; // Program CFG is not complete for these funcs due to calls from orphaned code
 
 	std::map<STARS_ea_t, SMPBasicBlock *> UnreachableInstBlockMap;  // unreachable instructions, removed from their functions, mapped to blocks
 	std::vector<SMPBasicBlock *> UnreachableBlocks; // unreachable blocks, removed from their functions
diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp
index d3d287dee20ec0a7131bb79b938ddf2c11a4126b..072e77009d9d99b7d755318e31e0153e4dabf8e3 100644
--- a/src/base/SMPFunction.cpp
+++ b/src/base/SMPFunction.cpp
@@ -158,6 +158,7 @@ SMPFunction::SMPFunction(STARS_Function_t *Info, SMPProgram* pgm) {
 //	this->SetSharedChunks(false);
 	this->UnsharedChunks = false;
 	this->MultipleEntryPoints = false;
+	this->CalledFromOrphanCode = false;
 	this->CallsAlloca = false;
 	this->PushAfterLocalVarAlloc = false;
 	this->LinkerStub = false;
@@ -3872,6 +3873,9 @@ void SMPFunction::AnalyzeFunc(void) {
 	this->SetLinks();
 	this->RPONumberBlocks();
 	this->DetectLinkerStubFunction();
+	if (this->GetProg()->IsFuncAddrCalledFromOrphanedCode(this->GetFirstFuncAddr())) {
+		this->SetIsCalledFromOrphanedCode();
+	}
 
 	FragmentWorkList.clear();
 	return;
@@ -9613,7 +9617,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)) {
+				if (!(this->PossibleIndirectCallTarget || this->MultipleEntryPoints || this->IsCalledFromOrphanedCode())) {
 					global_STARS_program->PrintCodeToCodeXrefComplete(ReturnInstAddr, RetInstSize, this->ReturnTargets.size());
 				}
 			}
diff --git a/src/base/SMPProgram.cpp b/src/base/SMPProgram.cpp
index e38653631e988036557405e473b80c401b8ae986..45286945f527bf13b503dd689f171a7ef9e9b9d4 100644
--- a/src/base/SMPProgram.cpp
+++ b/src/base/SMPProgram.cpp
@@ -177,6 +177,12 @@ bool SMPProgram::InsertDataToCodeXref(STARS_ea_t TargetAddr) {
 	return InsertResult.second;
 } // end of SMPProgram::InsertDataToCodeXref()
 
+// TargetAddr is called from orphaned code
+void SMPProgram::SetFuncAddrCalledFromOrphanedCode(STARS_ea_t TargetAddr) {
+	this->FuncAddrsCalledFromOrphanedCode.insert(TargetAddr);
+	return;
+}
+
 // Add unreachable block and its instructions to containers
 void SMPProgram::AddUnreachableBlock(SMPBasicBlock *DeadBlock) {
 	assert(NULL != DeadBlock);
@@ -224,6 +230,12 @@ bool SMPProgram::IsCodeXrefFromData(STARS_ea_t InstAddr) const {
 	return Found;
 }
 
+// Look up in address set of targets from orphaned code
+bool SMPProgram::IsFuncAddrCalledFromOrphanedCode(STARS_ea_t InstAddr) const {
+	bool Found = (this->FuncAddrsCalledFromOrphanedCode.find(InstAddr) != this->FuncAddrsCalledFromOrphanedCode.end());
+	return Found;
+}
+
 // Main program analysis driver. Goes through all functions and
 //  analyzes all functions and global static data.
 void SMPProgram::Analyze(ProfilerInformation *pi, FILE *AnnotFile, FILE *InfoAnnotFile) {
diff --git a/src/drivers/idapro/SMPStaticAnalyzer.cpp b/src/drivers/idapro/SMPStaticAnalyzer.cpp
index 76b984deeeff9a9c3c2c542d6b82c0eff002a304..aa73d8b93bb19e431f37d2a55cd909810d78c8f7 100644
--- a/src/drivers/idapro/SMPStaticAnalyzer.cpp
+++ b/src/drivers/idapro/SMPStaticAnalyzer.cpp
@@ -83,7 +83,7 @@ int FuncsProcessed = 0;
 #define SMP_FIXUP_IDB 0  // Try to fix the IDA database? NOTE: Needs lots of updating before re-enabling.
 #define SMP_DEBUG_FIXUP_IDB 0  // debugging output for FixupIDB chain
 #define SMP_FIND_ORPHANS 1  // find code outside of functions
-#define SMP_DEBUG_CODE_ORPHANS 1 // Detect whether we are causing code to be orphaned
+#define SMP_DEBUG_CODE_ORPHANS 0 // Detect whether we are causing code to be orphaned
 
 #define SMP_IDAP_RUN_DELAY 0  // Delay in IDAP_run() so we can attach debugger to process.
 
@@ -96,9 +96,7 @@ static SMPProgram *CurrProg = NULL;
 STARS_Interface_t* global_stars_interface = NULL;
 STARS_Program_t *global_STARS_program = NULL;
 
-#if SMP_DEBUG_CODE_ORPHANS
 set<STARS_ea_t> CodeOrphans;
-#endif
 
 // Should we convert the x86 LOCK prefix byte to a no-op to avoid
 //  IDA Pro problems with instructions that jump past the LOCK
@@ -179,6 +177,7 @@ void FindDataInCode(void);
 void AuditTailChunkOwnership(void);
 void FindOrphanedCode(STARS_Segment_t *, FILE *, FILE *);
 void Debug_FindOrphanedCode(STARS_Segment_t *, bool);
+void FindLinksFromOrphanedCode(STARS_Segment_t *);
 void FixCodeIdentification(void);
 int FixupNewCodeChunks(void);
 void AuditCodeTargets(void);
@@ -428,6 +427,14 @@ void IDAP_run(int arg) {
 	}
 	
 	CurrProg->ProfGranularityFinished(global_STARS_program->GetAnnotFile(), global_STARS_program->GetInfoAnnotFile());
+
+	RecentAddr = STARS_BADADDR;
+	for (STARS_Segment_t *seg = SMP_get_first_seg(); NULL != seg; seg = SMP_get_next_seg(RecentAddr)) {
+		RecentAddr = seg->get_startEA();
+		if (seg->IsCodeSegment())
+			FindLinksFromOrphanedCode(seg);
+	}
+
 	CurrProg->Analyze(prof_info, global_STARS_program->GetAnnotFile(), global_STARS_program->GetInfoAnnotFile());
 	if (!global_STARS_program->ShouldSTARSPerformReducedAnalysis()) {
 		CurrProg->EmitAnnotations(global_STARS_program->GetAnnotFile(), global_STARS_program->GetInfoAnnotFile());
@@ -1461,6 +1468,52 @@ void FindOrphanedCode(STARS_Segment_t *CurrSeg, FILE *AnnotFile, FILE *InfoAnnot
 	} // end for (ea_t addr = CurrSeg->startEA; ...)
 } // end of FindOrphanedCode()
 
+// Find calls and jumps from orphaned code to functions. Mark those functions
+//  so that we will know that the program CFG is not complete.
+void FindLinksFromOrphanedCode(STARS_Segment_t *CurrSeg) {
+	char disasm[MAXSTR];
+	for (STARS_ea_t addr = CurrSeg->get_startEA(); addr < CurrSeg->get_endEA(); addr = SMP_get_item_end(addr)) {
+		flags_t InstrFlags = getFlags(addr);
+		if (SMP_isHead(InstrFlags) && SMP_isCode(InstrFlags)) {
+			// Does IDA Pro think addr is inside a function?
+			func_t* CurrIDAFunc = ::get_func(addr);
+			if (NULL == CurrIDAFunc) {
+				SMPInstr CurrInst(addr);
+				CurrInst.Analyze();
+				// Do machine-dependent fixes for DEF and USE lists.
+				//  The fixes can help produce better annotations.
+				CurrInst.MDFixupDefUseLists();
+
+				if (CurrInst.IsAnalyzeable()) {
+					// If instruction is control flow, see if it reaches an addr in a function.
+					SMPitype CurrDataFlow = CurrInst.GetDataFlowType();
+					if (IsBranchOrCall(CurrDataFlow)) {
+						STARS_ea_t TargetAddr = CurrInst.GetCallTarget();
+						if (STARS_BADADDR == TargetAddr) {
+							TargetAddr = CurrInst.GetJumpTarget();
+						}
+						if (STARS_BADADDR != TargetAddr) {
+							// See if TargetAddr is inside a function.
+							func_t* TargetFunc = ::get_func(TargetAddr);
+							if (NULL != TargetFunc) {
+								STARS_ea_t FirstAddrInFunc = TargetFunc->startEA;
+								if (FirstAddrInFunc != TargetAddr) {
+									SMP_msg("WARNING: Orphaned code at %llx calls %llx which is inside func starting at %llx\n",
+										(unsigned long long) addr, (unsigned long long) TargetAddr, (unsigned long long) FirstAddrInFunc);
+								}
+								CurrProg->SetFuncAddrCalledFromOrphanedCode(FirstAddrInFunc);
+								SMP_msg("INFO: Orphaned code at %llx calls func at %llx\n",
+									(unsigned long long) addr, (unsigned long long) FirstAddrInFunc);
+							}
+						}
+					}
+				}
+			} // end if (NULL == CurrFunc)
+		} // end if addr is code and isHead
+	} // end for (ea_t addr = CurrSeg->startEA; ...)
+	return;
+} // end of FindLinksFromOrphanedCode()
+
 // Version of FindOrphanedCode that does not emit annotations but can be used
 //  to determine at what point in time code becomes orphaned.
 void Debug_FindOrphanedCode(STARS_Segment_t *CurrSeg, bool FirstRun) {