viewcore.c 11 KB

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