Merge branch 'next' of https://source.denx.de/u-boot/custodians/u-boot-coldfire into next

- Relocation support
diff --git a/arch/Kconfig b/arch/Kconfig
index 90345cb..19f2891 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -68,7 +68,6 @@
 	bool "M68000 architecture"
 	select HAVE_PRIVATE_LIBGCC
 	select USE_PRIVATE_LIBGCC
-	select NEEDS_MANUAL_RELOC
 	select SYS_BOOT_GET_CMDLINE
 	select SYS_BOOT_GET_KBD
 	select SYS_CACHE_SHIFT_4
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 1911563..587edd5 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -4,8 +4,8 @@
 config SYS_ARCH
 	default "m68k"
 
-config NEEDS_MANUAL_RELOC
-	def_bool y
+config STATIC_RELA
+	default y
 
 # processor family
 config MCF520x
diff --git a/arch/m68k/config.mk b/arch/m68k/config.mk
index 3ccbe49..643b7d1 100644
--- a/arch/m68k/config.mk
+++ b/arch/m68k/config.mk
@@ -3,8 +3,8 @@
 # (C) Copyright 2000-2002
 # Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 
-PLATFORM_CPPFLAGS += -D__M68K__
-KBUILD_LDFLAGS  += -n
+PLATFORM_CPPFLAGS += -D__M68K__ -fPIC
+KBUILD_LDFLAGS    += -n -pie
 PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
 PLATFORM_RELFLAGS += -ffixed-d7 -msep-data
-LDFLAGS_FINAL                  += --gc-sections
+LDFLAGS_FINAL     += --gc-sections -pie
diff --git a/arch/m68k/cpu/mcf523x/start.S b/arch/m68k/cpu/mcf523x/start.S
index d2a21c3..c609e82 100644
--- a/arch/m68k/cpu/mcf523x/start.S
+++ b/arch/m68k/cpu/mcf523x/start.S
@@ -177,6 +177,39 @@
 	cmp.l	%a1,%a2
 	bgt.s	1b
 
+#define R_68K_32	1
+#define R_68K_RELATIVE	22
+
+	move.l #(__rel_dyn_start), %a1
+	move.l #(__rel_dyn_end), %a2
+
+fixloop:
+	move.l	(%a1)+, %d1	/* Elf32_Rela r_offset */
+	move.l	(%a1)+, %d2	/* Elf32_Rela r_info */
+	move.l	(%a1)+, %d3	/* Elf32_Rela r_addend */
+
+	andi.l	#0xff, %d2
+	cmp.l	#R_68K_32, %d2
+	beq.s	fixup
+	cmp.l	#R_68K_RELATIVE, %d2
+	beq.s	fixup
+
+	bra	fixnext
+
+fixup:
+	/* relative fix: store addend plus offset at dest location */
+	move.l	%a0, %a3
+	add.l	%d1, %a3
+	sub.l   #CONFIG_SYS_MONITOR_BASE, %a3
+	move.l	(%a3), %d4
+	add.l	%a0, %d4
+	sub.l   #CONFIG_SYS_MONITOR_BASE, %d4
+	move.l	%d4, (%a3)
+
+fixnext:
+	cmp.l	%a1, %a2
+	bge.s	fixloop
+
 /*
  * We are done. Do not return, instead branch to second part of board
  * initialization, now running from RAM.
@@ -191,10 +224,8 @@
 	/*
 	 * Now clear BSS segment
 	 */
-	move.l	%a0, %a1
-	add.l	#(_sbss - CONFIG_SYS_MONITOR_BASE),%a1
-	move.l	%a0, %d1
-	add.l	#(_ebss - CONFIG_SYS_MONITOR_BASE),%d1
+	move.l	#(_sbss), %a1
+	move.l	#(_ebss), %d1
 6:
 	clr.l	(%a1)+
 	cmp.l	%a1,%d1
