diff --git a/include/base/SMPDataFlowAnalysis.h b/include/base/SMPDataFlowAnalysis.h
index da891dd19f228ce6578d32f93756f74de3d3c603..001ecefe22248bfa2455bed3d4dc2b962a475d74 100644
--- a/include/base/SMPDataFlowAnalysis.h
+++ b/include/base/SMPDataFlowAnalysis.h
@@ -973,4 +973,7 @@ void GetPointerArgPositionsForCallName(std::string CalleeName, unsigned int &Arg
 // Utility to count bits set in an unsigned int, e.g. ArgPosBits.
 unsigned int CountBitsSet(unsigned int ArgPosBits);
 
+// Is FuncName a standard library function name?
+bool IsLibFuncName(std::string CalleeName);
+
 #endif
diff --git a/include/base/SMPFunction.h b/include/base/SMPFunction.h
index 1c48d02690e7ddc89f49b0be81cfc74180131daa..c359f5add04836373625620f748b3406cd48967a 100644
--- a/include/base/SMPFunction.h
+++ b/include/base/SMPFunction.h
@@ -378,6 +378,7 @@ public:
 	bool FindReachingStackDelta(STARS_sval_t &StackDelta); // Find maximum stack delta in TempStackDeltaReachesList; return true if one consistent delta is in the list
 	void GatherIncomingArgTypes(void); // Use the SSA marker inst to record incoming arg types in member InArgTypes.
 	void EmitAnnotations(FILE *AnnotFile, FILE *InfoAnnotFile);
+	void PreProcessForSPARKAdaTranslation(void); // Perform look-ahead steps needed before translation to SPARK Ada.
 	void EmitFuncSPARKAda(void); // Emit SPARK Ada translation of function
 	void LiveVariableAnalysis(bool Recomputing);  // Perform Live Variable Analysis across all blocks
 	void RecomputeSSA(void); // Recompute LVA and SSA and all dependent data structures now that unreachable blocks have been removed.
diff --git a/include/base/SMPProgram.h b/include/base/SMPProgram.h
index fbece3c40a7a1895eb16603c1097adc2eb88a4f6..a2feacf3d66e0445a506b5ec075c8c1dfe0c428b 100644
--- a/include/base/SMPProgram.h
+++ b/include/base/SMPProgram.h
@@ -119,6 +119,8 @@ public:
 	inline ProfilerInformation *GetProfInfo(void) { return ProfInfo; };
 	SMPFunction* FindFunction(STARS_ea_t FirstAddr); // get function from first addr in function
 	inline std::size_t GetFuncCount(void) const { return FuncMap.size(); };
+	inline std::set<std::string>::iterator GetFirstLibraryFuncName(void) { return LibraryCallTargetNames.begin(); };
+	inline std::set<std::string>::iterator GetLastLibraryFuncName(void) { return LibraryCallTargetNames.end(); };
 
 	// Set methods
 	void ProfGranularityFinished(FILE *AnnotFile, FILE *InfoAnnotFile);  // notification from ProfilerInformation
@@ -129,6 +131,7 @@ public:
 	void AddBlockToRemovalList(SMPBasicBlock *UnreachableBlock); // Add block, e.g. with "call 0" instruction, to later removal list.
 	std::pair<std::map<std::string, STARS_ea_t>::iterator, bool> InsertGlobalNameAddrMapEntry(std::pair<std::string, STARS_ea_t> TempPair) { return GlobalNameMap.insert(TempPair); };
 	void InsertGlobalVarTableEntry(std::pair<STARS_ea_t, struct GlobalVar> VarItem) { GlobalVarTable.insert(VarItem); };
+	inline std::pair<std::set<std::string>::iterator, bool> InsertLibraryFuncName(std::string FuncName) { return LibraryCallTargetNames.insert(FuncName); };
 
 	// Query methods
 	bool IsUnsharedFragment(STARS_ea_t InstAddr); // Does InstAddr begin an unshared function fragment?
@@ -169,6 +172,7 @@ private:
 	std::list<SMPInstr *> UnreachableInstList; // unreachable instructions, removed from their functions
 	std::list<SMPBasicBlock *> BlocksPendingRemoval; // blocks that need to be removed later as unreachable
 	std::set<SMPFunction *> FuncsWithBlocksRemoved;
+	std::set<std::string> LibraryCallTargetNames; // Standard library functions called by program; used in SPARK Ada translation
 
 	// Methods
 	void InitStaticDataTable(void); // Gather info about global static data locations
diff --git a/src/base/SMPDataFlowAnalysis.cpp b/src/base/SMPDataFlowAnalysis.cpp
index cfc7dc75bbbf46a4fb125ffee8ca1278d9ab4012..7f913ed0cfb5936e6ef55446e4db515669736a92 100644
--- a/src/base/SMPDataFlowAnalysis.cpp
+++ b/src/base/SMPDataFlowAnalysis.cpp
@@ -4189,3 +4189,39 @@ void GetLibFuncFGInfo(string FuncName, struct FineGrainedInfo &InitFGInfo) {
 } // end of GetLibFuncFGInfo()
 
 
+// Is FuncName a standard library function name?
+bool IsLibFuncName(std::string CalleeName) {
+	// Return true if we find the name in any of our function type maps.
+
+	map<string, struct FineGrainedInfo>::iterator RetTypeIter = ReturnRegisterTypeMap.find(CalleeName);
+	if (RetTypeIter != ReturnRegisterTypeMap.end()) { // found
+		return true;
+	}
+
+	map<string, unsigned int>::iterator PtrArgIter = PointerArgPositionMap.find(CalleeName);
+	if (PtrArgIter != PointerArgPositionMap.end()) { // found it
+		return true;
+	}
+
+	map<string, unsigned int>::iterator TaintIter = TaintWarningArgPositionMap.find(CalleeName);
+	if (TaintIter != TaintWarningArgPositionMap.end()) { // found it
+		return true;
+	}
+
+	map<string, unsigned int>::iterator UnsignedIter = UnsignedArgPositionMap.find(CalleeName);
+	if (UnsignedIter != UnsignedArgPositionMap.end()) { // found it
+		return true;
+	}
+
+	map<string, string>::iterator SinkIter = IntegerErrorCallSinkMap.find(CalleeName);
+	if (SinkIter != IntegerErrorCallSinkMap.end()) { // found it
+		return true;
+	}
+
+	// Put searches for additional library function names here.
+	if (0 == CalleeName.compare("setuid")) {
+		return true;
+	}
+
+	return false;
+} // end of IsLibFuncName()
diff --git a/src/base/SMPFunction.cpp b/src/base/SMPFunction.cpp
index 6a21dadf0282915d02fd68d7bb717a37d075affd..ea5a97ef3fc15926766e55d275f09e4492b424a3 100644
--- a/src/base/SMPFunction.cpp
+++ b/src/base/SMPFunction.cpp
@@ -8677,6 +8677,26 @@ void SMPFunction::MarkFunctionSafe() {
 	return;
 } // end of SMPFunction::MarkFunctionSafe()
 
+// Perform look-ahead steps needed before translation to SPARK Ada.
+void SMPFunction::PreProcessForSPARKAdaTranslation(void) {
+	for (vector<SMPBasicBlock *>::iterator BlockIter = this->RPOBlocks.begin(); BlockIter != this->RPOBlocks.end(); ++BlockIter) {
+		SMPBasicBlock *CurrBlock = (*BlockIter);
+		if (CurrBlock->HasCallInstruction()) {
+			for (vector<SMPInstr *>::iterator InstIter = CurrBlock->GetFirstInst(); InstIter != CurrBlock->GetLastInst(); ++InstIter) {
+				SMPInstr *CurrInst = (*InstIter);
+				if (CurrInst->GetDataFlowType() == CALL) {
+					string CalledFuncName = CurrInst->GetTrimmedCalledFunctionName();
+					if (IsLibFuncName(CalledFuncName)) {
+						pair<set<string>::iterator, bool> InsertResult = this->Program->InsertLibraryFuncName(CalledFuncName);
+					}
+				}
+			}
+		}
+	}
+
+	return;
+} // end of SMPFunction::PreProcessForSPARKAdaTranslation()
+
 // For debugging purposes, only emit SPARK Ada for main().
 #define STARS_EMIT_ADA_FOR_MAIN_ONLY 1
 
@@ -8685,6 +8705,7 @@ void SMPFunction::EmitFuncSPARKAda(void) {
 	if (this->IsLinkerStub()) {
 		return;
 	}
+
 	string AdaFuncName(this->GetFuncName());
 #if STARS_EMIT_ADA_FOR_MAIN_ONLY
 	if (0 != strcmp("main", AdaFuncName.c_str())) {
@@ -8701,9 +8722,10 @@ void SMPFunction::EmitFuncSPARKAda(void) {
 
 	// Emit beginning of function body.
 	SMP_fprintf(BodyFile, "procedure %s\nis\n", AdaFuncName.c_str());
-	SMP_fprintf(BodyFile, "\tra0 : Unsigned8 := X86.ReadMem8(X86.RSP);\n");
+	SMP_fprintf(BodyFile, "\tSaveStackPtr : Unsigned64 := X86.RSP with Ghost;\n");
+	SMP_fprintf(BodyFile, "\tra0 : Unsigned8 := X86.ReadMem8(X86.RSP) with Ghost;\n");
 	for (unsigned short i = 1; i < ByteWidth; ++i) {
-		SMP_fprintf(BodyFile, "\tra%u : Unsigned8 := X86.ReadMem8(X86.RSP + %u);\n", i, i);
+		SMP_fprintf(BodyFile, "\tra%u : Unsigned8 := X86.ReadMem8(X86.RSP + %u) with Ghost;\n", i, i);
 	}
 	SMP_fprintf(BodyFile, "\nbegin\n");
 
diff --git a/src/base/SMPProgram.cpp b/src/base/SMPProgram.cpp
index b343346a65bc70ef587007482c5cee32de008958..4074c3618e175f56cc2f2ae3b293e2dabcc77973 100644
--- a/src/base/SMPProgram.cpp
+++ b/src/base/SMPProgram.cpp
@@ -788,6 +788,7 @@ bool SMPProgram::EmitProgramSPARKAda(void) {
 	FILE *BodyFile = global_STARS_program->GetSPARKSourceFile(); // SPARK Ada *.adb implementation
 	FILE *SpecFile = global_STARS_program->GetSPARKHeaderFile(); // SPARK Ada *.ads specification
 	string RootName(global_STARS_program->GetRootFileName());    // original file name without path, e.g. foo.exe
+	size_t ByteWidth = global_STARS_program->GetSTARS_ISA_Bytewidth();
 
 	// Extract "foo" from "foo.exe" to get the Ada package name
 	string PackageName;
@@ -815,8 +816,38 @@ bool SMPProgram::EmitProgramSPARKAda(void) {
 	SMP_fprintf(SpecFile, "\tsubtype Unsigned16 is X86.Unsigned16;\n");
 	SMP_fprintf(SpecFile, "\tsubtype Unsigned8  is X86.Unsigned8;\n\n");
 
-	// Loop through all functions and emit annotations for each.
+	// Loop through all functions and perform look-ahead pre-processing needed for later annotation emission.
 	map<STARS_ea_t, SMPFunction *>::iterator FuncIter;
+	for (FuncIter = this->FuncMap.begin(); FuncIter != this->FuncMap.end(); ++FuncIter) {
+		SMPFunction *TempFunc = FuncIter->second;
+		if (TempFunc == NULL) continue;
+		if (TempFunc->HasReducibleControlFlow()) {
+			TempFunc->PreProcessForSPARKAdaTranslation();
+		}
+	} // end for all functions
+
+	// Emit procedure specifications and bodies for library functions
+	for (set<string>::iterator NameIter = this->LibraryCallTargetNames.begin(); NameIter != this->LibraryCallTargetNames.end(); ++NameIter) {
+		string LibFuncName = (*NameIter);
+		SMP_fprintf(SpecFile, "procedure %s with\n", LibFuncName.c_str());
+		SMP_fprintf(BodyFile, "procedure %s is\nbegin\n\tX86.RSP := X86.RSP + %u;\n", LibFuncName.c_str(), ByteWidth);
+		if (0 != LibFuncName.compare("setuid")) {
+			// Emit minimal stub
+			SMP_fprintf(SpecFile, "\tGlobal => (In_Out => X86.RSP),\n");
+			SMP_fprintf(SpecFile, "\tPost => (X86.RSP = X86.RSP'Old + 8);\n\n");
+		}
+		else { // emit setuid stub
+			SMP_fprintf(SpecFile, "\tGlobal => (Input  => (X86.RDI),\n");
+			SMP_fprintf(SpecFile, "\t\tIn_Out => (Dummy_Var, X86.RSP)),\n");
+			SMP_fprintf(SpecFile, "\tPre => (X86.RDI /= 0),\n");
+			SMP_fprintf(SpecFile, "\tPost => ((Dummy_Var = Dummy_Var'Old + Unsigned64(X86.EDI)) and\n");
+			SMP_fprintf(SpecFile, "\t\t(X86.RSP = X86.RSP'Old + 8));\n\n");
+			SMP_fprintf(BodyFile, "\tDummy_Var := Dummy_Var + Unsigned64(X86.EDI);\n");
+		}
+		SMP_fprintf(BodyFile, "end %s;\n\n", LibFuncName.c_str());
+	}
+
+	// Loop through all functions and emit annotations for each.
 	for (FuncIter = this->FuncMap.begin(); FuncIter != this->FuncMap.end(); ++FuncIter) {
 		SMPFunction *TempFunc = FuncIter->second;
 		if (TempFunc == NULL) continue;
diff --git a/src/drivers/idapro/SMPStaticAnalyzer.cpp b/src/drivers/idapro/SMPStaticAnalyzer.cpp
index 6e3bf2ff4442370c1a7ee9291647e3d16f037f34..a8c55b1cd3f483e3fe7565d79c5daef56c911748 100644
--- a/src/drivers/idapro/SMPStaticAnalyzer.cpp
+++ b/src/drivers/idapro/SMPStaticAnalyzer.cpp
@@ -62,7 +62,7 @@
 
 using namespace std;
 
-#define SMP_DEBUG_DELAY 1   // for setting an early breakpoint
+#define SMP_DEBUG_DELAY 0   // for setting an early breakpoint
 
 // Set to 1 for debugging output
 #define SMP_DEBUG 1