1 //===-- IRMemoryMap.cpp -----------------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "lldb/Core/DataBufferHeap.h" 11 #include "lldb/Core/DataExtractor.h" 12 #include "lldb/Core/Error.h" 13 #include "lldb/Core/Log.h" 14 #include "lldb/Core/Scalar.h" 15 #include "lldb/Expression/IRMemoryMap.h" 16 #include "lldb/Target/Process.h" 17 #include "lldb/Target/Target.h" 18 19 using namespace lldb_private; 20 21 IRMemoryMap::IRMemoryMap (lldb::TargetSP target_sp) : 22 m_target_wp(target_sp) 23 { 24 if (target_sp) 25 m_process_wp = target_sp->GetProcessSP(); 26 } 27 28 IRMemoryMap::~IRMemoryMap () 29 { 30 lldb::ProcessSP process_sp = m_process_wp.lock(); 31 32 if (process_sp) 33 { 34 AllocationMap::iterator iter; 35 36 Error err; 37 38 while ((iter = m_allocations.begin()) != m_allocations.end()) 39 { 40 err.Clear(); 41 if (iter->second.m_leak) 42 m_allocations.erase(iter); 43 else 44 Free(iter->first, err); 45 } 46 } 47 } 48 49 lldb::addr_t 50 IRMemoryMap::FindSpace (size_t size) 51 { 52 lldb::TargetSP target_sp = m_target_wp.lock(); 53 lldb::ProcessSP process_sp = m_process_wp.lock(); 54 55 lldb::addr_t ret = LLDB_INVALID_ADDRESS; 56 57 if (process_sp && process_sp->CanJIT() && process_sp->IsAlive()) 58 { 59 Error alloc_error; 60 61 ret = process_sp->AllocateMemory(size, lldb::ePermissionsReadable | lldb::ePermissionsWritable, alloc_error); 62 63 if (!alloc_error.Success()) 64 return LLDB_INVALID_ADDRESS; 65 else 66 return ret; 67 } 68 69 if (process_sp) 70 { 71 ret = process_sp->GetReservationCache().Find(size); 72 73 if (ret != LLDB_INVALID_ADDRESS) 74 return ret; 75 } 76 77 for (int iterations = 0; iterations < 16; ++iterations) 78 { 79 lldb::addr_t candidate = LLDB_INVALID_ADDRESS; 80 81 switch (target_sp->GetArchitecture().GetAddressByteSize()) 82 { 83 case 4: 84 { 85 uint32_t random_data = random(); 86 candidate = random_data; 87 candidate &= ~0xfffull; 88 break; 89 } 90 case 8: 91 { 92 uint32_t random_low = random(); 93 uint32_t random_high = random(); 94 candidate = random_high; 95 candidate <<= 32ull; 96 candidate |= random_low; 97 candidate &= ~0xfffull; 98 break; 99 } 100 } 101 102 if (IntersectsAllocation(candidate, size)) 103 continue; 104 105 char buf[1]; 106 107 Error err; 108 109 if (process_sp && 110 (process_sp->ReadMemory(candidate, buf, 1, err) == 1 || 111 process_sp->ReadMemory(candidate + size, buf, 1, err) == 1)) 112 continue; 113 114 ret = candidate; 115 116 if (process_sp) 117 process_sp->GetReservationCache().Reserve(candidate, size); 118 119 return ret; 120 } 121 122 return ret; 123 } 124 125 IRMemoryMap::AllocationMap::iterator 126 IRMemoryMap::FindAllocation (lldb::addr_t addr, size_t size) 127 { 128 if (addr == LLDB_INVALID_ADDRESS) 129 return m_allocations.end(); 130 131 AllocationMap::iterator iter = m_allocations.lower_bound (addr); 132 133 if (iter == m_allocations.end() || 134 iter->first > addr) 135 { 136 if (iter == m_allocations.begin()) 137 return m_allocations.end(); 138 iter--; 139 } 140 141 if (iter->first <= addr && iter->first + iter->second.m_size >= addr + size) 142 return iter; 143 144 return m_allocations.end(); 145 } 146 147 bool 148 IRMemoryMap::IntersectsAllocation (lldb::addr_t addr, size_t size) 149 { 150 if (addr == LLDB_INVALID_ADDRESS) 151 return false; 152 153 AllocationMap::iterator iter = m_allocations.lower_bound (addr); 154 155 if (iter == m_allocations.end() || 156 iter->first > addr) 157 { 158 if (iter == m_allocations.begin()) 159 return false; 160 161 iter--; 162 } 163 164 while (iter != m_allocations.end() && iter->second.m_process_alloc < addr + size) 165 { 166 if (iter->second.m_process_start + iter->second.m_size > addr) 167 return true; 168 169 ++iter; 170 } 171 172 return false; 173 } 174 175 lldb::ByteOrder 176 IRMemoryMap::GetByteOrder() 177 { 178 lldb::ProcessSP process_sp = m_process_wp.lock(); 179 180 if (process_sp) 181 return process_sp->GetByteOrder(); 182 183 lldb::TargetSP target_sp = m_target_wp.lock(); 184 185 if (target_sp) 186 return target_sp->GetArchitecture().GetByteOrder(); 187 188 return lldb::eByteOrderInvalid; 189 } 190 191 uint32_t 192 IRMemoryMap::GetAddressByteSize() 193 { 194 lldb::ProcessSP process_sp = m_process_wp.lock(); 195 196 if (process_sp) 197 return process_sp->GetAddressByteSize(); 198 199 lldb::TargetSP target_sp = m_target_wp.lock(); 200 201 if (target_sp) 202 return target_sp->GetArchitecture().GetAddressByteSize(); 203 204 return UINT32_MAX; 205 } 206 207 ExecutionContextScope * 208 IRMemoryMap::GetBestExecutionContextScope() 209 { 210 lldb::ProcessSP process_sp = m_process_wp.lock(); 211 212 if (process_sp) 213 return process_sp.get(); 214 215 lldb::TargetSP target_sp = m_target_wp.lock(); 216 217 if (target_sp) 218 return target_sp.get(); 219 220 return NULL; 221 } 222 223 IRMemoryMap::Allocation::Allocation (lldb::addr_t process_alloc, 224 lldb::addr_t process_start, 225 size_t size, 226 uint32_t permissions, 227 uint8_t alignment, 228 AllocationPolicy policy) 229 { 230 m_process_alloc = process_alloc; 231 m_process_start = process_start; 232 m_size = size; 233 m_permissions = permissions; 234 m_alignment = alignment; 235 m_policy = policy; 236 237 switch (policy) 238 { 239 default: 240 assert (0 && "We cannot reach this!"); 241 case eAllocationPolicyHostOnly: 242 m_data.SetByteSize(size); 243 memset(m_data.GetBytes(), 0, size); 244 break; 245 case eAllocationPolicyProcessOnly: 246 break; 247 case eAllocationPolicyMirror: 248 m_data.SetByteSize(size); 249 memset(m_data.GetBytes(), 0, size); 250 break; 251 } 252 } 253 254 lldb::addr_t 255 IRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, Error &error) 256 { 257 error.Clear(); 258 259 lldb::ProcessSP process_sp; 260 lldb::addr_t allocation_address = LLDB_INVALID_ADDRESS; 261 lldb::addr_t aligned_address = LLDB_INVALID_ADDRESS; 262 263 size_t alignment_mask = alignment - 1; 264 size_t allocation_size; 265 266 if (size == 0) 267 allocation_size = alignment; 268 else 269 allocation_size = (size & alignment_mask) ? ((size + alignment) & (~alignment_mask)) : size; 270 271 switch (policy) 272 { 273 default: 274 error.SetErrorToGenericError(); 275 error.SetErrorString("Couldn't malloc: invalid allocation policy"); 276 return LLDB_INVALID_ADDRESS; 277 case eAllocationPolicyHostOnly: 278 allocation_address = FindSpace(allocation_size); 279 if (allocation_address == LLDB_INVALID_ADDRESS) 280 { 281 error.SetErrorToGenericError(); 282 error.SetErrorString("Couldn't malloc: address space is full"); 283 return LLDB_INVALID_ADDRESS; 284 } 285 break; 286 case eAllocationPolicyMirror: 287 process_sp = m_process_wp.lock(); 288 if (process_sp && process_sp->CanJIT() && process_sp->IsAlive()) 289 { 290 allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error); 291 if (!error.Success()) 292 return LLDB_INVALID_ADDRESS; 293 } 294 else 295 { 296 policy = eAllocationPolicyHostOnly; 297 allocation_address = FindSpace(allocation_size); 298 if (allocation_address == LLDB_INVALID_ADDRESS) 299 { 300 error.SetErrorToGenericError(); 301 error.SetErrorString("Couldn't malloc: address space is full"); 302 return LLDB_INVALID_ADDRESS; 303 } 304 } 305 break; 306 case eAllocationPolicyProcessOnly: 307 process_sp = m_process_wp.lock(); 308 if (process_sp) 309 { 310 if (process_sp->CanJIT() && process_sp->IsAlive()) 311 { 312 allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error); 313 if (!error.Success()) 314 return LLDB_INVALID_ADDRESS; 315 } 316 else 317 { 318 error.SetErrorToGenericError(); 319 error.SetErrorString("Couldn't malloc: process doesn't support allocating memory"); 320 return LLDB_INVALID_ADDRESS; 321 } 322 } 323 else 324 { 325 error.SetErrorToGenericError(); 326 error.SetErrorString("Couldn't malloc: process doesn't exist, and this memory must be in the process"); 327 return LLDB_INVALID_ADDRESS; 328 } 329 break; 330 } 331 332 333 lldb::addr_t mask = alignment - 1; 334 aligned_address = (allocation_address + mask) & (~mask); 335 336 m_allocations[aligned_address] = Allocation(allocation_address, 337 aligned_address, 338 allocation_size, 339 permissions, 340 alignment, 341 policy); 342 343 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)) 344 { 345 const char * policy_string; 346 347 switch (policy) 348 { 349 default: 350 policy_string = "<invalid policy>"; 351 break; 352 case eAllocationPolicyHostOnly: 353 policy_string = "eAllocationPolicyHostOnly"; 354 break; 355 case eAllocationPolicyProcessOnly: 356 policy_string = "eAllocationPolicyProcessOnly"; 357 break; 358 case eAllocationPolicyMirror: 359 policy_string = "eAllocationPolicyMirror"; 360 break; 361 } 362 363 log->Printf("IRMemoryMap::Malloc (%" PRIu64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", %s) -> 0x%" PRIx64, 364 (uint64_t)allocation_size, 365 (uint64_t)alignment, 366 (uint64_t)permissions, 367 policy_string, 368 aligned_address); 369 } 370 371 return aligned_address; 372 } 373 374 void 375 IRMemoryMap::Leak (lldb::addr_t process_address, Error &error) 376 { 377 error.Clear(); 378 379 AllocationMap::iterator iter = m_allocations.find(process_address); 380 381 if (iter == m_allocations.end()) 382 { 383 error.SetErrorToGenericError(); 384 error.SetErrorString("Couldn't leak: allocation doesn't exist"); 385 return; 386 } 387 388 Allocation &allocation = iter->second; 389 390 allocation.m_leak = true; 391 } 392 393 void 394 IRMemoryMap::Free (lldb::addr_t process_address, Error &error) 395 { 396 error.Clear(); 397 398 AllocationMap::iterator iter = m_allocations.find(process_address); 399 400 if (iter == m_allocations.end()) 401 { 402 error.SetErrorToGenericError(); 403 error.SetErrorString("Couldn't free: allocation doesn't exist"); 404 return; 405 } 406 407 Allocation &allocation = iter->second; 408 409 switch (allocation.m_policy) 410 { 411 default: 412 case eAllocationPolicyHostOnly: 413 { 414 lldb::ProcessSP process_sp = m_process_wp.lock(); 415 if (process_sp) 416 { 417 if (process_sp->CanJIT() && process_sp->IsAlive()) 418 process_sp->DeallocateMemory(allocation.m_process_alloc); // FindSpace allocated this for real 419 else 420 process_sp->GetReservationCache().Unreserve(allocation.m_process_alloc); // FindSpace registered this memory 421 } 422 423 break; 424 } 425 case eAllocationPolicyMirror: 426 case eAllocationPolicyProcessOnly: 427 { 428 lldb::ProcessSP process_sp = m_process_wp.lock(); 429 if (process_sp) 430 process_sp->DeallocateMemory(allocation.m_process_alloc); 431 } 432 } 433 434 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)) 435 { 436 log->Printf("IRMemoryMap::Free (0x%" PRIx64 ") freed [0x%" PRIx64 "..0x%" PRIx64 ")", 437 (uint64_t)process_address, 438 iter->second.m_process_start, 439 iter->second.m_process_start + iter->second.m_size); 440 } 441 442 m_allocations.erase(iter); 443 } 444 445 void 446 IRMemoryMap::WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, size_t size, Error &error) 447 { 448 error.Clear(); 449 450 AllocationMap::iterator iter = FindAllocation(process_address, size); 451 452 if (iter == m_allocations.end()) 453 { 454 lldb::ProcessSP process_sp = m_process_wp.lock(); 455 456 if (process_sp) 457 { 458 process_sp->WriteMemory(process_address, bytes, size, error); 459 return; 460 } 461 462 error.SetErrorToGenericError(); 463 error.SetErrorString("Couldn't write: no allocation contains the target range and the process doesn't exist"); 464 return; 465 } 466 467 Allocation &allocation = iter->second; 468 469 uint64_t offset = process_address - allocation.m_process_start; 470 471 lldb::ProcessSP process_sp; 472 473 switch (allocation.m_policy) 474 { 475 default: 476 error.SetErrorToGenericError(); 477 error.SetErrorString("Couldn't write: invalid allocation policy"); 478 return; 479 case eAllocationPolicyHostOnly: 480 if (!allocation.m_data.GetByteSize()) 481 { 482 error.SetErrorToGenericError(); 483 error.SetErrorString("Couldn't write: data buffer is empty"); 484 return; 485 } 486 ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size); 487 break; 488 case eAllocationPolicyMirror: 489 if (!allocation.m_data.GetByteSize()) 490 { 491 error.SetErrorToGenericError(); 492 error.SetErrorString("Couldn't write: data buffer is empty"); 493 return; 494 } 495 ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size); 496 process_sp = m_process_wp.lock(); 497 if (process_sp) 498 { 499 process_sp->WriteMemory(process_address, bytes, size, error); 500 if (!error.Success()) 501 return; 502 } 503 break; 504 case eAllocationPolicyProcessOnly: 505 process_sp = m_process_wp.lock(); 506 if (process_sp) 507 { 508 process_sp->WriteMemory(process_address, bytes, size, error); 509 if (!error.Success()) 510 return; 511 } 512 break; 513 } 514 515 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)) 516 { 517 log->Printf("IRMemoryMap::WriteMemory (0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRId64 ") went to [0x%" PRIx64 "..0x%" PRIx64 ")", 518 (uint64_t)process_address, 519 (uint64_t)bytes, 520 (uint64_t)size, 521 (uint64_t)allocation.m_process_start, 522 (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size); 523 } 524 } 525 526 void 527 IRMemoryMap::WriteScalarToMemory (lldb::addr_t process_address, Scalar &scalar, size_t size, Error &error) 528 { 529 error.Clear(); 530 531 if (size == UINT32_MAX) 532 size = scalar.GetByteSize(); 533 534 if (size > 0) 535 { 536 uint8_t buf[32]; 537 const size_t mem_size = scalar.GetAsMemoryData (buf, size, GetByteOrder(), error); 538 if (mem_size > 0) 539 { 540 return WriteMemory(process_address, buf, mem_size, error); 541 } 542 else 543 { 544 error.SetErrorToGenericError(); 545 error.SetErrorString ("Couldn't write scalar: failed to get scalar as memory data"); 546 } 547 } 548 else 549 { 550 error.SetErrorToGenericError(); 551 error.SetErrorString ("Couldn't write scalar: its size was zero"); 552 } 553 return; 554 } 555 556 void 557 IRMemoryMap::WritePointerToMemory (lldb::addr_t process_address, lldb::addr_t address, Error &error) 558 { 559 error.Clear(); 560 561 Scalar scalar(address); 562 563 WriteScalarToMemory(process_address, scalar, GetAddressByteSize(), error); 564 } 565 566 void 567 IRMemoryMap::ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t size, Error &error) 568 { 569 error.Clear(); 570 571 AllocationMap::iterator iter = FindAllocation(process_address, size); 572 573 if (iter == m_allocations.end()) 574 { 575 lldb::ProcessSP process_sp = m_process_wp.lock(); 576 577 if (process_sp) 578 { 579 process_sp->ReadMemory(process_address, bytes, size, error); 580 return; 581 } 582 583 lldb::TargetSP target_sp = m_target_wp.lock(); 584 585 if (target_sp) 586 { 587 Address absolute_address(process_address); 588 target_sp->ReadMemory(absolute_address, false, bytes, size, error); 589 return; 590 } 591 592 error.SetErrorToGenericError(); 593 error.SetErrorString("Couldn't read: no allocation contains the target range, and neither the process nor the target exist"); 594 return; 595 } 596 597 Allocation &allocation = iter->second; 598 599 uint64_t offset = process_address - allocation.m_process_start; 600 601 lldb::ProcessSP process_sp; 602 603 switch (allocation.m_policy) 604 { 605 default: 606 error.SetErrorToGenericError(); 607 error.SetErrorString("Couldn't read: invalid allocation policy"); 608 return; 609 case eAllocationPolicyHostOnly: 610 if (!allocation.m_data.GetByteSize()) 611 { 612 error.SetErrorToGenericError(); 613 error.SetErrorString("Couldn't read: data buffer is empty"); 614 return; 615 } 616 ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size); 617 break; 618 case eAllocationPolicyMirror: 619 process_sp = m_process_wp.lock(); 620 if (process_sp) 621 { 622 process_sp->ReadMemory(process_address, bytes, size, error); 623 if (!error.Success()) 624 return; 625 } 626 else 627 { 628 if (!allocation.m_data.GetByteSize()) 629 { 630 error.SetErrorToGenericError(); 631 error.SetErrorString("Couldn't read: data buffer is empty"); 632 return; 633 } 634 ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size); 635 } 636 break; 637 case eAllocationPolicyProcessOnly: 638 process_sp = m_process_wp.lock(); 639 if (process_sp) 640 { 641 process_sp->ReadMemory(process_address, bytes, size, error); 642 if (!error.Success()) 643 return; 644 } 645 break; 646 } 647 648 if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)) 649 { 650 log->Printf("IRMemoryMap::ReadMemory (0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRId64 ") came from [0x%" PRIx64 "..0x%" PRIx64 ")", 651 (uint64_t)process_address, 652 (uint64_t)bytes, 653 (uint64_t)size, 654 (uint64_t)allocation.m_process_start, 655 (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size); 656 } 657 } 658 659 void 660 IRMemoryMap::ReadScalarFromMemory (Scalar &scalar, lldb::addr_t process_address, size_t size, Error &error) 661 { 662 error.Clear(); 663 664 if (size > 0) 665 { 666 DataBufferHeap buf(size, 0); 667 ReadMemory(buf.GetBytes(), process_address, size, error); 668 669 if (!error.Success()) 670 return; 671 672 DataExtractor extractor(buf.GetBytes(), buf.GetByteSize(), GetByteOrder(), GetAddressByteSize()); 673 674 lldb::offset_t offset = 0; 675 676 switch (size) 677 { 678 default: 679 error.SetErrorToGenericError(); 680 error.SetErrorStringWithFormat("Couldn't read scalar: unsupported size %" PRIu64, (uint64_t)size); 681 return; 682 case 1: scalar = extractor.GetU8(&offset); break; 683 case 2: scalar = extractor.GetU16(&offset); break; 684 case 4: scalar = extractor.GetU32(&offset); break; 685 case 8: scalar = extractor.GetU64(&offset); break; 686 } 687 } 688 else 689 { 690 error.SetErrorToGenericError(); 691 error.SetErrorString ("Couldn't read scalar: its size was zero"); 692 } 693 return; 694 } 695 696 void 697 IRMemoryMap::ReadPointerFromMemory (lldb::addr_t *address, lldb::addr_t process_address, Error &error) 698 { 699 error.Clear(); 700 701 Scalar pointer_scalar; 702 ReadScalarFromMemory(pointer_scalar, process_address, GetAddressByteSize(), error); 703 704 if (!error.Success()) 705 return; 706 707 *address = pointer_scalar.ULongLong(); 708 709 return; 710 } 711 712 void 713 IRMemoryMap::GetMemoryData (DataExtractor &extractor, lldb::addr_t process_address, size_t size, Error &error) 714 { 715 error.Clear(); 716 717 if (size > 0) 718 { 719 AllocationMap::iterator iter = FindAllocation(process_address, size); 720 721 if (iter == m_allocations.end()) 722 { 723 error.SetErrorToGenericError(); 724 error.SetErrorStringWithFormat("Couldn't find an allocation containing [0x%" PRIx64 "..0x%" PRIx64 ")", process_address, process_address + size); 725 return; 726 } 727 728 Allocation &allocation = iter->second; 729 730 switch (allocation.m_policy) 731 { 732 default: 733 error.SetErrorToGenericError(); 734 error.SetErrorString("Couldn't get memory data: invalid allocation policy"); 735 return; 736 case eAllocationPolicyProcessOnly: 737 error.SetErrorToGenericError(); 738 error.SetErrorString("Couldn't get memory data: memory is only in the target"); 739 return; 740 case eAllocationPolicyMirror: 741 { 742 lldb::ProcessSP process_sp = m_process_wp.lock(); 743 744 if (!allocation.m_data.GetByteSize()) 745 { 746 error.SetErrorToGenericError(); 747 error.SetErrorString("Couldn't get memory data: data buffer is empty"); 748 return; 749 } 750 if (process_sp) 751 { 752 process_sp->ReadMemory(allocation.m_process_start, allocation.m_data.GetBytes(), allocation.m_data.GetByteSize(), error); 753 if (!error.Success()) 754 return; 755 uint64_t offset = process_address - allocation.m_process_start; 756 extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize()); 757 return; 758 } 759 } 760 case eAllocationPolicyHostOnly: 761 if (!allocation.m_data.GetByteSize()) 762 { 763 error.SetErrorToGenericError(); 764 error.SetErrorString("Couldn't get memory data: data buffer is empty"); 765 return; 766 } 767 uint64_t offset = process_address - allocation.m_process_start; 768 extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize()); 769 return; 770 } 771 } 772 else 773 { 774 error.SetErrorToGenericError(); 775 error.SetErrorString ("Couldn't get memory data: its size was zero"); 776 return; 777 } 778 } 779 780 781