1 /* 2 * (c) 2008-2009 Alexander Warg <warg@os.inf.tu-dresden.de> 3 * economic rights: Technische Universität Dresden (Germany) 4 * 5 * This file is part of TUD:OS and distributed under the terms of the 6 * GNU General Public License 2. 7 * Please see the COPYING-GPL-2 file for details. 8 */ 9 #pragma once 10 #include "region.h" 11 #include "globals.h" 12 13 #include <l4/re/env> 14 #include <l4/libloader/loader> 15 #include <l4/libloader/local_app_model> 16 #include <cstring> 17 #include <l4/re/l4aux.h> 18 19 20 class L4Re_stack 21 { 22 private: 23 l4_addr_t _addr; 24 unsigned long _size; 25 char *sp; 26 27 public: set_local_addr(l4_addr_t addr)28 void set_local_addr(l4_addr_t addr) 29 { sp = (char *)addr + _size; } 30 set_target_stack(l4_addr_t addr,l4_size_t size)31 void set_target_stack(l4_addr_t addr, l4_size_t size) 32 { _addr = addr; _size = size; } 33 stack_size()34 l4_size_t stack_size() const { return _size; } target_addr()35 l4_addr_t target_addr() const { return _addr; } 36 push_object(void const * src,unsigned long size)37 char *push_object(void const *src, unsigned long size) 38 { 39 sp -= size; 40 memcpy(sp, src, size); 41 return sp; 42 } 43 44 template<typename T> push(T const & v)45 T *push(T const &v) 46 { return reinterpret_cast<T*>(push_object(&v, sizeof(T))); } 47 push_local_ptr(void const * p)48 void const **push_local_ptr(void const *p) 49 { return push(p); } 50 align(unsigned long size)51 void align(unsigned long size) 52 { 53 l4_addr_t p = l4_addr_t(sp); 54 unsigned bits; 55 for (bits = 0; (1UL << bits) <= size; ++bits) 56 ; 57 58 p &= ~0UL << bits; 59 sp = (char *)p; 60 } 61 ptr()62 char const *ptr() const { return sp; } ptr(char * p)63 void ptr(char *p) { sp = p; } 64 }; 65 66 struct L4Re_app_model : public Ldr::Base_app_model<L4Re_stack> 67 { 68 typedef L4::Cap<L4Re::Dataspace> Const_dataspace; 69 typedef L4::Cap<L4Re::Dataspace> Dataspace; 70 71 L4::Cap<L4Re::Rm> _rm; 72 L4Re_app_modelL4Re_app_model73 L4Re_app_model(L4::Cap<L4Re::Rm> rm, void *) : _rm(rm) {} 74 75 Dataspace alloc_ds(unsigned long size) const; 76 77 static Const_dataspace open_file(char const *name); 78 79 void prog_attach_ds(l4_addr_t addr, unsigned long size, 80 Const_dataspace ds, unsigned long offset, 81 L4Re::Rm::Flags flags, char const *what); 82 83 static void copy_ds(Dataspace dst, unsigned long dst_offs, 84 Const_dataspace src, unsigned long src_offs, 85 unsigned long size); 86 87 static bool all_segs_cow(); 88 89 l4_addr_t local_attach_ds(Const_dataspace ds, unsigned long size, 90 unsigned long offset) const; 91 92 void local_detach_ds(l4_addr_t addr, unsigned long size) const; 93 94 int prog_reserve_area(l4_addr_t *start, unsigned long size, 95 L4Re::Rm::Flags flags, unsigned char align); 96 97 Dataspace alloc_app_stack(); 98 init_progL4Re_app_model99 void init_prog() 100 {} 101 reserved_areaL4Re_app_model102 static Const_dataspace reserved_area() 103 { return L4::Cap<L4Re::Dataspace>::Invalid; } 104 local_kip_dsL4Re_app_model105 static Dataspace local_kip_ds() 106 { 107 return L4::Cap<L4Re::Dataspace>(Global::l4re_aux->kip_ds); 108 } 109 local_kip_capL4Re_app_model110 static L4::Cap<void> local_kip_cap() 111 { return local_kip_ds(); } 112 prog_kip_dsL4Re_app_model113 static L4::Cap<void> prog_kip_ds() 114 { 115 return L4::Cap<L4Re::Dataspace>(Global::l4re_aux->kip_ds); 116 } 117 generate_l4auxL4Re_app_model118 void const *generate_l4aux(char const *) const 119 { return Global::l4re_aux; } 120 121 void extra_elf_auxv(); 122 void push_envp(); 123 void push_argv(); 124 125 L4Re::Env *add_env(); 126 void start_prog(L4Re::Env const *env); 127 }; 128 129 typedef Ldr::Local_app_model<L4Re_app_model> L4Re_x_app_model; 130 131 class Loader 132 { 133 public: 134 bool start(L4::Cap<L4Re::Dataspace> bin, Region_map *rm, l4re_aux_t *aux); 135 bool __start(L4::Cap<L4Re::Dataspace> bin, Region_map *rm); 136 virtual bool launch(L4::Cap<L4Re::Dataspace> bin, L4::Cap<L4Re::Rm>) = 0; ~Loader()137 virtual ~Loader() {} 138 }; 139