neatcc top-level makefile
[neatcc_make.git] / neatdbg / coredump.c
blobec829d3ac432e8eeb726ceb808fba3df0509e740
1 /*
2 * a simple elf core file backtrace viewer
4 * Copyright (C) 2010-2013 Ali Gholami Rudi
6 * This program is released under the Modified BSD license.
7 */
8 #include <elf.h>
9 #include <fcntl.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <sys/mman.h>
13 #include <sys/stat.h>
14 #include <unistd.h>
15 #include "elfcore.h"
17 /* simplified elf struct and macro names */
18 #ifdef __x86_64__
19 # define Elf_Phdr Elf64_Phdr
20 # define Elf_Ehdr Elf64_Ehdr
21 #else
22 # define Elf_Phdr Elf32_Phdr
23 # define Elf_Ehdr Elf32_Ehdr
24 #endif
26 #define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
27 #define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
29 static long readlong(char *mem, unsigned long addr)
31 Elf_Ehdr *ehdr = (void *) mem;
32 Elf_Phdr *phdr = (void *) (mem + ehdr->e_phoff);
33 int i;
34 for (i = 0; i < ehdr->e_phnum; i++) {
35 unsigned long beg = phdr[i].p_vaddr;
36 if (addr >= beg && addr < beg + phdr[i].p_filesz) {
37 unsigned long diff = addr - beg;
38 return *(long *) (mem + phdr[i].p_offset + diff);
41 return 0;
44 static void dump_prstatus(char *mem, struct elf_prstatus *prs)
46 struct user_regs_struct *regs = (void *) &prs->pr_reg;
47 unsigned long bp = regs->bp;
48 printf("ip=%lx, sp=%lx, bp=%lx\n\n", regs->ip, regs->sp, regs->bp);
49 printf("\t%lx: %lx\n", regs->ip, regs->bp);
50 while (bp) {
51 printf("\t%lx: %lx\n",
52 readlong(mem, bp + sizeof(long)), readlong(mem, bp));
53 bp = readlong(mem, bp);
55 printf("\n");
58 struct elfnote {
59 int namesz;
60 int descsz;
61 int type;
64 static void dumpnote(char *mem, char *note, int len)
66 struct elfnote *elfnote;
67 char *end = note + len;
68 while (note < end) {
69 elfnote = (void *) note;
70 note += sizeof(*elfnote);
71 note += ALIGN(elfnote->namesz, 4);
72 if (elfnote->type == NT_PRSTATUS)
73 dump_prstatus(mem, (void *) note);
74 note += ALIGN(elfnote->descsz, 4);
78 static void dumpelf(char *mem)
80 Elf_Ehdr *ehdr = (void *) mem;
81 Elf_Phdr *phdr = (void *) (mem + ehdr->e_phoff);
82 if (ehdr->e_type == ET_CORE && phdr[0].p_type == PT_NOTE)
83 dumpnote(mem, mem + phdr[0].p_offset, phdr[0].p_filesz);
86 static void die(char *msg)
88 perror(msg);
89 exit(1);
92 static long filesize(int fd)
94 struct stat stat;
95 fstat(fd, &stat);
96 return stat.st_size;
99 int main(int argc, char **argv)
101 int fd;
102 long size;
103 void *mem;
104 if (argc < 2) {
105 printf("Usage: %s path\n", argv[0]);
106 return 0;
108 fd = open(argv[1], O_RDONLY);
109 if (fd == -1)
110 die("open");
111 size = filesize(fd);
112 mem = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
113 if (!mem)
114 die("mmap");
115 dumpelf(mem);
116 munmap(mem, size);
117 close(fd);
118 return 0;