viewcore.c 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464
  1. /** BEGIN COPYRIGHT BLOCK
  2. * Copyright 2001 Sun Microsystems, Inc.
  3. * Portions copyright 1999, 2001-2003 Netscape Communications Corporation.
  4. * All rights reserved.
  5. * END COPYRIGHT BLOCK **/
  6. #include <fcntl.h>
  7. #include <stdio.h>
  8. #ifdef linux
  9. #include <elf.h>
  10. #include <libelf/libelf.h>
  11. #else
  12. #if defined(__osf__)
  13. #include <elf_abi.h>
  14. #else
  15. #ifndef _AIX
  16. #include <libelf.h>
  17. #endif
  18. #endif
  19. #endif
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <ctype.h>
  23. #if defined(sparc) || defined(__sparc)
  24. #include <sys/elf_SPARC.h>
  25. #else
  26. #if !defined(linux) && !defined(_AIX) && !defined(__osf__)
  27. #include <sys/elf_386.h>
  28. #endif
  29. #endif
  30. char *reldate = "23-APR-2002";
  31. char *ofname = NULL;
  32. FILE *of = NULL;
  33. static void failure(char *s);
  34. struct segment {
  35. char *vaddr;
  36. int len;
  37. char *physaddr;
  38. };
  39. struct segment segments[65536];
  40. int segment_max;
  41. char *modes[8] = { "---", "--X", "-W-", "-WX", "R--", "R-X", "RW-", "RWX" };
  42. char *erf;
  43. char *erf2;
  44. char *find_string(char *addr,int l)
  45. {
  46. int i,off,j;
  47. char *np;
  48. for (i = 0; i < segment_max;i++) {
  49. if (addr >= segments[i].vaddr &&
  50. addr <= (segments[i].vaddr + segments[i].len)) {
  51. off = addr - segments[i].vaddr;
  52. np = segments[i].physaddr + off;
  53. for (j = 0; j < 256; j++) {
  54. if (np[j] == '\0') {
  55. return np;
  56. }
  57. if (!isascii(np[j])) {
  58. break;
  59. }
  60. }
  61. if (l) {
  62. return("<bad pointer>");
  63. }
  64. return NULL;
  65. }
  66. }
  67. if (l) {
  68. return "<out of segment>";
  69. }
  70. return NULL;
  71. }
  72. struct iii_msgarray {
  73. unsigned int magic1;
  74. unsigned int magic2;
  75. unsigned int pos;
  76. unsigned int magic4;
  77. void *pointers[128][5];
  78. } iii_msgarray;
  79. void view_debug(char *cp)
  80. {
  81. int i;
  82. char *s;
  83. char *s2;
  84. struct iii_msgarray *p = (struct iii_msgarray *)cp;
  85. for (i = 0; i < 128; i++) {
  86. int dl;
  87. int j,ap = 1;
  88. if (p->pointers[i][1] == NULL) continue;
  89. if (i == p->pos) {
  90. fprintf(of,"*");
  91. } else {
  92. fprintf(of," ");
  93. }
  94. dl = (int)p->pointers[i][0];
  95. switch(dl) {
  96. case 0:
  97. fprintf(of,"E ");
  98. break;
  99. case 1:
  100. fprintf(of," ");
  101. break;
  102. case 4:
  103. fprintf(of,"A ");
  104. break;
  105. case 8:
  106. fprintf(of,"C ");
  107. break;
  108. case 64:
  109. fprintf(of,"G ");
  110. break;
  111. case 4096:
  112. fprintf(of,"R ");
  113. break;
  114. case 0xffff:
  115. fprintf(of,"A ");
  116. break;
  117. default:
  118. fprintf(of," %5d ",p->pointers[i][0]);
  119. }
  120. s = find_string(p->pointers[i][1],1);
  121. for (j = 0; s[j] != '\0'; j++) {
  122. if (s[j] == '\n') break;
  123. if (s[j] == '%') {
  124. if (s[j+1] == 'l') j++;
  125. switch(s[j+1]) {
  126. case '%':
  127. default:
  128. fprintf(of,"%c",s[j+1]);
  129. break;
  130. case 'x':
  131. ap++;
  132. if (ap >= 5) {
  133. fprintf(of,"(? (%%x)");
  134. } else {
  135. fprintf(of,"%x", p->pointers[i][ap]);
  136. }
  137. break;
  138. case 'd':
  139. ap++;
  140. if (ap >= 5) {
  141. fprintf(of,"(? (%%d)");
  142. } else {
  143. fprintf(of,"%d", p->pointers[i][ap]);
  144. }
  145. break;
  146. case 's':
  147. ap++;
  148. if (ap >= 5) {
  149. fprintf(of,"(? (%%s)");
  150. } else {
  151. s2 = find_string(p->pointers[i][ap],0);
  152. if (s2) {
  153. fprintf(of,"%s", s2);
  154. } else {
  155. fprintf(of,"(0x%x)", p->pointers[i][ap]);
  156. }
  157. }
  158. break;
  159. }
  160. j++;
  161. } else {
  162. fprintf(of,"%c",s[j]);
  163. }
  164. }
  165. fprintf(of,"\n");
  166. }
  167. }
  168. int seek_debug(char *erf,int start, int mx)
  169. {
  170. int i;
  171. unsigned int m1 = 0x0abbccdd;
  172. unsigned int m2 = 0xdeadbeef;
  173. for (i=start; i < mx; i+= sizeof(m1)) {
  174. if (memcmp(&erf[i],&m1,sizeof(m1)) == 0 &&
  175. memcmp(&erf[i+4],&m2,sizeof(m2)) == 0) {
  176. view_debug(&erf[i]);
  177. return 1;
  178. }
  179. }
  180. return 0;
  181. }
  182. #if !defined(_AIX) && !defined(__osf__)
  183. void add_segment(Elf32_Phdr *phdr,char *base,int which)
  184. {
  185. int i;
  186. i = segment_max;
  187. if (i >= 65536) {
  188. fprintf(of,"too many segments\n");
  189. exit(1);
  190. }
  191. i++;
  192. segment_max = i;
  193. segments[i].vaddr = (char *)phdr->p_vaddr;
  194. segments[i].len = phdr->p_filesz;
  195. segments[i].physaddr = base + phdr->p_offset;
  196. }
  197. void load_segments(Elf *elf,int phnum,char *base,int flen, int which)
  198. {
  199. Elf32_Phdr *phdr;
  200. int i;
  201. phdr = elf32_getphdr(elf);
  202. if (phdr == NULL) {
  203. failure("getphdr");
  204. }
  205. /* printf("headers at %d\n",ehdr->e_phoff); */
  206. for (i = 0; i < phnum; i++) {
  207. if (phdr[i].p_type == PT_NOTE) {
  208. if (which) {
  209. fprintf(of,"%d: NOTE offset=0x%x filesz=0x%x flags=%d align=%d\n",
  210. i, phdr[i].p_offset,
  211. phdr[i].p_filesz,
  212. phdr[i].p_flags, phdr[i].p_align);
  213. }
  214. } else if (phdr[i].p_type == PT_LOAD) {
  215. if (which) {
  216. fprintf(of,"%d: LOAD vaddr=0x%x filesz=0x%x memsz=0x%x mode=%s\n",
  217. i, phdr[i].p_vaddr,
  218. phdr[i].p_filesz, phdr[i].p_memsz,
  219. modes[phdr[i].p_flags & 0x7]);
  220. }
  221. if (phdr[i].p_offset && phdr[i].p_filesz) {
  222. if (phdr[i].p_offset + phdr[i].p_filesz > flen) {
  223. fprintf(of,"%d: segment out of range - core file is incomplete.\n",i);
  224. continue;
  225. }
  226. }
  227. if ((phdr[i].p_flags == 7 || phdr[i].p_flags == 5) && phdr[i].p_filesz) {
  228. add_segment(&phdr[i],base,which);
  229. }
  230. } else {
  231. if (which) {
  232. fprintf(of,"%d: type=%d offset=0x%x vaddr=0x%x p=0x%x filesz=%d memsz=%d flags=%d align=%d\n",
  233. i, phdr[i].p_type,phdr[i].p_offset, phdr[i].p_vaddr,
  234. phdr[i].p_paddr, phdr[i].p_filesz, phdr[i].p_memsz,
  235. phdr[i].p_flags, phdr[i].p_align);
  236. }
  237. }
  238. }
  239. }
  240. #endif
  241. void try_adb(char *pf,char *cf)
  242. {
  243. char buf[2048];
  244. FILE *p;
  245. if (ofname != NULL) {
  246. sprintf(buf,"/usr/bin/adb %s %s >>%s",pf,cf,ofname);
  247. } else {
  248. sprintf(buf,"/usr/bin/adb %s %s",pf,cf);
  249. }
  250. p = popen(buf,"w");
  251. if (p == NULL) {
  252. perror(buf);
  253. return;
  254. }
  255. fprintf(p,"$L\n");
  256. fprintf(p,"$m\n");
  257. fprintf(p,"$?\n");
  258. fprintf(p,"$C\n");
  259. #ifdef notanymore
  260. fprintf(p,"sls_release_date /S\n");
  261. fprintf(p,"lash_release_date /S\n");
  262. #endif
  263. fprintf(p,"$q\n");
  264. pclose(p);
  265. }
  266. void
  267. main(int argc, char ** argv)
  268. {
  269. #if !defined(_AIX) && !defined(__osf__)
  270. Elf32_Ehdr * ehdr;
  271. Elf32_Phdr * phdr;
  272. Elf * elf;
  273. Elf * elf2;
  274. int fd,fd2;
  275. int exf = 0;
  276. int i;
  277. size_t flen = 0;
  278. size_t flen2 = 0;
  279. time_t t;
  280. if (of == NULL) {
  281. of = stdout;
  282. }
  283. time(&t);
  284. if (argc != 4) {
  285. fprintf(of,"Core analysis %s needs three arguments: executable, core file, dest file\n",
  286. reldate);
  287. exit(1);
  288. }
  289. ofname = argv[3];
  290. of = fopen(ofname,"a");
  291. fprintf(of,"Core analysis %s. Copyright 2001 Sun Microsystems, Inc.\nPortions copyright 1999, 2001-2003 Netscape Communications Corporation.\nAll rights reserved.\nCurrently %sOpening %s %s\n",reldate,ctime(&t),argv[1],argv[2]);
  292. if ((fd2 = open(argv[1], O_RDONLY)) == -1) {
  293. perror(argv[1]);
  294. exit(1);
  295. }
  296. (void) elf_version(EV_CURRENT);
  297. /* Obtain the ELF descriptor */
  298. if ((elf2 = elf_begin(fd2, ELF_C_READ, NULL)) == NULL)
  299. failure("beginining");
  300. if ((erf2 = elf_rawfile(elf2,&flen2)) == NULL) {
  301. failure("elf_rawfile");
  302. }
  303. /* Obtain the .shstrtab data buffer */
  304. if ((ehdr = elf32_getehdr(elf2)) == NULL) {
  305. failure("reading header");
  306. }
  307. if (ehdr->e_type == ET_CORE) {
  308. fprintf(of,"Executable file should be given as the first argument.\n");
  309. exit(1);
  310. }
  311. if (ehdr->e_machine == EM_SPARC ||
  312. ehdr->e_machine == EM_SPARC32PLUS ||
  313. ehdr->e_machine == EM_SPARCV9) {
  314. fprintf(of,"architecture is SPARC\n");
  315. exf = EM_SPARC;
  316. } else if (ehdr->e_machine == EM_386) {
  317. fprintf(of,"architecture is x86\n");
  318. exf = ehdr->e_machine;
  319. } else {
  320. fprintf(of,"unknown architecture %d\n",ehdr->e_machine);
  321. exit(1);
  322. }
  323. if (ehdr->e_phnum == 0) {
  324. fprintf(of,"no program header in program file\n");
  325. exit(1);
  326. }
  327. load_segments(elf2,ehdr->e_phnum,erf2,flen2,0);
  328. /* Open the input file */
  329. if ((fd = open(argv[2], O_RDONLY)) == -1) {
  330. perror(argv[2]);
  331. exit(1);
  332. }
  333. /* Obtain the ELF descriptor */
  334. if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL)
  335. failure("beginining");
  336. if ((erf = elf_rawfile(elf,&flen)) == NULL) {
  337. failure("elf_rawfile");
  338. }
  339. /* Obtain the .shstrtab data buffer */
  340. if ((ehdr = elf32_getehdr(elf)) == NULL) {
  341. failure("reading header");
  342. }
  343. if (ehdr->e_type != ET_CORE) {
  344. fprintf(of,"second argument is ELF but not a core file\n");
  345. exit(1);
  346. }
  347. if (ehdr->e_machine != exf) {
  348. fprintf(of,"Architecture mismatch between executable and core file.\n");
  349. exit(1);
  350. }
  351. if (ehdr->e_phnum == 0) {
  352. fprintf(of,"no program header in core file\n");
  353. exit(1);
  354. }
  355. load_segments(elf,ehdr->e_phnum,erf,flen,1);
  356. #ifdef notanymore
  357. fprintf(of,"Seeking debug information in core file.\n");
  358. phdr = elf32_getphdr(elf);
  359. for (i = 0; i < ehdr->e_phnum; i++) {
  360. if (phdr[i].p_type == PT_LOAD) {
  361. if (phdr[i].p_offset && phdr[i].p_filesz) {
  362. if (phdr[i].p_offset + phdr[i].p_filesz > flen) {
  363. continue;
  364. }
  365. if (seek_debug(erf,phdr[i].p_offset,phdr[i].p_filesz)) {
  366. break;
  367. }
  368. }
  369. }
  370. }
  371. #endif
  372. if (of != stdout) {
  373. fclose(of);
  374. }
  375. try_adb(argv[1],argv[2]);
  376. #endif
  377. }
  378. static void
  379. failure(char *msg)
  380. {
  381. fprintf(of, "%s: %s\n", msg, elf_errmsg(elf_errno()));
  382. exit(1);
  383. }