machine_kexec_reloc.c 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/elf.h>
  3. #include <asm/kexec.h>
  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. case R_390_GLOB_DAT:
  30. case R_390_JMP_SLOT:
  31. *(u64 *)loc = val;
  32. break;
  33. case R_390_PC16: /* PC relative 16 bit. */
  34. *(u16 *)loc = (val - addr);
  35. break;
  36. case R_390_PC16DBL: /* PC relative 16 bit shifted by 1. */
  37. *(u16 *)loc = (val - addr) >> 1;
  38. break;
  39. case R_390_PC32DBL: /* PC relative 32 bit shifted by 1. */
  40. *(u32 *)loc = (val - addr) >> 1;
  41. break;
  42. case R_390_PC32: /* PC relative 32 bit. */
  43. *(u32 *)loc = (val - addr);
  44. break;
  45. case R_390_PC64: /* PC relative 64 bit. */
  46. *(u64 *)loc = (val - addr);
  47. break;
  48. case R_390_RELATIVE:
  49. *(unsigned long *) loc = val;
  50. break;
  51. default:
  52. return 1;
  53. }
  54. return 0;
  55. }