@@ -203,24 +234,10 @@
 	/*
 	 * fix got table in RAM
 	 */
-	move.l	%a0, %a1
-	add.l	#(__got_start - CONFIG_SYS_MONITOR_BASE),%a1
-	move.l	%a1,%a5		/* * fix got pointer register a5 */
-
-	move.l	%a0, %a2
-	add.l	#(__got_end - CONFIG_SYS_MONITOR_BASE),%a2
-
-7:
-	move.l	(%a1),%d1
-	sub.l	#_start,%d1
-	add.l	%a0,%d1
-	move.l	%d1,(%a1)+
-	cmp.l	%a2, %a1
-	bne	7b
+	move.l	#(__got_start), %a5	/* fix got pointer register a5 */
 
 	/* calculate relative jump to board_init_r in ram */
-	move.l	%a0, %a1
-	add.l	#(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1
+	move.l	#(board_init_r), %a1
 
 	/* set parameters for board_init_r */
 	move.l	%a0,-(%sp)		/* dest_addr */
diff --git a/arch/m68k/cpu/mcf52x2/start.S b/arch/m68k/cpu/mcf52x2/start.S
index 51d2e23..3a27602 100644
--- a/arch/m68k/cpu/mcf52x2/start.S
+++ b/arch/m68k/cpu/mcf52x2/start.S
@@ -255,6 +255,39 @@
 	cmp.l	%a1,%a2
 	bgt.s	1b
 
+#define R_68K_32	1
+#define R_68K_RELATIVE	22
+
+	move.l #(__rel_dyn_start), %a1
+	move.l #(__rel_dyn_end), %a2
+
+fixloop:
+	move.l	(%a1)+, %d1	/* Elf32_Rela r_offset */
+	move.l	(%a1)+, %d2	/* Elf32_Rela r_info */
+	move.l	(%a1)+, %d3	/* Elf32_Rela r_addend */
+
+	andi.l	#0xff, %d2
+	cmp.l	#R_68K_32, %d2
+	beq.s	fixup
+	cmp.l	#R_68K_RELATIVE, %d2
+	beq.s	fixup
+
+	bra	fixnext
+
+fixup:
+	/* relative fix: store addend plus offset at dest location */
+	move.l	%a0, %a3
+	add.l	%d1, %a3
+	sub.l   #CONFIG_SYS_MONITOR_BASE, %a3
+	move.l	(%a3), %d4
+	add.l	%a0, %d4
+	sub.l   #CONFIG_SYS_MONITOR_BASE, %d4
+	move.l	%d4, (%a3)
+
+fixnext:
+	cmp.l	%a1, %a2
+	bge.s	fixloop
+
 /*
  * We are done. Do not return, instead branch to second part of board
  * initialization, now running from RAM.
@@ -269,10 +302,8 @@
 	/*
 	 * Now clear BSS segment
 	 */
-	move.l	%a0, %a1
-	add.l	#(_sbss - CONFIG_SYS_MONITOR_BASE),%a1
-	move.l	%a0, %d1
-	add.l	#(_ebss - CONFIG_SYS_MONITOR_BASE),%d1
+	move.l	#(_sbss), %a1
+	move.l	#(_ebss), %d1
 6:
 	clr.l	(%a1)+
 	cmp.l	%a1,%d1
@@ -281,24 +312,10 @@
 	/*
 	 * fix got table in RAM
 	 */
-	move.l	%a0, %a1
-	add.l	#(__got_start - CONFIG_SYS_MONITOR_BASE),%a1
-	move.l	%a1,%a5			/* fix got pointer register a5 */
-
-	move.l	%a0, %a2
-	add.l	#(__got_end - CONFIG_SYS_MONITOR_BASE),%a2
-
-7:
-	move.l	(%a1),%d1
-	sub.l	#_start,%d1
-	add.l	%a0,%d1
-	move.l	%d1,(%a1)+
-	cmp.l	%a2, %a1
-	bne	7b
+	move.l	#(__got_start), %a5	/* fix got pointer register a5 */
 
 	/* calculate relative jump to board_init_r in ram */
