Subversion Repositories HelenOS

Rev

Rev 2990 | 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. #include <elf_dyn.h>
  38. #include <rtld.h>
  39. #include <pcb.h>
  40.  
  41. void __main(void);
  42. void __io_init(void);
  43. void __exit(void);
  44.  
  45. static void kputint(unsigned i)
  46. {
  47.     unsigned dummy;
  48.     asm volatile (
  49.         "movl $31, %%eax;"
  50.         "int $0x30"
  51.         : "=d" (dummy) /* output - %edx clobbered */
  52.         : "d" (i) /* input */
  53.         : "%eax","%ecx" /* all scratch registers clobbered */
  54.     ); 
  55. }
  56.  
  57. void __bootstrap(void)
  58. {
  59.     unsigned bias;
  60.     unsigned *got;
  61.     elf_dyn_t *dynamic;
  62.     void *dptr;
  63.     unsigned dval;
  64.     int i;
  65.  
  66.     size_t rel_entries;
  67.     size_t r_offset;
  68.     elf_word r_info;
  69.     unsigned rel_type;
  70.     elf_word sym_idx;
  71.     uintptr_t sym_addr;
  72.    
  73.     elf_symbol_t *sym_table;
  74.     elf_rel_t *rel_table;
  75.     elf_rel_t *jmp_rel_table;
  76.     size_t jmp_rel_entries;
  77.     pcb_t *pcb;
  78.    
  79.     pcb = __pcb_get();
  80.  
  81.     /* The program loader (iloader) kindly provided us with these */
  82.     dynamic = pcb->rtld_dynamic;
  83.     bias = pcb->rtld_bias;
  84. /*
  85. asm volatile (
  86.     // Calculate the bias into %0
  87.     // Generates "fake" R_386_RELATIVE run-time relocation
  88. "   call .L0;"
  89. ".L0:   pop %0;"
  90. "   subl $.L0, %0;"
  91.  
  92.     // Calculate run-time address of _DYNAMIC into %1
  93.     // Generates "fake" R_386_RELATIVE run-time relocation
  94. "   movl $_DYNAMIC, %1;"    // Again, at link time 0-based VMA gets in
  95. "   addl %0, %1;"       // Add bias to compute run-time address
  96.  
  97. : "=r" (bias), "=r" (dynamic)
  98. );
  99. */
  100.     kputint(bias);
  101.     kputint((unsigned)dynamic);
  102.  
  103.     /* parse DYNAMIC */
  104.     got = 0;
  105.     sym_table = 0;
  106.     rel_table = 0;
  107.     rel_entries = 0;
  108.     jmp_rel_table = 0;
  109.     jmp_rel_entries = 0;
  110.  
  111.     i = 0;
  112.     while (dynamic[i].d_tag != 0) {
  113.         dptr = (void *)(dynamic[i].d_un.d_val + bias);
  114.         dval = dynamic[i].d_un.d_val;
  115.  
  116.         switch (dynamic[i].d_tag) {
  117.         case DT_PLTRELSZ: jmp_rel_entries = dval/8; break;
  118.         case DT_JMPREL: jmp_rel_table = dptr; break;
  119.         case DT_PLTGOT:
  120.             /* GOT address */
  121.             got = dptr; break;
  122.         case DT_SYMTAB: sym_table = dptr; break;
  123.         case DT_REL: rel_table = dptr; break;
  124.         case DT_RELSZ: rel_entries = dval / 8; break;
  125.         default: break;
  126.         }
  127.  
  128.         ++i;
  129.     }
  130.    
  131.     kputint(1);
  132.     kputint((unsigned)sym_table);
  133.     kputint((unsigned)rel_table);
  134.     kputint((unsigned)rel_entries);
  135.  
  136.     /* Now relocate all our dynsyms */
  137.     kputint(-1);
  138.    
  139.     for (i=0; i<rel_entries; i++) {
  140.         kputint(i);
  141.         r_offset = rel_table[i].r_offset;
  142.         r_info = rel_table[i].r_info;
  143.  
  144.         rel_type = ELF32_R_TYPE(r_info);
  145.  
  146.         kputint(rel_type);
  147.         kputint(r_offset);
  148.  
  149.         switch (rel_type) {
  150.         case R_386_GLOB_DAT:
  151.         case R_386_JUMP_SLOT:
  152.             kputint(16);
  153.             sym_idx = ELF32_R_SYM(r_info);
  154.  
  155.             sym_addr = sym_table[sym_idx].st_value + bias;
  156.             kputint(sym_idx);
  157.             kputint(sym_addr);
  158.  
  159.             *(unsigned *)(r_offset+bias) = sym_addr;
  160.             break;
  161.  
  162.         case R_386_32:
  163.             kputint(16);
  164.             sym_idx = ELF32_R_SYM(r_info);
  165.  
  166.             sym_addr = sym_table[sym_idx].st_value + bias;
  167.             kputint(sym_idx);
  168.             kputint(sym_addr);
  169.  
  170.             *(unsigned *)(r_offset+bias) += sym_addr;
  171.             break;
  172.            
  173.         case R_386_RELATIVE:
  174.             kputint(16);
  175.             *(unsigned *)(r_offset+bias) += bias;
  176.             break;
  177.         }
  178.     }
  179.  
  180.     kputint(-1);
  181.    
  182.     for (i=0; i<jmp_rel_entries; i++) {
  183.         kputint(i);
  184.         r_offset = jmp_rel_table[i].r_offset;
  185.         r_info = jmp_rel_table[i].r_info;
  186.  
  187.         rel_type = ELF32_R_TYPE(r_info);
  188.  
  189.         kputint(rel_type);
  190.         kputint(r_offset);
  191.  
  192.         switch (rel_type) {
  193.         case R_386_GLOB_DAT:
  194.         case R_386_JUMP_SLOT:
  195.             kputint(16);
  196.             sym_idx = ELF32_R_SYM(r_info);
  197.  
  198.             sym_addr = sym_table[sym_idx].st_value + bias;
  199.             kputint(sym_idx);
  200.             kputint(sym_addr);
  201.  
  202.             *(unsigned *)(r_offset+bias) = sym_addr;
  203.             break;
  204.  
  205.         case R_386_32:
  206.             kputint(16);
  207.             sym_idx = ELF32_R_SYM(r_info);
  208.  
  209.             sym_addr = sym_table[sym_idx].st_value + bias;
  210.             kputint(sym_idx);
  211.             kputint(sym_addr);
  212.  
  213.             *(unsigned *)(r_offset+bias) += sym_addr;
  214.             break;
  215.            
  216.         case R_386_RELATIVE:
  217.             kputint(16);
  218.             *(unsigned *)(r_offset+bias) += bias;
  219.             break;
  220.         }
  221.     }
  222.  
  223.     kputint(-1);
  224.  
  225.     /* This will come in handy */
  226.     runtime_env.rtld_dynamic = dynamic;
  227.     runtime_env.rtld.bias = bias;
  228.    
  229.     /* Init libc and run rtld main */
  230.     __main();
  231.  
  232.     kputint(33);
  233.     __io_init();
  234.     kputint(34);
  235.     _rtld_main();
  236.     kputint(35);
  237.     __exit();
  238.  
  239.     kputint(36);
  240.  
  241.     asm (
  242.         "movl $250, %%eax;"
  243.         "int $0x30"
  244.         : /* output */
  245.         : /* input */
  246.         : "%eax","%ecx","%edx" /* all scratch registers clobbered */
  247.     );
  248. }
  249.  
  250. /** @}
  251.  */
  252.