diff --git a/.gitattributes b/.gitattributes
index 7c99ab9ae1853e07fbdd6764251d51cf1d989137..35aa5c324058ca9252db405ab8b97e5d61a38996 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -234,16 +234,20 @@ libIRDB/test/read_variantir.cpp -text
 libIRDB/test/unfix_calls.cpp -text
 libIRDB/test/unwind-pe.h -text
 libMEDSannotation/Makefile -text
+libMEDSannotation/include/FuncExitAnnotation.hpp -text
 libMEDSannotation/include/MEDS.hpp -text
 libMEDSannotation/include/MEDS_AnnotationBase.hpp -text
 libMEDSannotation/include/MEDS_AnnotationParser.hpp -text
+libMEDSannotation/include/MEDS_FRSafeAnnotation.hpp -text
 libMEDSannotation/include/MEDS_FuncAnnotation.hpp -text
 libMEDSannotation/include/MEDS_InstructionCheckAnnotation.hpp -text
 libMEDSannotation/include/MEDS_ProblemFuncAnnotation.hpp -text
 libMEDSannotation/include/MEDS_Register.hpp -text
 libMEDSannotation/include/MEDS_SafeFuncAnnotation.hpp -text
 libMEDSannotation/include/VirtualOffset.hpp -text
+libMEDSannotation/src/FuncExitAnnotation.cpp -text
 libMEDSannotation/src/MEDS_AnnotationParser.cpp -text
+libMEDSannotation/src/MEDS_FRSafeAnnotation.cpp -text
 libMEDSannotation/src/MEDS_InstructionCheckAnnotation.cpp -text
 libMEDSannotation/src/MEDS_ProblemFuncAnnotation.cpp -text
 libMEDSannotation/src/MEDS_Register.cpp -text
@@ -401,6 +405,8 @@ tools/ret_shadow_stack/Makefile -text
 tools/ret_shadow_stack/rss_driver.cpp -text
 tools/ret_shadow_stack/rss_instrument.cpp -text
 tools/ret_shadow_stack/rss_instrument.hpp -text
+tools/safefr/Makefile -text
+tools/safefr/fill_in_safefr.cpp -text
 tools/spasm/Makefile -text
 tools/spasm/ben_lib.cpp -text
 tools/spasm/ben_lib.h -text
diff --git a/libIRDB/test/fix_calls.cpp b/libIRDB/test/fix_calls.cpp
index c8406a6fa3956a89cb3314ab06394a58d1772d44..00a179dea7ee2bdc908f37b29b9bb7118ba4f9f7 100644
--- a/libIRDB/test/fix_calls.cpp
+++ b/libIRDB/test/fix_calls.cpp
@@ -58,6 +58,16 @@ bool check_entry(bool &found, ControlFlowGraph_t* cfg)
 
 bool call_needs_fix(Instruction_t* insn)
 {
+
+	for(set<Relocation_t*>::iterator it=insn->GetRelocations().begin();
+		it!=insn->GetRelocations().end();
+		++it
+	   )
+	{
+		Relocation_t* reloc=*it;
+		if(string("safefr") == reloc->GetType())
+			return false;
+	}
 	Instruction_t *target=insn->GetTarget();
 	Instruction_t *fallthru=insn->GetFallthrough();
 	DISASM disasm;
@@ -698,6 +708,29 @@ void fix_other_pcrel(FileIR_t* firp, Instruction_t *insn, UIntPtr virt_offset)
 	}
 }
 
+void fix_safefr(FileIR_t* firp, Instruction_t *insn, UIntPtr virt_offset)
+{
+	/* if this has already been fixed, we can skip it */
+	if(virt_offset==0 || virt_offset==-1)
+		return;
+
+	for(set<Relocation_t*>::iterator it=insn->GetRelocations().begin();
+		it!=insn->GetRelocations().end();
+		++it)
+	{
+		Relocation_t* reloc=*it;
+		assert(reloc);
+		if(string("safefr") == reloc->GetType())
+		{
+			AddressID_t* addr	=new AddressID_t;
+			addr->SetFileID(insn->GetAddress()->GetFileID());
+			firp->GetAddresses().insert(addr);
+			insn->SetAddress(addr);
+		}
+	}
+}
+
+
 void fix_other_pcrel(FileIR_t* firp)
 {
 
@@ -709,6 +742,7 @@ void fix_other_pcrel(FileIR_t* firp)
 	{
 		Instruction_t* insn=*it;
 		fix_other_pcrel(firp,insn, insn->GetAddress()->GetVirtualOffset());
+		fix_safefr(firp,insn, insn->GetAddress()->GetVirtualOffset());
 	}
 }
 
