/tools/jprof/elf.cpp

http://github.com/zpao/v8monkey · C++ · 164 lines · 112 code · 12 blank · 40 comment · 25 complexity · 986f4ce126c906ab1a000127ea1f9d4e MD5 · raw file

  1. /* ***** BEGIN LICENSE BLOCK *****
  2. * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3. *
  4. * The contents of this file are subject to the Mozilla Public License Version
  5. * 1.1 (the "License"); you may not use this file except in compliance with
  6. * the License. You may obtain a copy of the License at
  7. * http://www.mozilla.org/MPL/
  8. *
  9. * Software distributed under the License is distributed on an "AS IS" basis,
  10. * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11. * for the specific language governing rights and limitations under the
  12. * License.
  13. *
  14. * The Original Code is mozilla.org code.
  15. *
  16. * The Initial Developer of the Original Code is Netscape Communications Corp.
  17. * Portions created by the Initial Developer are Copyright (C) 1998
  18. * the Initial Developer. All Rights Reserved.
  19. *
  20. * Contributor(s):
  21. *
  22. * Alternatively, the contents of this file may be used under the terms of
  23. * either the GNU General Public License Version 2 or later (the "GPL"), or
  24. * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  25. * in which case the provisions of the GPL or the LGPL are applicable instead
  26. * of those above. If you wish to allow use of your version of this file only
  27. * under the terms of either the GPL or the LGPL, and not to allow others to
  28. * use your version of this file under the terms of the MPL, indicate your
  29. * decision by deleting the provisions above and replace them with the notice
  30. * and other provisions required by the GPL or the LGPL. If you do not delete
  31. * the provisions above, a recipient may use your version of this file under
  32. * the terms of any one of the MPL, the GPL or the LGPL.
  33. *
  34. * ***** END LICENSE BLOCK ***** */
  35. #include "leaky.h"
  36. #ifdef USE_ELF
  37. #include "leaky.h"
  38. #include <stdio.h>
  39. #include <malloc.h>
  40. #include <libelf/libelf.h>
  41. #include <unistd.h>
  42. #include <fcntl.h>
  43. #include <string.h>
  44. void leaky::readSymbols(const char *fileName)
  45. {
  46. int fd = ::open(fileName, O_RDONLY);
  47. if (fd < 0) {
  48. fprintf(stderr, "%s: unable to open \"%s\"\n", applicationName,
  49. fileName);
  50. exit(-1);
  51. }
  52. elf_version(EV_CURRENT);
  53. Elf *elf = elf_begin(fd, ELF_C_READ, 0);
  54. if (!elf) {
  55. fprintf(stderr, "%s: \"%s\": has no symbol table\n", applicationName,
  56. fileName);
  57. exit(-1);
  58. }
  59. long alloced = 10000;
  60. Symbol* syms = (Symbol*) malloc(sizeof(Symbol) * 10000);
  61. Symbol* sp = syms;
  62. Symbol* last = syms + alloced;
  63. // Get each of the relevant sections and add them to the list of
  64. // symbols.
  65. Elf32_Ehdr *ehdr = elf32_getehdr(elf);
  66. if (!ehdr) {
  67. fprintf(stderr, "%s: elf library lossage\n", applicationName);
  68. exit(-1);
  69. }
  70. #if 0
  71. Elf32_Half ndx = ehdr->e_shstrndx;
  72. #endif
  73. Elf_Scn *scn = 0;
  74. int strtabndx = -1;
  75. for (int i = 1; (scn = elf_nextscn(elf, scn)) != 0; i++) {
  76. Elf32_Shdr *shdr = elf32_getshdr(scn);
  77. #if 0
  78. char *name = elf_strptr(elf, ndx, (size_t) shdr->sh_name);
  79. printf("Section %s (%d 0x%x)\n", name ? name : "(null)",
  80. shdr->sh_type, shdr->sh_type);
  81. #endif
  82. if (shdr->sh_type == SHT_STRTAB) {
  83. /* We assume here that string tables preceed symbol tables... */
  84. strtabndx = i;
  85. continue;
  86. }
  87. #if 0
  88. if (shdr->sh_type == SHT_DYNAMIC) {
  89. /* Dynamic */
  90. Elf_Data *data = elf_getdata(scn, 0);
  91. if (!data || !data->d_size) {
  92. printf("No data...");
  93. continue;
  94. }
  95. Elf32_Dyn *dyn = (Elf32_Dyn*) data->d_buf;
  96. Elf32_Dyn *lastdyn =
  97. (Elf32_Dyn*) ((char*) data->d_buf + data->d_size);
  98. for (; dyn < lastdyn; dyn++) {
  99. printf("tag=%d value=0x%x\n", dyn->d_tag, dyn->d_un.d_val);
  100. }
  101. } else
  102. #endif
  103. if ((shdr->sh_type == SHT_SYMTAB) ||
  104. (shdr->sh_type == SHT_DYNSYM)) {
  105. /* Symbol table */
  106. Elf_Data *data = elf_getdata(scn, 0);
  107. if (!data || !data->d_size) {
  108. printf("No data...");
  109. continue;
  110. }
  111. /* In theory we now have the symbols... */
  112. Elf32_Sym *esym = (Elf32_Sym*) data->d_buf;
  113. Elf32_Sym *lastsym =
  114. (Elf32_Sym*) ((char*) data->d_buf + data->d_size);
  115. for (; esym < lastsym; esym++) {
  116. #if 0
  117. char *nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name);
  118. printf("%20s 0x%08x %02x %02x\n",
  119. nm, esym->st_value, ELF32_ST_BIND(esym->st_info),
  120. ELF32_ST_TYPE(esym->st_info));
  121. #endif
  122. if ((esym->st_value == 0) ||
  123. (ELF32_ST_BIND(esym->st_info) == STB_WEAK) ||
  124. (ELF32_ST_BIND(esym->st_info) == STB_NUM) ||
  125. (ELF32_ST_TYPE(esym->st_info) != STT_FUNC)) {
  126. continue;
  127. }
  128. #if 1
  129. char *nm = elf_strptr(elf, strtabndx, (size_t)esym->st_name);
  130. #endif
  131. sp->name = nm ? strdup(nm) : "(no name)";
  132. sp->address = esym->st_value;
  133. sp++;
  134. if (sp >= last) {
  135. long n = alloced + 10000;
  136. syms = (Symbol*)
  137. realloc(syms, (size_t) (sizeof(Symbol) * n));
  138. last = syms + n;
  139. sp = syms + alloced;
  140. alloced = n;
  141. }
  142. }
  143. }
  144. }
  145. int interesting = sp - syms;
  146. if (!quiet) {
  147. printf("Total of %d symbols\n", interesting);
  148. }
  149. usefulSymbols = interesting;
  150. externalSymbols = syms;
  151. }
  152. #endif /* USE_ELF */