-	move.l	%a0, %a1
-	add.l	#(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1
+	move.l	#(board_init_r), %a1
 
 	/* set parameters for board_init_r */
 	move.l	%a0,-(%sp)		/* dest_addr */
diff --git a/arch/m68k/cpu/mcf530x/start.S b/arch/m68k/cpu/mcf530x/start.S
index cef8d79..552e020 100644
--- a/arch/m68k/cpu/mcf530x/start.S
+++ b/arch/m68k/cpu/mcf530x/start.S
@@ -180,6 +180,39 @@
 	cmp.l	%a1,%a2
 	bgt.s	1b
 
+#define R_68K_32	1
+#define R_68K_RELATIVE	22
+
+	move.l #(__rel_dyn_start), %a1
+	move.l #(__rel_dyn_end), %a2
+
+fixloop:
+	move.l	(%a1)+, %d1	/* Elf32_Rela r_offset */
+	move.l	(%a1)+, %d2	/* Elf32_Rela r_info */
+	move.l	(%a1)+, %d3	/* Elf32_Rela r_addend */
+
+	andi.l	#0xff, %d2
+	cmp.l	#R_68K_32, %d2
+	beq.s	fixup
+	cmp.l	#R_68K_RELATIVE, %d2
+	beq.s	fixup
+
+	bra	fixnext
+
+fixup:
+	/* relative fix: store addend plus offset at dest location */
+	move.l	%a0, %a3
+	add.l	%d1, %a3
+	sub.l   #CONFIG_SYS_MONITOR_BASE, %a3
+	move.l	(%a3), %d4
+	add.l	%a0, %d4
+	sub.l   #CONFIG_SYS_MONITOR_BASE, %d4
+	move.l	%d4, (%a3)
+
+fixnext:
+	cmp.l	%a1, %a2
+	bge.s	fixloop
+
 /*
  * We are done. Do not return, instead branch to second part of board
  * initialization, now running from RAM.
@@ -194,10 +227,8 @@
 	/*
 	 * Now clear BSS segment
 	 */
-	move.l	%a0, %a1
-	add.l	#(_sbss - CONFIG_SYS_MONITOR_BASE), %a1
-	move.l	%a0, %d1
-	add.l	#(_ebss - CONFIG_SYS_MONITOR_BASE), %d1
+	move.l	#(_sbss), %a1
+	move.l	#(_ebss), %d1
 6:
 	clr.l	(%a1)+
 	cmp.l	%a1,%d1
@@ -206,26 +237,10 @@
 	/*
 	 * fix got table in RAM
 	 */
-	move.l	%a0, %a1
-	add.l	#(__got_start - CONFIG_SYS_MONITOR_BASE), %a1
-
-	/* fix got pointer register a5 */
-	move.l	%a1,%a5
-
-	move.l	%a0, %a2
-	add.l	#(__got_end - CONFIG_SYS_MONITOR_BASE), %a2
-
-7:
-	move.l	(%a1),%d1
-	sub.l	#_start, %d1
-	add.l	%a0,%d1
-	move.l	%d1,(%a1)+
-	cmp.l	%a2, %a1
-	bne	7b
+	move.l	#(__got_start), %a5	/* fix got pointer register a5 */
 
 	/* calculate relative jump to board_init_r in ram */
-	move.l	%a0, %a1
-	add.l	#(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1
+	move.l	#(board_init_r), %a1
 
 	/* set parameters for board_init_r */
 	move.l	%a0,-(%sp)	/* dest_addr */
diff --git a/arch/m68k/cpu/mcf532x/start.S b/arch/m68k/cpu/mcf532x/start.S
index 72a2f99..c3eae73 100644
--- a/arch/m68k/cpu/mcf532x/start.S
+++ b/arch/m68k/cpu/mcf532x/start.S
@@ -192,6 +192,39 @@
 	cmp.l	%a1,%a2
 	bgt.s	1b
 