diff --git a/libMEDSannotation/include/FuncExitAnnotation.hpp b/libMEDSannotation/include/FuncExitAnnotation.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..b02764e71e93c3fc34517e78d399de60cc51cc52
--- /dev/null
+++ b/libMEDSannotation/include/FuncExitAnnotation.hpp
@@ -0,0 +1,37 @@
+#ifndef _FUNCEXITANNOTATION_H_
+#define _FUNCEXITANNOTATION_H_
+
+#include <string>
+#include "VirtualOffset.hpp"
+#include "MEDS_Register.hpp"
+#include "MEDS_AnnotationBase.hpp"
+
+
+namespace MEDS_Annotation 
+{
+
+using namespace std;
+using namespace MEDS_Annotation;
+
+//
+// Class to handle one MEDS  annotation
+//
+class MEDS_FuncExitAnnotation : public MEDS_AnnotationBase
+{
+	public:
+		MEDS_FuncExitAnnotation() {};
+		MEDS_FuncExitAnnotation(const string &p_rawLine);
+		virtual ~MEDS_FuncExitAnnotation(){}
+
+		virtual const string toString() const { return "tail call: "+m_rawInputLine; }
+
+	private:
+		void init();
+		void parse();
+
+	private:
+		std::string m_rawInputLine;
+};
+
+}
+#endif
diff --git a/libMEDSannotation/include/MEDS_AnnotationParser.hpp b/libMEDSannotation/include/MEDS_AnnotationParser.hpp
index 8305b4f3c0e0a05224a8f6782e8f0e8d3e8e2983..d353a2f4148449853ee74a179d8ad17f8fedd6fc 100644
--- a/libMEDSannotation/include/MEDS_AnnotationParser.hpp
+++ b/libMEDSannotation/include/MEDS_AnnotationParser.hpp
@@ -23,8 +23,8 @@ class MEDS_AnnotationParser
 		MEDS_AnnotationParser(std::istream &); 	/* pass opened file */
 		void parseFile(std::istream &);
 		void parseFile(const std::string &);	 /* pass filename */
-		MEDS_Annotations_t         getAnnotations() { return m_annotations; }
-		MEDS_FuncAnnotations_t getFuncAnnotations() { return m_func_annotations; }
+		MEDS_Annotations_t &         getAnnotations() { return m_annotations; }
+		MEDS_FuncAnnotations_t & getFuncAnnotations() { return m_func_annotations; }
 
 	private:
 		MEDS_Annotations_t m_annotations;
