Changeset a33f0a6 in mainline for uspace/lib/c/generic/elf/elf_load.c


Ignore:
Timestamp:
2011-08-03T17:34:57Z (14 years ago)
Author:
Oleg Romanenko <romanenko.oleg@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1940326
Parents:
52a79081 (diff), 3fab770 (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 from mainline

File:
1 moved

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/elf/elf_load.c

    r52a79081 ra33f0a6  
    22 * Copyright (c) 2006 Sergey Bondari
    33 * Copyright (c) 2006 Jakub Jermar
    4  * Copyright (c) 2008 Jiri Svoboda
     4 * Copyright (c) 2011 Jiri Svoboda
    55 * All rights reserved.
    66 *
     
    2929 */
    3030
    31 /** @addtogroup generic 
     31/** @addtogroup generic
    3232 * @{
    3333 */
     
    4949#include <assert.h>
    5050#include <as.h>
     51#include <elf/elf.h>
    5152#include <unistd.h>
    5253#include <fcntl.h>
    5354#include <smc.h>
    5455#include <loader/pcb.h>
    55 
    56 #include "elf.h"
    57 #include "elf_load.h"
    58 #include "arch.h"
     56#include <entry_point.h>
     57
     58#include <elf/elf_load.h>
    5959
    6060#define DPRINTF(...)
     
    7474static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry);
    7575
    76 /** Read until the buffer is read in its entirety. */
    77 static int my_read(int fd, void *buf, size_t len)
    78 {
    79         int cnt = 0;
    80         do {
    81                 buf += cnt;
    82                 len -= cnt;
    83                 cnt = read(fd, buf, len);
    84         } while ((cnt > 0) && ((len - cnt) > 0));
    85 
    86         return cnt;
    87 }
    88 
    8976/** Load ELF binary from a file.
    9077 *
     
    10390 *
    10491 */
    105 int elf_load_file(const char *file_name, size_t so_bias, elf_info_t *info)
     92int elf_load_file(const char *file_name, size_t so_bias, eld_flags_t flags,
     93    elf_info_t *info)
    10694{
    10795        elf_ld_t elf;
     
    118106        elf.fd = fd;
    119107        elf.info = info;
     108        elf.flags = flags;
    120109
    121110        rc = elf_load(&elf, so_bias);
     
    124113
    125114        return rc;
    126 }
    127 
    128 /** Run an ELF executable.
    129  *
    130  * Transfers control to the entry point of an ELF executable loaded
    131  * earlier with elf_load_file(). This function does not return.
    132  *
    133  * @param info Info structure filled earlier by elf_load_file()
    134  *
    135  */
    136 void elf_run(elf_info_t *info, pcb_t *pcb)
    137 {
    138         program_run(info->entry, pcb);
    139 
    140         /* not reached */
    141115}
    142116
     
    153127        pcb->entry = info->entry;
    154128        pcb->dynamic = info->dynamic;
     129        pcb->rtld_runtime = NULL;
    155130}
    156131
     
    172147        int i, rc;
    173148
    174         rc = my_read(elf->fd, header, sizeof(elf_header_t));
    175         if (rc < 0) {
     149        rc = read_all(elf->fd, header, sizeof(elf_header_t));
     150        if (rc != sizeof(elf_header_t)) {
    176151                DPRINTF("Read error.\n");
    177152                return EE_INVALID;
     
    234209                        + i * sizeof(elf_segment_header_t), SEEK_SET);
    235210
    236                 rc = my_read(elf->fd, &segment_hdr,
     211                rc = read_all(elf->fd, &segment_hdr,
    237212                    sizeof(elf_segment_header_t));
    238                 if (rc < 0) {
     213                if (rc != sizeof(elf_segment_header_t)) {
    239214                        DPRINTF("Read error.\n");
    240215                        return EE_INVALID;
     
    256231                    + i * sizeof(elf_section_header_t), SEEK_SET);
    257232
    258                 rc = my_read(elf->fd, &section_hdr,
     233                rc = read_all(elf->fd, &section_hdr,
    259234                    sizeof(elf_section_header_t));
    260                 if (rc < 0) {
     235                if (rc != sizeof(elf_section_header_t)) {
    261236                        DPRINTF("Read error.\n");
    262237                        return EE_INVALID;
     
    306281                break;
    307282        case PT_INTERP:
    308                 /* Assume silently interp == "/rtld.so" */
    309                 elf->info->interp = "/rtld.so";
     283                /* Assume silently interp == "/app/dload" */
     284                elf->info->interp = "/app/dload";
    310285                break;
    311286        case PT_DYNAMIC:
     287                /* Record pointer to dynamic section into info structure */
     288                elf->info->dynamic =
     289                    (void *)((uint8_t *)entry->p_vaddr + elf->bias);
     290                DPRINTF("dynamic section found at 0x%x\n",
     291                        (uintptr_t)elf->info->dynamic);
     292                break;
     293        case 0x70000000:
     294                /* FIXME: MIPS reginfo */
     295                break;
    312296        case PT_SHLIB:
    313         case PT_LOPROC:
    314         case PT_HIPROC:
     297//      case PT_LOPROC:
     298//      case PT_HIPROC:
    315299        default:
    316300                DPRINTF("Segment p_type %d unknown.\n", entry->p_type);
     
    337321        uintptr_t seg_addr;
    338322        size_t mem_sz;
    339         int rc;
     323        ssize_t rc;
    340324
    341325        bias = elf->bias;
     
    383367            AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
    384368        if (a == (void *)(-1)) {
    385                 DPRINTF("Memory mapping failed.\n");
     369                DPRINTF("memory mapping failed (0x%x, %d)\n",
     370                        base+bias, mem_sz);
    386371                return EE_MEMORY;
    387372        }
     
    414399                if (now > left) now = left;
    415400
    416                 rc = my_read(elf->fd, dp, now);
    417 
    418                 if (rc < 0) {
     401                rc = read_all(elf->fd, dp, now);
     402
     403                if (rc != (ssize_t) now) {
    419404                        DPRINTF("Read error.\n");
    420405                        return EE_INVALID;
     
    425410        }
    426411
     412        /*
     413         * The caller wants to modify the segments first. He will then
     414         * need to set the right access mode and ensure SMC coherence.
     415         */
     416        if ((elf->flags & ELDF_RW) != 0) return EE_OK;
     417
     418//      printf("set area flags to %d\n", flags);
    427419        rc = as_area_change_flags(seg_ptr, flags);
    428420        if (rc != 0) {
Note: See TracChangeset for help on using the changeset viewer.