zend_elf.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Zend JIT |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | https://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Dmitry Stogov <dmitry@php.net> |
  16. | Xinchen Hui <laruence@php.net> |
  17. +----------------------------------------------------------------------+
  18. */
  19. #include <sys/types.h>
  20. #include <sys/stat.h>
  21. #if defined(__FreeBSD__) || defined(__DragonFly__)
  22. #include <sys/sysctl.h>
  23. #elif defined(__HAIKU__)
  24. #include <FindDirectory.h>
  25. #endif
  26. #include <fcntl.h>
  27. #include <unistd.h>
  28. #include "zend_API.h"
  29. #include "zend_elf.h"
  30. static void* zend_elf_read_sect(int fd, zend_elf_sectheader *sect)
  31. {
  32. void *s = emalloc(sect->size);
  33. if (lseek(fd, sect->ofs, SEEK_SET) < 0) {
  34. efree(s);
  35. return NULL;
  36. }
  37. if (read(fd, s, sect->size) != (ssize_t)sect->size) {
  38. efree(s);
  39. return NULL;
  40. }
  41. return s;
  42. }
  43. void zend_elf_load_symbols(void)
  44. {
  45. zend_elf_header hdr;
  46. zend_elf_sectheader sect;
  47. int i;
  48. #if defined(__linux__)
  49. int fd = open("/proc/self/exe", O_RDONLY);
  50. #elif defined(__NetBSD__)
  51. int fd = open("/proc/curproc/exe", O_RDONLY);
  52. #elif defined(__FreeBSD__) || defined(__DragonFly__)
  53. char path[PATH_MAX];
  54. size_t pathlen = sizeof(path);
  55. int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1};
  56. if (sysctl(mib, 4, path, &pathlen, NULL, 0) == -1) {
  57. return;
  58. }
  59. int fd = open(path, O_RDONLY);
  60. #elif defined(__sun)
  61. int fd = open("/proc/self/path/a.out", O_RDONLY);
  62. #elif defined(__HAIKU__)
  63. char path[PATH_MAX];
  64. if (find_path(B_APP_IMAGE_SYMBOL, B_FIND_PATH_IMAGE_PATH,
  65. NULL, path, sizeof(path)) != B_OK) {
  66. return;
  67. }
  68. int fd = open(path, O_RDONLY);
  69. #else
  70. // To complete eventually for other ELF platforms.
  71. // Otherwise APPLE is Mach-O
  72. int fd = -1;
  73. #endif
  74. if (fd >= 0) {
  75. if (read(fd, &hdr, sizeof(hdr)) == sizeof(hdr)
  76. && hdr.emagic[0] == '\177'
  77. && hdr.emagic[1] == 'E'
  78. && hdr.emagic[2] == 'L'
  79. && hdr.emagic[3] == 'F'
  80. && lseek(fd, hdr.shofs, SEEK_SET) >= 0) {
  81. for (i = 0; i < hdr.shnum; i++) {
  82. if (read(fd, &sect, sizeof(sect)) == sizeof(sect)
  83. && sect.type == ELFSECT_TYPE_SYMTAB) {
  84. uint32_t n, count = sect.size / sizeof(zend_elf_symbol);
  85. zend_elf_symbol *syms = zend_elf_read_sect(fd, &sect);
  86. char *str_tbl;
  87. if (syms) {
  88. if (lseek(fd, hdr.shofs + sect.link * sizeof(sect), SEEK_SET) >= 0
  89. && read(fd, &sect, sizeof(sect)) == sizeof(sect)
  90. && (str_tbl = (char*)zend_elf_read_sect(fd, &sect)) != NULL) {
  91. for (n = 0; n < count; n++) {
  92. if (syms[n].name
  93. && (ELFSYM_TYPE(syms[n].info) == ELFSYM_TYPE_FUNC
  94. /*|| ELFSYM_TYPE(syms[n].info) == ELFSYM_TYPE_DATA*/)
  95. && (ELFSYM_BIND(syms[n].info) == ELFSYM_BIND_LOCAL
  96. /*|| ELFSYM_BIND(syms[n].info) == ELFSYM_BIND_GLOBAL*/)) {
  97. zend_jit_disasm_add_symbol(str_tbl + syms[n].name, syms[n].value, syms[n].size);
  98. }
  99. }
  100. efree(str_tbl);
  101. }
  102. efree(syms);
  103. }
  104. if (lseek(fd, hdr.shofs + (i + 1) * sizeof(sect), SEEK_SET) < 0) {
  105. break;
  106. }
  107. }
  108. }
  109. }
  110. close(fd);
  111. }
  112. }