]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libloader/include/remote_mem
update
[l4.git] / l4 / pkg / libloader / include / remote_mem
1 // vi:ft=cpp
2 /*
3  * (c) 2008-2009 Alexander Warg <warg@os.inf.tu-dresden.de>
4  *     economic rights: Technische Universität Dresden (Germany)
5  * This file is part of TUD:OS and distributed under the terms of the
6  * GNU Lesser General Public License 2.1.
7  * Please see the COPYING-LGPL-2.1 file for details.
8  */
9 #pragma once
10
11 #include <l4/sys/types.h>
12 #include <l4/re/l4aux.h>
13 #include <cstddef>
14 #include <l4/libloader/stack>
15
16 namespace Ldr {
17
18 struct Mem_check_ok
19 { void check_access(char *, size_t) {} };
20
21 template< typename Mem_check = Mem_check_ok>
22 class Remote_stack : public Ldr::Stack, public Mem_check
23 {
24 public:
25
26   void access_ok(char *p, size_t sz)
27   {
28     // for downward growing stack first subtract the size
29     Mem_check::check_access(p - sz, sz);
30   }
31
32   explicit Remote_stack(char *p = 0) : _target_top(0), _top(p), _p(p) {}
33   char *ptr() const { return _p; }
34   void ptr(char *p) { _p = p; }
35   void set_target_stack(l4_addr_t addr, l4_size_t size)
36   { _target_top = addr + size; _size = size; }
37
38   template < typename T >
39   T relocate(T src) const
40   { return (T)(l4_addr_t(src) + (_target_top - l4_addr_t(_top))); }
41
42   char const *push_str(char const *s, size_t len);
43   char *push_object(void const *o, unsigned long size);
44
45   template< typename T >
46   T *push(T const &v)
47   {
48     access_ok(_p, sizeof(T));
49     T *p = reinterpret_cast<T*>(_p);
50     *(--p) = v;
51     _p = reinterpret_cast<char*>(p);
52     return p;
53   }
54
55   void align(unsigned long size)
56   {
57     l4_addr_t p = l4_addr_t(_p);
58     unsigned bits;
59     for (bits = 0; (1UL << bits) <= size; ++bits)
60       ;
61
62     p &= ~0UL << bits;
63     _p = (char *)p;
64   }
65
66   void const **push_local_ptr(void const *p)
67   {
68     void const *x = relocate(p);
69     return push(x);
70   }
71
72   l4_addr_t target_ptr() const { return relocate(l4_addr_t(_p)); }
73   l4_addr_t target_top() const { return _target_top; }
74   l4_addr_t target_addr() const { return _target_top - _size; }
75   l4_size_t stack_size() const { return _size; }
76   void set_local_top(char *top)
77   { _top = top; _p = top; }
78
79 private:
80   l4_addr_t _target_top;
81   l4_size_t _size;
82   char *_top;
83   char *_p;
84 };
85
86
87 template<typename Mem_check>
88 char const *
89 Remote_stack<Mem_check>::push_str(char const *s, size_t len)
90 {
91   access_ok(_p, len + 1);
92   _p -= len + 1;
93   __builtin_memcpy(_p, s, len);
94   _p[len] = 0;
95
96   return _p;
97 }
98
99 template<typename Mem_check>
100 char *
101 Remote_stack<Mem_check>::push_object(void const *o, unsigned long size)
102 {
103   access_ok(_p, size);
104   _p -= size;
105   __builtin_memcpy(_p, o, size);
106   return _p;
107 }
108
109 };