1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/elf.h> 3 4 int arch_kexec_do_relocs(int r_type, void *loc, unsigned long val, 5 unsigned long addr) 6 { 7 switch (r_type) { 8 case R_390_NONE: 9 break; 10 case R_390_8: /* Direct 8 bit. */ 11 *(u8 *)loc = val; 12 break; 13 case R_390_12: /* Direct 12 bit. */ 14 *(u16 *)loc &= 0xf000; 15 *(u16 *)loc |= val & 0xfff; 16 break; 17 case R_390_16: /* Direct 16 bit. */ 18 *(u16 *)loc = val; 19 break; 20 case R_390_20: /* Direct 20 bit. */ 21 *(u32 *)loc &= 0xf00000ff; 22 *(u32 *)loc |= (val & 0xfff) << 16; /* DL */ 23 *(u32 *)loc |= (val & 0xff000) >> 4; /* DH */ 24 break; 25 case R_390_32: /* Direct 32 bit. */ 26 *(u32 *)loc = val; 27 break; 28 case R_390_64: /* Direct 64 bit. */ 29 *(u64 *)loc = val; 30 break; 31 case R_390_PC16: /* PC relative 16 bit. */ 32 *(u16 *)loc = (val - addr); 33 break; 34 case R_390_PC16DBL: /* PC relative 16 bit shifted by 1. */ 35 *(u16 *)loc = (val - addr) >> 1; 36 break; 37 case R_390_PC32DBL: /* PC relative 32 bit shifted by 1. */ 38 *(u32 *)loc = (val - addr) >> 1; 39 break; 40 case R_390_PC32: /* PC relative 32 bit. */ 41 *(u32 *)loc = (val - addr); 42 break; 43 case R_390_PC64: /* PC relative 64 bit. */ 44 *(u64 *)loc = (val - addr); 45 break; 46 case R_390_RELATIVE: 47 *(unsigned long *) loc = val; 48 break; 49 default: 50 return 1; 51 } 52 return 0; 53 } 54