0001
0002 #include <linux/elf.h>
0003 #include <asm/kexec.h>
0004
0005 int arch_kexec_do_relocs(int r_type, void *loc, unsigned long val,
0006 unsigned long addr)
0007 {
0008 switch (r_type) {
0009 case R_390_NONE:
0010 break;
0011 case R_390_8:
0012 *(u8 *)loc = val;
0013 break;
0014 case R_390_12:
0015 *(u16 *)loc &= 0xf000;
0016 *(u16 *)loc |= val & 0xfff;
0017 break;
0018 case R_390_16:
0019 *(u16 *)loc = val;
0020 break;
0021 case R_390_20:
0022 *(u32 *)loc &= 0xf00000ff;
0023 *(u32 *)loc |= (val & 0xfff) << 16;
0024 *(u32 *)loc |= (val & 0xff000) >> 4;
0025 break;
0026 case R_390_32:
0027 *(u32 *)loc = val;
0028 break;
0029 case R_390_64:
0030 case R_390_GLOB_DAT:
0031 case R_390_JMP_SLOT:
0032 *(u64 *)loc = val;
0033 break;
0034 case R_390_PC16:
0035 *(u16 *)loc = (val - addr);
0036 break;
0037 case R_390_PC16DBL:
0038 *(u16 *)loc = (val - addr) >> 1;
0039 break;
0040 case R_390_PC32DBL:
0041 *(u32 *)loc = (val - addr) >> 1;
0042 break;
0043 case R_390_PC32:
0044 *(u32 *)loc = (val - addr);
0045 break;
0046 case R_390_PC64:
0047 *(u64 *)loc = (val - addr);
0048 break;
0049 case R_390_RELATIVE:
0050 *(unsigned long *) loc = val;
0051 break;
0052 default:
0053 return 1;
0054 }
0055 return 0;
0056 }