cbfstool: Handle elf with different virtual and physical address

Adds support in cbfstool to adjust the entry field based on the
virtual and physical address in program header.

BUG=chrome-os-partner:40713
BRANCH=None
TEST=Verified correct entry point address. Trusty loads and boots correctly.

Change-Id: I215b0bea689626deec65e15fb3280e369d816406
Signed-off-by: Patrick Georgi <pgeorgi@chromium.org>
Original-Commit-Id: 32a740f0b628c124d3251cc416e2fc133bb15c57
Original-Change-Id: Ia999b5c55887c86ef1e43794ceaef2d867957f4d
Original-Signed-off-by: Furquan Shaikh <furquan@google.com>
Original-Reviewed-on: https://chromium-review.googlesource.com/274087
Original-Trybot-Ready: Furquan Shaikh <furquan@chromium.org>
Original-Tested-by: Furquan Shaikh <furquan@chromium.org>
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Original-Commit-Queue: Furquan Shaikh <furquan@chromium.org>
Reviewed-on: http://review.coreboot.org/10690
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
diff --git a/util/cbfstool/cbfs-mkstage.c b/util/cbfstool/cbfs-mkstage.c
index f94d0da..3e62525d 100644
--- a/util/cbfstool/cbfs-mkstage.c
+++ b/util/cbfstool/cbfs-mkstage.c
@@ -102,6 +102,7 @@
 	Elf64_Phdr *phdr;
 	Elf64_Ehdr *ehdr;
 	Elf64_Shdr *shdr_ignored;
+	Elf64_Addr virt_to_phys;
 	char *buffer;
 	struct buffer outheader;
 	int ret = -1;
@@ -143,6 +144,7 @@
 	data_start = ~0;
 	data_end = 0;
 	mem_end = 0;
+	virt_to_phys = 0;
 
 	for (i = 0; i < headers; i++) {
 		unsigned int start, mend, rend;
@@ -169,6 +171,9 @@
 
 		if (mend > mem_end)
 			mem_end = mend;
+
+		if (virt_to_phys == 0)
+			virt_to_phys = phdr[i].p_paddr - phdr[i].p_vaddr;
 	}
 
 	if (data_start < *location) {
@@ -262,7 +267,10 @@
 	 * Maybe we should just change the spec.
 	 */
 	xdr_le.put32(&outheader, algo);
-	xdr_le.put64(&outheader, ehdr->e_entry);
+	/* Coreboot expects entry point to be physical address. Thus, adjust the
+	 * entry point accordingly.
+	 */
+	xdr_le.put64(&outheader, ehdr->e_entry + virt_to_phys);
 	xdr_le.put64(&outheader, data_start);
 	xdr_le.put32(&outheader, outlen);
 	xdr_le.put32(&outheader, mem_end - data_start);