elf.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/export.h>
  3. #include <linux/sched.h>
  4. #include <linux/personality.h>
  5. #include <linux/binfmts.h>
  6. #include <linux/elf.h>
  7. #include <linux/elf-fdpic.h>
  8. #include <asm/system_info.h>
  9. int elf_check_arch(const struct elf32_hdr *x)
  10. {
  11. unsigned int eflags;
  12. /* Make sure it's an ARM executable */
  13. if (x->e_machine != EM_ARM)
  14. return 0;
  15. /* Make sure the entry address is reasonable */
  16. if (x->e_entry & 1) {
  17. if (!(elf_hwcap & HWCAP_THUMB))
  18. return 0;
  19. } else if (x->e_entry & 3)
  20. return 0;
  21. eflags = x->e_flags;
  22. if ((eflags & EF_ARM_EABI_MASK) == EF_ARM_EABI_UNKNOWN) {
  23. unsigned int flt_fmt;
  24. /* APCS26 is only allowed if the CPU supports it */
  25. if ((eflags & EF_ARM_APCS_26) && !(elf_hwcap & HWCAP_26BIT))
  26. return 0;
  27. flt_fmt = eflags & (EF_ARM_VFP_FLOAT | EF_ARM_SOFT_FLOAT);
  28. /* VFP requires the supporting code */
  29. if (flt_fmt == EF_ARM_VFP_FLOAT && !(elf_hwcap & HWCAP_VFP))
  30. return 0;
  31. }
  32. return 1;
  33. }
  34. EXPORT_SYMBOL(elf_check_arch);
  35. void elf_set_personality(const struct elf32_hdr *x)
  36. {
  37. unsigned int eflags = x->e_flags;
  38. unsigned int personality = current->personality & ~PER_MASK;
  39. /*
  40. * We only support Linux ELF executables, so always set the
  41. * personality to LINUX.
  42. */
  43. personality |= PER_LINUX;
  44. /*
  45. * APCS-26 is only valid for OABI executables
  46. */
  47. if ((eflags & EF_ARM_EABI_MASK) == EF_ARM_EABI_UNKNOWN &&
  48. (eflags & EF_ARM_APCS_26))
  49. personality &= ~ADDR_LIMIT_32BIT;
  50. else
  51. personality |= ADDR_LIMIT_32BIT;
  52. set_personality(personality);
  53. /*
  54. * Since the FPA coprocessor uses CP1 and CP2, and iWMMXt uses CP0
  55. * and CP1, we only enable access to the iWMMXt coprocessor if the
  56. * binary is EABI or softfloat (and thus, guaranteed not to use
  57. * FPA instructions.)
  58. */
  59. if (elf_hwcap & HWCAP_IWMMXT &&
  60. eflags & (EF_ARM_EABI_MASK | EF_ARM_SOFT_FLOAT)) {
  61. set_thread_flag(TIF_USING_IWMMXT);
  62. } else {
  63. clear_thread_flag(TIF_USING_IWMMXT);
  64. }
  65. }
  66. EXPORT_SYMBOL(elf_set_personality);
  67. /*
  68. * Set READ_IMPLIES_EXEC if:
  69. * - the binary requires an executable stack
  70. * - we're running on a CPU which doesn't support NX.
  71. */
  72. int arm_elf_read_implies_exec(int executable_stack)
  73. {
  74. if (executable_stack != EXSTACK_DISABLE_X)
  75. return 1;
  76. if (cpu_architecture() < CPU_ARCH_ARMv6)
  77. return 1;
  78. return 0;
  79. }
  80. EXPORT_SYMBOL(arm_elf_read_implies_exec);
  81. #if defined(CONFIG_MMU) && defined(CONFIG_BINFMT_ELF_FDPIC)
  82. void elf_fdpic_arch_lay_out_mm(struct elf_fdpic_params *exec_params,
  83. struct elf_fdpic_params *interp_params,
  84. unsigned long *start_stack,
  85. unsigned long *start_brk)
  86. {
  87. elf_set_personality(&exec_params->hdr);
  88. exec_params->load_addr = 0x8000;
  89. interp_params->load_addr = ELF_ET_DYN_BASE;
  90. *start_stack = TASK_SIZE - SZ_16M;
  91. if ((exec_params->flags & ELF_FDPIC_FLAG_ARRANGEMENT) == ELF_FDPIC_FLAG_INDEPENDENT) {
  92. exec_params->flags &= ~ELF_FDPIC_FLAG_ARRANGEMENT;
  93. exec_params->flags |= ELF_FDPIC_FLAG_CONSTDISP;
  94. }
  95. }
  96. #endif