--------------4A6501B25EBBC8F7EDB6F7D
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Darrin R. Smith wrote:
> No -- `file` used to give the name of the prog. that dumped
> the core file. Since the switchover to elf, it's output was changed
> to the garbage^h^h^h^h^h^h^h useless info line you see above. This has
> been irritating me for a long time -- I would *love* to see the old
> functionality put back in.
Here's a program to do more than you want. It should be easy enough to
hack or hack into 'file'.
Sorry it's a MIME attachment; its the best I can do now.
J
--------------4A6501B25EBBC8F7EDB6F7D
Content-Type: text/plain; charset=us-ascii; name="dcore.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="dcore.c"
/*
* Show goo about ELF core files
* Jeremy Fitzhardinge <jeremy@zip.com.au> 1996
*/
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <string.h>
#include <linux/elf.h>
#include <linux/elfcore.h>
static void fperror(const char *str)
{
perror(str);
exit(1);
}
static size_t myread(int fd, void *buf, size_t sz)
{
size_t ret;
if ((ret = read(fd, buf, sz)) != sz)
fperror("read failed");
return ret;
}
static void print_prstatus(const prstatus_t *pr)
{
unsigned i;
static const char *regs[] = { "ebx", "ecx", "edx", "esi", "edi", "ebp",
"eax", "ds", "es", "fs", "gs",
"orig_eax", "eip", "cs",
"efl", "uesp", "ss"};
printf(" pid=%d ppid=%d pgrp=%d sid=%d\n",
pr->pr_pid, pr->pr_ppid, pr->pr_pgrp, pr->pr_sid);
for(i = 0; i < NGREG; i++)
{
unsigned long val = pr->pr_reg[i];
printf(" %-2u %-5s=%08lx %lu\n", i, regs[i], val, val);
}
}
static void print_prpsinfo(const prpsinfo_t *ps)
{
printf(" uid=%d gid=%d\n", ps->pr_uid, ps->pr_gid);
printf(" comm=%s\n", ps->pr_fname);
printf(" psargs=%s\n", ps->pr_psargs);
}
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
static void do_note(int fd, Elf32_Phdr *phdr)
{
off_t here = lseek(fd, 0, SEEK_CUR);
int size = phdr->p_filesz;
char *raw = alloca(size), *end;
end = raw+size;
lseek(fd, phdr->p_offset, SEEK_SET);
myread(fd, raw, size);
while(raw < end)
{
Elf32_Nhdr *note = (Elf32_Nhdr *)raw;
const char *str;
const char *name, *desc;
raw += sizeof(*note);
name = raw;
raw += roundup(note->n_namesz, sizeof(long));
desc = raw;
raw += roundup(note->n_descsz, sizeof(long));
printf(" name=%.*s", (int)note->n_namesz, name);
if(strncmp(name, "CORE", note->n_namesz) != 0)
{
printf("\n");
continue;
}
switch(note->n_type)
{
#define X(x) case x: str = #x; break;
X(NT_PRSTATUS);
X(NT_PRFPREG);
X(NT_PRPSINFO);
X(NT_TASKSTRUCT);
#undef X
default:
str = "???";
}
printf(" n_type=%s n_descsz=%ld\n",
str, note->n_descsz);
switch(note->n_type)
{
case NT_PRSTATUS:
print_prstatus((prstatus_t *)desc);
break;
case NT_PRPSINFO:
print_prpsinfo((prpsinfo_t *)desc);
break;
}
}
lseek(fd, here, SEEK_SET);
}
int main(int argc, char *argv[])
{
int fd;
Elf32_Ehdr elf;
int i;
if (argc != 2)
{
fprintf(stderr, "Usage: %s corefile\n", argv[0]);
exit(1);
}
if ((fd = open(argv[1], O_RDONLY)) == -1)
fperror("open of core");
myread(fd, &elf, sizeof(elf));
if (memcmp(ELFMAG, elf.e_ident, SELFMAG) != 0)
printf("bad magic\n");
if (elf.e_ident[EI_CLASS] != ELFCLASS32)
printf("wrong class\n");
if (elf.e_ident[EI_DATA] != ELFDATA2LSB)
printf("wrong endianess\n");
if (elf.e_ident[EI_VERSION] != EV_CURRENT)
printf("wrong version\n");
{
const char *str;
switch(elf.e_type)
{
#define C(x) case ET_##x: str = #x; break;
C(NONE);
C(REL);
C(EXEC);
C(DYN);
C(CORE);
#undef C
default: str = "???"; break;
}
printf("elf file type ET_%s\n", str);
}
if (elf.e_machine != EM_386 && elf.e_machine != EM_486)
printf("not i386 or i486\n");
if (elf.e_ehsize != sizeof(elf))
printf("wrong header size\n");
if (elf.e_phentsize != sizeof(Elf32_Phdr))
printf("wrong phdr size\n");
if (lseek(fd, elf.e_phoff, SEEK_SET) != (off_t)elf.e_phoff)
fperror("lseek to phdr failed\n");
for(i = 0; i < elf.e_phnum; i++)
{
Elf32_Phdr phdr;
const char *str;
myread(fd, &phdr, sizeof(phdr));
switch(phdr.p_type)
{
#define C(x) case PT_##x: str = #x; break;
C(NULL);
C(LOAD);
C(DYNAMIC);
C(INTERP);
C(NOTE);
C(SHLIB);
C(PHDR);
#undef C
default:
str = "???"; break;
}
printf("type PT_%s off=%ld vaddr=%lx filesz=%ld flags=%lx\n",
str, phdr.p_offset, phdr.p_vaddr, phdr.p_filesz,
(unsigned long)phdr.p_flags);
if (phdr.p_type == PT_NOTE)
do_note(fd, &phdr);
}
exit(0);
}
--------------4A6501B25EBBC8F7EDB6F7D--