]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/libloader/include/remote_mem
4a6774b4d2d12248835fd8ffe7f578862980a60b
[l4.git] / l4 / pkg / libloader / include / remote_mem
1 // vi:ft=cpp
2 /*
3  * (c) 2008-2009 Technische Universität Dresden
4  * This file is part of TUD:OS and distributed under the terms of the
5  * GNU Lesser General Public License 2.1.
6  * Please see the COPYING-LGPL-2.1 file for details.
7  */
8 #pragma once
9
10 #include <l4/sys/types.h>
11 #include <l4/re/l4aux.h>
12 #include <cstddef>
13 #include <l4/libloader/stack>
14
15 namespace Ldr {
16
17 struct Mem_check_ok
18 { void check_access(char *, size_t) {} };
19
20 template< typename Mem_check = Mem_check_ok>
21 class Remote_stack : public Ldr::Stack, public Mem_check
22 {
23 public:
24
25   void access_ok(char *p, size_t sz)
26   {
27     // for downward growing stack first subtract the size
28     Mem_check::check_access(p - sz, sz);
29   }
30
31   explicit Remote_stack(char *p = 0) : _target_top(0), _top(p), _p(p) {}
32   char *ptr() const { return _p; }
33   void ptr(char *p) { _p = p; }
34   void set_ma_cnt(char const *before_vma);
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 void
89 Remote_stack<Mem_check>::set_ma_cnt(char const *before_vma)
90 {
91   push((l4_umword_t)((before_vma - _p) / sizeof(l4re_mem_area_t)));
92 }
93
94
95 template<typename Mem_check>
96 char const *
97 Remote_stack<Mem_check>::push_str(char const *s, size_t len)
98 {
99   access_ok(_p, len + 1);
100   _p -= len + 1;
101   __builtin_memcpy(_p, s, len);
102   _p[len] = 0;
103
104   return _p;
105 }
106
107 template<typename Mem_check>
108 char *
109 Remote_stack<Mem_check>::push_object(void const *o, unsigned long size)
110 {
111   access_ok(_p, size);
112   _p -= size;
113   __builtin_memcpy(_p, o, size);
114   return _p;
115 }
116
117 };