1// vi:set ft=cpp: -*- Mode: C++ -*- 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 16namespace Ldr { 17 18struct Mem_check_ok 19{ void check_access(char *, size_t) {} }; 20 21template< typename Mem_check = Mem_check_ok> 22class Remote_stack : public Ldr::Stack, public Mem_check 23{ 24public: 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 79private: 80 l4_addr_t _target_top; 81 l4_size_t _size; 82 char *_top; 83 char *_p; 84}; 85 86 87template<typename Mem_check> 88char const * 89Remote_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 99template<typename Mem_check> 100char * 101Remote_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}; 110