From eb805879dfc297045200c95789095f3bfe48773c Mon Sep 17 00:00:00 2001
From: Adubbz <Adubbz@users.noreply.github.com>
Date: Sat, 30 Mar 2019 16:49:59 +1100
Subject: [PATCH] Automatically set the entry point for kip1s

---
 .../common/SwitchProgramBuilder.java          | 35 ++++++++++++++++++-
 .../switchloader/kip1/KIP1ProgramBuilder.java | 10 ++++++
 2 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/src/main/java/adubbz/switchloader/common/SwitchProgramBuilder.java b/src/main/java/adubbz/switchloader/common/SwitchProgramBuilder.java
index 1c7cedf..049a5b3 100644
--- a/src/main/java/adubbz/switchloader/common/SwitchProgramBuilder.java
+++ b/src/main/java/adubbz/switchloader/common/SwitchProgramBuilder.java
@@ -81,7 +81,7 @@ public abstract class SwitchProgramBuilder
     protected Program program;
     protected MemoryBlockUtil mbu;
     
-    long baseAddress;
+    protected long baseAddress;
     protected AddressSpace aSpace;
     protected MemoryBlockHelper memBlockHelper;
 
@@ -515,9 +515,42 @@ private String[] getDynamicLibraryNames()
         return dynamicLibraryNames;
     }
     
+    protected Address createEntryFunction(String name, long entryAddr, TaskMonitor monitor) 
+    {
+        Address entryAddress = this.aSpace.getAddress(entryAddr);
+
+        // TODO: Entry may refer to a pointer - make sure we have execute permission
+        MemoryBlock block = this.program.getMemory().getBlock(entryAddress);
+        
+        if (block == null || !block.isExecute()) 
+        {
+            return entryAddress;
+        }
+
+        Function function = program.getFunctionManager().getFunctionAt(entryAddress);
+        
+        if (function != null) 
+        {
+            program.getSymbolTable().addExternalEntryPoint(entryAddress);
+            return entryAddress; // symbol-based function already created
+        }
+
+        try 
+        {
+            createOneByteFunction(name, entryAddress, true);
+        }
+        catch (Exception e) 
+        {
+            Msg.error(this, "Could not create symbol at entry point: " + e);
+        }
+
+        return entryAddress;
+    }
+    
     private Set<Long> processRelocations(Program program, BinaryReader provider, List<Relocation> relocs, ElfSymbolTable symtab, long rel, long relsz) throws IOException 
     {
         Set<Long> locations = new HashSet<Long>();
+        
         for (long i = 0; i < relsz / 0x18; i++) 
         {
             long offset = provider.readLong(rel + i * 0x18);
diff --git a/src/main/java/adubbz/switchloader/kip1/KIP1ProgramBuilder.java b/src/main/java/adubbz/switchloader/kip1/KIP1ProgramBuilder.java
index 1d14d65..f4e5e31 100644
--- a/src/main/java/adubbz/switchloader/kip1/KIP1ProgramBuilder.java
+++ b/src/main/java/adubbz/switchloader/kip1/KIP1ProgramBuilder.java
@@ -15,6 +15,7 @@
 import ghidra.app.util.bin.ByteArrayProvider;
 import ghidra.app.util.bin.ByteProvider;
 import ghidra.app.util.importer.MemoryConflictHandler;
+import ghidra.program.model.address.Address;
 import ghidra.program.model.address.AddressOutOfBoundsException;
 import ghidra.program.model.address.AddressOverflowException;
 import ghidra.program.model.address.AddressSpace;
@@ -38,6 +39,15 @@ public static void loadKIP1(KIP1Header header, ByteProvider provider, Program pr
         builder.load(monitor);
     }
     
+    @Override
+    protected void load(TaskMonitor monitor)
+    {
+        super.load(monitor);
+        
+        // KIP1s always start with a branch instruction at the start of their text
+        this.createEntryFunction("entry", this.baseAddress, monitor);
+    }
+    
     @Override
     protected void loadDefaultSegments(TaskMonitor monitor) throws IOException, AddressOverflowException, AddressOutOfBoundsException
     {