Subversion Repositories HelenOS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2008 Jiri Svoboda
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup rtld rtld
  30.  * @brief
  31.  * @{
  32.  */
  33. /**
  34.  * @file
  35.  */
  36.  
  37. void _rtld_main(void);
  38.  
  39. #define ELF32_R_SYM(i) ((i)>>8)
  40. #define ELF32_R_TYPE(i) ((unsigned char)(i))
  41.  
  42. typedef struct {
  43.     int d_tag;
  44.     union {
  45.         unsigned d_val;
  46.         unsigned *d_ptr;
  47.     } d_un;
  48. } elf32_dyn;
  49.  
  50. typedef struct {
  51.     unsigned r_offset;
  52.     unsigned r_info;
  53. } elf32_rel;
  54.  
  55. typedef struct {
  56.     unsigned st_name;
  57.     unsigned st_value;
  58.     unsigned st_size;
  59.     unsigned char st_info;
  60.     unsigned char st_other;
  61.     unsigned short st_shndx;
  62. } elf32_sym;
  63.  
  64. static void kputint(unsigned i)
  65. {
  66.     unsigned dummy;
  67.     asm volatile (
  68.         "movl $30, %%eax;"
  69.         "int $0x30"
  70.         : "=d" (dummy) /* output - %edx clobbered */
  71.         : "d" (i) /* input */
  72.         : "%eax","%ecx" /* all scratch registers clobbered */
  73.     ); 
  74. }
  75.  
  76. void __bootstrap(void)
  77. {
  78.     unsigned bias;
  79.     unsigned *got;
  80.     elf32_dyn *dynamic;
  81.     unsigned *dptr;
  82.     unsigned dval;
  83.     int i;
  84.  
  85.     unsigned rel_entries;
  86.     unsigned r_offset;
  87.     unsigned r_info;
  88.     unsigned rel_type;
  89.     unsigned sym_idx;
  90.     unsigned sym_addr;
  91.    
  92.     elf32_sym *sym_table;
  93.     elf32_rel *rel_table;
  94.  
  95.     asm volatile (
  96.     "movl $30, %eax;"
  97.     "int $0x30"
  98.     );
  99.  
  100.     /* Copied from libc/arch/ia32/entry.s */
  101. /*asm volatile (
  102.     "mov %ss, %ax;"
  103.     "mov %ax, %ds;"
  104.     "mov %ax, %es;"
  105.     "mov %ax, %fs;"
  106. );*/
  107.  
  108.  
  109. asm volatile (
  110.     /* Calculate the bias into %0 */
  111. "   call .L0;"
  112. ".L0:   pop %0;"
  113. "   subl $.L0, %0;"
  114.  
  115.     /* Calculate run-time address of _DYNAMIC into %1 */
  116. "   movl $_DYNAMIC, %1;"    /* Again, at link time 0-based VMA gets in */
  117. "   addl %0, %1;"       /* Add bias to compute run-time address */
  118.  
  119. : "=r" (bias), "=r" (dynamic)
  120. );
  121.  
  122.     kputint(bias);
  123.     kputint((unsigned)dynamic);
  124.  
  125.     /* parse DYNAMIC */
  126.     got = 0;
  127.     sym_table = 0;
  128.     rel_table = 0;
  129.     rel_entries = 0;
  130.  
  131.     i = 0;
  132.     while (dynamic[i].d_tag != 0) {
  133.         dptr = (unsigned *)(dynamic[i].d_un.d_val + bias);
  134.         dval = dynamic[i].d_un.d_val;
  135.  
  136.         switch (dynamic[i].d_tag) {
  137.         case 3 /* DT_PLTGOT */:
  138.             /* GOT address */
  139.             got = dptr; break;
  140.         case 6 /* DT_SYMTAB */ : sym_table = dptr; break;
  141.         case 17 /* DT_REL */ : rel_table = dptr; break;
  142.         case 18 /* DT_RELSZ */ : rel_entries = dval / 8; break;
  143.         default: break;
  144.         }
  145.  
  146.         ++i;
  147.     }
  148.    
  149.     kputint(1);
  150.     kputint((unsigned)sym_table);
  151.     kputint((unsigned)rel_table);
  152.     kputint((unsigned)rel_entries);
  153.  
  154.     /* Now relocate all our dynsyms */
  155.     kputint(-1);
  156.    
  157.     for (i=0; i<rel_entries; i++) {
  158.         kputint(i);
  159.         r_offset = rel_table[i].r_offset;
  160.         r_info = rel_table[i].r_info;
  161.  
  162.         rel_type = ELF32_R_TYPE(r_info);
  163.  
  164.         kputint(rel_type);
  165.         kputint(r_offset);
  166.  
  167.         if (rel_type == 7 /* R_386_JUMP_SLOT */) {
  168.             kputint(16);
  169.             sym_idx = ELF32_R_SYM(r_info);
  170.  
  171.             sym_addr = sym_table[sym_idx].st_value + bias;
  172.             kputint(sym_idx);
  173.             kputint(sym_addr);
  174.  
  175.             *(unsigned *)(r_offset+bias) = sym_addr;
  176.         }
  177.     }
  178.  
  179.     kputint(-1);
  180.  
  181.     kputint(32);
  182.  
  183.     _rtld_main();
  184.  
  185.     asm (
  186.         "movl $250, %%eax;"
  187.         "int $0x30"
  188.         : /* output */
  189.         : /* input */
  190.         : "%eax","%ecx","%edx" /* all scratch registers clobbered */
  191.     );
  192. }
  193.  
  194. /** @}
  195.  */
  196.