From b75732bb9eff8671d7fd36c28ce5fda828eda08c Mon Sep 17 00:00:00 2001
From: jdh8d <jdh8d@git.zephyr-software.com>
Date: Tue, 7 Oct 2014 20:48:41 +0000
Subject: [PATCH] callbacks almost working

---
 callbacks/lib/Makefile.in |  2 +-
 include/zipr.h            |  2 ++
 src/zipr.cpp              | 25 ++++++++++++++++++++-----
 src/zipr_options.cpp      |  2 ++
 4 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/callbacks/lib/Makefile.in b/callbacks/lib/Makefile.in
index 3742bac76..e2d903050 100644
--- a/callbacks/lib/Makefile.in
+++ b/callbacks/lib/Makefile.in
@@ -26,7 +26,7 @@ all: $(OBJS) $(relocatable_obj)
 
 $(relocatable_obj): $(OBJS) $(LIB)
 	$(LD) -Wl,--whole-archive $(LDFLAGS) $(OBJS) $(LIB) -o $@
-	$(LD) -Bstatic -static -Wl,--whole-archive callbacks.exe.o -nostdlib -o callbacks.exe -shared
+	$(LD) -Bstatic -static -Wl,--whole-archive callbacks.exe.o -nostdlib -o callbacks.exe 
 
 clean:
 	rm -f *.o *.a callbacks.exe.o callbacks.exe
diff --git a/include/zipr.h b/include/zipr.h
index 52f290c28..108ec2ed1 100644
--- a/include/zipr.h
+++ b/include/zipr.h
@@ -105,6 +105,8 @@ class Zipr_t
 		void RewritePCRelOffset(RangeAddress_t from_addr,RangeAddress_t to_addr, int insn_length, int offset_pos);
 		void ApplyPatch(RangeAddress_t from_addr, RangeAddress_t to_addr);
 		void PatchCall(RangeAddress_t at_addr, RangeAddress_t to_addr);
+		void CallToNop(RangeAddress_t at_addr);
+
 
 
 		// outputing new .exe
diff --git a/src/zipr.cpp b/src/zipr.cpp
index 76f606761..79b1ef201 100644
--- a/src/zipr.cpp
+++ b/src/zipr.cpp
@@ -96,6 +96,10 @@ void Zipr_t::CreateBinaryFile(const std::string &name)
 	// now that pinning is done, start emitting unpinnned instructions, and patching where needed.
 	PlopTheUnpinnedInstructions();
 
+	// now that all instructions are put down, we can figure out where the callbacks for this file wil go.
+	// go ahead and update any callback sites with the new locations 
+	UpdateCallbacks();
+
 	// write binary file to disk 
 	OutputBinaryFile(name);
 
@@ -843,6 +847,12 @@ void Zipr_t::PlopJump(RangeAddress_t addr)
 }
 
 
+void Zipr_t::CallToNop(RangeAddress_t at_addr)
+{
+	char bytes[]={0x90,0x90,0x90,0x90,0x90}; // nop;nop;nop;nop;nop
+	PlopBytes(at_addr,bytes,sizeof(bytes));
+}
+
 void Zipr_t::PatchCall(RangeAddress_t at_addr, RangeAddress_t to_addr)
 {
 	uintptr_t off=to_addr-at_addr-5;
@@ -1554,8 +1564,7 @@ static RangeAddress_t getSymbolAddress(const string &symbolFilename, const strin
         if(addressString.empty())
         {
                 cerr<<"Cannot find symbol "<< symbol << " in " << symbolFilename << "."<<endl;
-                cerr<<"Exiting zipr early."<<endl;
-                assert(!addressString.empty());
+		addressString="0x0";
         }
 
         pclose(fp);
@@ -1571,8 +1580,11 @@ RangeAddress_t Zipr_t::FindCallbackAddress(RangeAddress_t end_of_new_space, Rang
 
 		RangeAddress_t addr=getSymbolAddress(m_opts.GetCallbackFileName(),callback);
 
-		/* adjust by start of new location, - beginning of old location */
-		addr=addr+end_of_new_space-start_addr;
+		if(addr!=0)
+		{
+			/* adjust by start of new location, - beginning of old location */
+			addr=addr+end_of_new_space-start_addr;
+		}
 		callback_addrs[callback]=addr;
 	}
 	return callback_addrs[callback];
@@ -1596,6 +1608,9 @@ void Zipr_t::UpdateCallbacks()
 		Instruction_t *insn=it->first;
 		RangeAddress_t at=it->second;
 		RangeAddress_t to=FindCallbackAddress(end_of_new_space,start_addr,insn->GetCallback());
-		PatchCall(at,to);
+		if(to)
+			PatchCall(at,to);
+		else
+			CallToNop(at);
 	}
 }
diff --git a/src/zipr_options.cpp b/src/zipr_options.cpp
index 972d9650d..35f494957 100644
--- a/src/zipr_options.cpp
+++ b/src/zipr_options.cpp
@@ -16,6 +16,8 @@ void Options_t::print_usage(int p_argc, char *p_argv[])
 		"Enable an optimization. Repeatable. Optional. \n");
 	printf("\t-j path\t\t--objcopy path: "
 		"Set the path of objcopy to use. Optional. \n");
+	printf("\t-c callback.exe\t\t--path to callbacks file: "
+		"Set the path of the file which contains any required callacks.  Missing callbacks elided. \n");
 }
 
 Options_t* Options_t::parse_args(int p_argc, char* p_argv[])
-- 
GitLab