Advertisement
Guest User

Untitled

a guest
May 26th, 2019
70
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.96 KB | None | 0 0
  1. #![allow(dead_code)]
  2.  
  3. use std::cell::UnsafeCell;
  4. use std::collections::HashMap;
  5. use std::iter;
  6. use std::marker::PhantomData;
  7. use std::mem;
  8. use std::ops::Deref;
  9. use std::ops::Range;
  10. use std::sync::Mutex;
  11. use std::thread;
  12. use lazy_static::lazy_static;
  13.  
  14. // Jump to the examples at the end!
  15.  
  16. // The metadata we store is just a colour for each memory address.
  17. struct MetaData(Mutex<HashMap<Address, Colour>>);
  18.  
  19. lazy_static! { static ref METADATA: MetaData = MetaData(Mutex::new(HashMap::new())); }
  20.  
  21. // Memory addresses are just a word
  22. type Address = usize;
  23.  
  24. // The different states of memory
  25. #[derive(Clone, Copy, Debug, Eq, PartialEq)]
  26. enum Colour {
  27. Unreachable, // Memory that is allocated but can't be reached from safe code
  28. Unique, // Memory that is reachable from safe code as a &mut T reference
  29. Shared(usize), // Memory that is reachable from safe code as a &T reference
  30. }
  31.  
  32. // Types that know how to iterate over their addresses
  33. trait Addressable {
  34. type Addresses: Iterator<Item = Address>;
  35. fn addresses(&self) -> Self::Addresses;
  36. }
  37.  
  38. impl Addressable for u8 {
  39. type Addresses = iter::Once<Address>;
  40. fn addresses(&self) -> Self::Addresses {
  41. iter::once(self as *const u8 as Address)
  42. }
  43. }
  44.  
  45. impl Addressable for u16 {
  46. type Addresses = Range<Address>;
  47. fn addresses(&self) -> Self::Addresses {
  48. let address = self as *const u16 as Address;
  49. (address..address+2)
  50. }
  51. }
  52.  
  53. impl Addressable for u32 {
  54. type Addresses = Range<Address>;
  55. fn addresses(&self) -> Self::Addresses {
  56. let address = self as *const u32 as Address;
  57. (address..address+4)
  58. }
  59. }
  60.  
  61. impl Addressable for u64 {
  62. type Addresses = Range<Address>;
  63. fn addresses(&self) -> Self::Addresses {
  64. let address = self as *const u64 as Address;
  65. (address..address+8)
  66. }
  67. }
  68.  
  69. impl<T, U> Addressable for (T, U) where T: Addressable, U: Addressable {
  70. type Addresses = iter::Chain<T::Addresses, U::Addresses>;
  71. fn addresses(&self) -> Self::Addresses {
  72. self.0.addresses().chain(self.1.addresses())
  73. }
  74. }
  75.  
  76. impl<T> Addressable for UnsafeCell<T> where T: Addressable {
  77. type Addresses = iter::Empty<Address>;
  78. fn addresses(&self) -> Self::Addresses {
  79. iter::empty()
  80. }
  81. }
  82.  
  83. // How we model &T
  84. struct Ref<'a, T: 'a + Addressable>(&'a T);
  85.  
  86. impl<'a, T: 'a + Addressable> Drop for Ref<'a, T> {
  87. fn drop(&mut self) {
  88. if thread::panicking() { return; }
  89. let mut metadata = METADATA.0.lock().unwrap();
  90. for address in self.0.addresses() {
  91. let n = match metadata.get(&address) {
  92. Some(Colour::Shared(n)) => *n,
  93. colour => panic!("Expected Shared, found {:?} at address 0x{:x}", colour, address),
  94. };
  95. assert!(n > 0);
  96. let colour = if n == 1 {
  97. Colour::Unreachable
  98. } else {
  99. Colour::Shared(n - 1)
  100. };
  101. metadata.insert(address, colour);
  102. println!("Colouring 0x{:x} as {:?}", address, colour);
  103. }
  104. }
  105. }
  106.  
  107. impl<'a, T: 'a + Addressable> Clone for Ref<'a, T> {
  108. fn clone(&self) -> Self {
  109. let mut metadata = METADATA.0.lock().unwrap();
  110. for address in self.0.addresses() {
  111. let n = match metadata.get(&address) {
  112. Some(Colour::Shared(n)) => *n,
  113. colour => panic!("Expected Shared, found {:?} at address 0x{:x}", colour, address),
  114. };
  115. metadata.insert(address, Colour::Shared(n + 1));
  116. println!("Colouring 0x{:x} as Shared({})", address, n + 1);
  117. }
  118. Ref(self.0)
  119. }
  120. }
  121.  
  122. impl<'a, T: 'a + Addressable> Ref<'a, T> {
  123. fn get(&self) -> T where T: Clone {
  124. self.0.clone()
  125. }
  126.  
  127. fn as_ptr(self) -> *const T {
  128. self.0 as *const T
  129. }
  130.  
  131. unsafe fn from_ptr(ptr: *const T) -> Ref<'a, T> {
  132. let mut metadata = METADATA.0.lock().unwrap();
  133. let reference = &*ptr;
  134. for address in reference.addresses() {
  135. let n = match metadata.get(&address) {
  136. Some(Colour::Shared(n)) => *n,
  137. Some(Colour::Unreachable) => 0,
  138. colour => panic!("UB: Expected Shared or Unreachable, found {:?} at address 0x{:x}", colour, address),
  139. };
  140. metadata.insert(address, Colour::Shared(n + 1));
  141. println!("Colouring 0x{:x} as Shared({})", address, n + 1);
  142. }
  143. Ref(reference)
  144. }
  145.  
  146. }
  147.  
  148. // How we model &mut T
  149. struct RefMut<'a, T: 'a + Addressable>(&'a mut T);
  150.  
  151. impl<'a, T: 'a + Addressable> RefMut<'a, T> {
  152. fn new(x: &'a mut T) -> Self {
  153. let mut metadata = METADATA.0.lock().unwrap();
  154. for address in x.addresses() {
  155. let colour = metadata.get(&address).cloned().unwrap_or(Colour::Unreachable);
  156. assert!(colour == Colour::Unreachable,
  157. "Expected Unreachable, found {:?} at address 0x{:x}", colour, address);
  158. metadata.insert(address, Colour::Unique);
  159. println!("Colouring 0x{:x} as Unique", address);
  160. }
  161. RefMut(x)
  162. }
  163.  
  164. fn as_ref<'b>(&'b mut self) -> Ref<'b, T> {
  165. let mut metadata = METADATA.0.lock().unwrap();
  166. for address in self.0.addresses() {
  167. let colour = metadata.get(&address).cloned().unwrap_or(Colour::Unreachable);
  168. assert!((colour == Colour::Unreachable) || (colour == Colour::Unique),
  169. "Expected Unreachable or Unique, found {:?} at address 0x{:x}", colour, address);
  170. metadata.insert(address, Colour::Shared(1));
  171. println!("Colouring 0x{:x} as Shared(1)", address);
  172. }
  173. Ref(self.0)
  174. }
  175.  
  176. unsafe fn from_ptr(ptr: *mut T) -> RefMut<'a, T> {
  177. let mut metadata = METADATA.0.lock().unwrap();
  178. let reference = &mut *ptr;
  179. for address in reference.addresses() {
  180. let colour = metadata.get(&address).cloned().unwrap_or(Colour::Unreachable);
  181. assert!(colour == Colour::Unreachable,
  182. "UB: Expected Unreachable, found {:?} at address 0x{:x}", colour, address);
  183. metadata.insert(address, Colour::Unique);
  184. println!("Colouring 0x{:x} as Unique", address);
  185. }
  186. RefMut(reference)
  187. }
  188.  
  189. fn set(&mut self, x: T) {
  190. let mut metadata = METADATA.0.lock().unwrap();
  191. for address in self.0.addresses() {
  192. let colour = metadata.get(&address).cloned().unwrap_or(Colour::Unreachable);
  193. assert!((colour == Colour::Unreachable) || (colour == Colour::Unique),
  194. "Expected Unreachable or Unique, found {:?} at address 0x{:x}", colour, address);
  195. metadata.insert(address, Colour::Unique);
  196. println!("Colouring 0x{:x} as Unique", address);
  197. }
  198. *self.0 = x;
  199. }
  200. }
  201.  
  202. macro_rules! let_ref_mut {
  203. ($x:ident = $e:expr) => {
  204. let ref mut tmp = $e;
  205. let mut $x = RefMut::new(tmp);
  206. }
  207. }
  208.  
  209. /*
  210. // Another example, from Ralf Jung
  211.  
  212. fn aliasing_mut_and_shr() {
  213. fn inner(rc: &RefCell<u32>, aliasing: &mut u32) {
  214. *aliasing += 4;
  215. let _escape_to_raw : *const RefCell<u32> = rc;
  216. *aliasing += 4;
  217. let _shr = &*rc;
  218. *aliasing += 4;
  219. // also turning this into a frozen ref now must work
  220. let aliasing : &u32 = aliasing;
  221. let _val = *aliasing;
  222. let _escape_to_raw : *const RefCell<u32> = rc;
  223. let _val = *aliasing;
  224. let _shr = &*rc; // this must NOT unfreeze
  225. let _val = *aliasing;
  226. }
  227.  
  228. let refcell = RefCell::new(23);
  229. let rc: &mut RefCell<u32> = &mut refcell;
  230. let rc: &RefCell<u32> = rc;
  231. let mut bmut : RefMut<u32> = rc.borrow_mut();
  232. inner(&rc, &mut *bmut);
  233. drop(bmut);
  234. assert_eq!(*rc.borrow(), 23+12);
  235. }
  236.  
  237. fn main() {
  238. aliasing_mut_and_shr()
  239. }
  240. */
  241.  
  242. fn bad(p: Ref<u8>) {
  243. let q = p.as_ptr() as *mut u8;
  244. let mut r = unsafe { RefMut::from_ptr(q) };
  245. r.set(5);
  246. }
  247.  
  248. fn main() {
  249. let_ref_mut!(x = 37);
  250. let y = x.as_ref();
  251. println!("*y = {}", y.get());
  252. bad(y);
  253. let z = x.as_ref();
  254. println!("*z = {}", z.get());
  255. bad(z.clone());
  256. println!("*z = {}", z.get());
  257. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement