From 2607a6c7a00f9e35944d54de4dd44c1d62463473 Mon Sep 17 00:00:00 2001
From: Matthew McGill <mm8bx@mega-techx41.maas>
Date: Mon, 16 Jul 2018 20:13:18 +0000
Subject: [PATCH] Assign new address for IBTA and only if currently unpinned

Former-commit-id: 1faee274ed1171449db889a4a2e996949dce9e31
---
 libIRDB/test/fill_in_indtargs.cpp | 42 ++++++++++++++++++++++---------
 libIRDB/test/fix_calls.cpp        |  9 +++++--
 2 files changed, 37 insertions(+), 14 deletions(-)

diff --git a/libIRDB/test/fill_in_indtargs.cpp b/libIRDB/test/fill_in_indtargs.cpp
index 54545f177..241c8ff0b 100644
--- a/libIRDB/test/fill_in_indtargs.cpp
+++ b/libIRDB/test/fill_in_indtargs.cpp
@@ -2344,10 +2344,16 @@ void unpin_elf_tables(FileIR_t *firp, int64_t do_unpin_opt)
 
 						if(getenv("UNPIN_VERBOSE")!=0)
 							cout<<"Unpinning "+scoop->GetName()+" entry at offset "<<dec<<i<<endl;
-						// mark as unpinned
-						if(insn->GetIndirectBranchTargetAddress()!=NULL)
+						// mark as unpinned (if it wasn't already pinned by something else)
+						if(insn->GetIndirectBranchTargetAddress()==NULL)
 						{
-							insn->GetIndirectBranchTargetAddress()->SetVirtualOffset(0);
+							auto newaddr = new AddressID_t;
+							assert(newaddr);
+							newaddr->SetFileID(insn->GetAddress()->GetFileID());
+							newaddr->SetVirtualOffset(0);	// unpinne
+	
+							firp->GetAddresses().insert(newaddr);
+							insn->SetIndirectBranchTargetAddress(newaddr);
 						}
 					}
 				}
@@ -2457,11 +2463,17 @@ void unpin_elf_tables(FileIR_t *firp, int64_t do_unpin_opt)
 						firp->GetRelocations().insert(nr);
 						scoop->GetRelocations().insert(nr);
 
-						// mark as unpinned
-                                                if(insn->GetIndirectBranchTargetAddress()!=NULL)
+						// mark as unpinned (if it wasn't already pinned by something else)
+                                                if(insn->GetIndirectBranchTargetAddress()==NULL)
                                                 {
-                                                        insn->GetIndirectBranchTargetAddress()->SetVirtualOffset(0);
-                                                }
+                                                        auto newaddr = new AddressID_t;
+                                                        assert(newaddr);
+                                                        newaddr->SetFileID(insn->GetAddress()->GetFileID());
+                                                        newaddr->SetVirtualOffset(0);   // unpinne
+
+                                                        firp->GetAddresses().insert(newaddr);
+                                                        insn->SetIndirectBranchTargetAddress(newaddr);
+                                                }	
 					}
 					else
 					{
@@ -2615,11 +2627,17 @@ void unpin_type3_switchtable(FileIR_t* firp,Instruction_t* insn,DataScoop_t* sco
 					targets[table_entry]=newprov;
 					switch_targs.insert(ibt);
 
-					// mark as unpinned
-                                        if(ibt->GetIndirectBranchTargetAddress()!=NULL)
-                                        {
-                                                ibt->GetIndirectBranchTargetAddress()->SetVirtualOffset(0);
-                                        }
+					 // mark as unpinned (if it wasn't already pinned by something else)
+                                         if(ibt->GetIndirectBranchTargetAddress()==NULL)
+                                         {
+                                                 auto newaddr = new AddressID_t;
+                                                 assert(newaddr);
+                                                 newaddr->SetFileID(ibt->GetAddress()->GetFileID());
+                                                 newaddr->SetVirtualOffset(0);   // unpinne
+
+                                                 firp->GetAddresses().insert(newaddr);
+                                                 ibt->SetIndirectBranchTargetAddress(newaddr);
+                                         }	
 				}
 			}
 		}
diff --git a/libIRDB/test/fix_calls.cpp b/libIRDB/test/fix_calls.cpp
index ff35805b0..0a5946779 100644
--- a/libIRDB/test/fix_calls.cpp
+++ b/libIRDB/test/fix_calls.cpp
@@ -638,8 +638,13 @@ void fix_call(Instruction_t* insn, FileIR_t *firp, bool can_unpin)
 				    <<hex<<insn->GetBaseID()<<":"<<insn->getDisassembly()<<endl;
 			}
 			// set newindirtarg as unpinned IBT
-		 	newindirtarg->GetIndirectBranchTargetAddress()->SetVirtualOffset(0);	
-			reloc->SetWRT(newindirtarg);
+		        auto newaddr = new AddressID_t;
+                        assert(newaddr); 
+                        newaddr->SetFileID(newindirtarg->GetAddress()->GetFileID());
+                        newaddr->SetVirtualOffset(0);   // unpinned
+                        firp->GetAddresses().insert(newaddr);
+                        newindirtarg->SetIndirectBranchTargetAddress(newaddr);
+      			reloc->SetWRT(newindirtarg);
 		}
 	}
 
-- 
GitLab