Changes in / [73b3ecd:054476d] in mainline


Ignore:
Files:
4 added
29 edited

Legend:

Unmodified
Added
Removed
  • .bzrignore

    r73b3ecd r054476d  
    33*.prev
    44*.ag.probe.[cs]
     5*.lo
     6*.la
     7*.so.*
    58Makefile.depend
    69Makefile.common
  • boot/Makefile.common

    r73b3ecd r054476d  
    158158ifeq ($(CONFIG_BUILD_SHARED_LIBS), y)
    159159        RD_LIBS += \
    160                 $(USPACE_PATH)/lib/c/libc.so0 \
    161                 $(USPACE_PATH)/lib/softint/libsofti.so0
     160                $(USPACE_PATH)/lib/c/libc.so.0 \
     161                $(USPACE_PATH)/lib/softint/libsoftint.so.0 \
     162                $(USPACE_PATH)/lib/math/libmath.so.0
    162163        RD_APPS += \
    163164                $(USPACE_PATH)/app/dltest/dltest
  • kernel/arch/ia32/include/arch/barrier.h

    r73b3ecd r054476d  
    5454NO_TRACE static inline void cpuid_serialization(void)
    5555{
    56 #ifndef __IN_SHARED_LIBC__
     56#ifndef __PIC__
    5757        asm volatile (
    5858                "xorl %%eax, %%eax\n"
  • uspace/Makefile.common

    r73b3ecd r054476d  
    203203        endif
    204204else
    205         BASE_LIBS = $(LIBC_PREFIX)/libc.so0 $(LIBSOFTINT_PREFIX)/libsofti.so0
     205        BASE_LIBS = $(LIBC_PREFIX)/libc.so.0 $(LIBSOFTINT_PREFIX)/libsoftint.so.0
    206206        LFLAGS += -Bdynamic
    207207        LINKER_SCRIPT ?= $(LIBC_PREFIX)/arch/$(UARCH)/_link-dlexe.ld
    208208        ifeq ($(MATH),y)
    209                 BASE_LIBS += $(LIBMATH_PREFIX)/libmath.so0
     209                BASE_LIBS += $(LIBMATH_PREFIX)/libmath.so.0
    210210        endif
    211211endif
     
    270270        -integrated-as -pipe -g -target $(CLANG_TARGET) -D__$(ENDIANESS)__
    271271
    272 LIB_CFLAGS = $(CFLAGS) -fPIC -D__IN_SHARED_LIBC__
     272LIB_CFLAGS = $(CFLAGS) -fPIC
    273273LIB_LFLAGS = $(LFLAGS) -shared -soname $(LSONAME) --whole-archive
    274274
  • uspace/app/corecfg/corecfg.c

    r73b3ecd r054476d  
    3737#include <stdio.h>
    3838
    39 #define NAME "dnscfg"
     39#define NAME "corecfg"
    4040
    4141static void print_syntax(void)
  • uspace/lib/c/Makefile

    r73b3ecd r054476d  
    4545LIBRARY = libc
    4646SLIBRARY = libc.so.0.0
    47 LSONAME = libc.so0
     47LSONAME = libc.so.0
    4848
    4949LIBS = $(LIBURCU_PREFIX)/liburcu.a
     
    7979        generic/dlfcn.c \
    8080        generic/elf/elf_load.c \
     81        generic/elf/elf_mod.c \
    8182        generic/event.c \
    8283        generic/errno.c \
  • uspace/lib/c/arch/ia32/src/rtld/reloc.c

    r73b3ecd r054476d  
    6969        uint32_t sym_size;
    7070        char *str_tab;
    71        
     71
    7272        elf_symbol_t *sym_def;
    7373        module_t *dest;
     
    8080
    8181        DPRINTF("address: 0x%x, entries: %d\n", (uintptr_t)rt, rt_entries);
    82        
     82
    8383        for (i = 0; i < rt_entries; ++i) {
    8484//              DPRINTF("symbol %d: ", i);
     
    100100//                      DPRINTF("rel_type: %x, rel_offset: 0x%x\n", rel_type, r_offset);
    101101                        sym_def = symbol_def_find(str_tab + sym->st_name,
    102                             m, &dest);
     102                            m, ssf_none, &dest);
    103103//                      DPRINTF("dest name: '%s'\n", dest->dyn.soname);
    104104//                      DPRINTF("dest bias: 0x%x\n", dest->bias);
     
    137137                        /*
    138138                         * Copy symbol data from shared object to specified
    139                          * location.
     139                         * location. Need to find the 'source', i.e. the
     140                         * other instance of the object than the one in the
     141                         * executable program.
    140142                         */
    141143                        DPRINTF("fixup R_386_COPY (s)\n");
     144
     145                        sym_def = symbol_def_find(str_tab + sym->st_name,
     146                            m, ssf_noroot, &dest);
     147
     148                        if (sym_def) {
     149                                sym_addr = (uint32_t)
     150                                    symbol_get_addr(sym_def, dest);
     151                        } else {
     152                                printf("Source definition of '%s' not found.\n",
     153                                    str_tab + sym->st_name);
     154                                continue;
     155                        }
     156
    142157                        sym_size = sym->st_size;
    143158                        if (sym_size != sym_def->st_size) {
     
    147162                                        sym_size = sym_def->st_size;
    148163                        }
     164
    149165                        memcpy(r_ptr, (const void *)sym_addr, sym_size);
    150166                        break;
    151                        
     167
    152168                case R_386_RELATIVE:
    153169                        DPRINTF("fixup R_386_RELATIVE (b+a)\n");
  • uspace/lib/c/generic/dlfcn.c

    r73b3ecd r054476d  
    4242
    4343#include <rtld/module.h>
     44#include <rtld/rtld.h>
    4445#include <rtld/symbol.h>
    4546
     
    5657
    5758        printf("module_find('%s')\n", path);
    58         m = module_find(path);
     59        m = module_find(runtime_env, path);
    5960        if (m == NULL) {
    6061                printf("NULL. module_load('%s')\n", path);
    61                 m = module_load(path);
     62                m = module_load(runtime_env, path);
    6263                printf("module_load_deps(m)\n");
    6364                module_load_deps(m);
     
    8182
    8283        printf("dlsym(0x%lx, \"%s\")\n", (long)mod, sym_name);
    83         sd = symbol_bfs_find(sym_name, (module_t *) mod, &sm);
     84        sd = symbol_bfs_find(sym_name, (module_t *) mod, ssf_none, &sm);
    8485        if (sd != NULL) {
    8586                return symbol_get_addr(sd, sm);
  • uspace/lib/c/generic/elf/elf_load.c

    r73b3ecd r054476d  
    11/*
    2  * Copyright (c) 2006 Sergey Bondari
    3  * Copyright (c) 2006 Jakub Jermar
    4  * Copyright (c) 2011 Jiri Svoboda
     2 * Copyright (c) 2016 Jiri Svoboda
    53 * All rights reserved.
    64 *
     
    3634 * @file
    3735 * @brief       Userspace ELF loader.
    38  *
    39  * This module allows loading ELF binaries (both executables and
    40  * shared objects) from VFS. The current implementation allocates
    41  * anonymous memory, fills it with segment data and then adjusts
    42  * the memory areas' flags to the final value. In the future,
    43  * the segments will be mapped directly from the file.
    4436 */
    4537
     38#include <elf/elf_load.h>
     39#include <elf/elf_mod.h>
     40#include <errno.h>
    4641#include <stdio.h>
    47 #include <sys/types.h>
    48 #include <align.h>
    49 #include <assert.h>
    50 #include <as.h>
    51 #include <elf/elf.h>
    52 #include <unistd.h>
    53 #include <fcntl.h>
    54 #include <smc.h>
    55 #include <loader/pcb.h>
    56 #include <entry_point.h>
     42#include <stdlib.h>
    5743
    58 #include <elf/elf_load.h>
     44#ifdef CONFIG_RTLD
     45#include <rtld/rtld.h>
     46#endif
    5947
    6048#define DPRINTF(...)
    6149
    62 static const char *error_codes[] = {
    63         "no error",
    64         "invalid image",
    65         "address space error",
    66         "incompatible image",
    67         "unsupported image type",
    68         "irrecoverable error"
    69 };
    70 
    71 static unsigned int elf_load(elf_ld_t *elf, size_t so_bias);
    72 static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry);
    73 static int section_header(elf_ld_t *elf, elf_section_header_t *entry);
    74 static int load_segment(elf_ld_t *elf, elf_segment_header_t *entry);
    75 
    76 /** Load ELF binary from a file.
     50/** Load ELF program.
    7751 *
    78  * Load an ELF binary from the specified file. If the file is
    79  * an executable program, it is loaded unbiased. If it is a shared
    80  * object, it is loaded with the bias @a so_bias. Some information
    81  * extracted from the binary is stored in a elf_info_t structure
    82  * pointed to by @a info.
    83  *
    84  * @param file_name Path to the ELF file.
    85  * @param so_bias   Bias to use if the file is a shared object.
    86  * @param info      Pointer to a structure for storing information
    87  *                  extracted from the binary.
    88  *
    89  * @return EOK on success or negative error code.
    90  *
     52 * @param file_name File name
     53 * @param info Place to store ELF program information
     54 * @return EOK on success or non-zero error code
    9155 */
    92 int elf_load_file(const char *file_name, size_t so_bias, eld_flags_t flags,
    93     elf_info_t *info)
     56int elf_load(const char *file_name, elf_info_t *info)
    9457{
    95         elf_ld_t elf;
    96 
    97         int fd;
     58#ifdef CONFIG_RTLD
     59        rtld_t *env;
     60#endif
    9861        int rc;
    9962
    100         fd = open(file_name, O_RDONLY);
    101         if (fd < 0) {
    102                 DPRINTF("failed opening file\n");
    103                 return -1;
     63        rc = elf_load_file(file_name, 0, 0, &info->finfo);
     64        if (rc != EE_OK) {
     65                DPRINTF("Failed to load executable '%s'.\n", file_name);
     66                return rc;
    10467        }
    10568
    106         elf.fd = fd;
    107         elf.info = info;
    108         elf.flags = flags;
     69        if (info->finfo.interp == NULL) {
     70                /* Statically linked program */
     71                DPRINTF("Binary is statically linked.\n");
     72                info->env = NULL;
     73                return EE_OK;
     74        }
    10975
    110         rc = elf_load(&elf, so_bias);
     76        DPRINTF("Binary is dynamically linked.\n");
     77#ifdef CONFIG_RTLD
     78        DPRINTF( "- prog dynamic: %p\n", info->finfo.dynamic);
    11179
    112         close(fd);
    113 
     80        rc = rtld_prog_process(&info->finfo, &env);
     81        info->env = env;
     82#else
     83        rc = EE_UNSUPPORTED;
     84#endif
    11485        return rc;
    11586}
    11687
    117 /** Create the program control block (PCB).
     88/** Set ELF-related PCB entries.
    11889 *
    11990 * Fills the program control block @a pcb with information from
     
    12192 *
    12293 * @param info  Program info structure
    123  * @return EOK on success or negative error code
     94 * @param pcb PCB
    12495 */
    125 void elf_create_pcb(elf_info_t *info, pcb_t *pcb)
     96void elf_set_pcb(elf_info_t *info, pcb_t *pcb)
    12697{
    127         pcb->entry = info->entry;
    128         pcb->dynamic = info->dynamic;
    129         pcb->rtld_runtime = NULL;
    130 }
    131 
    132 
    133 /** Load an ELF binary.
    134  *
    135  * The @a elf structure contains the loader state, including
    136  * an open file, from which the binary will be loaded,
    137  * a pointer to the @c info structure etc.
    138  *
    139  * @param elf           Pointer to loader state buffer.
    140  * @param so_bias       Bias to use if the file is a shared object.
    141  * @return EE_OK on success or EE_xx error code.
    142  */
    143 static unsigned int elf_load(elf_ld_t *elf, size_t so_bias)
    144 {
    145         elf_header_t header_buf;
    146         elf_header_t *header = &header_buf;
    147         int i, rc;
    148 
    149         rc = read(elf->fd, header, sizeof(elf_header_t));
    150         if (rc != sizeof(elf_header_t)) {
    151                 DPRINTF("Read error.\n");
    152                 return EE_INVALID;
    153         }
    154 
    155         elf->header = header;
    156 
    157         /* Identify ELF */
    158         if (header->e_ident[EI_MAG0] != ELFMAG0 ||
    159             header->e_ident[EI_MAG1] != ELFMAG1 ||
    160             header->e_ident[EI_MAG2] != ELFMAG2 ||
    161             header->e_ident[EI_MAG3] != ELFMAG3) {
    162                 DPRINTF("Invalid header.\n");
    163                 return EE_INVALID;
    164         }
    165        
    166         /* Identify ELF compatibility */
    167         if (header->e_ident[EI_DATA] != ELF_DATA_ENCODING ||
    168             header->e_machine != ELF_MACHINE ||
    169             header->e_ident[EI_VERSION] != EV_CURRENT ||
    170             header->e_version != EV_CURRENT ||
    171             header->e_ident[EI_CLASS] != ELF_CLASS) {
    172                 DPRINTF("Incompatible data/version/class.\n");
    173                 return EE_INCOMPATIBLE;
    174         }
    175 
    176         if (header->e_phentsize != sizeof(elf_segment_header_t)) {
    177                 DPRINTF("e_phentsize:%d != %d\n", header->e_phentsize,
    178                     sizeof(elf_segment_header_t));
    179                 return EE_INCOMPATIBLE;
    180         }
    181 
    182         if (header->e_shentsize != sizeof(elf_section_header_t)) {
    183                 DPRINTF("e_shentsize:%d != %d\n", header->e_shentsize,
    184                     sizeof(elf_section_header_t));
    185                 return EE_INCOMPATIBLE;
    186         }
    187 
    188         /* Check if the object type is supported. */
    189         if (header->e_type != ET_EXEC && header->e_type != ET_DYN) {
    190                 DPRINTF("Object type %d is not supported\n", header->e_type);
    191                 return EE_UNSUPPORTED;
    192         }
    193 
    194         /* Shared objects can be loaded with a bias */
    195         if (header->e_type == ET_DYN)
    196                 elf->bias = so_bias;
    197         else
    198                 elf->bias = 0;
    199 
    200         elf->info->interp = NULL;
    201         elf->info->dynamic = NULL;
    202 
    203         /* Walk through all segment headers and process them. */
    204         for (i = 0; i < header->e_phnum; i++) {
    205                 elf_segment_header_t segment_hdr;
    206 
    207                 /* Seek to start of segment header */
    208                 lseek(elf->fd, header->e_phoff
    209                         + i * sizeof(elf_segment_header_t), SEEK_SET);
    210 
    211                 rc = read(elf->fd, &segment_hdr,
    212                     sizeof(elf_segment_header_t));
    213                 if (rc != sizeof(elf_segment_header_t)) {
    214                         DPRINTF("Read error.\n");
    215                         return EE_INVALID;
    216                 }
    217 
    218                 rc = segment_header(elf, &segment_hdr);
    219                 if (rc != EE_OK)
    220                         return rc;
    221         }
    222 
    223         DPRINTF("Parse sections.\n");
    224 
    225         /* Inspect all section headers and proccess them. */
    226         for (i = 0; i < header->e_shnum; i++) {
    227                 elf_section_header_t section_hdr;
    228 
    229                 /* Seek to start of section header */
    230                 lseek(elf->fd, header->e_shoff
    231                     + i * sizeof(elf_section_header_t), SEEK_SET);
    232 
    233                 rc = read(elf->fd, &section_hdr,
    234                     sizeof(elf_section_header_t));
    235                 if (rc != sizeof(elf_section_header_t)) {
    236                         DPRINTF("Read error.\n");
    237                         return EE_INVALID;
    238                 }
    239 
    240                 rc = section_header(elf, &section_hdr);
    241                 if (rc != EE_OK)
    242                         return rc;
    243         }
    244 
    245         elf->info->entry =
    246             (entry_point_t)((uint8_t *)header->e_entry + elf->bias);
    247 
    248         DPRINTF("Done.\n");
    249 
    250         return EE_OK;
    251 }
    252 
    253 /** Print error message according to error code.
    254  *
    255  * @param rc Return code returned by elf_load().
    256  *
    257  * @return NULL terminated description of error.
    258  */
    259 const char *elf_error(unsigned int rc)
    260 {
    261         assert(rc < sizeof(error_codes) / sizeof(char *));
    262 
    263         return error_codes[rc];
    264 }
    265 
    266 /** Process segment header.
    267  *
    268  * @param entry Segment header.
    269  *
    270  * @return EE_OK on success, error code otherwise.
    271  */
    272 static int segment_header(elf_ld_t *elf, elf_segment_header_t *entry)
    273 {
    274         switch (entry->p_type) {
    275         case PT_NULL:
    276         case PT_PHDR:
    277         case PT_NOTE:
    278                 break;
    279         case PT_LOAD:
    280                 return load_segment(elf, entry);
    281                 break;
    282         case PT_INTERP:
    283                 /* Assume silently interp == "/app/dload" */
    284                 elf->info->interp = "/app/dload";
    285                 break;
    286         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;
    296         case PT_SHLIB:
    297 //      case PT_LOPROC:
    298 //      case PT_HIPROC:
    299         default:
    300                 DPRINTF("Segment p_type %d unknown.\n", entry->p_type);
    301                 return EE_UNSUPPORTED;
    302                 break;
    303         }
    304         return EE_OK;
    305 }
    306 
    307 /** Load segment described by program header entry.
    308  *
    309  * @param elf   Loader state.
    310  * @param entry Program header entry describing segment to be loaded.
    311  *
    312  * @return EE_OK on success, error code otherwise.
    313  */
    314 int load_segment(elf_ld_t *elf, elf_segment_header_t *entry)
    315 {
    316         void *a;
    317         int flags = 0;
    318         uintptr_t bias;
    319         uintptr_t base;
    320         void *seg_ptr;
    321         uintptr_t seg_addr;
    322         size_t mem_sz;
    323         ssize_t rc;
    324 
    325         bias = elf->bias;
    326 
    327         seg_addr = entry->p_vaddr + bias;
    328         seg_ptr = (void *) seg_addr;
    329 
    330         DPRINTF("Load segment at addr %p, size 0x%x\n", (void *) seg_addr,
    331                 entry->p_memsz);
    332 
    333         if (entry->p_align > 1) {
    334                 if ((entry->p_offset % entry->p_align) !=
    335                     (seg_addr % entry->p_align)) {
    336                         DPRINTF("Align check 1 failed offset%%align=%d, "
    337                             "vaddr%%align=%d\n",
    338                             entry->p_offset % entry->p_align,
    339                             seg_addr % entry->p_align
    340                         );
    341                         return EE_INVALID;
    342                 }
    343         }
    344 
    345         /* Final flags that will be set for the memory area */
    346 
    347         if (entry->p_flags & PF_X)
    348                 flags |= AS_AREA_EXEC;
    349         if (entry->p_flags & PF_W)
    350                 flags |= AS_AREA_WRITE;
    351         if (entry->p_flags & PF_R)
    352                 flags |= AS_AREA_READ;
    353         flags |= AS_AREA_CACHEABLE;
    354        
    355         base = ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE);
    356         mem_sz = entry->p_memsz + (entry->p_vaddr - base);
    357 
    358         DPRINTF("Map to seg_addr=%p-%p.\n", (void *) seg_addr,
    359             (void *) (entry->p_vaddr + bias +
    360             ALIGN_UP(entry->p_memsz, PAGE_SIZE)));
    361 
    362         /*
    363          * For the course of loading, the area needs to be readable
    364          * and writeable.
    365          */
    366         a = as_area_create((uint8_t *) base + bias, mem_sz,
    367             AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
    368         if (a == AS_MAP_FAILED) {
    369                 DPRINTF("memory mapping failed (0x%x, %d)\n",
    370                     base + bias, mem_sz);
    371                 return EE_MEMORY;
    372         }
    373 
    374         DPRINTF("as_area_create(%p, %#zx, %d) -> %p\n",
    375             (void *) (base + bias), mem_sz, flags, (void *) a);
    376 
    377         /*
    378          * Load segment data
    379          */
    380         rc = lseek(elf->fd, entry->p_offset, SEEK_SET);
    381         if (rc < 0) {
    382                 printf("seek error\n");
    383                 return EE_INVALID;
    384         }
    385 
    386 /*      rc = read(fd, (void *)(entry->p_vaddr + bias), entry->p_filesz);
    387         if (rc < 0) { printf("read error\n"); return EE_INVALID; }*/
    388 
    389         /* Long reads are not possible yet. Load segment piecewise. */
    390 
    391         unsigned left, now;
    392         uint8_t *dp;
    393 
    394         left = entry->p_filesz;
    395         dp = seg_ptr;
    396 
    397         while (left > 0) {
    398                 now = 16384;
    399                 if (now > left) now = left;
    400 
    401                 rc = read(elf->fd, dp, now);
    402 
    403                 if (rc != (ssize_t) now) {
    404                         DPRINTF("Read error.\n");
    405                         return EE_INVALID;
    406                 }
    407 
    408                 left -= now;
    409                 dp += now;
    410         }
    411 
    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);
    419         rc = as_area_change_flags(seg_ptr, flags);
    420         if (rc != 0) {
    421                 DPRINTF("Failed to set memory area flags.\n");
    422                 return EE_MEMORY;
    423         }
    424 
    425         if (flags & AS_AREA_EXEC) {
    426                 /* Enforce SMC coherence for the segment */
    427                 if (smc_coherence(seg_ptr, entry->p_filesz))
    428                         return EE_MEMORY;
    429         }
    430 
    431         return EE_OK;
    432 }
    433 
    434 /** Process section header.
    435  *
    436  * @param elf   Loader state.
    437  * @param entry Segment header.
    438  *
    439  * @return EE_OK on success, error code otherwise.
    440  */
    441 static int section_header(elf_ld_t *elf, elf_section_header_t *entry)
    442 {
    443         switch (entry->sh_type) {
    444         case SHT_PROGBITS:
    445                 if (entry->sh_flags & SHF_TLS) {
    446                         /* .tdata */
    447                 }
    448                 break;
    449         case SHT_NOBITS:
    450                 if (entry->sh_flags & SHF_TLS) {
    451                         /* .tbss */
    452                 }
    453                 break;
    454         case SHT_DYNAMIC:
    455                 /* Record pointer to dynamic section into info structure */
    456                 elf->info->dynamic =
    457                     (void *)((uint8_t *)entry->sh_addr + elf->bias);
    458                 DPRINTF("Dynamic section found at %p.\n",
    459                     (void *) elf->info->dynamic);
    460                 break;
    461         default:
    462                 break;
    463         }
    464        
    465         return EE_OK;
     98        pcb->entry = info->finfo.entry;
     99        pcb->dynamic = info->finfo.dynamic;
     100        pcb->rtld_runtime = info->env;
    466101}
    467102
  • uspace/lib/c/generic/libc.c

    r73b3ecd r054476d  
    8989        char **argv;
    9090       
    91 #ifdef __IN_SHARED_LIBC__
     91#ifdef CONFIG_RTLD
    9292        if (__pcb != NULL && __pcb->rtld_runtime != NULL) {
    93                 runtime_env = (runtime_env_t *) __pcb->rtld_runtime;
     93                runtime_env = (rtld_t *) __pcb->rtld_runtime;
    9494        }
    9595#endif
  • uspace/lib/c/generic/rtld/module.c

    r73b3ecd r054476d  
    9191 * path components are ignored.
    9292 */
    93 module_t *module_find(const char *name)
     93module_t *module_find(rtld_t *rtld, const char *name)
    9494{
    9595        const char *p, *soname;
     
    106106
    107107        /* Traverse list of all modules. Not extremely fast, but simple */
    108         list_foreach(runtime_env->modules, modules_link, module_t, m) {
     108        list_foreach(rtld->modules, modules_link, module_t, m) {
    109109                DPRINTF("m = %p\n", m);
    110110                if (str_cmp(m->dyn.soname, soname) == 0) {
     
    122122 * Currently this trivially tries to load '/<name>'.
    123123 */
    124 module_t *module_load(const char *name)
    125 {
    126         elf_info_t info;
     124module_t *module_load(rtld_t *rtld, const char *name)
     125{
     126        elf_finfo_t info;
    127127        char name_buf[NAME_BUF_SIZE];
    128128        module_t *m;
     
    135135        }
    136136
     137        m->rtld = rtld;
     138
    137139        if (str_size(name) > NAME_BUF_SIZE - 2) {
    138140                printf("soname too long. increase NAME_BUF_SIZE\n");
     
    145147
    146148        /* FIXME: need to real allocation of address space */
    147         m->bias = runtime_env->next_bias;
    148         runtime_env->next_bias += 0x100000;
     149        m->bias = rtld->next_bias;
     150        rtld->next_bias += 0x100000;
    149151
    150152        DPRINTF("filename:'%s'\n", name_buf);
     
    171173
    172174        /* Insert into the list of loaded modules */
    173         list_append(&m->modules_link, &runtime_env->modules);
     175        list_append(&m->modules_link, &rtld->modules);
    174176
    175177        return m;
     
    221223
    222224                        DPRINTF("%s needs %s\n", m->dyn.soname, dep_name);
    223                         dm = module_find(dep_name);
     225                        dm = module_find(m->rtld, dep_name);
    224226                        if (!dm) {
    225                                 dm = module_load(dep_name);
     227                                dm = module_load(m->rtld, dep_name);
    226228                                module_load_deps(dm);
    227229                        }
     
    241243 * @param       start   The module where to start from.
    242244 */
    243 void modules_process_relocs(module_t *start)
    244 {
    245         list_foreach(runtime_env->modules, modules_link, module_t, m) {
    246                 /* Skip rtld, since it has already been processed */
    247                 if (m != &runtime_env->rtld) {
     245void modules_process_relocs(rtld_t *rtld, module_t *start)
     246{
     247        list_foreach(rtld->modules, modules_link, module_t, m) {
     248                /* Skip rtld module, since it has already been processed */
     249                if (m != &rtld->rtld) {
    248250                        module_process_relocs(m);
    249251                }
     
    253255/** Clear BFS tags of all modules.
    254256 */
    255 void modules_untag(void)
    256 {
    257         list_foreach(runtime_env->modules, modules_link, module_t, m) {
     257void modules_untag(rtld_t *rtld)
     258{
     259        list_foreach(rtld->modules, modules_link, module_t, m) {
    258260                m->bfs_tag = false;
    259261        }
  • uspace/lib/c/generic/rtld/rtld.c

    r73b3ecd r054476d  
    3535 */
    3636
     37#include <errno.h>
     38#include <rtld/module.h>
    3739#include <rtld/rtld.h>
     40#include <rtld/rtld_debug.h>
     41#include <stdlib.h>
    3842
    39 runtime_env_t *runtime_env;
    40 static runtime_env_t rt_env_static;
     43rtld_t *runtime_env;
     44static rtld_t rt_env_static;
     45static module_t prog_mod;
    4146
    42 /** Initialize the loder for use in a statically-linked binary. */
     47/** Initialize the runtime linker for use in a statically-linked executable. */
    4348void rtld_init_static(void)
    4449{
     
    4954}
    5055
     56/** Initialize and process a dynamically linked executable.
     57 *
     58 * @param p_info Program info
     59 * @return EOK on success or non-zero error code
     60 */
     61int rtld_prog_process(elf_finfo_t *p_info, rtld_t **rre)
     62{
     63        rtld_t *env;
     64
     65        DPRINTF("Load dynamically linked program.\n");
     66
     67        /* Allocate new RTLD environment to pass to the loaded program */
     68        env = calloc(1, sizeof(rtld_t));
     69        if (env == NULL)
     70                return ENOMEM;
     71
     72        /*
     73         * First we need to process dynamic sections of the executable
     74         * program and insert it into the module graph.
     75         */
     76
     77        DPRINTF("Parse program .dynamic section at %p\n", p_info->dynamic);
     78        dynamic_parse(p_info->dynamic, 0, &prog_mod.dyn);
     79        prog_mod.bias = 0;
     80        prog_mod.dyn.soname = "[program]";
     81        prog_mod.rtld = env;
     82
     83        /* Initialize list of loaded modules */
     84        list_initialize(&env->modules);
     85        list_append(&prog_mod.modules_link, &env->modules);
     86
     87        /* Pointer to program module. Used as root of the module graph. */
     88        env->program = &prog_mod;
     89
     90        /* Work around non-existent memory space allocation. */
     91        env->next_bias = 0x1000000;
     92
     93        /*
     94         * Now we can continue with loading all other modules.
     95         */
     96
     97        DPRINTF("Load all program dependencies\n");
     98        module_load_deps(&prog_mod);
     99
     100        /*
     101         * Now relocate/link all modules together.
     102         */
     103
     104        /* Process relocations in all modules */
     105        DPRINTF("Relocate all modules\n");
     106        modules_process_relocs(env, &prog_mod);
     107
     108        *rre = env;
     109        return EOK;
     110}
     111
    51112/** @}
    52113 */
  • uspace/lib/c/generic/rtld/symbol.c

    r73b3ecd r054476d  
    3939
    4040#include <elf/elf.h>
     41#include <rtld/module.h>
    4142#include <rtld/rtld.h>
    4243#include <rtld/rtld_debug.h>
     
    111112 * @param name          Name of the symbol to search for.
    112113 * @param start         Module in which to start the search..
     114 * @param flags         @c ssf_none or @c ssf_noroot to not look for the symbol
     115 *                      in @a start
    113116 * @param mod           (output) Will be filled with a pointer to the module
    114117 *                      that contains the symbol.
    115118 */
    116 elf_symbol_t *symbol_bfs_find(const char *name, module_t *start, module_t **mod)
     119elf_symbol_t *symbol_bfs_find(const char *name, module_t *start,
     120    symbol_search_flags_t flags, module_t **mod)
    117121{
    118122        module_t *m, *dm;
     
    129133
    130134        /* Mark all vertices (modules) as unvisited */ 
    131         modules_untag();
     135        modules_untag(start->rtld);
    132136
    133137        /* Insert root (the program) into the queue and tag it */
     
    145149                list_remove(&m->queue_link);
    146150
    147                 s = def_find_in_module(name, m);
    148                 if (s != NULL) {
    149                         /* Symbol found */
    150                         sym = s;
    151                         *mod = m;
    152                         break;
     151                /* If ssf_noroot is specified, do not look in start module */
     152                if (m != start || (flags & ssf_noroot) == 0) {
     153                        s = def_find_in_module(name, m);
     154                        if (s != NULL) {
     155                                /* Symbol found */
     156                                sym = s;
     157                                *mod = m;
     158                                break;
     159                        }
    153160                }
    154161
     
    179186
    180187
    181 /** Find the definition of a symbol..
     188/** Find the definition of a symbol.
    182189 *
    183190 * By definition in System V ABI, if module origin has the flag DT_SYMBOLIC,
     
    188195 * @param name          Name of the symbol to search for.
    189196 * @param origin        Module in which the dependency originates.
     197 * @param flags         @c ssf_none or @c ssf_noroot to not look for the symbol
     198 *                      in the executable program.
    190199 * @param mod           (output) Will be filled with a pointer to the module
    191200 *                      that contains the symbol.
    192201 */
    193 elf_symbol_t *symbol_def_find(const char *name, module_t *origin, module_t **mod)
     202elf_symbol_t *symbol_def_find(const char *name, module_t *origin,
     203    symbol_search_flags_t flags, module_t **mod)
    194204{
    195205        elf_symbol_t *s;
     
    210220        /* Not DT_SYMBOLIC or no match. Now try other locations. */
    211221
    212         if (runtime_env->program) {
     222        if (origin->rtld->program) {
    213223                /* Program is dynamic -- start with program as root. */
    214                 return symbol_bfs_find(name, runtime_env->program, mod);
     224                return symbol_bfs_find(name, origin->rtld->program, flags, mod);
    215225        } else {
    216226                /* Program is static -- start with @a origin as root. */
    217                 return symbol_bfs_find(name, origin, mod);
     227                return symbol_bfs_find(name, origin, ssf_none, mod);
    218228        }
    219229}
  • uspace/lib/c/include/elf/elf_load.h

    r73b3ecd r054476d  
    11/*
    2  * Copyright (c) 2006 Sergey Bondari
    3  * Copyright (c) 2008 Jiri Svoboda
     2 * Copyright (c) 2016 Jiri Svoboda
    43 * All rights reserved.
    54 *
     
    3231 */
    3332/** @file
    34  * @brief ELF loader structures and public functions.
     33 * @brief
    3534 */
    3635
     
    3837#define ELF_LOAD_H_
    3938
    40 #include <elf/elf.h>
    41 #include <sys/types.h>
    42 #include <loader/pcb.h>
     39#include <elf/elf_mod.h>
    4340
    44 /**
    45  * ELF error return codes
    46  */
    47 #define EE_OK                   0       /* No error */
    48 #define EE_INVALID              1       /* Invalid ELF image */
    49 #define EE_MEMORY               2       /* Cannot allocate address space */
    50 #define EE_INCOMPATIBLE         3       /* ELF image is not compatible with current architecture */
    51 #define EE_UNSUPPORTED          4       /* Non-supported ELF (e.g. dynamic ELFs) */
    52 #define EE_LOADER               5       /* The image is actually a program loader. */
    53 #define EE_IRRECOVERABLE        6
    54 
    55 typedef enum {
    56         /** Leave all segments in RW access mode. */
    57         ELDF_RW = 1
    58 } eld_flags_t;
    59 
    60 /**
    61  * Some data extracted from the headers are stored here
    62  */
     41/** Information on loaded ELF program */
    6342typedef struct {
    64         /** Entry point */
    65         entry_point_t entry;
    66 
    67         /** ELF interpreter name or NULL if statically-linked */
    68         const char *interp;
    69 
    70         /** Pointer to the dynamic section */
    71         void *dynamic;
     43        elf_finfo_t finfo;
     44        struct rtld *env;
    7245} elf_info_t;
    7346
    74 /**
    75  * Holds information about an ELF binary being loaded.
    76  */
    77 typedef struct {
    78         /** Filedescriptor of the file from which we are loading */
    79         int fd;
    80 
    81         /** Difference between run-time addresses and link-time addresses */
    82         uintptr_t bias;
    83 
    84         /** Flags passed to the ELF loader. */
    85         eld_flags_t flags;
    86 
    87         /** A copy of the ELF file header */
    88         elf_header_t *header;
    89 
    90         /** Store extracted info here */
    91         elf_info_t *info;
    92 } elf_ld_t;
    93 
    94 extern const char *elf_error(unsigned int);
    95 extern int elf_load_file(const char *, size_t, eld_flags_t, elf_info_t *);
    96 extern void elf_create_pcb(elf_info_t *, pcb_t *);
     47extern int elf_load(const char *, elf_info_t *);
     48extern void elf_set_pcb(elf_info_t *, pcb_t *);
    9749
    9850#endif
  • uspace/lib/c/include/loader/pcb.h

    r73b3ecd r054476d  
    6969        /** Pointer to ELF dynamic section of the program. */
    7070        void *dynamic;
    71         /** Pointer to dynamic linker state structure (runtime_env_t). */
     71        /** Pointer to dynamic linker state structure (rtld_t). */
    7272        void *rtld_runtime;
    7373} pcb_t;
  • uspace/lib/c/include/rtld/module.h

    r73b3ecd r054476d  
    3939#include <rtld/dynamic.h>
    4040#include <adt/list.h>
     41#include <types/rtld/module.h>
     42#include <types/rtld/rtld.h>
    4143
    42 typedef struct module {
    43         dyn_info_t dyn;
    44         size_t bias;
     44extern void module_process_relocs(module_t *);
     45extern module_t *module_find(rtld_t *, const char *);
     46extern module_t *module_load(rtld_t *, const char *);
     47extern void module_load_deps(module_t *);
    4548
    46         /** Array of pointers to directly dependent modules */
    47         struct module **deps;
    48         /** Number of fields in deps */
    49         size_t n_deps;
    50 
    51         /** True iff relocations have already been processed in this module. */
    52         bool relocated;
    53 
    54         /** Link to list of all modules in runtime environment */
    55         link_t modules_link;
    56 
    57         /** Link to BFS queue. Only used when doing a BFS of the module graph */
    58         link_t queue_link;
    59         /** Tag for modules already processed during a BFS */
    60         bool bfs_tag;
    61 } module_t;
    62 
    63 void module_process_relocs(module_t *m);
    64 module_t *module_find(const char *name);
    65 module_t *module_load(const char *name);
    66 void module_load_deps(module_t *m);
    67 
    68 void modules_process_relocs(module_t *start);
    69 void modules_untag(void);
     49extern void modules_process_relocs(rtld_t *, module_t *);
     50extern void modules_untag(rtld_t *);
    7051
    7152#endif
  • uspace/lib/c/include/rtld/rtld.h

    r73b3ecd r054476d  
    3636#define LIBC_RTLD_H_
    3737
     38#include <adt/list.h>
     39#include <elf/elf_mod.h>
    3840#include <sys/types.h>
    39 #include <adt/list.h>
    4041
    4142#include <rtld/dynamic.h>
    42 #include <rtld/module.h>
     43#include <types/rtld/rtld.h>
    4344
    44 typedef struct {
    45         elf_dyn_t *rtld_dynamic;
    46         module_t rtld;
    47 
    48         module_t *program;
    49 
    50         /** List of all loaded modules including rtld and the program */
    51         list_t modules;
    52 
    53         /** Temporary hack to place each module at different address. */
    54         uintptr_t next_bias;
    55 } runtime_env_t;
    56 
    57 extern runtime_env_t *runtime_env;
     45extern rtld_t *runtime_env;
    5846
    5947extern void rtld_init_static(void);
     48extern int rtld_prog_process(elf_finfo_t *, rtld_t **);
    6049
    6150#endif
  • uspace/lib/c/include/rtld/rtld_debug.h

    r73b3ecd r054476d  
    3636#define LIBC_RTLD_RTLD_DEBUG_H_
    3737
     38#include <stdio.h>
     39
    3840/* Define to enable debugging mode. */
    3941#undef RTLD_DEBUG
  • uspace/lib/c/include/rtld/symbol.h

    r73b3ecd r054476d  
    3939#include <rtld/rtld.h>
    4040
    41 elf_symbol_t *symbol_bfs_find(const char *name, module_t *start, module_t **mod);
    42 elf_symbol_t *symbol_def_find(const char *name, module_t *origin, module_t **mod);
    43 void *symbol_get_addr(elf_symbol_t *sym, module_t *m);
     41/** Symbol search flags */
     42typedef enum {
     43        /** No flags */
     44        ssf_none = 0,
     45        /** Do not search tree root */
     46        ssf_noroot = 0x1
     47} symbol_search_flags_t;
     48
     49extern elf_symbol_t *symbol_bfs_find(const char *, module_t *,
     50    symbol_search_flags_t, module_t **);
     51extern elf_symbol_t *symbol_def_find(const char *, module_t *,
     52    symbol_search_flags_t, module_t **);
     53extern void *symbol_get_addr(elf_symbol_t *, module_t *);
    4454
    4555#endif
  • uspace/lib/draw/Makefile

    r73b3ecd r054476d  
    3030LIBRARY = libdraw
    3131SLIBRARY = libdraw.so.0.0
    32 LSONAME = libdraw.so0
     32LSONAME = libdraw.so.0
    3333EXTRA_CFLAGS += -I$(LIBSOFTREND_PREFIX) -I$(LIBCOMPRESS_PREFIX)
    3434
  • uspace/lib/graph/Makefile

    r73b3ecd r054476d  
    3030LIBRARY = libgraph
    3131SLIBRARY = libgraph.so.0.0
    32 LSONAME = libgraph.so0
     32LSONAME = libgraph.so.0
    3333
    3434SOURCES = \
  • uspace/lib/gui/Makefile

    r73b3ecd r054476d  
    3030LIBRARY = libgui
    3131SLIBRARY = libgui.so.0.0
    32 LSONAME = libgui.so0
     32LSONAME = libgui.so.0
    3333EXTRA_CFLAGS += -I$(LIBDRAW_PREFIX) -I$(LIBSOFTREND_PREFIX) -I$(LIBGRAPH_PREFIX)
    3434
  • uspace/lib/http/Makefile

    r73b3ecd r054476d  
    3030LIBRARY = libhttp
    3131SLIBRARY = libhttp.so.0.0
    32 LSONAME = libhttp.so0
     32LSONAME = libhttp.so.0
    3333EXTRA_CFLAGS += -Iinclude
    3434
  • uspace/lib/math/Makefile

    r73b3ecd r054476d  
    3434LIBRARY = libmath
    3535SLIBRARY = libmath.so.0.0
    36 LSONAME = libmath.so0
     36LSONAME = libmath.so.0
    3737MATH = y
    3838
  • uspace/lib/posix/Makefile

    r73b3ecd r054476d  
    3131LIBRARY = libposix
    3232SLIBRARY = libposix.so.0.0
    33 LSONAME = libposix.so0
     33LSONAME = libposix.so.0
    3434
    3535EXTRA_CFLAGS = -Iinclude/
  • uspace/lib/softint/Makefile

    r73b3ecd r054476d  
    3232LIBRARY = libsoftint
    3333SLIBRARY = libsoftint.so.0.0
    34 LSONAME = libsofti.so0
     34LSONAME = libsoftint.so.0
    3535
    3636SOURCES = \
  • uspace/lib/softrend/Makefile

    r73b3ecd r054476d  
    3030LIBRARY = libsoftrend
    3131SLIBRARY = libsoftrend.so.0.0
    32 LSONAME = libsoftrend.so0
     32LSONAME = libsoftrend.so.0
    3333MATH = y
    3434
  • uspace/lib/uri/Makefile

    r73b3ecd r054476d  
    3030LIBRARY = liburi
    3131SLIBRARY = liburi.so.0.0
    32 LSONAME = liburi.so0
     32LSONAME = liburi.so.0
    3333#EXTRA_CFLAGS +=
    3434
  • uspace/srv/loader/main.c

    r73b3ecd r054476d  
    6363#include <vfs/vfs.h>
    6464
    65 #ifdef CONFIG_RTLD
    66 #include <rtld/rtld.h>
    67 #include <rtld/dynamic.h>
    68 #include <rtld/module.h>
    69 
    70 static int ldr_load_dyn_linked(elf_info_t *p_info);
    71 #endif
    72 
    7365#define DPRINTF(...)
    7466
     
    9688/** Used to limit number of connections to one. */
    9789static bool connected = false;
    98 
    99 #ifdef CONFIG_RTLD
    100 /** State structure of the dynamic linker. */
    101 runtime_env_t dload_re;
    102 static module_t prog_mod;
    103 #endif
    10490
    10591static void ldr_get_taskid(ipc_callid_t rid, ipc_call_t *request)
     
    268254        int rc;
    269255       
    270         rc = elf_load_file(pathname, 0, 0, &prog_info);
     256        rc = elf_load(pathname, &prog_info);
    271257        if (rc != EE_OK) {
    272258                DPRINTF("Failed to load executable '%s'.\n", pathname);
     
    275261        }
    276262       
    277         elf_create_pcb(&prog_info, &pcb);
     263        elf_set_pcb(&prog_info, &pcb);
    278264       
    279265        pcb.cwd = cwd;
     
    283269       
    284270        pcb.filc = filc;
    285        
    286         if (prog_info.interp == NULL) {
    287                 /* Statically linked program */
    288                 async_answer_0(rid, EOK);
    289                 return 0;
    290         }
    291        
    292         DPRINTF("Binary is dynamically linked.\n");
    293 #ifdef CONFIG_RTLD
    294         DPRINTF(" - pcb address: %p\n", &pcb);
    295         DPRINTF( "- prog dynamic: %p\n", prog_info.dynamic);
    296 
    297         rc = ldr_load_dyn_linked(&prog_info);
    298 #else
    299         rc = ENOTSUP;
    300 #endif
     271        printf("dynamic=%p rtld_env=%p\n", pcb.dynamic, pcb.rtld_runtime);
     272       
    301273        async_answer_0(rid, rc);
    302274        return 0;
    303275}
    304 
    305 #ifdef CONFIG_RTLD
    306 
    307 static int ldr_load_dyn_linked(elf_info_t *p_info)
    308 {
    309         runtime_env = &dload_re;
    310 
    311         DPRINTF("Load dynamically linked program.\n");
    312 
    313         /*
    314          * First we need to process dynamic sections of the executable
    315          * program and insert it into the module graph.
    316          */
    317 
    318         DPRINTF("Parse program .dynamic section at %p\n", p_info->dynamic);
    319         dynamic_parse(p_info->dynamic, 0, &prog_mod.dyn);
    320         prog_mod.bias = 0;
    321         prog_mod.dyn.soname = "[program]";
    322 
    323         /* Initialize list of loaded modules */
    324         list_initialize(&runtime_env->modules);
    325         list_append(&prog_mod.modules_link, &runtime_env->modules);
    326 
    327         /* Pointer to program module. Used as root of the module graph. */
    328         runtime_env->program = &prog_mod;
    329 
    330         /* Work around non-existent memory space allocation. */
    331         runtime_env->next_bias = 0x1000000;
    332 
    333         /*
    334          * Now we can continue with loading all other modules.
    335          */
    336 
    337         DPRINTF("Load all program dependencies\n");
    338         module_load_deps(&prog_mod);
    339 
    340         /*
    341          * Now relocate/link all modules together.
    342          */
    343 
    344         /* Process relocations in all modules */
    345         DPRINTF("Relocate all modules\n");
    346         modules_process_relocs(&prog_mod);
    347 
    348         /* Pass runtime evironment pointer through PCB. */
    349         pcb.rtld_runtime = (void *) runtime_env;
    350 
    351         return 0;
    352 }
    353 #endif
    354276
    355277/** Run the previously loaded program.
     
    374296        async_answer_0(rid, EOK);
    375297        DPRINTF("Jump to entry point at %p\n", pcb.entry);
    376         entry_point_jmp(prog_info.entry, &pcb);
     298        entry_point_jmp(prog_info.finfo.entry, &pcb);
    377299       
    378300        /* Not reached */
Note: See TracChangeset for help on using the changeset viewer.