+#define R_68K_32	1
+#define R_68K_RELATIVE	22
+
+	move.l #(__rel_dyn_start), %a1
+	move.l #(__rel_dyn_end), %a2
+
+fixloop:
+	move.l	(%a1)+, %d1	/* Elf32_Rela r_offset */
+	move.l	(%a1)+, %d2	/* Elf32_Rela r_info */
+	move.l	(%a1)+, %d3	/* Elf32_Rela r_addend */
+
+	andi.l	#0xff, %d2
+	cmp.l	#R_68K_32, %d2
+	beq.s	fixup
+	cmp.l	#R_68K_RELATIVE, %d2
+	beq.s	fixup
+
+	bra	fixnext
+
+fixup:
+	/* relative fix: store addend plus offset at dest location */
+	move.l	%a0, %a3
+	add.l	%d1, %a3
+	sub.l   #CONFIG_SYS_MONITOR_BASE, %a3
+	move.l	(%a3), %d4
+	add.l	%a0, %d4
+	sub.l   #CONFIG_SYS_MONITOR_BASE, %d4
+	move.l	%d4, (%a3)
+
+fixnext:
+	cmp.l	%a1, %a2
+	bge.s	fixloop
+
 /*
  * We are done. Do not return, instead branch to second part of board
  * initialization, now running from RAM.
@@ -206,10 +239,8 @@
 	/*
 	 * Now clear BSS segment
 	 */
-	move.l	%a0, %a1
-	add.l	#(_sbss - CONFIG_SYS_MONITOR_BASE),%a1
-	move.l	%a0, %d1
-	add.l	#(_ebss - CONFIG_SYS_MONITOR_BASE),%d1
+	move.l	#(_sbss), %a1
+	move.l	#(_ebss), %d1
 6:
 	clr.l	(%a1)+
 	cmp.l	%a1,%d1
@@ -218,24 +249,10 @@
 	/*
 	 * fix got table in RAM
 	 */
-	move.l	%a0, %a1
-	add.l	#(__got_start - CONFIG_SYS_MONITOR_BASE),%a1
-	move.l	%a1,%a5			/* fix got pointer register a5 */
-
-	move.l	%a0, %a2
-	add.l	#(__got_end - CONFIG_SYS_MONITOR_BASE),%a2
-
-7:
-	move.l	(%a1),%d1
-	sub.l	#_start,%d1
-	add.l	%a0,%d1
-	move.l	%d1,(%a1)+
-	cmp.l	%a2, %a1
-	bne	7b
+	move.l	#(__got_start), %a5	/* fix got pointer register a5 */
 
 	/* calculate relative jump to board_init_r in ram */
-	move.l	%a0, %a1
-	add.l	#(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1
+	move.l	#(board_init_r), %a1
 
 	/* set parameters for board_init_r */
 	move.l	%a0,-(%sp)		/* dest_addr */
diff --git a/arch/m68k/cpu/mcf5445x/start.S b/arch/m68k/cpu/mcf5445x/start.S
index a083c3d..5c3bfff 100644
--- a/arch/m68k/cpu/mcf5445x/start.S
+++ b/arch/m68k/cpu/mcf5445x/start.S
@@ -533,6 +533,39 @@
 	cmp.l	%a1,%a2
 	bgt.s	1b
 
