target_os_elf.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * openbsd ELF definitions
  3. *
  4. * Copyright (c) 2013 Stacey D. Son
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #ifndef TARGET_OS_ELF_H
  20. #define TARGET_OS_ELF_H
  21. #include "target_arch_elf.h"
  22. #include "elf.h"
  23. #include "user/tswap-target.h"
  24. /* this flag is uneffective under linux too, should be deleted */
  25. #ifndef MAP_DENYWRITE
  26. #define MAP_DENYWRITE 0
  27. #endif
  28. /* should probably go in elf.h */
  29. #ifndef ELIBBAD
  30. #define ELIBBAD 80
  31. #endif
  32. #ifndef ELF_PLATFORM
  33. #define ELF_PLATFORM (NULL)
  34. #endif
  35. #ifndef ELF_HWCAP
  36. #define ELF_HWCAP 0
  37. #endif
  38. #ifdef TARGET_ABI32
  39. #undef ELF_CLASS
  40. #define ELF_CLASS ELFCLASS32
  41. #undef bswaptls
  42. #define bswaptls(ptr) bswap32s(ptr)
  43. #endif
  44. /* max code+data+bss space allocated to elf interpreter */
  45. #define INTERP_MAP_SIZE (32 * 1024 * 1024)
  46. /* max code+data+bss+brk space allocated to ET_DYN executables */
  47. #define ET_DYN_MAP_SIZE (128 * 1024 * 1024)
  48. /* Necessary parameters */
  49. #define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE
  50. #define TARGET_ELF_PAGESTART(_v) ((_v) & \
  51. ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE - 1))
  52. #define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE - 1))
  53. #define DLINFO_ITEMS 12
  54. static abi_ulong target_create_elf_tables(abi_ulong p, int argc, int envc,
  55. abi_ulong stringp,
  56. struct elfhdr *exec,
  57. abi_ulong load_addr,
  58. abi_ulong load_bias,
  59. abi_ulong interp_load_addr,
  60. struct image_info *info)
  61. {
  62. abi_ulong sp;
  63. int size;
  64. abi_ulong u_platform;
  65. const char *k_platform;
  66. const int n = sizeof(elf_addr_t);
  67. sp = p;
  68. u_platform = 0;
  69. k_platform = ELF_PLATFORM;
  70. if (k_platform) {
  71. size_t len = strlen(k_platform) + 1;
  72. sp -= (len + n - 1) & ~(n - 1);
  73. u_platform = sp;
  74. /* FIXME - check return value of memcpy_to_target() for failure */
  75. memcpy_to_target(sp, k_platform, len);
  76. }
  77. /*
  78. * Force 16 byte _final_ alignment here for generality.
  79. */
  80. sp = sp & ~(abi_ulong)15;
  81. size = (DLINFO_ITEMS + 1) * 2;
  82. if (k_platform) {
  83. size += 2;
  84. }
  85. #ifdef DLINFO_ARCH_ITEMS
  86. size += DLINFO_ARCH_ITEMS * 2;
  87. #endif
  88. size += envc + argc + 2;
  89. size += 1; /* argc itself */
  90. size *= n;
  91. if (size & 15) {
  92. sp -= 16 - (size & 15);
  93. }
  94. /*
  95. * OpenBSD defines elf_addr_t as Elf32_Off / Elf64_Off
  96. */
  97. #define NEW_AUX_ENT(id, val) do { \
  98. sp -= n; put_user_ual(val, sp); \
  99. sp -= n; put_user_ual(id, sp); \
  100. } while (0)
  101. NEW_AUX_ENT(AT_NULL, 0);
  102. /* There must be exactly DLINFO_ITEMS entries here. */
  103. NEW_AUX_ENT(AT_PHDR, (abi_ulong)(load_addr + exec->e_phoff));
  104. NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof(struct elf_phdr)));
  105. NEW_AUX_ENT(AT_PHNUM, (abi_ulong)(exec->e_phnum));
  106. NEW_AUX_ENT(AT_PAGESZ, (abi_ulong)(TARGET_PAGE_SIZE));
  107. NEW_AUX_ENT(AT_BASE, (abi_ulong)(interp_load_addr));
  108. NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0);
  109. NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry);
  110. NEW_AUX_ENT(AT_UID, (abi_ulong)getuid());
  111. NEW_AUX_ENT(AT_EUID, (abi_ulong)geteuid());
  112. NEW_AUX_ENT(AT_GID, (abi_ulong)getgid());
  113. NEW_AUX_ENT(AT_EGID, (abi_ulong)getegid());
  114. NEW_AUX_ENT(AT_HWCAP, (abi_ulong)ELF_HWCAP);
  115. NEW_AUX_ENT(AT_CLKTCK, (abi_ulong)sysconf(_SC_CLK_TCK));
  116. if (k_platform) {
  117. NEW_AUX_ENT(AT_PLATFORM, u_platform);
  118. }
  119. #ifdef ARCH_DLINFO
  120. /*
  121. * ARCH_DLINFO must come last so platform specific code can enforce
  122. * special alignment requirements on the AUXV if necessary (eg. PPC).
  123. */
  124. ARCH_DLINFO;
  125. #endif
  126. #undef NEW_AUX_ENT
  127. sp = loader_build_argptr(envc, argc, sp, stringp);
  128. return sp;
  129. }
  130. #endif /* TARGET_OS_ELF_H */