Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 5baf209 in mainline


Ignore:
Timestamp:
2011-07-23T12:37:16Z (10 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master
Children:
90b8d58
Parents:
a701812
Message:

Write register state to core files (only ia32).

Location:
uspace
Files:
11 added
5 edited
1 moved

Legend:

Unmodified
Added
Removed
  • uspace/app/taskdump/elf_core.c

    ra701812 r5baf209  
    11/*
    2  * Copyright (c) 2010 Jiri Svoboda
     2 * Copyright (c) 2011 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3838 * Looking at core files produced by Linux, these don't have section headers,
    3939 * only program headers, although objdump shows them as having sections.
    40  * Basically at the beginning there should be a note segment (which we
    41  * do not write) and one loadable segment per memory area (which we do write).
    42  *
    43  * The note segment probably contains register state, etc. -- we don't
    44  * deal with these yet. Nevertheless you can use these core files with
    45  * objdump or gdb.
    46  */
    47 
     40 * Basically at the beginning there should be a note segment followed
     41 * by one loadable segment per memory area.
     42 *
     43 * The note segment contains a series of records with register state,
     44 * process info etc. We only write one record NT_PRSTATUS which contains
     45 * process/register state (anything which is not register state we fill
     46 * with zeroes).
     47 */
     48
     49#include <align.h>
     50#include <elf/elf.h>
     51#include <elf/elf_linux.h>
    4852#include <stdio.h>
    4953#include <stdlib.h>
     
    5862#include <udebug.h>
    5963#include <macros.h>
    60 
    61 #include <elf.h>
    62 #include "include/elf_core.h"
     64#include <libarch/istate.h>
     65
     66#include "elf_core.h"
    6367
    6468static off64_t align_foff_up(off64_t, uintptr_t, size_t);
    65 static int write_all(int, void *, size_t);
     69static int write_all(int, const void *, size_t);
     70static int align_pos(int, size_t);
    6671static int write_mem_area(int, as_area_info_t *, async_sess_t *);
    6772
     
    8388 */
    8489int elf_core_save(const char *file_name, as_area_info_t *ainfo, unsigned int n,
    85     async_sess_t *sess)
     90    async_sess_t *sess, istate_t *istate)
    8691{
    8792        elf_header_t elf_hdr;
     
    9095        elf_word flags;
    9196        elf_segment_header_t *p_hdr;
     97        elf_prstatus_t pr_status;
     98        elf_note_t note;
     99        size_t word_size;
    92100
    93101        int fd;
     
    95103        unsigned int i;
    96104
    97         n_ph = n;
    98 
    99         p_hdr = malloc(sizeof(elf_segment_header_t) * n);
     105#ifdef __32_BITS__
     106        word_size = 4;
     107#endif
     108#ifdef __64_BITS__
     109        word_size = 8;
     110#endif
     111        memset(&pr_status, 0, sizeof(pr_status));
     112        istate_to_elf_regs(istate, &pr_status.regs);
     113
     114        n_ph = n + 1;
     115
     116        p_hdr = malloc(sizeof(elf_segment_header_t) * n_ph);
    100117        if (p_hdr == NULL) {
    101118                printf("Failed allocating memory.\n");
     
    115132         *      ELF header
    116133         *      program headers
     134         *      note segment
    117135         * repeat:
    118136         *      (pad for alignment)
    119          *      segment data
     137         *      core segment
    120138         * end repeat
    121139         */
     
    147165        foff = elf_hdr.e_phoff + n_ph * sizeof(elf_segment_header_t);
    148166
    149         for (i = 1; i <= n; ++i) {
    150                 foff = align_foff_up(foff, ainfo[i - 1].start_addr, PAGE_SIZE);
     167        memset(&p_hdr[0], 0, sizeof(p_hdr[0]));
     168        p_hdr[0].p_type = PT_NOTE;
     169        p_hdr[0].p_offset = foff;
     170        p_hdr[0].p_vaddr = 0;
     171        p_hdr[0].p_paddr = 0;
     172        p_hdr[0].p_filesz = sizeof(elf_note_t)
     173            + ALIGN_UP((str_size("CORE") + 1), word_size)
     174            + ALIGN_UP(sizeof(elf_prstatus_t), word_size);
     175        p_hdr[0].p_memsz = 0;
     176        p_hdr[0].p_flags = 0;
     177        p_hdr[0].p_align = 1;
     178
     179        foff += p_hdr[0].p_filesz;
     180
     181        for (i = 0; i < n; ++i) {
     182                foff = align_foff_up(foff, ainfo[i].start_addr, PAGE_SIZE);
    151183
    152184                flags = 0;
    153                 if (ainfo[i - 1].flags & AS_AREA_READ)
     185                if (ainfo[i].flags & AS_AREA_READ)
    154186                        flags |= PF_R;
    155                 if (ainfo[i - 1].flags & AS_AREA_WRITE)
     187                if (ainfo[i].flags & AS_AREA_WRITE)
    156188                        flags |= PF_W;
    157                 if (ainfo[i - 1].flags & AS_AREA_EXEC)
     189                if (ainfo[i].flags & AS_AREA_EXEC)
    158190                        flags |= PF_X;
    159191
    160                 memset(&p_hdr[i - 1], 0, sizeof(p_hdr[i - 1]));
    161                 p_hdr[i - 1].p_type = PT_LOAD;
    162                 p_hdr[i - 1].p_offset = foff;
    163                 p_hdr[i - 1].p_vaddr = ainfo[i - 1].start_addr;
    164                 p_hdr[i - 1].p_paddr = 0;
    165                 p_hdr[i - 1].p_filesz = ainfo[i - 1].size;
    166                 p_hdr[i - 1].p_memsz = ainfo[i - 1].size;
    167                 p_hdr[i - 1].p_flags = flags;
    168                 p_hdr[i - 1].p_align = PAGE_SIZE;
    169 
    170                 foff += ainfo[i - 1].size;
     192                memset(&p_hdr[i + 1], 0, sizeof(p_hdr[i + 1]));
     193                p_hdr[i + 1].p_type = PT_LOAD;
     194                p_hdr[i + 1].p_offset = foff;
     195                p_hdr[i + 1].p_vaddr = ainfo[i].start_addr;
     196                p_hdr[i + 1].p_paddr = 0;
     197                p_hdr[i + 1].p_filesz = ainfo[i].size;
     198                p_hdr[i + 1].p_memsz = ainfo[i].size;
     199                p_hdr[i + 1].p_flags = flags;
     200                p_hdr[i + 1].p_align = PAGE_SIZE;
     201
     202                foff += ainfo[i].size;
    171203        }
    172204
     
    187219        }
    188220
    189         for (i = 0; i < n_ph; ++i) {
     221        if (lseek(fd, p_hdr[0].p_offset, SEEK_SET) == (off64_t) -1) {
     222                printf("Failed writing memory data.\n");
     223                free(p_hdr);
     224                return EIO;
     225        }
     226
     227        /*
     228         * Write note header
     229         */
     230        note.namesz = str_size("CORE") + 1;
     231        note.descsz = sizeof(elf_prstatus_t);
     232        note.type = NT_PRSTATUS;
     233
     234        rc = write_all(fd, &note, sizeof(elf_note_t));
     235        if (rc != EOK) {
     236                printf("Failed writing note header.\n");
     237                free(p_hdr);
     238                return EIO;
     239        }
     240
     241        rc = write_all(fd, "CORE", note.namesz);
     242        if (rc != EOK) {
     243                printf("Failed writing note header.\n");
     244                free(p_hdr);
     245                return EIO;
     246        }
     247
     248        rc = align_pos(fd, word_size);
     249        if (rc != EOK) {
     250                printf("Failed writing note header.\n");
     251                free(p_hdr);
     252                return EIO;
     253        }
     254
     255        rc = write_all(fd, &pr_status, sizeof(elf_prstatus_t));
     256        if (rc != EOK) {
     257                printf("Failed writing register data.\n");
     258                free(p_hdr);
     259                return EIO;
     260        }
     261
     262        for (i = 1; i < n_ph; ++i) {
    190263                if (lseek(fd, p_hdr[i].p_offset, SEEK_SET) == (off64_t) -1) {
    191264                        printf("Failed writing memory data.\n");
     
    193266                        return EIO;
    194267                }
    195                 if (write_mem_area(fd, &ainfo[i], sess) != EOK) {
     268                if (write_mem_area(fd, &ainfo[i - 1], sess) != EOK) {
    196269                        printf("Failed writing memory data.\n");
    197270                        free(p_hdr);
     
    210283        off64_t rva = vaddr % page_size;
    211284        off64_t rfo = foff % page_size;
    212        
     285
    213286        if (rva >= rfo)
    214287                return (foff + (rva - rfo));
    215        
     288
    216289        return (foff + (page_size + (rva - rfo)));
    217290}
     
    268341 *                      failed.
    269342 */
    270 static int write_all(int fd, void *data, size_t len)
     343static int write_all(int fd, const void *data, size_t len)
    271344{
    272345        int cnt = 0;
     
    287360}
    288361
     362static int align_pos(int fd, size_t align)
     363{
     364        off64_t cur_pos;
     365        size_t rem, adv;
     366
     367        cur_pos = lseek(fd, 0, SEEK_CUR);
     368        if (cur_pos < 0)
     369                return -1;
     370
     371        rem = cur_pos % align;
     372        adv = align - rem;
     373
     374        cur_pos = lseek(fd, adv, SEEK_CUR);
     375        if (cur_pos < 0)
     376                return -1;
     377
     378        return EOK;
     379}
    289380
    290381/** @}
  • uspace/app/taskdump/include/elf_core.h

    ra701812 r5baf209  
    3737
    3838#include <async.h>
     39#include <elf/elf_linux.h>
     40#include <libarch/istate.h>
    3941
    4042extern int elf_core_save(const char *, as_area_info_t *, unsigned int,
    41     async_sess_t *);
     43    async_sess_t *, istate_t *);
    4244
    4345#endif
  • uspace/app/taskdump/include/symtab.h

    ra701812 r5baf209  
    3636#define SYMTAB_H_
    3737
     38#include <elf/elf.h>
    3839#include <sys/types.h>
    39 #include <elf.h>
    4040
    4141typedef struct {
  • uspace/app/taskdump/symtab.c

    ra701812 r5baf209  
    3636 */
    3737
     38#include <elf/elf.h>
    3839#include <stdio.h>
    3940#include <stdlib.h>
     
    4344#include <fcntl.h>
    4445
    45 #include <elf.h>
    4646#include "include/symtab.h"
    4747
  • uspace/app/taskdump/taskdump.c

    ra701812 r5baf209  
    3434
    3535#include <async.h>
     36#include <elf/elf_linux.h>
    3637#include <stdio.h>
    3738#include <stdlib.h>
     
    7273static char *get_app_task_name(void);
    7374static char *fmt_sym_address(uintptr_t addr);
     75
     76static istate_t reg_state;
    7477
    7578int main(int argc, char *argv[])
     
    293296        if (write_core_file) {
    294297                printf("Writing core file '%s'\n", core_file_name);
    295                 rc = elf_core_save(core_file_name, ainfo_buf, n_areas, sess);
     298
     299                rc = elf_core_save(core_file_name, ainfo_buf, n_areas, sess,
     300                    &reg_state);
     301
    296302                if (rc != EOK) {
    297303                        printf("Failed writing core file.\n");
     
    321327        pc = istate_get_pc(&istate);
    322328        fp = istate_get_fp(&istate);
     329
     330        /* Save register state for dumping to core file later. */
     331        reg_state = istate;
    323332
    324333        sym_pc = fmt_sym_address(pc);
  • uspace/lib/c/include/elf/elf.h

    ra701812 r5baf209  
    2727 */
    2828
    29 /** @addtogroup generic 
     29/** @addtogroup generic
    3030 * @{
    3131 */
     
    3333 */
    3434
    35 #ifndef ELF_H_
    36 #define ELF_H_
     35#ifndef LIBC_ELF_H_
     36#define LIBC_ELF_H_
    3737
    3838#include <arch/elf.h>
     
    4444#define EV_CURRENT      1
    4545
    46 /** 
    47  * ELF types 
     46/**
     47 * ELF types
    4848 */
    4949#define ET_NONE         0       /* No type */
     
    329329};
    330330
    331 #ifdef __32_BITS__
     331/*
     332 * ELF note segment entry
     333 */
     334struct elf32_note {
     335        elf_word namesz;
     336        elf_word descsz;
     337        elf_word type;
     338};
     339struct elf64_note {
     340        elf_xword namesz;
     341        elf_xword descsz;
     342        elf_xword type;
     343};
     344
     345#ifdef __32_BITS__
    332346typedef struct elf32_header elf_header_t;
    333347typedef struct elf32_segment_header elf_segment_header_t;
    334348typedef struct elf32_section_header elf_section_header_t;
    335349typedef struct elf32_symbol elf_symbol_t;
     350typedef struct elf32_note elf_note_t;
    336351#endif
    337352#ifdef __64_BITS__
     
    340355typedef struct elf64_section_header elf_section_header_t;
    341356typedef struct elf64_symbol elf_symbol_t;
     357typedef struct elf64_note elf_note_t;
    342358#endif
    343359
     360/*
     361 * Note types are not defined by the standard. These are the ones used
     362 * by SVr4 derivatives.
     363 */
     364#define NT_PRSTATUS     1
     365
    344366extern char *elf_error(unsigned int rc);
    345367
Note: See TracChangeset for help on using the changeset viewer.