mkbootimg: Add Loki support

* I want my target-files built images to be Loki'd if the device
  needs Loki.
* With this, devices that rely on Loki can ship Lineage Recovery
  officially.
* Import loki_tool from: https://github.com/Stricted/android_external_loki.

Change-Id: I45ef363e05566268c8f24f7e8939a2d785478fbe
diff --git a/loki_tool/loki_find.c b/loki_tool/loki_find.c
new file mode 100644
index 0000000..151a309
--- /dev/null
+++ b/loki_tool/loki_find.c
@@ -0,0 +1,91 @@
+#include <stdio.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <string.h>
+
+#include "loki.h"
+
+#define BOOT_PATTERN1 "\x4f\xf4\x70\x40\xb3\x49\x2d\xe9"	/* Samsung GS4 */
+#define BOOT_PATTERN2 "\x2d\xe9\xf0\x4f\xad\xf5\x82\x5d"	/* LG */
+#define BOOT_PATTERN3 "\x2d\xe9\xf0\x4f\x4f\xf4\x70\x40"	/* LG */
+#define BOOT_PATTERN4 "\x2d\xe9\xf0\x4f\xad\xf5\x80\x5d"	/* LG G2 */
+
+int loki_find(const char* aboot_image)
+{
+	int aboot_fd;
+	struct stat st;
+	void *aboot, *ptr;
+	unsigned long aboot_base, check_sigs, boot_mmc;
+
+	aboot_fd = open(aboot_image, O_RDONLY);
+	if (aboot_fd < 0) {
+		printf("[-] Failed to open %s for reading.\n", aboot_image);
+		return 1;
+	}
+
+	if (fstat(aboot_fd, &st)) {
+		printf("[-] fstat() failed.\n");
+		return 1;
+	}
+
+	aboot = mmap(0, (st.st_size + 0xfff) & ~0xfff, PROT_READ, MAP_PRIVATE, aboot_fd, 0);
+	if (aboot == MAP_FAILED) {
+		printf("[-] Failed to mmap aboot.\n");
+		return 1;
+	}
+
+	check_sigs = 0;
+	aboot_base = *(unsigned int *)(aboot + 12) - 0x28;
+
+	/* Do a pass to find signature checking function */
+	for (ptr = aboot; ptr < aboot + st.st_size - 0x1000; ptr++) {
+		if (!memcmp(ptr, PATTERN1, 8) ||
+			!memcmp(ptr, PATTERN2, 8) ||
+			!memcmp(ptr, PATTERN3, 8) ||
+			!memcmp(ptr, PATTERN4, 8) ||
+			!memcmp(ptr, PATTERN5, 8)) {
+
+			check_sigs = (unsigned long)ptr - (unsigned long)aboot + aboot_base;
+			break;
+		}
+
+		if (!memcmp(ptr, PATTERN6, 8)) {
+
+			check_sigs = (unsigned long)ptr - (unsigned long)aboot + aboot_base;
+
+			/* Don't break, because the other LG patterns override this one */
+			continue;
+		}
+	}
+
+	if (!check_sigs) {
+		printf("[-] Could not find signature checking function.\n");
+		return 1;
+	}
+
+	printf("[+] Signature check function: %.08lx\n", check_sigs);
+
+	boot_mmc = 0;
+
+	/* Do a second pass for the boot_linux_from_emmc function */
+	for (ptr = aboot; ptr < aboot + st.st_size - 0x1000; ptr++) {
+		if (!memcmp(ptr, BOOT_PATTERN1, 8) ||
+			!memcmp(ptr, BOOT_PATTERN2, 8) ||
+			!memcmp(ptr, BOOT_PATTERN3, 8) ||
+			!memcmp(ptr, BOOT_PATTERN4, 8)) {
+
+			boot_mmc = (unsigned long)ptr - (unsigned long)aboot + aboot_base;
+			break;
+		}
+    }
+
+	if (!boot_mmc) {
+		printf("[-] Could not find boot_linux_from_mmc.\n");
+		return 1;
+	}
+
+	printf("[+] boot_linux_from_mmc: %.08lx\n", boot_mmc);
+
+	return 0;
+}