]>
git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arc/lib/relocate.c
2 * Copyright (C) 2013-2014 Synopsys, Inc. All rights reserved.
4 * SPDX-License-Identifier: GPL-2.0+
9 #include <asm/sections.h>
11 DECLARE_GLOBAL_DATA_PTR
;
14 * Base functionality is taken from x86 version with added ARC-specifics
16 int do_elf_reloc_fixups(void)
18 Elf32_Rela
*re_src
= (Elf32_Rela
*)(&__rel_dyn_start
);
19 Elf32_Rela
*re_end
= (Elf32_Rela
*)(&__rel_dyn_end
);
21 Elf32_Addr
*offset_ptr_rom
, *last_offset
= NULL
;
22 Elf32_Addr
*offset_ptr_ram
;
25 /* Get the location from the relocation entry */
26 offset_ptr_rom
= (Elf32_Addr
*)re_src
->r_offset
;
28 /* Check that the location of the relocation is in .text */
29 if (offset_ptr_rom
>= (Elf32_Addr
*)CONFIG_SYS_TEXT_BASE
&&
30 offset_ptr_rom
> last_offset
) {
32 /* Switch to the in-RAM version */
33 offset_ptr_ram
= (Elf32_Addr
*)((ulong
)offset_ptr_rom
+
37 * Use "memcpy" because target location might be
38 * 16-bit aligned on ARC so we may need to read
39 * byte-by-byte. On attempt to read entire word by
40 * CPU throws an exception
42 memcpy(&val
, offset_ptr_ram
, sizeof(int));
44 #ifdef __LITTLE_ENDIAN__
45 /* If location in ".text" section swap value */
46 if ((unsigned int)offset_ptr_rom
<
47 (unsigned int)&__text_end
)
48 val
= (val
<< 16) | (val
>> 16);
51 /* Check that the target points into .text */
52 if (val
>= CONFIG_SYS_TEXT_BASE
&& val
<=
53 (unsigned int)&__bss_end
) {
55 #ifdef __LITTLE_ENDIAN__
56 /* If location in ".text" section swap value */
57 if ((unsigned int)offset_ptr_rom
<
58 (unsigned int)&__text_end
)
59 val
= (val
<< 16) | (val
>> 16);
61 memcpy(offset_ptr_ram
, &val
, sizeof(int));
63 debug(" %p: rom reloc %x, ram %p, value %x, limit %x\n",
64 re_src
, re_src
->r_offset
, offset_ptr_ram
,
65 val
, (unsigned int)&__bss_end
);
68 debug(" %p: rom reloc %x, last %p\n", re_src
,
69 re_src
->r_offset
, last_offset
);
71 last_offset
= offset_ptr_rom
;
73 } while (++re_src
< re_end
);