viewcore.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. /** BEGIN COPYRIGHT BLOCK
  2. * This Program is free software; you can redistribute it and/or modify it under
  3. * the terms of the GNU General Public License as published by the Free Software
  4. * Foundation; version 2 of the License.
  5. *
  6. * This Program is distributed in the hope that it will be useful, but WITHOUT
  7. * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  8. * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  9. *
  10. * You should have received a copy of the GNU General Public License along with
  11. * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
  12. * Place, Suite 330, Boston, MA 02111-1307 USA.
  13. *
  14. * In addition, as a special exception, Red Hat, Inc. gives You the additional
  15. * right to link the code of this Program with code not covered under the GNU
  16. * General Public License ("Non-GPL Code") and to distribute linked combinations
  17. * including the two, subject to the limitations in this paragraph. Non-GPL Code
  18. * permitted under this exception must only link to the code of this Program
  19. * through those well defined interfaces identified in the file named EXCEPTION
  20. * found in the source code files (the "Approved Interfaces"). The files of
  21. * Non-GPL Code may instantiate templates or use macros or inline functions from
  22. * the Approved Interfaces without causing the resulting work to be covered by
  23. * the GNU General Public License. Only Red Hat, Inc. may make changes or
  24. * additions to the list of Approved Interfaces. You must obey the GNU General
  25. * Public License in all respects for all of the Program code and other code used
  26. * in conjunction with the Program except the Non-GPL Code covered by this
  27. * exception. If you modify this file, you may extend this exception to your
  28. * version of the file, but you are not obligated to do so. If you do not wish to
  29. * provide this exception without modification, you must delete this exception
  30. * statement from your version and license this file solely under the GPL without
  31. * exception.
  32. *
  33. *
  34. * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
  35. * Copyright (C) 2005 Red Hat, Inc.
  36. * All rights reserved.
  37. * END COPYRIGHT BLOCK **/
  38. #include <fcntl.h>
  39. #include <stdio.h>
  40. #ifdef linux
  41. #include <elf.h>
  42. #include <libelf/libelf.h>
  43. #else
  44. #if defined(__osf__)
  45. #include <elf_abi.h>
  46. #else
  47. #ifndef _AIX
  48. #include <libelf.h>
  49. #endif
  50. #endif
  51. #endif
  52. #include <stdlib.h>
  53. #include <string.h>
  54. #include <ctype.h>
  55. #if defined(sparc) || defined(__sparc)
  56. #include <sys/elf_SPARC.h>
  57. #else
  58. #if !defined(linux) && !defined(_AIX) && !defined(__osf__)
  59. #include <sys/elf_386.h>
  60. #endif
  61. #endif
  62. char *reldate = "23-APR-2002";
  63. char *ofname = NULL;
  64. FILE *of = NULL;
  65. static void failure(char *s);
  66. struct segment {
  67. char *vaddr;
  68. int len;
  69. char *physaddr;
  70. };
  71. struct segment segments[65536];
  72. int segment_max;
  73. char *modes[8] = { "---", "--X", "-W-", "-WX", "R--", "R-X", "RW-", "RWX" };
  74. char *erf;
  75. char *erf2;
  76. char *find_string(char *addr,int l)
  77. {
  78. int i,off,j;
  79. char *np;
  80. for (i = 0; i < segment_max;i++) {
  81. if (addr >= segments[i].vaddr &&
  82. addr <= (segments[i].vaddr + segments[i].len)) {
  83. off = addr - segments[i].vaddr;
  84. np = segments[i].physaddr + off;
  85. for (j = 0; j < 256; j++) {
  86. if (np[j] == '\0') {
  87. return np;
  88. }
  89. if (!isascii(np[j])) {
  90. break;
  91. }
  92. }
  93. if (l) {
  94. return("<bad pointer>");
  95. }
  96. return NULL;
  97. }
  98. }
  99. if (l) {
  100. return "<out of segment>";
  101. }
  102. return NULL;
  103. }
  104. struct iii_msgarray {
  105. unsigned int magic1;
  106. unsigned int magic2;
  107. unsigned int pos;
  108. unsigned int magic4;
  109. void *pointers[128][5];
  110. } iii_msgarray;
  111. void view_debug(char *cp)
  112. {
  113. int i;
  114. char *s;
  115. char *s2;
  116. struct iii_msgarray *p = (struct iii_msgarray *)cp;
  117. for (i = 0; i < 128; i++) {
  118. int dl;
  119. int j,ap = 1;
  120. if (p->pointers[i][1] == NULL) continue;
  121. if (i == p->pos) {
  122. fprintf(of,"*");
  123. } else {
  124. fprintf(of," ");
  125. }
  126. dl = (int)p->pointers[i][0];
  127. switch(dl) {
  128. case 0:
  129. fprintf(of,"E ");
  130. break;
  131. case 1:
  132. fprintf(of," ");
  133. break;
  134. case 4:
  135. fprintf(of,"A ");
  136. break;
  137. case 8:
  138. fprintf(of,"C ");
  139. break;
  140. case 64:
  141. fprintf(of,"G ");
  142. break;
  143. case 4096:
  144. fprintf(of,"R ");
  145. break;
  146. case 0xffff:
  147. fprintf(of,"A ");
  148. break;
  149. default:
  150. fprintf(of," %5d ",p->pointers[i][0]);
  151. }
  152. s = find_string(p->pointers[i][1],1);
  153. for (j = 0; s[j] != '\0'; j++) {
  154. if (s[j] == '\n') break;
  155. if (s[j] == '%') {
  156. if (s[j+1] == 'l') j++;
  157. switch(s[j+1]) {
  158. case '%':
  159. default:
  160. fprintf(of,"%c",s[j+1]);
  161. break;
  162. case 'x':
  163. ap++;
  164. if (ap >= 5) {
  165. fprintf(of,"(? (%%x)");
  166. } else {
  167. fprintf(of,"%x", p->pointers[i][ap]);
  168. }
  169. break;
  170. case 'd':
  171. ap++;
  172. if (ap >= 5) {
  173. fprintf(of,"(? (%%d)");
  174. } else {
  175. fprintf(of,"%d", p->pointers[i][ap]);
  176. }
  177. break;
  178. case 's':
  179. ap++;
  180. if (ap >= 5) {
  181. fprintf(of,"(? (%%s)");
  182. } else {
  183. s2 = find_string(p->pointers[i][ap],0);
  184. if (s2) {
  185. fprintf(of,"%s", s2);
  186. } else {
  187. fprintf(of,"(0x%x)", p->pointers[i][ap]);
  188. }
  189. }
  190. break;
  191. }
  192. j++;
  193. } else {
  194. fprintf(of,"%c",s[j]);
  195. }
  196. }
  197. fprintf(of,"\n");
  198. }
  199. }
  200. int seek_debug(char *erf,int start, int mx)
  201. {
  202. int i;
  203. unsigned int m1 = 0x0abbccdd;
  204. unsigned int m2 = 0xdeadbeef;
  205. for (i=start; i < mx; i+= sizeof(m1)) {
  206. if (memcmp(&erf[i],&m1,sizeof(m1)) == 0 &&
  207. memcmp(&erf[i+4],&m2,sizeof(m2)) == 0) {
  208. view_debug(&erf[i]);
  209. return 1;
  210. }
  211. }
  212. return 0;
  213. }
  214. #if !defined(_AIX) && !defined(__osf__)
  215. void add_segment(Elf32_Phdr *phdr,char *base,int which)
  216. {
  217. int i;
  218. i = segment_max;
  219. if (i >= 65536) {
  220. fprintf(of,"too many segments\n");
  221. exit(1);
  222. }
  223. i++;
  224. segment_max = i;
  225. segments[i].vaddr = (char *)phdr->p_vaddr;
  226. segments[i].len = phdr->p_filesz;
  227. segments[i].physaddr = base + phdr->p_offset;
  228. }
  229. void load_segments(Elf *elf,int phnum,char *base,int flen, int which)
  230. {
  231. Elf32_Phdr *phdr;
  232. int i;
  233. phdr = elf32_getphdr(elf);
  234. if (phdr == NULL) {
  235. failure("getphdr");
  236. }
  237. /* printf("headers at %d\n",ehdr->e_phoff); */
  238. for (i = 0; i < phnum; i++) {
  239. if (phdr[i].p_type == PT_NOTE) {
  240. if (which) {
  241. fprintf(of,"%d: NOTE offset=0x%x filesz=0x%x flags=%d align=%d\n",
  242. i, phdr[i].p_offset,
  243. phdr[i].p_filesz,
  244. phdr[i].p_flags, phdr[i].p_align);
  245. }
  246. } else if (phdr[i].p_type == PT_LOAD) {
  247. if (which) {
  248. fprintf(of,"%d: LOAD vaddr=0x%x filesz=0x%x memsz=0x%x mode=%s\n",
  249. i, phdr[i].p_vaddr,
  250. phdr[i].p_filesz, phdr[i].p_memsz,
  251. modes[phdr[i].p_flags & 0x7]);
  252. }
  253. if (phdr[i].p_offset && phdr[i].p_filesz) {
  254. if (phdr[i].p_offset + phdr[i].p_filesz > flen) {
  255. fprintf(of,"%d: segment out of range - core file is incomplete.\n",i);
  256. continue;
  257. }
  258. }
  259. if ((phdr[i].p_flags == 7 || phdr[i].p_flags == 5) && phdr[i].p_filesz) {
  260. add_segment(&phdr[i],base,which);
  261. }
  262. } else {
  263. if (which) {
  264. fprintf(of,"%d: type=%d offset=0x%x vaddr=0x%x p=0x%x filesz=%d memsz=%d flags=%d align=%d\n",
  265. i, phdr[i].p_type,phdr[i].p_offset, phdr[i].p_vaddr,
  266. phdr[i].p_paddr, phdr[i].p_filesz, phdr[i].p_memsz,
  267. phdr[i].p_flags, phdr[i].p_align);
  268. }
  269. }
  270. }
  271. }
  272. #endif
  273. void try_adb(char *pf,char *cf)
  274. {
  275. char buf[2048];
  276. FILE *p;
  277. if (ofname != NULL) {
  278. sprintf(buf,"/usr/bin/adb %s %s >>%s",pf,cf,ofname);
  279. } else {
  280. sprintf(buf,"/usr/bin/adb %s %s",pf,cf);
  281. }
  282. p = popen(buf,"w");
  283. if (p == NULL) {
  284. perror(buf);
  285. return;
  286. }
  287. fprintf(p,"$L\n");
  288. fprintf(p,"$m\n");
  289. fprintf(p,"$?\n");
  290. fprintf(p,"$C\n");
  291. #ifdef notanymore
  292. fprintf(p,"sls_release_date /S\n");
  293. fprintf(p,"lash_release_date /S\n");
  294. #endif
  295. fprintf(p,"$q\n");
  296. pclose(p);
  297. }
  298. void
  299. main(int argc, char ** argv)
  300. {
  301. #if !defined(_AIX) && !defined(__osf__)
  302. Elf32_Ehdr * ehdr;
  303. Elf32_Phdr * phdr;
  304. Elf * elf;
  305. Elf * elf2;
  306. int fd,fd2;
  307. int exf = 0;
  308. int i;
  309. size_t flen = 0;
  310. size_t flen2 = 0;
  311. time_t t;
  312. if (of == NULL) {
  313. of = stdout;
  314. }
  315. time(&t);
  316. if (argc != 4) {
  317. fprintf(of,"Core analysis %s needs three arguments: executable, core file, dest file\n",
  318. reldate);
  319. exit(1);
  320. }
  321. ofname = argv[3];
  322. of = fopen(ofname,"a");
  323. fprintf(of,"Core analysis %s. Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.\nCopyright (C) 2005 Red Hat, Inc.\nAll rights reserved.\nCurrently %sOpening %s %s\n",reldate,ctime(&t),argv[1],argv[2]);
  324. if ((fd2 = open(argv[1], O_RDONLY)) == -1) {
  325. perror(argv[1]);
  326. exit(1);
  327. }
  328. (void) elf_version(EV_CURRENT);
  329. /* Obtain the ELF descriptor */
  330. if ((elf2 = elf_begin(fd2, ELF_C_READ, NULL)) == NULL)
  331. failure("beginining");
  332. if ((erf2 = elf_rawfile(elf2,&flen2)) == NULL) {
  333. failure("elf_rawfile");
  334. }
  335. /* Obtain the .shstrtab data buffer */
  336. if ((ehdr = elf32_getehdr(elf2)) == NULL) {
  337. failure("reading header");
  338. }
  339. if (ehdr->e_type == ET_CORE) {
  340. fprintf(of,"Executable file should be given as the first argument.\n");
  341. exit(1);
  342. }
  343. if (ehdr->e_machine == EM_SPARC ||
  344. ehdr->e_machine == EM_SPARC32PLUS ||
  345. ehdr->e_machine == EM_SPARCV9) {
  346. fprintf(of,"architecture is SPARC\n");
  347. exf = EM_SPARC;
  348. } else if (ehdr->e_machine == EM_386) {
  349. fprintf(of,"architecture is x86\n");
  350. exf = ehdr->e_machine;
  351. } else {
  352. fprintf(of,"unknown architecture %d\n",ehdr->e_machine);
  353. exit(1);
  354. }
  355. if (ehdr->e_phnum == 0) {
  356. fprintf(of,"no program header in program file\n");
  357. exit(1);
  358. }
  359. load_segments(elf2,ehdr->e_phnum,erf2,flen2,0);
  360. /* Open the input file */
  361. if ((fd = open(argv[2], O_RDONLY)) == -1) {
  362. perror(argv[2]);
  363. exit(1);
  364. }
  365. /* Obtain the ELF descriptor */
  366. if ((elf = elf_begin(fd, ELF_C_READ, NULL)) == NULL)
  367. failure("beginining");
  368. if ((erf = elf_rawfile(elf,&flen)) == NULL) {
  369. failure("elf_rawfile");
  370. }
  371. /* Obtain the .shstrtab data buffer */
  372. if ((ehdr = elf32_getehdr(elf)) == NULL) {
  373. failure("reading header");
  374. }
  375. if (ehdr->e_type != ET_CORE) {
  376. fprintf(of,"second argument is ELF but not a core file\n");
  377. exit(1);
  378. }
  379. if (ehdr->e_machine != exf) {
  380. fprintf(of,"Architecture mismatch between executable and core file.\n");
  381. exit(1);
  382. }
  383. if (ehdr->e_phnum == 0) {
  384. fprintf(of,"no program header in core file\n");
  385. exit(1);
  386. }
  387. load_segments(elf,ehdr->e_phnum,erf,flen,1);
  388. #ifdef notanymore
  389. fprintf(of,"Seeking debug information in core file.\n");
  390. phdr = elf32_getphdr(elf);
  391. for (i = 0; i < ehdr->e_phnum; i++) {
  392. if (phdr[i].p_type == PT_LOAD) {
  393. if (phdr[i].p_offset && phdr[i].p_filesz) {
  394. if (phdr[i].p_offset + phdr[i].p_filesz > flen) {
  395. continue;
  396. }
  397. if (seek_debug(erf,phdr[i].p_offset,phdr[i].p_filesz)) {
  398. break;
  399. }
  400. }
  401. }
  402. }
  403. #endif
  404. if (of != stdout) {
  405. fclose(of);
  406. }
  407. try_adb(argv[1],argv[2]);
  408. #endif
  409. }
  410. static void
  411. failure(char *msg)
  412. {
  413. fprintf(of, "%s: %s\n", msg, elf_errmsg(elf_errno()));
  414. exit(1);
  415. }