diff --git a/libMEDSannotation/include/MEDS_FRSafeAnnotation.hpp b/libMEDSannotation/include/MEDS_FRSafeAnnotation.hpp
new file mode 100644
index 0000000000000000000000000000000000000000..1a43102af73dba6429c3c9a8994bc102dc2d0bab
--- /dev/null
+++ b/libMEDSannotation/include/MEDS_FRSafeAnnotation.hpp
@@ -0,0 +1,37 @@
+#ifndef _MEDS_FRSAFEANNOTATION_H_
+#define _MEDS_FRSAFEANNOTATION_H_
+
+#include <string>
+#include "VirtualOffset.hpp"
+#include "MEDS_Register.hpp"
+#include "MEDS_AnnotationBase.hpp"
+
+
+namespace MEDS_Annotation 
+{
+
+using namespace std;
+using namespace MEDS_Annotation;
+
+//
+// Class to handle one MEDS (integer vulnerability) annotation
+//
+class MEDS_FRSafeAnnotation : public MEDS_AnnotationBase
+{
+	public:
+		MEDS_FRSafeAnnotation() {};
+		MEDS_FRSafeAnnotation(const string &p_rawLine);
+		virtual ~MEDS_FRSafeAnnotation(){}
+
+		virtual const string toString() const { return "fr safe func: "+m_rawInputLine; }
+
+	private:
+		void init();
+		void parse();
+
+	private:
+		std::string m_rawInputLine;
+};
+
+}
+#endif
diff --git a/libMEDSannotation/src/FuncExitAnnotation.cpp b/libMEDSannotation/src/FuncExitAnnotation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a213c4dfb2483c2cb84c53ceba579efb1aa567b0
--- /dev/null
+++ b/libMEDSannotation/src/FuncExitAnnotation.cpp
@@ -0,0 +1,61 @@
+#include <stdlib.h>
+
+#include <iostream>
+#include <cstdio>
+#include <string>
+#include <string.h>
+
+#include "MEDS_Register.hpp"
+#include "FuncExitAnnotation.hpp"
+
+using namespace std;
+using namespace MEDS_Annotation;
+
+
+
+
+
+MEDS_FuncExitAnnotation::MEDS_FuncExitAnnotation(const string &p_rawLine)
+{
+	init();
+	m_rawInputLine=p_rawLine;
+	parse();
+}
+
+void MEDS_FuncExitAnnotation::init()
+{
+}
+
+
+/*
+	Example format -- subject to change:
+   804925b      5 INSTR CALL TAILCALL jmp     check_one_fd
+
+
+*/
+void MEDS_FuncExitAnnotation::parse()
+{
+
+	if (m_rawInputLine.find(" INSTR ")==string::npos)
+                return;
+
+        if (
+		m_rawInputLine.find(" INSTR RETURN ")==string::npos  &&
+		m_rawInputLine.find(" INSTR CALL TAILCALL ")==string::npos 
+	   )
+	{
+		/* INSTR  that's not for a safe fast return */
+		return;
+	}
+
+        // get offset
+        VirtualOffset vo(m_rawInputLine);
+        m_virtualOffset = vo;
+
+	setValid();	// no additional info recorded for right now.
+
+//	if(getenv("VERBOSE")!=NULL)
+		cout<<"Found TAILCALL annotation for "<<vo.to_string()<<endl;
+
+}
+
diff --git a/libMEDSannotation/src/MEDS_AnnotationParser.cpp b/libMEDSannotation/src/MEDS_AnnotationParser.cpp
index f9cea504a134b9c75cfa6d3f19b5913b5f80c832..79aab05acd774b3166b2bdc197a78ea9dadd663d 100644
--- a/libMEDSannotation/src/MEDS_AnnotationParser.cpp
+++ b/libMEDSannotation/src/MEDS_AnnotationParser.cpp
@@ -3,8 +3,10 @@
 
 #include "MEDS_AnnotationParser.hpp"
 #include "MEDS_InstructionCheckAnnotation.hpp"
+#include "FuncExitAnnotation.hpp"
 #include "MEDS_SafeFuncAnnotation.hpp"
 #include "MEDS_ProblemFuncAnnotation.hpp"
+#include "MEDS_FRSafeAnnotation.hpp"
 
 // @todo: multiple annotation per instruction
 
@@ -62,6 +64,8 @@ void MEDS_AnnotationParser::parseFile(istream &p_inputStream)
 		ADD_AND_CONTINUE_IF_VALID(MEDS_InstructionCheckAnnotation);
 		ADD_AND_CONTINUE_IF_VALID(MEDS_SafeFuncAnnotation);
 		ADD_AND_CONTINUE_IF_VALID(MEDS_ProblemFuncAnnotation);
+		ADD_AND_CONTINUE_IF_VALID(MEDS_FRSafeAnnotation);
+		ADD_AND_CONTINUE_IF_VALID(MEDS_FuncExitAnnotation);
 
 //				cout<<"Found annotation: "<<annot->toString()<<endl;\
 		
