Ignore:
File:
1 edited

Legend:

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

    r8fd04ba9 r79ae36dd  
    11/*
    2  * Copyright (c) 2011 Jiri Svoboda
     2 * Copyright (c) 2010 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 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>
     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
    5248#include <stdio.h>
    5349#include <stdlib.h>
     
    6258#include <udebug.h>
    6359#include <macros.h>
    64 #include <libarch/istate.h>
    65 
    66 #include "elf_core.h"
     60
     61#include <elf.h>
     62#include "include/elf_core.h"
    6763
    6864static off64_t align_foff_up(off64_t, uintptr_t, size_t);
    69 static int align_pos(int, size_t);
     65static int write_all(int, void *, size_t);
    7066static int write_mem_area(int, as_area_info_t *, async_sess_t *);
    7167
     
    8783 */
    8884int elf_core_save(const char *file_name, as_area_info_t *ainfo, unsigned int n,
    89     async_sess_t *sess, istate_t *istate)
     85    async_sess_t *sess)
    9086{
    9187        elf_header_t elf_hdr;
     
    9490        elf_word flags;
    9591        elf_segment_header_t *p_hdr;
    96         elf_prstatus_t pr_status;
    97         elf_note_t note;
    98         size_t word_size;
    9992
    10093        int fd;
    101         ssize_t rc;
     94        int rc;
    10295        unsigned int i;
    10396
    104 #ifdef __32_BITS__
    105         word_size = 4;
    106 #endif
    107 #ifdef __64_BITS__
    108         word_size = 8;
    109 #endif
    110         memset(&pr_status, 0, sizeof(pr_status));
    111         istate_to_elf_regs(istate, &pr_status.regs);
    112 
    113         n_ph = n + 1;
    114 
    115         p_hdr = malloc(sizeof(elf_segment_header_t) * n_ph);
     97        n_ph = n;
     98
     99        p_hdr = malloc(sizeof(elf_segment_header_t) * n);
    116100        if (p_hdr == NULL) {
    117101                printf("Failed allocating memory.\n");
     
    131115         *      ELF header
    132116         *      program headers
    133          *      note segment
    134117         * repeat:
    135118         *      (pad for alignment)
    136          *      core segment
     119         *      segment data
    137120         * end repeat
    138121         */
     
    164147        foff = elf_hdr.e_phoff + n_ph * sizeof(elf_segment_header_t);
    165148
    166         memset(&p_hdr[0], 0, sizeof(p_hdr[0]));
    167         p_hdr[0].p_type = PT_NOTE;
    168         p_hdr[0].p_offset = foff;
    169         p_hdr[0].p_vaddr = 0;
    170         p_hdr[0].p_paddr = 0;
    171         p_hdr[0].p_filesz = sizeof(elf_note_t)
    172             + ALIGN_UP((str_size("CORE") + 1), word_size)
    173             + ALIGN_UP(sizeof(elf_prstatus_t), word_size);
    174         p_hdr[0].p_memsz = 0;
    175         p_hdr[0].p_flags = 0;
    176         p_hdr[0].p_align = 1;
    177 
    178         foff += p_hdr[0].p_filesz;
    179 
    180         for (i = 0; i < n; ++i) {
    181                 foff = align_foff_up(foff, ainfo[i].start_addr, PAGE_SIZE);
     149        for (i = 1; i <= n; ++i) {
     150                foff = align_foff_up(foff, ainfo[i - 1].start_addr, PAGE_SIZE);
    182151
    183152                flags = 0;
    184                 if (ainfo[i].flags & AS_AREA_READ)
     153                if (ainfo[i - 1].flags & AS_AREA_READ)
    185154                        flags |= PF_R;
    186                 if (ainfo[i].flags & AS_AREA_WRITE)
     155                if (ainfo[i - 1].flags & AS_AREA_WRITE)
    187156                        flags |= PF_W;
    188                 if (ainfo[i].flags & AS_AREA_EXEC)
     157                if (ainfo[i - 1].flags & AS_AREA_EXEC)
    189158                        flags |= PF_X;
    190159
    191                 memset(&p_hdr[i + 1], 0, sizeof(p_hdr[i + 1]));
    192                 p_hdr[i + 1].p_type = PT_LOAD;
    193                 p_hdr[i + 1].p_offset = foff;
    194                 p_hdr[i + 1].p_vaddr = ainfo[i].start_addr;
    195                 p_hdr[i + 1].p_paddr = 0;
    196                 p_hdr[i + 1].p_filesz = ainfo[i].size;
    197                 p_hdr[i + 1].p_memsz = ainfo[i].size;
    198                 p_hdr[i + 1].p_flags = flags;
    199                 p_hdr[i + 1].p_align = PAGE_SIZE;
    200 
    201                 foff += ainfo[i].size;
     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;
    202171        }
    203172
    204173        rc = write_all(fd, &elf_hdr, sizeof(elf_hdr));
    205         if (rc != sizeof(elf_hdr)) {
     174        if (rc != EOK) {
    206175                printf("Failed writing ELF header.\n");
    207176                free(p_hdr);
     
    211180        for (i = 0; i < n_ph; ++i) {
    212181                rc = write_all(fd, &p_hdr[i], sizeof(p_hdr[i]));
    213                 if (rc != sizeof(p_hdr[i])) {
     182                if (rc != EOK) {
    214183                        printf("Failed writing program header.\n");
    215184                        free(p_hdr);
     
    218187        }
    219188
    220         if (lseek(fd, p_hdr[0].p_offset, SEEK_SET) == (off64_t) -1) {
    221                 printf("Failed writing memory data.\n");
    222                 free(p_hdr);
    223                 return EIO;
    224         }
    225 
    226         /*
    227          * Write note header
    228          */
    229         note.namesz = str_size("CORE") + 1;
    230         note.descsz = sizeof(elf_prstatus_t);
    231         note.type = NT_PRSTATUS;
    232 
    233         rc = write_all(fd, &note, sizeof(elf_note_t));
    234         if (rc != sizeof(elf_note_t)) {
    235                 printf("Failed writing note header.\n");
    236                 free(p_hdr);
    237                 return EIO;
    238         }
    239 
    240         rc = write_all(fd, "CORE", note.namesz);
    241         if (rc != (ssize_t) note.namesz) {
    242                 printf("Failed writing note header.\n");
    243                 free(p_hdr);
    244                 return EIO;
    245         }
    246 
    247         rc = align_pos(fd, word_size);
    248         if (rc != EOK) {
    249                 printf("Failed writing note header.\n");
    250                 free(p_hdr);
    251                 return EIO;
    252         }
    253 
    254         rc = write_all(fd, &pr_status, sizeof(elf_prstatus_t));
    255         if (rc != sizeof(elf_prstatus_t)) {
    256                 printf("Failed writing register data.\n");
    257                 free(p_hdr);
    258                 return EIO;
    259         }
    260 
    261         for (i = 1; i < n_ph; ++i) {
     189        for (i = 0; i < n_ph; ++i) {
    262190                if (lseek(fd, p_hdr[i].p_offset, SEEK_SET) == (off64_t) -1) {
    263191                        printf("Failed writing memory data.\n");
     
    265193                        return EIO;
    266194                }
    267                 if (write_mem_area(fd, &ainfo[i - 1], sess) != EOK) {
     195                if (write_mem_area(fd, &ainfo[i], sess) != EOK) {
    268196                        printf("Failed writing memory data.\n");
    269197                        free(p_hdr);
     
    282210        off64_t rva = vaddr % page_size;
    283211        off64_t rfo = foff % page_size;
    284 
     212       
    285213        if (rva >= rfo)
    286214                return (foff + (rva - rfo));
    287 
     215       
    288216        return (foff + (page_size + (rva - rfo)));
    289217}
     
    303231        size_t total;
    304232        uintptr_t addr;
    305         ssize_t rc;
     233        int rc;
    306234
    307235        addr = area->start_addr;
     
    317245
    318246                rc = write_all(fd, buffer, to_copy);
    319                 if (rc != (ssize_t) to_copy) {
     247                if (rc != EOK) {
    320248                        printf("Failed writing memory contents.\n");
    321249                        return EIO;
     
    329257}
    330258
    331 static int align_pos(int fd, size_t align)
    332 {
    333         off64_t cur_pos;
    334         size_t rem, adv;
    335 
    336         cur_pos = lseek(fd, 0, SEEK_CUR);
    337         if (cur_pos < 0)
    338                 return -1;
    339 
    340         rem = cur_pos % align;
    341         adv = align - rem;
    342 
    343         cur_pos = lseek(fd, adv, SEEK_CUR);
    344         if (cur_pos < 0)
    345                 return -1;
     259/** Write until the buffer is written in its entirety.
     260 *
     261 * This function fails if it cannot write exactly @a len bytes to the file.
     262 *
     263 * @param fd            The file to write to.
     264 * @param buf           Data, @a len bytes long.
     265 * @param len           Number of bytes to write.
     266 *
     267 * @return              EOK on error, return value from write() if writing
     268 *                      failed.
     269 */
     270static int write_all(int fd, void *data, size_t len)
     271{
     272        int cnt = 0;
     273
     274        do {
     275                data += cnt;
     276                len -= cnt;
     277                cnt = write(fd, data, len);
     278        } while (cnt > 0 && (len - cnt) > 0);
     279
     280        if (cnt < 0)
     281                return cnt;
     282
     283        if (len - cnt > 0)
     284                return EIO;
    346285
    347286        return EOK;
    348287}
    349288
     289
    350290/** @}
    351291 */
Note: See TracChangeset for help on using the changeset viewer.