elf_aux.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * arch/um/kernel/elf_aux.c
  4. *
  5. * Scan the ELF auxiliary vector provided by the host to extract
  6. * information about vsyscall-page, etc.
  7. *
  8. * Copyright (C) 2004 Fujitsu Siemens Computers GmbH
  9. * Author: Bodo Stroesser (bodo.stroesser@fujitsu-siemens.com)
  10. */
  11. #include <elf.h>
  12. #include <stddef.h>
  13. #include <init.h>
  14. #include <elf_user.h>
  15. #include <mem_user.h>
  16. #include "internal.h"
  17. typedef Elf32_auxv_t elf_auxv_t;
  18. /* These are initialized very early in boot and never changed */
  19. char * elf_aux_platform;
  20. extern long elf_aux_hwcap;
  21. unsigned long vsyscall_ehdr;
  22. unsigned long vsyscall_end;
  23. unsigned long __kernel_vsyscall;
  24. __init void scan_elf_aux( char **envp)
  25. {
  26. long page_size = 0;
  27. elf_auxv_t * auxv;
  28. while ( *envp++ != NULL) ;
  29. for ( auxv = (elf_auxv_t *)envp; auxv->a_type != AT_NULL; auxv++) {
  30. switch ( auxv->a_type ) {
  31. case AT_SYSINFO:
  32. __kernel_vsyscall = auxv->a_un.a_val;
  33. /* See if the page is under TASK_SIZE */
  34. if (__kernel_vsyscall < (unsigned long) envp)
  35. __kernel_vsyscall = 0;
  36. break;
  37. case AT_SYSINFO_EHDR:
  38. vsyscall_ehdr = auxv->a_un.a_val;
  39. /* See if the page is under TASK_SIZE */
  40. if (vsyscall_ehdr < (unsigned long) envp)
  41. vsyscall_ehdr = 0;
  42. break;
  43. case AT_HWCAP:
  44. elf_aux_hwcap = auxv->a_un.a_val;
  45. break;
  46. case AT_PLATFORM:
  47. /* elf.h removed the pointer elements from
  48. * a_un, so we have to use a_val, which is
  49. * all that's left.
  50. */
  51. elf_aux_platform =
  52. (char *) (long) auxv->a_un.a_val;
  53. break;
  54. case AT_PAGESZ:
  55. page_size = auxv->a_un.a_val;
  56. break;
  57. }
  58. }
  59. if ( ! __kernel_vsyscall || ! vsyscall_ehdr ||
  60. ! elf_aux_hwcap || ! elf_aux_platform ||
  61. ! page_size || (vsyscall_ehdr % page_size) ) {
  62. __kernel_vsyscall = 0;
  63. vsyscall_ehdr = 0;
  64. elf_aux_hwcap = 0;
  65. elf_aux_platform = "i586";
  66. }
  67. else {
  68. vsyscall_end = vsyscall_ehdr + page_size;
  69. }
  70. }