[PATCH 13/20] RISC-V: implement PBL and relocation support

Ahmad Fatoum a.fatoum at pengutronix.de
Mon Mar 15 07:43:54 GMT 2021


On 14.03.21 13:27, Ahmad Fatoum wrote:
> Given that we only support a single RISC-V board, this puts us in
> a good position to make this a multi-image-only architecture.
> 
> This commit adds the necessary bits. It's highly inspired by the ARM PBL
> support. Notable difference is that for relocations to be generated, it
> was necessary to compile with -fpic. The relocation code assumes the
> relocation entries to preprocessed. This is done at build-time by
> means of the prelink-riscv script imported from U-Boot.
> 
> Actual migration to -fpic and prelinking is done along with porting
> erizo in a follow-up commit.
> 
> Cc: Masahiro Yamada <masahiroy at kernel.org>
> Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
> 
> ---
> Hello Masahiro,
> 
> Do you know if Kernel Kbuild has a similiar prelink stage somewhere,
> i.e. an optional architecture-specific rule that processes the ELF file
> before continuing normally? I'd like for arch/risc/Makefile to define
> PRELINK as a command that takes the ELF as an argument and for the
> Makefiles to have no knowledge about PRELINK's content or architecture,
> but I don't know how to best go about this.
> 
> Thanks
> ---
>  arch/riscv/Makefile                    |   1 +
>  arch/riscv/boot/Makefile               |   3 +
>  arch/riscv/boot/entry.c                |  33 +++++
>  arch/riscv/boot/entry.h                |  15 ++
>  arch/riscv/boot/entry_ll.S             |  15 ++
>  arch/riscv/boot/start.c                | 197 +++++++++++++++++++++++++
>  arch/riscv/boot/uncompress.c           |  74 ++++++++++
>  arch/riscv/include/asm/barebox-riscv.h | 101 +++++++++++++
>  arch/riscv/include/asm/common.h        |  10 +-
>  arch/riscv/include/asm/elf.h           |   7 +
>  arch/riscv/include/asm/linkage.h       |   4 +
>  arch/riscv/include/asm/sections.h      |  15 ++
>  arch/riscv/lib/Makefile                |   3 +
>  arch/riscv/lib/barebox.lds.S           |  14 +-
>  arch/riscv/lib/pbl.lds.S               |  83 +++++++++++
>  arch/riscv/lib/reloc.c                 |  64 ++++++++
>  arch/riscv/lib/runtime-offset.S        |  12 ++
>  arch/riscv/lib/sections.c              |   9 ++
>  arch/riscv/lib/setupc.S                |  55 +++++++
>  scripts/.gitignore                     |   1 +
>  scripts/Makefile                       |   1 +
>  scripts/Makefile.lib                   |  11 ++
>  scripts/prelink-riscv.c                | 122 +++++++++++++++
>  scripts/prelink-riscv.inc              | 123 +++++++++++++++
>  24 files changed, 969 insertions(+), 4 deletions(-)
>  create mode 100644 arch/riscv/boot/Makefile
>  create mode 100644 arch/riscv/boot/entry.c
>  create mode 100644 arch/riscv/boot/entry.h
>  create mode 100644 arch/riscv/boot/entry_ll.S
>  create mode 100644 arch/riscv/boot/start.c
>  create mode 100644 arch/riscv/boot/uncompress.c
>  create mode 100644 arch/riscv/include/asm/barebox-riscv.h
>  create mode 100644 arch/riscv/lib/pbl.lds.S
>  create mode 100644 arch/riscv/lib/reloc.c
>  create mode 100644 arch/riscv/lib/runtime-offset.S
>  create mode 100644 arch/riscv/lib/sections.c
>  create mode 100644 arch/riscv/lib/setupc.S
>  create mode 100644 scripts/prelink-riscv.c
>  create mode 100644 scripts/prelink-riscv.inc
> 
> diff --git a/arch/riscv/Makefile b/arch/riscv/Makefile
> index d9cefe32c057..df2b5bb681a4 100644
> --- a/arch/riscv/Makefile
> +++ b/arch/riscv/Makefile
> @@ -43,6 +43,7 @@ endif
>  common-y += $(MACH)
>  common-y += arch/riscv/boards/
>  common-y += arch/riscv/lib/
> +common-y += arch/riscv/boot/
>  
>  common-$(CONFIG_OFTREE) += arch/riscv/dts/
>  
> diff --git a/arch/riscv/boot/Makefile b/arch/riscv/boot/Makefile
> new file mode 100644
> index 000000000000..954e9b602287
> --- /dev/null
> +++ b/arch/riscv/boot/Makefile
> @@ -0,0 +1,3 @@
> +# SPDX-License-Identifier: GPL-2.0
> +obj-y += start.o
> +obj-pbl-y += entry.o entry_ll.o uncompress.o
> diff --git a/arch/riscv/boot/entry.c b/arch/riscv/boot/entry.c
> new file mode 100644
> index 000000000000..ec506acfa3b2
> --- /dev/null
> +++ b/arch/riscv/boot/entry.c
> @@ -0,0 +1,33 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#include <types.h>
> +
> +#include <asm/barebox-riscv.h>
> +
> +#include "entry.h"
> +#include <debug_ll.h>
> +
> +/*
> + * Main RISC-V entry point. Call this with the memory region you can
> + * spare for barebox. This doesn't necessarily have to be the full
> + * SDRAM. The currently running binary can be inside or outside of
> + * this region. The PBL can be running inside or outside of this
> + * region.
> + *
> + * -> membase + memsize
> + *   STACK_SIZE              - stack
> + *   128KiB                  - early memory space
> + * -> maximum end of barebox binary
> + */
> +
> +void __noreturn __barebox_riscv_entry(unsigned long membase,
> +				      unsigned long memsize,
> +				      void *boarddata,
> +				      unsigned long sp);
> +
> +void __noreturn barebox_riscv_entry(unsigned long membase,
> +				    unsigned long memsize, void *boarddata)
> +{
> +	__barebox_riscv_entry(membase, memsize, boarddata,
> +			      riscv_mem_stack_top(membase, membase + memsize));
> +}
> +
> diff --git a/arch/riscv/boot/entry.h b/arch/riscv/boot/entry.h
> new file mode 100644
> index 000000000000..b3a24d2783f7
> --- /dev/null
> +++ b/arch/riscv/boot/entry.h
> @@ -0,0 +1,15 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#ifndef __ENTRY_H__
> +#define __ENTRY_H__
> +
> +#include <common.h>
> +
> +void __noreturn barebox_non_pbl_start(unsigned long membase,
> +				      unsigned long memsize,
> +				      void *boarddata);
> +
> +void __noreturn barebox_pbl_start(unsigned long membase,
> +				  unsigned long memsize,
> +				  void *boarddata);
> +
> +#endif
> diff --git a/arch/riscv/boot/entry_ll.S b/arch/riscv/boot/entry_ll.S
> new file mode 100644
> index 000000000000..7011fefad865
> --- /dev/null
> +++ b/arch/riscv/boot/entry_ll.S
> @@ -0,0 +1,15 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#include <linux/linkage.h>
> +#include <asm/sections.h>
> +
> +/*
> + * a0: memory base
> + * a1: memory size
> + * a2: board data
> + * a3: new value for SP
> + */
> +.section .text.__barebox_riscv_entry
> +ENTRY(__barebox_riscv_entry)
> +	move	sp, a3
> +	j	barebox_pbl_start
> +ENDPROC(__barebox_riscv_entry)
> diff --git a/arch/riscv/boot/start.c b/arch/riscv/boot/start.c
> new file mode 100644
> index 000000000000..7fcbafcc0758
> --- /dev/null
> +++ b/arch/riscv/boot/start.c
> @@ -0,0 +1,197 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +// SPDX-FileCopyrightText: 2010 Sascha Hauer <s.hauer at pengutronix.de>, Pengutronix
> +
> +#define pr_fmt(fmt) "start.c: " fmt
> +
> +#include <common.h>
> +#include <init.h>
> +#include <linux/sizes.h>
> +#include <of.h>
> +#include <asm/barebox-riscv.h>
> +#include <asm-generic/memory_layout.h>
> +#include <asm/sections.h>
> +#include <asm/unaligned.h>
> +#include <linux/kasan.h>
> +#include <memory.h>
> +#include <uncompress.h>
> +#include <malloc.h>
> +
> +#include <debug_ll.h>
> +
> +#include "entry.h"
> +
> +unsigned long riscv_stack_top;
> +static unsigned long riscv_barebox_size;
> +static unsigned long riscv_endmem;
> +static void *barebox_boarddata;
> +static unsigned long barebox_boarddata_size;
> +
> +static bool blob_is_fdt(const void *blob)
> +{
> +	return get_unaligned_be32(blob) == FDT_MAGIC;
> +}
> +
> +static bool blob_is_compressed_fdt(const void *blob)
> +{
> +	const struct barebox_riscv_boarddata_compressed_dtb *dtb = blob;
> +
> +	return dtb->magic == BAREBOX_RISCV_BOARDDATA_COMPRESSED_DTB_MAGIC;
> +}
> +
> +void *barebox_riscv_boot_dtb(void)
> +{
> +	void *dtb;
> +	void *data;
> +	int ret;
> +	struct barebox_riscv_boarddata_compressed_dtb *compressed_dtb;
> +	static void *boot_dtb;
> +
> +	if (boot_dtb)
> +		return boot_dtb;
> +
> +	if (barebox_boarddata && blob_is_fdt(barebox_boarddata)) {
> +		pr_debug("%s: using barebox_boarddata\n", __func__);
> +		return barebox_boarddata;
> +	}
> +
> +	if (!IS_ENABLED(CONFIG_USE_COMPRESSED_DTB) || !barebox_boarddata
> +	    || !blob_is_compressed_fdt(barebox_boarddata))
> +		return NULL;
> +
> +	compressed_dtb = barebox_boarddata;
> +
> +	pr_debug("%s: using compressed_dtb\n", __func__);
> +
> +	dtb = malloc(compressed_dtb->datalen_uncompressed);
> +	if (!dtb)
> +		return NULL;
> +
> +	data = compressed_dtb + 1;
> +
> +	ret = uncompress(data, compressed_dtb->datalen, NULL, NULL, dtb, NULL, NULL);
> +	if (ret) {
> +		pr_err("uncompressing dtb failed\n");
> +		free(dtb);
> +		return NULL;
> +	}
> +
> +	boot_dtb = dtb;
> +
> +	return boot_dtb;
> +}
> +
> +static inline unsigned long riscv_mem_boarddata(unsigned long membase,
> +						unsigned long endmem,
> +						unsigned long size)
> +{
> +	unsigned long mem;
> +
> +	mem = riscv_mem_barebox_image(membase, endmem, riscv_barebox_size);
> +	mem -= ALIGN(size, 64);
> +
> +	return mem;
> +}
> +
> +unsigned long riscv_mem_ramoops_get(void)
> +{
> +	return riscv_mem_ramoops(0, riscv_stack_top);
> +}
> +EXPORT_SYMBOL_GPL(riscv_mem_ramoops_get);
> +
> +unsigned long riscv_mem_endmem_get(void)
> +{
> +	return riscv_endmem;
> +}
> +EXPORT_SYMBOL_GPL(riscv_mem_endmem_get);
> +
> +static int barebox_memory_areas_init(void)
> +{
> +	if(barebox_boarddata)
> +		request_sdram_region("board data", (unsigned long)barebox_boarddata,
> +				     barebox_boarddata_size);
> +
> +	return 0;
> +}
> +device_initcall(barebox_memory_areas_init);
> +
> +/*
> + * First function in the uncompressed image. We get here from
> + * the pbl. The stack already has been set up by the pbl.
> + */
> +__noreturn __no_sanitize_address __section(.text_entry)
> +void barebox_non_pbl_start(unsigned long membase, unsigned long memsize, void *boarddata)
> +{
> +	unsigned long endmem = membase + memsize;
> +	unsigned long malloc_start, malloc_end;
> +	unsigned long barebox_size = barebox_image_size + MAX_BSS_SIZE;
> +	unsigned long barebox_base = riscv_mem_barebox_image(membase, endmem, barebox_size);
> +
> +	relocate_to_current_adr();
> +
> +	setup_c();
> +
> +	barrier();
> +
> +	pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize);
> +
> +	riscv_endmem = endmem;
> +	riscv_stack_top = riscv_mem_stack_top(membase, endmem);
> +	riscv_barebox_size = barebox_size;
> +	malloc_end = barebox_base;
> +
> +	if (boarddata) {
> +		uint32_t totalsize = 0;
> +		const char *name;
> +
> +		if (blob_is_fdt(boarddata)) {
> +			totalsize = get_unaligned_be32(boarddata + 4);
> +			name = "DTB";
> +		} else if (blob_is_compressed_fdt(boarddata)) {
> +			struct barebox_riscv_boarddata_compressed_dtb *bd = boarddata;
> +			totalsize = bd->datalen + sizeof(*bd);
> +			name = "Compressed DTB";
> +		}
> +
> +		if (totalsize) {
> +			unsigned long mem = riscv_mem_boarddata(membase, endmem, totalsize);
> +			pr_debug("found %s in boarddata, copying to 0x%08lx\n", name, mem);
> +			barebox_boarddata = memcpy((void *)mem, boarddata, totalsize);
> +			barebox_boarddata_size = totalsize;
> +			malloc_end = mem;
> +		}
> +	}
> +
> +	/*
> +	 * Maximum malloc space is the Kconfig value if given
> +	 * or 1GB.
> +	 */
> +	if (MALLOC_SIZE > 0) {
> +		malloc_start = malloc_end - MALLOC_SIZE;
> +		if (malloc_start < membase)
> +			malloc_start = membase;
> +	} else {
> +		malloc_start = malloc_end - (malloc_end - membase) / 2;
> +		if (malloc_end - malloc_start > SZ_1G)
> +			malloc_start = malloc_end - SZ_1G;
> +	}
> +
> +	pr_debug("initializing malloc pool at 0x%08lx (size 0x%08lx)\n",
> +			malloc_start, malloc_end - malloc_start);
> +
> +	mem_malloc_init((void *)malloc_start, (void *)malloc_end - 1);
> +
> +	pr_debug("starting barebox...\n");
> +
> +	start_barebox();
> +}
> +
> +void start(unsigned long membase, unsigned long memsize, void *boarddata);
> +/*
> + * First function in the uncompressed image. We get here from
> + * the pbl. The stack already has been set up by the pbl.
> + */
> +void __no_sanitize_address __section(.text_entry) start(unsigned long membase,
> +		unsigned long memsize, void *boarddata)
> +{
> +	barebox_non_pbl_start(membase, memsize, boarddata);
> +}
> diff --git a/arch/riscv/boot/uncompress.c b/arch/riscv/boot/uncompress.c
> new file mode 100644
> index 000000000000..cf268bece1bf
> --- /dev/null
> +++ b/arch/riscv/boot/uncompress.c
> @@ -0,0 +1,74 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +// SPDX-FileCopyrightText: 2010-2013 Sascha Hauer <s.hauer at pengutronix.de>, Pengutronix
> +// SPDX-FileCopyrightText: 2012 Jean-Christophe PLAGNIOL-VILLARD <plagnioj at jcrosoft.com>
> +
> +/* uncompress.c - uncompressor code for self extracing pbl image */
> +
> +#define pr_fmt(fmt) "uncompress.c: " fmt
> +
> +#include <common.h>
> +#include <init.h>
> +#include <linux/sizes.h>
> +#include <pbl.h>
> +#include <asm/barebox-riscv.h>
> +#include <asm-generic/memory_layout.h>
> +#include <asm/sections.h>
> +#include <asm/unaligned.h>
> +
> +#include <debug_ll.h>
> +
> +#include "entry.h"
> +
> +unsigned long free_mem_ptr;
> +unsigned long free_mem_end_ptr;
> +
> +extern unsigned char input_data[];
> +extern unsigned char input_data_end[];
> +
> +void __noreturn barebox_pbl_start(unsigned long membase, unsigned long memsize,
> +				  void *fdt)
> +{
> +	uint32_t pg_len, uncompressed_len;
> +	void __noreturn (*barebox)(unsigned long, unsigned long, void *);
> +	unsigned long endmem = membase + memsize;
> +	unsigned long barebox_base;
> +	void *pg_start, *pg_end;
> +	unsigned long pc = get_pc();
> +
> +	pg_start = input_data + get_runtime_offset();
> +	pg_end = input_data_end + get_runtime_offset();
> +
> +	/*
> +	 * If we run from inside the memory just relocate the binary
> +	 * to the current address. Otherwise it may be a readonly location.
> +	 * Copy and relocate to the start of the memory in this case.
> +	 */
> +	if (pc > membase && pc - membase < memsize)
> +		relocate_to_current_adr();
> +	else
> +		relocate_to_adr(membase);
> +
> +	pg_len = pg_end - pg_start;
> +	uncompressed_len = get_unaligned((const u32 *)(pg_start + pg_len - 4));
> +
> +	barebox_base = riscv_mem_barebox_image(membase, endmem,
> +					       uncompressed_len + MAX_BSS_SIZE);
> +
> +	setup_c();
> +
> +	pr_debug("memory at 0x%08lx, size 0x%08lx\n", membase, memsize);
> +
> +	free_mem_ptr = riscv_mem_early_malloc(membase, endmem);
> +	free_mem_end_ptr = riscv_mem_early_malloc_end(membase, endmem);
> +
> +	pr_debug("uncompressing barebox binary at 0x%p (size 0x%08x) to 0x%08lx (uncompressed size: 0x%08x)\n",
> +			pg_start, pg_len, barebox_base, uncompressed_len);
> +
> +	pbl_barebox_uncompress((void*)barebox_base, pg_start, pg_len);
> +
> +	barebox = (void *)barebox_base;
> +
> +	pr_debug("jumping to uncompressed image at 0x%p. dtb=0x%p\n", barebox, fdt);
> +
> +	barebox(membase, memsize, fdt);
> +}
> diff --git a/arch/riscv/include/asm/barebox-riscv.h b/arch/riscv/include/asm/barebox-riscv.h
> new file mode 100644
> index 000000000000..05e076c4868b
> --- /dev/null
> +++ b/arch/riscv/include/asm/barebox-riscv.h
> @@ -0,0 +1,101 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/*
> + * (C) Copyright 2002
> + * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
> + * Marius Groeger <mgroeger at sysgo.de>
> + *
> + * (C) Copyright 2002
> + * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
> + * Alex Zuepke <azu at sysgo.de>
> + */
> +
> +#ifndef _BAREBOX_RISCV_H_
> +#define _BAREBOX_RISCV_H_
> +
> +#include <linux/sizes.h>
> +#include <asm-generic/memory_layout.h>
> +#include <linux/kernel.h>
> +#include <linux/types.h>
> +#include <linux/compiler.h>
> +#include <asm/sections.h>
> +
> +unsigned long get_runtime_offset(void);
> +
> +void setup_c(void);
> +void relocate_to_current_adr(void);
> +void relocate_to_adr(unsigned long target);
> +void __noreturn barebox_riscv_entry(unsigned long membase, unsigned long memsize, void *boarddata);
> +
> +unsigned long riscv_mem_ramoops_get(void);
> +unsigned long riscv_mem_endmem_get(void);
> +
> +struct barebox_riscv_boarddata_compressed_dtb {
> +#define BAREBOX_RISCV_BOARDDATA_COMPRESSED_DTB_MAGIC 0x7b66bcbd
> +	u32 magic;
> +	u32 datalen;
> +	u32 datalen_uncompressed;
> +};
> +
> +void *barebox_riscv_boot_dtb(void);
> +
> +static inline unsigned long riscv_mem_stack_top(unsigned long membase,
> +						unsigned long endmem)
> +{
> +	return endmem - SZ_2M;
> +}
> +
> +static inline unsigned long riscv_mem_stack(unsigned long membase,
> +					  unsigned long endmem)
> +{
> +	return riscv_mem_stack_top(membase, endmem) - STACK_SIZE;
> +}
> +
> +static inline unsigned long riscv_mem_early_malloc(unsigned long membase,
> +						   unsigned long endmem)
> +{
> +	return riscv_mem_stack(membase, endmem) - SZ_128K;
> +}
> +
> +static inline unsigned long riscv_mem_early_malloc_end(unsigned long membase,
> +						       unsigned long endmem)
> +{
> +	return riscv_mem_stack(membase, endmem);
> +}
> +
> +static inline unsigned long riscv_mem_ramoops(unsigned long membase,
> +					      unsigned long endmem)
> +{
> +	endmem = riscv_mem_stack(membase, endmem);
> +#ifdef CONFIG_FS_PSTORE_RAMOOPS
> +	endmem -= CONFIG_FS_PSTORE_RAMOOPS_SIZE;
> +	endmem = ALIGN_DOWN(endmem, SZ_4K);
> +#endif
> +
> +	return endmem;
> +}
> +
> +static inline unsigned long riscv_mem_barebox_image(unsigned long membase,
> +						    unsigned long endmem,
> +						    unsigned long size)
> +{
> +	endmem = riscv_mem_ramoops(membase, endmem);
> +
> +	return ALIGN_DOWN(endmem - size, SZ_1M);
> +}
> +
> +#define ENTRY_FUNCTION(name, arg0, arg1, arg2)		\
> +	void name (ulong a0, ulong a1, ulong a2);	\
> +	void __section(.text_head_entry_##name) name (ulong a0, ulong a1, ulong a2)
> +
> +/*
> + * When using compressed images in conjunction with relocatable images
> + * the PBL code must pick a suitable place where to uncompress the barebox
> + * image. For doing this the PBL code must know the size of the final
> + * image including the BSS segment. The BSS size is unknown to the PBL
> + * code, so define a maximum BSS size here.
> + */
> +#define MAX_BSS_SIZE SZ_1M
> +
> +#define barebox_image_size (__image_end - __image_start)
> +
> +#endif	/* _BAREBOX_RISCV_H_ */
> diff --git a/arch/riscv/include/asm/common.h b/arch/riscv/include/asm/common.h
> index bc8a17e30bc5..a0982c548fe1 100644
> --- a/arch/riscv/include/asm/common.h
> +++ b/arch/riscv/include/asm/common.h
> @@ -1,6 +1,14 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/* SPDX-FileCopyrightText: Copyright (c) 2021 Ahmad Fatoum, Pengutronix */
>  #ifndef ASM_RISCV_COMMON_H
>  #define ASM_RISCV_COMMON_H
>  
> -/* nothing special yet */
> +#include <linux/compiler.h>
> +
> +static __always_inline unsigned long get_pc(void)
> +{
> +label:
> +	return (unsigned long)&&label;
> +}
>  
>  #endif /* ASM_RISCV_COMMON_H */
> diff --git a/arch/riscv/include/asm/elf.h b/arch/riscv/include/asm/elf.h
> index 7134fa05820a..adb8ec8f6ece 100644
> --- a/arch/riscv/include/asm/elf.h
> +++ b/arch/riscv/include/asm/elf.h
> @@ -1,3 +1,4 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
>  #ifndef __ASM_RISCV_ELF_H__
>  #define __ASM_RISCV_ELF_H__
>  
> @@ -8,4 +9,10 @@
>  #define ELF_CLASS	ELFCLASS32
>  #endif
>  
> +/* Relocation types used by the dynamic linker */
> +#define R_RISCV_NONE		0
> +#define R_RISCV_32		1
> +#define R_RISCV_64		2
> +#define R_RISCV_RELATIVE	3
> +
>  #endif /* __ASM_RISCV_ELF_H__ */
> diff --git a/arch/riscv/include/asm/linkage.h b/arch/riscv/include/asm/linkage.h
> index 9e88ba23cd2b..c6801294f388 100644
> --- a/arch/riscv/include/asm/linkage.h
> +++ b/arch/riscv/include/asm/linkage.h
> @@ -9,4 +9,8 @@
>  #define __ALIGN		.balign 4
>  #define __ALIGN_STR	".balign 4"
>  
> +#define ENDPROC(name) \
> +  .type name, %function; \
> +  END(name)
> +
>  #endif /* _ASM_RISCV_LINKAGE_H */
> diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h
> index 2b8c5160388f..b5fbba8f165a 100644
> --- a/arch/riscv/include/asm/sections.h
> +++ b/arch/riscv/include/asm/sections.h
> @@ -1 +1,16 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +#ifndef __ASM_SECTIONS_H
> +#define __ASM_SECTIONS_H
> +
> +#ifndef __ASSEMBLY__
>  #include <asm-generic/sections.h>
> +#include <linux/types.h>
> +
> +extern char __rel_dyn_start[];
> +extern char __rel_dyn_end[];
> +extern char __dynsym_start[];
> +extern char __dynsym_end[];
> +
> +#endif
> +
> +#endif /* __ASM_SECTIONS_H */
> diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile
> index b983ca8cdca0..5f57d9fcd2e2 100644
> --- a/arch/riscv/lib/Makefile
> +++ b/arch/riscv/lib/Makefile
> @@ -1,5 +1,8 @@
> +# SPDX-License-Identifier: GPL-2.0
> +
>  extra-y += barebox.lds
>  
>  obj-y += riscv_timer.o
> +obj-pbl-y += sections.o setupc.o reloc.o sections.o runtime-offset.o
>  obj-$(CONFIG_HAS_ARCH_SJLJ) += setjmp.o longjmp.o
>  obj-$(CONFIG_RISCV_OPTIMZED_STRING_FUNCTIONS) += memcpy.o memset.o memmove.o
> diff --git a/arch/riscv/lib/barebox.lds.S b/arch/riscv/lib/barebox.lds.S
> index 342769890bb0..c8a331c577cf 100644
> --- a/arch/riscv/lib/barebox.lds.S
> +++ b/arch/riscv/lib/barebox.lds.S
> @@ -43,10 +43,18 @@ SECTIONS
>  
>  	.barebox_imd : { BAREBOX_IMD }
>  
> -	. = ALIGN(8);
> -	.got : { *(.got*) }
> +	/DISCARD/ : { *(.rela.plt*) }
> +	.rela.dyn : {
> +		__rel_dyn_start = .;
> +		*(.rel*)
> +		__rel_dyn_end = .;
> +	}
>  
> -	.rela.dyn : { *(.rela*) }
> +	.dynsym : {
> +		__dynsym_start = .;
> +		*(.dynsym)
> +		__dynsym_end = .;
> +	}
>  
>  	_edata = .;
>  	. = ALIGN(8);
> diff --git a/arch/riscv/lib/pbl.lds.S b/arch/riscv/lib/pbl.lds.S
> new file mode 100644
> index 000000000000..33caab7b1024
> --- /dev/null
> +++ b/arch/riscv/lib/pbl.lds.S
> @@ -0,0 +1,83 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/* SPDX-FileCopyrightText: 2012 Sascha Hauer <s.hauer at pengutronix.de>, Pengutronix */
> +
> +#include <linux/sizes.h>
> +#include <asm-generic/barebox.lds.h>
> +#include <asm-generic/memory_layout.h>
> +
> +OUTPUT_ARCH(riscv)
> +SECTIONS
> +{
> +	. = 0x0;
> +
> +	.image_start : { *(.__image_start) }
> +
> +	. = ALIGN(4);
> +	._text : { *(._text) }
> +	.text      :
> +	{
> +		_stext = .;
> +		*(.text_head_entry*)
> +		__bare_init_start = .;
> +		*(.text_bare_init*)
> +		__bare_init_end = .;
> +		*(.text*)
> +	}
> +
> +	/* Discard unwind if enable in barebox */
> +	/DISCARD/ : { *(.ARM.ex*) }
> +
> +	BAREBOX_BARE_INIT_SIZE
> +	BAREBOX_PBL_SIZE
> +
> +	. = ALIGN(4);
> +	.rodata : { *(.rodata*) }
> +
> +	.barebox_imd : { BAREBOX_IMD }
> +
> +	_etext = .;			/* End of text and rodata section */
> +
> +	.data : { *(.data*) }
> +
> +	__shasum_start = .;
> +	.shasum : {
> +		KEEP(*(.shasum))
> +	}
> +	__shasum_end = .;
> +
> +	/DISCARD/ : { *(.rela.plt*) }
> +	.rela.dyn : {
> +		__rel_dyn_start = .;
> +		*(.rela*)
> +		__rel_dyn_end = .;
> +	}
> +
> +	.dynsym : {
> +		__dynsym_start = .;
> +		*(.dynsym)
> +		__dynsym_end = .;
> +	}
> +
> +	pbl_code_size =  .;
> +
> +	.__bss_start :  { *(.__bss_start) }
> +	.bss : { *(.bss*) }
> +	.__bss_stop :  { *(.__bss_stop) }
> +	_end = .;
> +
> +	pbl_memory_size =  .;
> +
> +	. = ALIGN(4);
> +	__piggydata_start = .;
> +	.piggydata : {
> +		*(.piggydata)
> +	}
> +	__piggydata_end = .;
> +
> +	.image_end : { KEEP(*(.__image_end)) }
> +
> +	pbl_image_size =  .;
> +
> +	_barebox_image_size = __image_end;
> +	_barebox_pbl_size = __bss_start;
> +}
> diff --git a/arch/riscv/lib/reloc.c b/arch/riscv/lib/reloc.c
> new file mode 100644
> index 000000000000..5e26c0be9c1c
> --- /dev/null
> +++ b/arch/riscv/lib/reloc.c
> @@ -0,0 +1,64 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +// SPDX-FileCopyrightText: Copyright (c) 2021 Ahmad Fatoum, Pengutronix
> +
> +#include <common.h>
> +#include <linux/linkage.h>
> +#include <asm/sections.h>
> +#include <asm/barebox-riscv.h>
> +#include <debug_ll.h>
> +#include <asm-generic/module.h>
> +
> +#include <elf.h>
> +
> +#if __riscv_xlen == 64
> +#define Elf_Rela			Elf64_Rela
> +#define R_RISCV_ABSOLUTE		R_RISCV_64
> +#define DYNSYM_ENTRY(dynsym, rela)	dynsym[ELF_R_SYM(rela->r_info) * 3 + 1]
> +#elif __riscv_xlen == 32
> +#define Elf_Rela			Elf32_Rela
> +#define R_RISCV_ABSOLUTE		R_RISCV_32
> +#define DYNSYM_ENTRY(dynsym, rela)	dynsym[ELF_R_SYM(rela->r_info) * 4 + 1]
> +#else
> +#error unknown riscv target
> +#endif
> +
> +#define RISC_R_TYPE(x)	((x) & 0xFF)
> +
> +void relocate_to_current_adr(void)
> +{
> +	unsigned long offset;
> +	unsigned long *dynsym;
> +	void *dstart, *dend;
> +	Elf_Rela *rela;
> +
> +	/* Get offset between linked address and runtime address */
> +	offset = get_runtime_offset();
> +
> +	dstart = __rel_dyn_start + offset;
> +	dend = __rel_dyn_end + offset;
> +	dynsym = (void *)__dynsym_start + offset;
> +
> +	for (rela = dstart; (void *)rela < dend; rela++) {
> +		unsigned long *fixup;
> +
> +		fixup = (unsigned long *)(rela->r_offset + offset);
> +
> +		switch (RISC_R_TYPE(rela->r_info)) {
> +		case R_RISCV_RELATIVE:
> +			*fixup = rela->r_addend + offset;
> +			break;
> +		case R_RISCV_ABSOLUTE:
> +			*fixup = DYNSYM_ENTRY(dynsym, rela) + rela->r_addend + offset;
> +			break;
> +		default:
> +			putc_ll('>');
> +			puthex_ll(rela->r_info);
> +			putc_ll(' ');
> +			puthex_ll(rela->r_offset);
> +			putc_ll(' ');
> +			puthex_ll(rela->r_addend);
> +			putc_ll('\n');
> +			panic("");
> +		}
> +	}
> +}
> diff --git a/arch/riscv/lib/runtime-offset.S b/arch/riscv/lib/runtime-offset.S
> new file mode 100644
> index 000000000000..f6a040628963
> --- /dev/null
> +++ b/arch/riscv/lib/runtime-offset.S
> @@ -0,0 +1,12 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +/* SPDX-FileCopyrightText: Copyright (c) 2021 Ahmad Fatoum, Pengutronix */
> +#include <linux/linkage.h>
> +#include <asm/sections.h>
> +
> +.section ".text_bare_init","ax"
> +ENTRY(get_runtime_offset)
> +	lla	a0, _text	/* load addr */
> +	la	a1, _text	/* link addr */
> +	sub	a0, a0, a1
> +	ret
> +ENDPROC(get_runtime_offset)
> diff --git a/arch/riscv/lib/sections.c b/arch/riscv/lib/sections.c
> new file mode 100644
> index 000000000000..e23a41dcf5d4
> --- /dev/null
> +++ b/arch/riscv/lib/sections.c
> @@ -0,0 +1,9 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +#include <asm/sections.h>
> +#include <linux/types.h>
> +
> +char _text[0] __attribute__((section("._text")));
> +char __bss_start[0] __attribute__((section(".__bss_start")));
> +char __bss_stop[0] __attribute__((section(".__bss_stop")));
> +char __image_start[0] __attribute__((section(".__image_start")));
> +char __image_end[0] __attribute__((section(".__image_end")));
> diff --git a/arch/riscv/lib/setupc.S b/arch/riscv/lib/setupc.S
> new file mode 100644
> index 000000000000..6d824d00f7e0
> --- /dev/null
> +++ b/arch/riscv/lib/setupc.S
> @@ -0,0 +1,55 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/* SPDX-FileCopyrightText: Copyright (c) 2021 Ahmad Fatoum, Pengutronix */
> +
> +#include <linux/linkage.h>
> +#include <asm/sections.h>
> +#include <asm/asm.h>
> +
> +/*
> + * setup_c: clear bss
> + */
> +.section .text.setup_c
> +ENTRY(setup_c)
> +	lla	a0, __bss_start
> +	li	a1, 0
> +	lla	a2, __bss_stop
> +	sub	a2, a2, a0
> +	j	__memset
> +ENDPROC(setup_c)
> +
> +/*
> + * void relocate_to_adr(unsigned long targetadr)
> + *
> + * Copy binary to targetadr, relocate code and continue
> + * executing at new address.
> + */
> +.section .text.relocate_to_adr
> +ENTRY(relocate_to_adr)
> +					/* a0: target address */
> +	addi	sp, sp, -SZREG * 2
> +	lla	a1, _text		/* a1: source address */
> +
> +	beq	a0, a1, copied		/* skip if already at new address */

This needs to be moved after spilling ra onto stack. Will fix in v2.

> +
> +	lla	a2, copied
> +	sub	a2, a2, a1
> +	add	a2, a2, a0
> +	REG_S	a2, (SZREG * 1)(sp)
> +
> +	/* adjust return address */
> +	sub	ra, ra, a1		/* sub address where we are actually running */
> +	add	ra, ra, a0		/* add address where we are going to run */
> +	REG_S	ra, (SZREG * 2)(sp)
> +
> +	lla	a2, __bss_start
> +	sub	a2, a2, a1		 /* a2: size */
> +
> +	jal	__memcpy
> +
> +	REG_L	a0, (SZREG * 1)(sp)
> +	jr	a0 			/* jump to relocated address */
> +copied:
> +	REG_L	ra, (SZREG * 2)(sp)
> +	addi	sp, sp, SZREG * 2
> +	j	relocate_to_current_adr	/* relocate binary */
> +ENDPROC(relocate_to_adr)
> diff --git a/scripts/.gitignore b/scripts/.gitignore
> index 7c9a3f55715f..9577d568edd0 100644
> --- a/scripts/.gitignore
> +++ b/scripts/.gitignore
> @@ -32,3 +32,4 @@ mips-relocs
>  rsatoc
>  stm32image
>  mvebuimg
> +prelink-riscv
> diff --git a/scripts/Makefile b/scripts/Makefile
> index 744f4dd0e7e6..4dc70815b7e6 100644
> --- a/scripts/Makefile
> +++ b/scripts/Makefile
> @@ -24,6 +24,7 @@ hostprogs-always-$(CONFIG_ARCH_SOCFPGA)			+= socfpga_mkimage
>  hostprogs-always-$(CONFIG_ARCH_MXS)			+= mxsimage mxsboot
>  hostprogs-always-$(CONFIG_ARCH_LAYERSCAPE)		+= pblimage
>  hostprogs-always-$(CONFIG_ARCH_STM32MP)			+= stm32image
> +hostprogs-always-$(CONFIG_RISCV)			+= prelink-riscv
>  KBUILD_HOSTCFLAGS += -I$(srctree)/scripts/include/
>  HOSTLDLIBS_mxsimage  = `pkg-config --libs openssl`
>  HOSTCFLAGS_omap3-usb-loader.o = `pkg-config --cflags libusb-1.0`
> diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
> index 2844d29be600..319ac19975ed 100644
> --- a/scripts/Makefile.lib
> +++ b/scripts/Makefile.lib
> @@ -247,6 +247,17 @@ $(obj)/%:: $(src)/%_shipped
>  #	and add target to extra-y so that we know we have to
>  #	read in the saved command line
>  
> +# Prelinking
> +# ---------------------------------------------------------------------------
> +
> +ifneq ($(CONFIG_RISCV),)
> +quiet_cmd_prelink__ = PRELINK $@
> +      cmd_prelink__ = $(objtree)/scripts/prelink-riscv $@
> +endif
> +
> +quiet_cmd_prelink__ ?=
> +      cmd_prelink__ ?=
> +
>  # Linking
>  # ---------------------------------------------------------------------------
>  
> diff --git a/scripts/prelink-riscv.c b/scripts/prelink-riscv.c
> new file mode 100644
> index 000000000000..c185d3981ca1
> --- /dev/null
> +++ b/scripts/prelink-riscv.c
> @@ -0,0 +1,122 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2017 Andes Technology
> + * Chih-Mao Chen <cmchen at andestech.com>
> + *
> + * Statically process runtime relocations on RISC-V ELF images
> + * so that it can be directly executed when loaded at LMA
> + * without fixup. Both RV32 and RV64 are supported.
> + */
> +
> +#include <errno.h>
> +#include <stdbool.h>
> +#include <stdint.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +
> +#include <elf.h>
> +#include <fcntl.h>
> +#include <sys/mman.h>
> +#include <sys/stat.h>
> +#include <sys/types.h>
> +#include <unistd.h>
> +#include "compiler.h"
> +
> +#ifndef EM_RISCV
> +#define EM_RISCV 243
> +#endif
> +
> +#ifndef R_RISCV_32
> +#define R_RISCV_32 1
> +#endif
> +
> +#ifndef R_RISCV_64
> +#define R_RISCV_64 2
> +#endif
> +
> +#ifndef R_RISCV_RELATIVE
> +#define R_RISCV_RELATIVE 3
> +#endif
> +
> +const char *argv0;
> +
> +#define die(fmt, ...) \
> +	do { \
> +		fprintf(stderr, "%s: " fmt "\n", argv0, ## __VA_ARGS__); \
> +		exit(EXIT_FAILURE); \
> +	} while (0)
> +
> +#define PRELINK_BYTEORDER le
> +#define PRELINK_INC_BITS 32
> +#include "prelink-riscv.inc"
> +#undef PRELINK_BYTEORDER
> +#undef PRELINK_INC_BITS
> +
> +#define PRELINK_BYTEORDER le
> +#define PRELINK_INC_BITS 64
> +#include "prelink-riscv.inc"
> +#undef PRELINK_BYTEORDER
> +#undef PRELINK_INC_BITS
> +
> +#define PRELINK_BYTEORDER be
> +#define PRELINK_INC_BITS 32
> +#include "prelink-riscv.inc"
> +#undef PRELINK_BYTEORDER
> +#undef PRELINK_INC_BITS
> +
> +#define PRELINK_BYTEORDER be
> +#define PRELINK_INC_BITS 64
> +#include "prelink-riscv.inc"
> +#undef PRELINK_BYTEORDER
> +#undef PRELINK_INC_BITS
> +
> +int main(int argc, const char *const *argv)
> +{
> +	argv0 = argv[0];
> +
> +	if (argc < 2) {
> +		fprintf(stderr, "Usage: %s <u-boot>\n", argv0);
> +		exit(EXIT_FAILURE);
> +	}
> +
> +	int fd = open(argv[1], O_RDWR, 0);
> +
> +	if (fd < 0)
> +		die("Cannot open %s: %s", argv[1], strerror(errno));
> +
> +	struct stat st;
> +
> +	if (fstat(fd, &st) < 0)
> +		die("Cannot stat %s: %s", argv[1], strerror(errno));
> +
> +	void *data =
> +		mmap(0, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
> +
> +	if (data == MAP_FAILED)
> +		die("Cannot mmap %s: %s", argv[1], strerror(errno));
> +
> +	close(fd);
> +
> +	unsigned char *e_ident = (unsigned char *)data;
> +
> +	if (memcmp(e_ident, ELFMAG, SELFMAG) != 0)
> +		die("Invalid ELF file %s", argv[1]);
> +
> +	bool is64 = e_ident[EI_CLASS] == ELFCLASS64;
> +	bool isbe = e_ident[EI_DATA] == ELFDATA2MSB;
> +
> +	if (is64) {
> +		if (isbe)
> +			prelink_be64(data);
> +		else
> +			prelink_le64(data);
> +	} else {
> +		if (isbe)
> +			prelink_be32(data);
> +		else
> +			prelink_le32(data);
> +	}
> +
> +	return 0;
> +}
> diff --git a/scripts/prelink-riscv.inc b/scripts/prelink-riscv.inc
> new file mode 100644
> index 000000000000..f2b5467f5b3c
> --- /dev/null
> +++ b/scripts/prelink-riscv.inc
> @@ -0,0 +1,123 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2017 Andes Technology
> + * Chih-Mao Chen <cmchen at andestech.com>
> + *
> + * Statically process runtime relocations on RISC-V ELF images
> + * so that it can be directly executed when loaded at LMA
> + * without fixup. Both RV32 and RV64 are supported.
> + */
> +
> +#define CONCAT_IMPL(x, y) x##y
> +#define CONCAT(x, y) CONCAT_IMPL(x, y)
> +#define CONCAT3(x, y, z) CONCAT(CONCAT(x, y), z)
> +
> +#define prelink_bonn    CONCAT3(prelink_, PRELINK_BYTEORDER, PRELINK_INC_BITS)
> +#define uintnn_t        CONCAT3(uint, PRELINK_INC_BITS, _t)
> +#define get_offset_bonn CONCAT3(get_offset_, PRELINK_BYTEORDER, PRELINK_INC_BITS)
> +#define Elf_Ehdr        CONCAT3(Elf, PRELINK_INC_BITS, _Ehdr)
> +#define Elf_Phdr        CONCAT3(Elf, PRELINK_INC_BITS, _Phdr)
> +#define Elf_Rela        CONCAT3(Elf, PRELINK_INC_BITS, _Rela)
> +#define Elf_Sym         CONCAT3(Elf, PRELINK_INC_BITS, _Sym)
> +#define Elf_Dyn         CONCAT3(Elf, PRELINK_INC_BITS, _Dyn)
> +#define Elf_Addr        CONCAT3(Elf, PRELINK_INC_BITS, _Addr)
> +#define ELF_R_TYPE      CONCAT3(ELF, PRELINK_INC_BITS, _R_TYPE)
> +#define ELF_R_SYM       CONCAT3(ELF, PRELINK_INC_BITS, _R_SYM)
> +#define target16_to_cpu CONCAT(PRELINK_BYTEORDER, 16_to_cpu)
> +#define target32_to_cpu CONCAT(PRELINK_BYTEORDER, 32_to_cpu)
> +#define target64_to_cpu CONCAT(PRELINK_BYTEORDER, 64_to_cpu)
> +#define targetnn_to_cpu CONCAT3(PRELINK_BYTEORDER, PRELINK_INC_BITS, _to_cpu)
> +#define cpu_to_target32 CONCAT3(cpu_to_, PRELINK_BYTEORDER, 32)
> +#define cpu_to_target64 CONCAT3(cpu_to_, PRELINK_BYTEORDER, 64)
> +
> +static void* get_offset_bonn (void* data, Elf_Phdr* phdrs, size_t phnum, Elf_Addr addr)
> +{
> +	Elf_Phdr *p;
> +
> +	for (p = phdrs; p < phdrs + phnum; ++p)
> +		if (targetnn_to_cpu(p->p_vaddr) <= addr && targetnn_to_cpu(p->p_vaddr) + targetnn_to_cpu(p->p_memsz) > addr)
> +			return data + targetnn_to_cpu(p->p_offset) + (addr - targetnn_to_cpu(p->p_vaddr));
> +
> +	return NULL;
> +}
> +
> +static void prelink_bonn(void *data)
> +{
> +	Elf_Ehdr *ehdr = data;
> +	Elf_Phdr *p;
> +	Elf_Dyn *dyn;
> +	Elf_Rela *r;
> +
> +	if (target16_to_cpu(ehdr->e_machine) != EM_RISCV)
> +		die("Machine type is not RISC-V");
> +
> +	Elf_Phdr *phdrs = data + targetnn_to_cpu(ehdr->e_phoff);
> +
> +	Elf_Dyn *dyns = NULL;
> +	for (p = phdrs; p < phdrs + target16_to_cpu(ehdr->e_phnum); ++p) {
> +		if (target32_to_cpu(p->p_type) == PT_DYNAMIC) {
> +			dyns = data + targetnn_to_cpu(p->p_offset);
> +			break;
> +		}
> +	}
> +
> +	if (dyns == NULL)
> +		die("No dynamic section found");
> +
> +	Elf_Rela *rela_dyn = NULL;
> +	size_t rela_count = 0;
> +	Elf_Sym *dynsym = NULL;
> +	for (dyn = dyns;; ++dyn) {
> +		if (targetnn_to_cpu(dyn->d_tag) == DT_NULL)
> +			break;
> +		else if (targetnn_to_cpu(dyn->d_tag) == DT_RELA)
> +			rela_dyn = get_offset_bonn(data, phdrs, target16_to_cpu(ehdr->e_phnum), + targetnn_to_cpu(dyn->d_un.d_ptr));
> +		else if (targetnn_to_cpu(dyn->d_tag) == DT_RELASZ)
> +		  rela_count = targetnn_to_cpu(dyn->d_un.d_val) / sizeof(Elf_Rela);
> +		else if (targetnn_to_cpu(dyn->d_tag) == DT_SYMTAB)
> +			dynsym = get_offset_bonn(data, phdrs, target16_to_cpu(ehdr->e_phnum), + targetnn_to_cpu(dyn->d_un.d_ptr));
> +
> +	}
> +
> +	if (rela_dyn == NULL)
> +		die("No .rela.dyn found");
> +
> +	if (dynsym == NULL)
> +		die("No .dynsym found");
> +
> +	for (r = rela_dyn; r < rela_dyn + rela_count; ++r) {
> +		void* buf = get_offset_bonn(data, phdrs, target16_to_cpu(ehdr->e_phnum), targetnn_to_cpu(r->r_offset));
> +
> +		if (buf == NULL)
> +			continue;
> +
> +		if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_RELATIVE)
> +			*((uintnn_t*) buf) = r->r_addend;
> +		else if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_32)
> +			*((uint32_t*) buf) = cpu_to_target32(targetnn_to_cpu(dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value) + targetnn_to_cpu(r->r_addend));
> +		else if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_64)
> +			*((uint64_t*) buf) = cpu_to_target64(targetnn_to_cpu(dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value) + targetnn_to_cpu(r->r_addend));
> +	}
> +}
> +
> +#undef prelink_bonn
> +#undef uintnn_t
> +#undef get_offset_bonn
> +#undef Elf_Ehdr
> +#undef Elf_Phdr
> +#undef Elf_Rela
> +#undef Elf_Sym
> +#undef Elf_Dyn
> +#undef Elf_Addr
> +#undef ELF_R_TYPE
> +#undef ELF_R_SYM
> +#undef target16_to_cpu
> +#undef target32_to_cpu
> +#undef target64_to_cpu
> +#undef targetnn_to_cpu
> +#undef cpu_to_target32
> +#undef cpu_to_target64
> +
> +#undef CONCAT_IMPL
> +#undef CONCAT
> +#undef CONCAT3
> 

-- 
Pengutronix e.K.                           |                             |
Steuerwalder Str. 21                       | http://www.pengutronix.de/  |
31137 Hildesheim, Germany                  | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |



More information about the barebox mailing list