dynamic.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2008 Jiri Svoboda
00003  * All rights reserved.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  *
00009  * - Redistributions of source code must retain the above copyright
00010  *   notice, this list of conditions and the following disclaimer.
00011  * - Redistributions in binary form must reproduce the above copyright
00012  *   notice, this list of conditions and the following disclaimer in the
00013  *   documentation and/or other materials provided with the distribution.
00014  * - The name of the author may not be used to endorse or promote products
00015  *   derived from this software without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00018  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00019  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00020  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00021  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00022  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00023  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00024  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027  */
00028 
00037 #include <stdio.h>
00038 
00039 #include <rtld/elf_dyn.h>
00040 #include <rtld/dynamic.h>
00041 #include <rtld/rtld.h>
00042 #include <rtld/rtld_debug.h>
00043 
00044 void dynamic_parse(elf_dyn_t *dyn_ptr, size_t bias, dyn_info_t *info)
00045 {
00046         elf_dyn_t *dp = dyn_ptr;
00047 
00048         void *d_ptr;
00049         elf_word d_val;
00050 
00051         elf_word soname_idx;
00052         elf_word rpath_idx;
00053 
00054         DPRINTF("memset\n");
00055         memset(info, 0, sizeof(dyn_info_t));
00056 
00057         soname_idx = 0;
00058         rpath_idx = 0;
00059 
00060         DPRINTF("pass 1\n");
00061         while (dp->d_tag != DT_NULL) {
00062                 d_ptr = (void *)((uint8_t *)dp->d_un.d_ptr + bias);
00063                 d_val = dp->d_un.d_val;
00064                 DPRINTF("tag=%u ptr=0x%x val=%u\n", (unsigned)dp->d_tag,
00065                         (unsigned)d_ptr, (unsigned)d_val);
00066 
00067                 switch (dp->d_tag) {
00068 
00069                 case DT_PLTRELSZ:       info->plt_rel_sz = d_val; break;
00070                 case DT_PLTGOT:         info->plt_got = d_ptr; break;
00071                 case DT_HASH:           info->hash = d_ptr; break;
00072                 case DT_STRTAB:         info->str_tab = d_ptr; break;
00073                 case DT_SYMTAB:         info->sym_tab = d_ptr; break;
00074                 case DT_RELA:           info->rela = d_ptr; break;
00075                 case DT_RELASZ:         info->rela_sz = d_val; break;
00076                 case DT_RELAENT:        info->rela_ent = d_val; break;
00077                 case DT_STRSZ:          info->str_sz = d_val; break;
00078                 case DT_SYMENT:         info->sym_ent = d_val; break;
00079                 case DT_INIT:           info->init = d_ptr; break;
00080                 case DT_FINI:           info->fini = d_ptr; break;
00081                 case DT_SONAME:         soname_idx = d_val; break;
00082                 case DT_RPATH:          rpath_idx = d_val; break;
00083                 case DT_SYMBOLIC:       info->symbolic = true; break;
00084                 case DT_REL:            info->rel = d_ptr; break;
00085                 case DT_RELSZ:          info->rel_sz = d_val; break;
00086                 case DT_RELENT:         info->rel_ent = d_val; break;
00087                 case DT_PLTREL:         info->plt_rel = d_val; break;
00088                 case DT_TEXTREL:        info->text_rel = true; break;
00089                 case DT_JMPREL:         info->jmp_rel = d_ptr; break;
00090                 case DT_BIND_NOW:       info->bind_now = true; break;
00091 
00092                 default:
00093                         if (dp->d_tag >= DT_LOPROC && dp->d_tag <= DT_HIPROC)
00094                                 dyn_parse_arch(dp, bias, info);
00095                         break;
00096                 }
00097 
00098                 ++dp;
00099         }
00100 
00101         info->soname = info->str_tab + soname_idx;
00102         info->rpath = info->str_tab + rpath_idx;
00103 
00104         /* This will be useful for parsing dependencies later */
00105         info->dynamic = dyn_ptr;
00106 
00107         DPRINTF("str_tab=0x%x, soname_idx=0x%x, soname=0x%x\n",
00108                 (uintptr_t)info->soname, soname_idx, (uintptr_t)info->soname);
00109         DPRINTF("soname='%s'\n", info->soname);
00110         DPRINTF("rpath='%s'\n", info->rpath);
00111         DPRINTF("hash=0x%x\n", (uintptr_t)info->hash);
00112         DPRINTF("dt_rela=0x%x\n", (uintptr_t)info->rela);
00113         DPRINTF("dt_rela_sz=0x%x\n", (uintptr_t)info->rela_sz);
00114         DPRINTF("dt_rel=0x%x\n", (uintptr_t)info->rel);
00115         DPRINTF("dt_rel_sz=0x%x\n", (uintptr_t)info->rel_sz);
00116 
00117         /*
00118          * Now that we have a pointer to the string table,
00119          * we can parse DT_NEEDED fields (which contain offsets into it).
00120          */
00121 
00122         DPRINTF("pass 2\n");
00123         dp = dyn_ptr;
00124         while (dp->d_tag != DT_NULL) {
00125                 d_val = dp->d_un.d_val;
00126 
00127                 switch (dp->d_tag) {
00128                 case DT_NEEDED:
00129                         /* Assume just for now there's only one dependency */
00130                         info->needed = info->str_tab + d_val;
00131                         DPRINTF("needed:'%s'\n", info->needed);
00132                         break;
00133 
00134                 default: break;
00135                 }
00136 
00137                 ++dp;
00138         }
00139 }
00140 

Generated on Thu Jun 2 07:45:45 2011 for HelenOS/USB by  doxygen 1.4.7