Skip to content

Commit d73d280

Browse files
pavelvkozlovabrodkin
authored andcommitted
ARC: add new disp25 reloc
Add the R_ARC_S25H_PCREL relocation to the list of known and resolve this relocation. Replacement of jump instructions (j) to branches (b) in the .fixup section (commit 955b7c7) cause to appearance of the new relocation type R_ARC_S25H_PCREL, which can be added by the compiler to handle relative offsets in kernel modules. Fixes: 955b7c7 (ARCv3: link above 4GB: handle 64-bit literals in final link) Signed-off-by: Pavel Kozlov <pavel.kozlov@synopsys.com>
1 parent 8d25135 commit d73d280

File tree

2 files changed

+17
-0
lines changed

2 files changed

+17
-0
lines changed

arch/arc/include/asm/elf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ int elf_check_arch(const struct elf32_hdr *x);
4848
/* ARC Relocations (kernel Modules only) */
4949
#define R_ARC_32 0x4
5050
#define R_ARC_64 0x5
51+
#define R_ARC_S25H_PCREL 0x10
5152
#define R_ARC_32_ME 0x1B
5253
#define R_ARC_32_PCREL 0x31
5354
#define R_ARC_LO32_ME 0x5c

arch/arc/kernel/module.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,19 @@ static inline void arc_write_me(unsigned short *addr, unsigned long value)
1919
*(addr + 1) = (value & 0xffff);
2020
}
2121

22+
static inline void arc_write_disp25h(unsigned short *addr, unsigned long value)
23+
{
24+
unsigned short ins = *addr & ~0x7fe;
25+
26+
ins |= (value & 0x03ff) << 1;
27+
*addr = ins;
28+
29+
ins = *(addr + 1) & ~0xffcf;
30+
ins |= ((value >> 10) & 0x03ff) << 6;
31+
ins |= ((value >> 20) & 0x000f) << 0;
32+
*(addr + 1) = ins;
33+
}
34+
2235
/*
2336
* This gets called before relocation loop in generic loader
2437
* Make a note of the section index of unwinding section
@@ -105,6 +118,9 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
105118
*((Elf_Addr *) location) = relocation;
106119
else if (R_ARC_32_PCREL == relo_type) /* ( S + A ) - PDATA ) */
107120
*((Elf_Addr *) location) = relocation - location;
121+
else if (R_ARC_S25H_PCREL == relo_type) /* ( S + A ) - PDATA ) >> 1 */
122+
arc_write_disp25h((unsigned short *)location,
123+
(relocation - location) >> 1);
108124
#ifdef CONFIG_64BIT
109125
else if (R_ARC_64 == relo_type) /* ( S + A ) */
110126
*((Elf_Addr *) location) = relocation;

0 commit comments

Comments
 (0)