Subversion Repositories HelenOS

Rev

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