+#define R_68K_32	1
+#define R_68K_RELATIVE	22
+
+	move.l #(__rel_dyn_start), %a1
+	move.l #(__rel_dyn_end), %a2
+
+fixloop:
+	move.l	(%a1)+, %d1	/* Elf32_Rela r_offset */
+	move.l	(%a1)+, %d2	/* Elf32_Rela r_info */
+	move.l	(%a1)+, %d3	/* Elf32_Rela r_addend */
+
+	andi.l	#0xff, %d2
+	cmp.l	#R_68K_32, %d2
+	beq.s	fixup
+	cmp.l	#R_68K_RELATIVE, %d2
+	beq.s	fixup
+
+	bra	fixnext
+
+fixup:
+	/* relative fix: store addend plus offset at dest location */
+	move.l	%a0, %a3
+	add.l	%d1, %a3
+	sub.l   #CONFIG_SYS_MONITOR_BASE, %a3
+	move.l	(%a3), %d4
+	add.l	%a0, %d4
+	sub.l   #CONFIG_SYS_MONITOR_BASE, %d4
+	move.l	%d4, (%a3)
+
+fixnext:
+	cmp.l	%a1, %a2
+	bge.s	fixloop
+
 /*
  * We are done. Do not return, instead branch to second part of board
  * initialization, now running from RAM.
@@ -547,10 +580,8 @@
 	/*
 	 * Now clear BSS segment
 	 */
-	move.l	%a0, %a1
-	add.l	#(_sbss - CONFIG_SYS_MONITOR_BASE),%a1
-	move.l	%a0, %d1
-	add.l	#(_ebss - CONFIG_SYS_MONITOR_BASE),%d1
+	move.l	#(_sbss), %a1
+	move.l	#(_ebss), %d1
 6:
 	clr.l	(%a1)+
 	cmp.l	%a1,%d1
@@ -559,24 +590,10 @@
 	/*
 	 * fix got table in RAM
 	 */
-	move.l	%a0, %a1
-	add.l	#(__got_start - CONFIG_SYS_MONITOR_BASE),%a1
-	move.l	%a1,%a5			/* fix got pointer register a5 */
-
-	move.l	%a0, %a2
-	add.l	#(__got_end - CONFIG_SYS_MONITOR_BASE),%a2
-
-7:
-	move.l	(%a1),%d1
-	sub.l	#_start,%d1
-	add.l	%a0,%d1
-	move.l	%d1,(%a1)+
-	cmp.l	%a2, %a1
-	bne	7b
+	move.l	#(__got_start), %a5	/* fix got pointer register a5 */
 
 	/* calculate relative jump to board_init_r in ram */
-	move.l	%a0, %a1
-	add.l	#(board_init_r - CONFIG_SYS_MONITOR_BASE), %a1
+	move.l	#(board_init_r), %a1
 
 	/* set parameters for board_init_r */
 	move.l	%a0,-(%sp)		/* dest_addr */
diff --git a/arch/m68k/cpu/u-boot.lds b/arch/m68k/cpu/u-boot.lds
index 133f791..03d427c 100644
--- a/arch/m68k/cpu/u-boot.lds
+++ b/arch/m68k/cpu/u-boot.lds
@@ -76,6 +76,20 @@
 	. = ALIGN(4);
 	__init_end = .;
 
+	. = ALIGN(4);
+	__rel_dyn_start = .;
+	.rela.dyn : {
+		*(.rela.dyn)
+	}
+	__rel_dyn_end = .;
+
+	. = ALIGN(4);
+	__dyn_sym_start = .;
+	.dynsym : {
+		*(.dynsym)
+	}
+	__dyn_sym_end = .;
+
 	_end = .;
 
 	__bss_start = .;
diff --git a/tools/relocate-rela.c b/tools/relocate-rela.c
index f230ec5..613abd2 100644
--- a/tools/relocate-rela.c
+++ b/tools/relocate-rela.c
@@ -24,6 +24,30 @@
 #define R_AARCH64_RELATIVE	1027
 #endif
 
+#ifndef EM_M68K
+#define EM_M68K			4
+#endif
+
+#ifndef R_68K_NONE
+#define R_68K_NONE		0
+#endif
+
+#ifndef R_68K_32
+#define R_68K_32		1
+#endif
+
+#ifndef R_68K_GLOB_DAT
+#define R_68K_GLOB_DAT		20
+#endif
+
+#ifndef R_68K_JMP_SLOT
+#define R_68K_JMP_SLOT		21
+#endif
+
+#ifndef R_68K_RELATIVE
+#define R_68K_RELATIVE		22
+#endif
+
 #ifndef EM_MICROBLAZE
 #define EM_MICROBLAZE		189
 #endif
