Changeset 00c2de63 in mainline for uspace/app/taskdump/elf_core.c


Ignore:
Timestamp:
2011-07-29T14:50:22Z (13 years ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b6759f4
Parents:
6c69d19 (diff), 7ae249d (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge libposix.

File:
1 edited

Legend:

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

    r6c69d19 r00c2de63  
    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 align_pos(int, size_t);
    6670static int write_mem_area(int, as_area_info_t *, async_sess_t *);
    6771
     
    8387 */
    8488int elf_core_save(const char *file_name, as_area_info_t *ainfo, unsigned int n,
    85     async_sess_t *sess)
     89    async_sess_t *sess, istate_t *istate)
    8690{
    8791        elf_header_t elf_hdr;
     
    9094        elf_word flags;
    9195        elf_segment_header_t *p_hdr;
     96        elf_prstatus_t pr_status;
     97        elf_note_t note;
     98        size_t word_size;
    9299
    93100        int fd;
    94         int rc;
     101        ssize_t rc;
    95102        unsigned int i;
    96103
    97         n_ph = n;
    98 
    99         p_hdr = malloc(sizeof(elf_segment_header_t) * n);
     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);
    100116        if (p_hdr == NULL) {
    101117                printf("Failed allocating memory.\n");
     
    115131         *      ELF header
    116132         *      program headers
     133         *      note segment
    117134         * repeat:
    118135         *      (pad for alignment)
    119          *      segment data
     136         *      core segment
    120137         * end repeat
    121138         */
     
    147164        foff = elf_hdr.e_phoff + n_ph * sizeof(elf_segment_header_t);
    148165
    149         for (i = 1; i <= n; ++i) {
    150                 foff = align_foff_up(foff, ainfo[i - 1].start_addr, PAGE_SIZE);
     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);
    151182
    152183                flags = 0;
    153                 if (ainfo[i - 1].flags & AS_AREA_READ)
     184                if (ainfo[i].flags & AS_AREA_READ)
    154185                        flags |= PF_R;
    155                 if (ainfo[i - 1].flags & AS_AREA_WRITE)
     186                if (ainfo[i].flags & AS_AREA_WRITE)
    156187                        flags |= PF_W;
    157                 if (ainfo[i - 1].flags & AS_AREA_EXEC)
     188                if (ainfo[i].flags & AS_AREA_EXEC)
    158189                        flags |= PF_X;
    159190
    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;
     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;
    171202        }
    172203
    173204        rc = write_all(fd, &elf_hdr, sizeof(elf_hdr));
    174         if (rc != EOK) {
     205        if (rc != sizeof(elf_hdr)) {
    175206                printf("Failed writing ELF header.\n");
    176207                free(p_hdr);
     
    180211        for (i = 0; i < n_ph; ++i) {
    181212                rc = write_all(fd, &p_hdr[i], sizeof(p_hdr[i]));
    182                 if (rc != EOK) {
     213                if (rc != sizeof(p_hdr[i])) {
    183214                        printf("Failed writing program header.\n");
    184215                        free(p_hdr);
     
    187218        }
    188219
    189         for (i = 0; i < n_ph; ++i) {
     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) {
    190262                if (lseek(fd, p_hdr[i].p_offset, SEEK_SET) == (off64_t) -1) {
    191263                        printf("Failed writing memory data.\n");
     
    193265                        return EIO;
    194266                }
    195                 if (write_mem_area(fd, &ainfo[i], sess) != EOK) {
     267                if (write_mem_area(fd, &ainfo[i - 1], sess) != EOK) {
    196268                        printf("Failed writing memory data.\n");
    197269                        free(p_hdr);
     
    210282        off64_t rva = vaddr % page_size;
    211283        off64_t rfo = foff % page_size;
    212        
     284
    213285        if (rva >= rfo)
    214286                return (foff + (rva - rfo));
    215        
     287
    216288        return (foff + (page_size + (rva - rfo)));
    217289}
     
    231303        size_t total;
    232304        uintptr_t addr;
    233         int rc;
     305        ssize_t rc;
    234306
    235307        addr = area->start_addr;
     
    245317
    246318                rc = write_all(fd, buffer, to_copy);
    247                 if (rc != EOK) {
     319                if (rc != (ssize_t) to_copy) {
    248320                        printf("Failed writing memory contents.\n");
    249321                        return EIO;
     
    257329}
    258330
    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  */
    270 static int write_all(int fd, void *data, size_t len)
     331static int align_pos(int fd, size_t align)
    271332{
    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;
     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;
    285346
    286347        return EOK;
    287348}
    288349
    289 
    290350/** @}
    291351 */
Note: See TracChangeset for help on using the changeset viewer.