diff --git a/libMEDSannotation/src/MEDS_FRSafeAnnotation.cpp b/libMEDSannotation/src/MEDS_FRSafeAnnotation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2d4ba01a12c9ff117029bb161216e0cb7d992b1a
--- /dev/null
+++ b/libMEDSannotation/src/MEDS_FRSafeAnnotation.cpp
@@ -0,0 +1,65 @@
+#include <stdlib.h>
+
+#include <iostream>
+#include <cstdio>
+#include <string>
+#include <string.h>
+
+#include "MEDS_Register.hpp"
+#include "MEDS_FRSafeAnnotation.hpp"
+
+using namespace std;
+using namespace MEDS_Annotation;
+
+
+
+
+
+MEDS_FRSafeAnnotation::MEDS_FRSafeAnnotation(const string &p_rawLine)
+{
+	init();
+	m_rawInputLine=p_rawLine;
+	parse();
+}
+
+void MEDS_FRSafeAnnotation::init()
+{
+}
+
+
+/*
+	Example format (as of July 31, 2014 ) -- subject to change:
+
+   804b3a6      5 INSTR CALL NOFASTRETURN RAUNSAFE ZZ call frame_dummy 
+   804c941      5 INSTR CALL FASTRETURN ZZ call    _ZN7GString3cmpEPKc; GString::cmp(char const*) 
+   804c511      3 INSTR INDIRCALL NOFASTRETURN INDIRECT ZZ call    dword ptr [eax+8] 
+   804c6fa      1 INSTR RETURN NOFASTRETURN NOCALLERS ZZ retn 
+
+*/
+void MEDS_FRSafeAnnotation::parse()
+{
+
+	if (m_rawInputLine.find(" INSTR ")==string::npos)
+                return;
+
+        if (
+		m_rawInputLine.find(" INSTR CALL FASTRETURN ")==string::npos &&
+		m_rawInputLine.find(" INSTR INDCALL FASTRETURN ")==string::npos &&
+		m_rawInputLine.find(" INSTR RETURN FASTRETURN ")==string::npos 
+	   )
+	{
+		/* INSTR  that's not for a safe fast return */
+		return;
+	}
+
+        // get offset
+        VirtualOffset vo(m_rawInputLine);
+        m_virtualOffset = vo;
+
+	setValid();	// no additional info recorded for right now.
+
+//	if(getenv("VERBOSE")!=NULL)
+		cout<<"Found FASTRETURN annotation for "<<vo.to_string()<<endl;
+
+}
+
diff --git a/libMEDSannotation/src/Makefile b/libMEDSannotation/src/Makefile
index cb8d4eb0f935f5316aad68f751e3b1c9f860d69d..ef9151510c66861995edad75d06c7c9795c4927f 100644
--- a/libMEDSannotation/src/Makefile
+++ b/libMEDSannotation/src/Makefile
@@ -1,7 +1,7 @@
 
 LIB=../lib/libMEDSannotation.a
 
-OBJS=VirtualOffset.o MEDS_Register.o MEDS_AnnotationParser.o MEDS_InstructionCheckAnnotation.o MEDS_SafeFuncAnnotation.o MEDS_ProblemFuncAnnotation.o
+OBJS=VirtualOffset.o MEDS_Register.o MEDS_AnnotationParser.o MEDS_InstructionCheckAnnotation.o MEDS_SafeFuncAnnotation.o MEDS_ProblemFuncAnnotation.o MEDS_FRSafeAnnotation.o FuncExitAnnotation.o
 
 all: $(OBJS)
 
diff --git a/tools/ret_shadow_stack/rss_driver.cpp b/tools/ret_shadow_stack/rss_driver.cpp
index 1401c37a3cba5b45086b7620a60d0f2e732178ff..cbc6442826727a6329a4b1a5213b0bdab0378514 100644
--- a/tools/ret_shadow_stack/rss_driver.cpp
+++ b/tools/ret_shadow_stack/rss_driver.cpp
@@ -72,6 +72,7 @@ int main(int argc, char **argv)
                         cerr << "annotation file: " << annotationFilename << endl;
 			annotationParser.parseFile(annotationFilename+".annot");
 			annotationParser.parseFile(annotationFilename+".infoannot");
