1
0

viewcore.c 9.0 KB

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