@@ -46,6 +70,7 @@
 
 static int ei_class;
 static int ei_data;
+static int machine;
 
 static uint64_t rela_start, rela_end, text_base, dyn_start;
 
@@ -78,6 +103,14 @@
 	return be32_to_cpu(data);
 }
 
+static uint32_t cpu_to_elf32(uint32_t data)
+{
+	if (ei_data == ELFDATA2LSB)
+		return cpu_to_le32(data);
+
+	return cpu_to_be32(data);
+}
+
 static bool supported_rela(Elf64_Rela *rela)
 {
 	uint64_t mask = 0xffffffffULL; /* would be different on 32-bit */
@@ -103,7 +136,7 @@
 	uint64_t sh_addr, sh_offset, sh_size;
 	Elf64_Half sh_index, sh_num;
 	Elf64_Shdr *sh_table; /* Elf symbol table */
-	int ret, i, machine;
+	int ret, i;
 	char *sh_str;
 
 	debug("64bit version\n");
@@ -237,7 +270,7 @@
 	uint32_t sh_addr, sh_offset, sh_size;
 	Elf32_Half sh_index, sh_num;
 	Elf32_Shdr *sh_table; /* Elf symbol table */
-	int ret, i, machine;
+	int ret, i;
 	char *sh_str;
 
 	debug("32bit version\n");
@@ -254,12 +287,20 @@
 	machine = elf16_to_cpu(header.e_machine);
 	debug("Machine %d\n", machine);
 
-	if (machine != EM_MICROBLAZE) {
+	if (machine != EM_MICROBLAZE && machine != EM_M68K) {
 		fprintf(stderr, "%s: Not supported machine type\n", argv[0]);
 		return 30;
 	}
 
 	text_base = elf32_to_cpu(header.e_entry);
+	/*
+	 * M68K ELF entry point is MONITOR_BASE, not TEXT_BASE.
+	 * TEXT_BASE is always MONITOR_BASE &~ 0x7ff, so clear
+	 * those bits here.
+	 */
+	if (machine == EM_M68K)
+		text_base &= ~0x7ff;
+
 	section_header_base = elf32_to_cpu(header.e_shoff);
 	section_header_size = elf16_to_cpu(header.e_shentsize) *
 			      elf16_to_cpu(header.e_shnum);
@@ -480,25 +521,44 @@
 
 	debug("Type:\t");
 
-	switch (*type) {
-	case R_MICROBLAZE_32:
-		debug("R_MICROBLAZE_32\n");
-		return true;
-	case R_MICROBLAZE_GLOB_DAT:
-		debug("R_MICROBLAZE_GLOB_DAT\n");
-		return true;
-	case R_MICROBLAZE_NONE:
-		debug("R_MICROBLAZE_NONE - ignoring - do nothing\n");
-		return false;
-	case R_MICROBLAZE_REL:
-		debug("R_MICROBLAZE_REL\n");
-		return true;
-	default:
-		fprintf(stderr, "warning: unsupported relocation type %"
-			PRIu32 " at %" PRIx32 "\n", *type, rela->r_offset);
-
-		return false;
+	if (machine == EM_M68K) {
+		switch (*type) {
+		case R_68K_32:
+			debug("R_68K_32\n");
+			return true;
+		case R_68K_GLOB_DAT:
+			debug("R_68K_GLOB_DAT\n");
+			return true;
+		case R_68K_JMP_SLOT:
+			debug("R_68K_JMP_SLOT\n");
+			return true;
+		case R_68K_NONE:
+			debug("R_68K_NONE - ignoring - do nothing\n");
+			return false;
+		case R_68K_RELATIVE:
+			debug("R_68K_RELATIVE\n");
+			return true;
+		}
+	} else {
+		switch (*type) {
+		case R_MICROBLAZE_32:
+			debug("R_MICROBLAZE_32\n");
+			return true;
+		case R_MICROBLAZE_GLOB_DAT:
+			debug("R_MICROBLAZE_GLOB_DAT\n");
+			return true;
+		case R_MICROBLAZE_NONE:
+			debug("R_MICROBLAZE_NONE - ignoring - do nothing\n");
+			return false;
+		case R_MICROBLAZE_REL:
+			debug("R_MICROBLAZE_REL\n");
+			return true;
+		}
 	}
+	fprintf(stderr, "warning: unsupported relocation type %"
+		PRIu32 " at %" PRIx32 "\n", *type, rela->r_offset);
+
+	return false;
 }
 
 static int rela_elf32(char **argv, FILE *f)
@@ -561,8 +621,8 @@
 
 		debug("Addr:\t0x%" PRIx32 "\n", addr);
 
-		switch (type) {
-		case R_MICROBLAZE_REL:
+		if ((machine == EM_M68K && type == R_68K_RELATIVE) ||
+		    (machine == EM_MICROBLAZE && type == R_MICROBLAZE_REL)) {
 			if (fseek(f, addr, SEEK_SET) < 0) {
 				fprintf(stderr, "%s: %s: seek to %"
 					PRIx32 " failed: %s\n",
@@ -577,9 +637,12 @@
 					argv[0], argv[1], addr);
 				return 4;
 			}
-			break;
-		case R_MICROBLAZE_32:
-		case R_MICROBLAZE_GLOB_DAT:
+		} else if ((machine == EM_M68K &&
+		            (type == R_68K_32 || type == R_68K_GLOB_DAT ||
+			     type == R_68K_JMP_SLOT)) ||
+			   (machine == EM_MICROBLAZE &&
+			    (type == R_MICROBLAZE_32 ||
+			     type == R_MICROBLAZE_GLOB_DAT))) {
 			/* global symbols read it and add reloc offset */
 			index = swrela.r_info >> 8;
 			pos_dyn = dyn_start + sizeof(Elf32_Sym) * index;
@@ -602,14 +665,16 @@
 			}
 
 			debug("Symbol description:\n");
-			debug(" st_name:\t0x%x\n", symbols.st_name);
-			debug(" st_value:\t0x%x\n", symbols.st_value);
-			debug(" st_size:\t0x%x\n", symbols.st_size);
+			debug(" st_name:\t0x%x\n", elf32_to_cpu(symbols.st_name));
+			debug(" st_value:\t0x%x\n", elf32_to_cpu(symbols.st_value));
+			debug(" st_size:\t0x%x\n", elf32_to_cpu(symbols.st_size));
 
-			value = swrela.r_addend + symbols.st_value;
+			value = swrela.r_addend + elf32_to_cpu(symbols.st_value);
 
 			debug("Value:\t0x%x\n", value);
 
+			value = cpu_to_elf32(value);
+
 			if (fseek(f, addr, SEEK_SET) < 0) {
 				fprintf(stderr, "%s: %s: seek to %"
 					PRIx32 " failed: %s\n",
@@ -622,12 +687,11 @@
 					argv[0], argv[1], addr);
 				return 4;
 			}
-
-			break;
-		case R_MICROBLAZE_NONE:
+		} else if (machine == EM_M68K && type == R_68K_NONE) {
+			debug("R_68K_NONE - skip\n");
+		} else if (machine == EM_MICROBLAZE && type == R_MICROBLAZE_NONE) {
 			debug("R_MICROBLAZE_NONE - skip\n");
-			break;
-		default:
+		} else {
 			fprintf(stderr, "warning: unsupported relocation type %"
 				PRIu32 " at %" PRIx32 "\n",
 				type, rela.r_offset);