+			annotationParser.parseFile(annotationFilename+".STARScallreturn");
 
 
 			RSS_Instrument rssi(firp, &annotationParser);
diff --git a/tools/ret_shadow_stack/rss_instrument.cpp b/tools/ret_shadow_stack/rss_instrument.cpp
index cb8b9b6e0d1a624b73e7faa3f43f6cbcae36e937..7596db788df58959ccb6c723d7e3ce4b22be1507 100644
--- a/tools/ret_shadow_stack/rss_instrument.cpp
+++ b/tools/ret_shadow_stack/rss_instrument.cpp
@@ -1,6 +1,7 @@
 
 #include "rss_instrument.hpp"
 #include "MEDS_SafeFuncAnnotation.hpp"
+#include "FuncExitAnnotation.hpp"
 #include "MEDS_ProblemFuncAnnotation.hpp"
 #include "Rewrite_Utility.hpp"
 #include <stdlib.h>
@@ -279,7 +280,24 @@ static 	bool add_rss_pop(FileIR_t* firp, Instruction_t* insn)
 	tmp=insertAssemblyAfter(firp,tmp,"mov rcx, [fs:0x12345678] "); create_tls_reloc(firp,tmp);
 	tmp=insertAssemblyAfter(firp,tmp,"lea rcx, [rcx-8]");
 	tmp=insertAssemblyAfter(firp,tmp,"mov [fs:0x12345678], rcx "); create_tls_reloc(firp,tmp);
+
+	/* if tss_print_stack is on, we want to zero the old location just for easy printing. */
+	/* doing so requires an extra register */
+	if(getenv("tss_print_stack")!=NULL)
+	{
+		tmp=insertAssemblyAfter(firp,tmp,"push rax");
+		tmp=insertAssemblyAfter(firp,tmp,"mov rax, rcx");
+	}
+
+	// load the old value 
 	tmp=insertAssemblyAfter(firp,tmp,"mov rcx, [rcx]");
+
+	/* if tss_print_stack is on, we want to zero the old location just for easy printing. */
+	if(getenv("tss_print_stack")!=NULL)
+	{
+		tmp=insertAssemblyAfter(firp,tmp,"mov dword [rax], 0");
+		tmp=insertAssemblyAfter(firp,tmp,"pop rax");
+	}
 	tmp=insertAssemblyAfter(firp,tmp,"sub rcx, [rsp+16]");
 	jmp_insn=tmp=insertDataBitsAfter(firp,tmp,getJecxzDataBits()); // jecxz L1
 	tmp=insertAssemblyAfter(firp,tmp,"hlt");
@@ -298,16 +316,46 @@ static 	bool add_rss_pop(FileIR_t* firp, Instruction_t* insn)
 	return true;
 }
 
-static bool is_exit_instruction(Instruction_t *insn)
+static bool is_exit_instruction(Instruction_t *insn, MEDS_AnnotationParser *meds_ap)
 {
 	DISASM d;
 	insn->Disassemble(d);
 	if(strstr(d.CompleteInstr,"ret")!=0)
 		return true;
+
+        assert(meds_ap);
+        std::pair<MEDS_Annotations_t::iterator,MEDS_Annotations_t::iterator> ret;
+
+	virtual_offset_t irdb_vo = insn->GetAddress()->GetVirtualOffset();
+	VirtualOffset vo(irdb_vo);
+
+        /* find it in the annotations */
+        ret = meds_ap->getAnnotations().equal_range(vo);
+        MEDS_FuncExitAnnotation annotation;
+        MEDS_FuncExitAnnotation* p_annotation;
+
+        /* for each annotation for this instruction */
+        for (MEDS_Annotations_t::iterator it = ret.first; it != ret.second; ++it)
+        {
+		/* is this annotation a funcSafe annotation? */
+		p_annotation=dynamic_cast<MEDS_FuncExitAnnotation*>(it->second);
+		if(p_annotation==NULL)
+			continue;
+
+		annotation = *p_annotation;
+
+		/* bad annotation? */
+		if(!annotation.isValid())
+			continue;
+		
+		return true;
+        }
+
+        /* couldn't find this insn as a function exit. */
 	return false;	
 }
 
