(path: &str)
| 228 | const MAX_PAGE_SIZE: usize = 65536; |
| 229 | |
| 230 | pub fn load<'a>(path: &str) -> Result<AndroidLibrary<'a>> { |
| 231 | let file = Box::new(fs::read(path)?); |
| 232 | let file_leak_ptr = Box::into_raw(file); |
| 233 | let file_leak = unsafe { file_leak_ptr.as_ref().unwrap() }; |
| 234 | let elf_file = ElfFile::new(&file_leak).map_err(|err| AndroidLoaderErr::ElfParsingError(err.to_string()))?; |
| 235 | |
| 236 | let mut minimum = usize::MAX; |
| 237 | let mut maximum = usize::MIN; |
| 238 | |
| 239 | let mut is_incompatible = false; |
| 240 | let mut offset = 0; |
| 241 | let mut overall_protection = Protection::NONE; |
| 242 | |
| 243 | for header in elf_file.program_iter() { |
| 244 | if header.get_type() == Ok(Type::Load) { |
| 245 | let flags = header.flags(); |
| 246 | |
| 247 | let start = region::page::floor(header.virtual_addr() as *const ()) as usize; |
| 248 | let end = region::page::ceil( |
| 249 | (header.virtual_addr() as usize + header.mem_size() as usize) |
| 250 | as *const (), |
| 251 | ) as usize; |
| 252 | |
| 253 | if offset == 0 { |
| 254 | let mut prot = Protection::NONE.bits(); |
| 255 | if flags.is_read() { |
| 256 | prot |= Protection::READ.bits(); |
| 257 | } |
| 258 | if flags.is_write() { |
| 259 | prot |= Protection::WRITE.bits(); |
| 260 | } |
| 261 | if flags.is_execute() { |
| 262 | prot |= Protection::EXECUTE.bits(); |
| 263 | } |
| 264 | overall_protection |= Protection::from_bits_truncate(prot); |
| 265 | if overall_protection == Protection::READ_WRITE_EXECUTE { |
| 266 | offset = page::ceil(start as *const ()) as usize - start; |
| 267 | } |
| 268 | } |
| 269 | |
| 270 | if !is_incompatible && page::ceil(maximum as *const ()) as usize > start { |
| 271 | is_incompatible = true; |
| 272 | warn!("library has not been made for this CPU. It may crash!"); |
| 273 | } |
| 274 | |
| 275 | if start < minimum { |
| 276 | minimum = start; |
| 277 | } |
| 278 | |
| 279 | if end > maximum { |
| 280 | maximum = end; |
| 281 | } |
| 282 | } |
| 283 | } |
| 284 | |
| 285 | let alloc_start = region::page::floor(minimum as *const ()) as usize; |
| 286 | let alloc_end = region::page::ceil(maximum as *const ()) as usize; |
| 287 |
nothing calls this directly
no test coverage detected