-static bool add_rss_instrumentation(FileIR_t* firp, Function_t* func)
+static bool add_rss_instrumentation(FileIR_t* firp, Function_t* func, MEDS_AnnotationParser *meds_ap)
 {
 	bool success=true;
 	if(func->GetEntryPoint()==NULL)
@@ -316,8 +364,6 @@ static bool add_rss_instrumentation(FileIR_t* firp, Function_t* func)
 	if(getenv("RSS_VERBOSE")!=NULL)
 		cout<<"Transforming function "<<func->GetName()<<endl;
 
-	success&=add_rss_push(firp, func->GetEntryPoint());
-
 
 	for(
 		set<Instruction_t*>::iterator it=func->GetInstructions().begin();
@@ -326,10 +372,13 @@ static bool add_rss_instrumentation(FileIR_t* firp, Function_t* func)
 	   )
 	{
 		Instruction_t* insn=*it;
-		if(is_exit_instruction(insn))
+		if(is_exit_instruction(insn, meds_ap))
 			success&=add_rss_pop(firp, insn);
 	}
 
+	/* need to do this second, as the function entry may actually change due to popping that may happen */
+	success&=add_rss_push(firp, func->GetEntryPoint());
+
 	return success;
 }
 
@@ -446,7 +495,7 @@ bool RSS_Instrument::execute()
 			if(func->GetEntryPoint())
 				cout<<"( "<<std::hex<<func->GetEntryPoint()->GetAddress()->GetVirtualOffset()<<")";
 			cout<<endl;
-			success|=add_rss_instrumentation(firp,func);
+			success|=add_rss_instrumentation(firp,func, meds_ap);
 		}
 		else
 		{
diff --git a/tools/safefr/Makefile b/tools/safefr/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..8b08b2f9bc3049391c662a1dc93cd06f91da3d48
--- /dev/null
+++ b/tools/safefr/Makefile
@@ -0,0 +1,23 @@
+
+
+INCLUDES= -I $(SECURITY_TRANSFORMS_HOME)/include -I$(SECURITY_TRANSFORMS_HOME)/beaengine/include -I $(SECURITY_TRANSFORMS_HOME)/libIRDB/include/ -I$(SECURITY_TRANSFORMS_HOME)/libMEDSannotation/include/ 
+LIBS= -L$(SECURITY_TRANSFORMS_HOME)/lib -lIRDB-core -lIRDB-cfg -lpqxx -L $(SECURITY_TRANSFORMS_HOME)/beaengine/lib/Linux.gnu.Debug -lBeaEngine_s_d -lMEDSannotation
+
+OPT=-g
+.SUFFIXES: .exe .cpp 
+
+PROGS=fill_in_safefr.exe 
+
+all: $(PROGS)
+
+$(PROGS): ../../lib/*
+
+
+.o.exe:  $< $(SECURITY_TRANSFORMS_HOME)/lib/*.a
+	g++ $< $(INCLUDES) $(LIBS) $(OPT)  -o $@
+
+.cpp.o:  $< 
+	g++ $< $(INCLUDES) $(LIBS) $(OPT) -o $@ -c
+
+clean:
+	rm -f $(PROGS) *.o
diff --git a/tools/safefr/fill_in_safefr.cpp b/tools/safefr/fill_in_safefr.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6f705260bfc94ba1339fee39c38f399e1c2bc83c
--- /dev/null
+++ b/tools/safefr/fill_in_safefr.cpp
@@ -0,0 +1,142 @@
+
+
+#include <libIRDB-core.hpp>
+#include <iostream>
+#include <fstream>
+#include <stdlib.h>
+#include <cctype>
+#include <assert.h>
+
+#include "targ-config.h"
+
+#include "MEDS_AnnotationParser.hpp"
+#include "MEDS_FRSafeAnnotation.hpp"
+
+using namespace libIRDB;
+using namespace std;
+using namespace MEDS_Annotation;
+
+
+#define BINARY_NAME "a.ncexe"
+#define SHARED_OBJECTS_DIR "shared_objects"
+
+static void add_annotations(FileIR_t* firp)
+{
+	char *fileBasename = basename((char*)firp->GetFile()->GetURL().c_str());
+
+	cout<<"Adding FR annotations to "<<firp->GetFile()->GetURL()<<endl;
+
+
+	MEDS_AnnotationParser annotationParser;
+	string annotationFilename;
+	// need to map filename to integer annotation file produced by STARS
+	// this should be retrieved from the IRDB but for now, we use files to store annotations
+	// convention from within the peasoup subdirectory is:
+	//      a.ncexe.infoannot
+	//      shared_objects/<shared-lib-filename>.infoannot
+	if (strcmp(fileBasename, BINARY_NAME) == 0)
+		annotationFilename = string(BINARY_NAME);
+	else   
+		annotationFilename = string(SHARED_OBJECTS_DIR) + "/" + fileBasename ;
+	
+	cerr << "annotation file: " << annotationFilename << endl;
+	annotationParser.parseFile(annotationFilename+".STARScallreturn");
+
+	// now, look through each instruction and match the insn to the annotation.
+
+       	cout<< "Annot size is "<<std::dec<< annotationParser.getAnnotations().size() << endl;
+
+	for(set<Instruction_t*>::iterator it=firp->GetInstructions().begin();
+		it!=firp->GetInstructions().end();
+		++it
+	   )
+	{
+		Instruction_t* insn=*it;
+		assert(insn);
+
+
+		/* find annotations for this insn */
+        	std::pair<MEDS_Annotations_t::iterator,MEDS_Annotations_t::iterator> ret;
+		VirtualOffset vo(insn->GetAddress()->GetVirtualOffset());
+
+		cout<<"Checking annotations for "<<std::hex<<vo.to_string()<<endl;
+
+        	/* find it in the annotations */
+        	ret = annotationParser.getAnnotations().equal_range(vo);
+        	MEDS_FRSafeAnnotation* p_annotation;
+	
+        	/* for each annotation for this instruction */
+        	for (MEDS_Annotations_t::iterator it2 = ret.first; it2 != ret.second; ++it2)
+        	{
+                        p_annotation=dynamic_cast<MEDS_FRSafeAnnotation*>(it2->second);
+                        if(p_annotation==NULL)
+                                continue;
+
+			cout<<"Found safe FR annotation for "<<std::hex<<insn->GetAddress()->GetVirtualOffset()<<endl;
+        		Relocation_t* reloc=new Relocation_t;
+                	reloc->SetOffset(0);
+                	reloc->SetType("safefr");
+        		insn->GetRelocations().insert(reloc);
+        		firp->GetRelocations().insert(reloc);
+		}
+	}
+}
+
+
+main(int argc, char* argv[])
+{
+
+	if(argc!=2)
+	{
+		cerr<<"Usage: ilr <id>"<<endl;
+		exit(-1);
+	}
+
+	VariantID_t *pidp=NULL;
+	FileIR_t *firp=NULL;
+
+	/* setup the interface to the sql server */
+	pqxxDB_t pqxx_interface;
+	BaseObj_t::SetInterface(&pqxx_interface);
+
+	cout<<"Reading variant "<<string(argv[1])<<" from database." << endl;
+	try 
+	{
+
+		pidp=new VariantID_t(atoi(argv[1]));
+		assert(pidp->IsRegistered()==true);
+
+
+                for(set<File_t*>::iterator it=pidp->GetFiles().begin();
+                        it!=pidp->GetFiles().end();
+                        ++it
+                    )
+                {
+                        File_t* this_file=*it;
+                        assert(this_file);
+
+			// read the db  
+			firp=new FileIR_t(*pidp,this_file);
+		
+			add_annotations(firp);	
+		
+			firp->WriteToDB();
+
+			delete firp;
+		}
+
+
+		pqxx_interface.Commit();
+
+	}
+	catch (DatabaseError_t pnide)
+	{
+		cout<<"Unexpected database error: "<<pnide<<endl;
+		exit(-1);
+        }
+
+	cout<<"Done!"<<endl;
+
+	delete pidp;
+}
+