1254721Semaste//===-- IRMemoryMap.cpp -----------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/Core/DataBufferHeap.h" 11254721Semaste#include "lldb/Core/DataExtractor.h" 12254721Semaste#include "lldb/Core/Error.h" 13254721Semaste#include "lldb/Core/Log.h" 14254721Semaste#include "lldb/Core/Scalar.h" 15254721Semaste#include "lldb/Expression/IRMemoryMap.h" 16254721Semaste#include "lldb/Target/Process.h" 17254721Semaste#include "lldb/Target/Target.h" 18254721Semaste 19254721Semasteusing namespace lldb_private; 20254721Semaste 21254721SemasteIRMemoryMap::IRMemoryMap (lldb::TargetSP target_sp) : 22254721Semaste m_target_wp(target_sp) 23254721Semaste{ 24254721Semaste if (target_sp) 25254721Semaste m_process_wp = target_sp->GetProcessSP(); 26254721Semaste} 27254721Semaste 28254721SemasteIRMemoryMap::~IRMemoryMap () 29254721Semaste{ 30254721Semaste lldb::ProcessSP process_sp = m_process_wp.lock(); 31254721Semaste 32254721Semaste if (process_sp) 33254721Semaste { 34254721Semaste AllocationMap::iterator iter; 35254721Semaste 36254721Semaste Error err; 37254721Semaste 38254721Semaste while ((iter = m_allocations.begin()) != m_allocations.end()) 39254721Semaste { 40254721Semaste err.Clear(); 41254721Semaste if (iter->second.m_leak) 42254721Semaste m_allocations.erase(iter); 43254721Semaste else 44254721Semaste Free(iter->first, err); 45254721Semaste } 46254721Semaste } 47254721Semaste} 48254721Semaste 49254721Semastelldb::addr_t 50254721SemasteIRMemoryMap::FindSpace (size_t size) 51254721Semaste{ 52254721Semaste lldb::TargetSP target_sp = m_target_wp.lock(); 53254721Semaste lldb::ProcessSP process_sp = m_process_wp.lock(); 54254721Semaste 55254721Semaste lldb::addr_t ret = LLDB_INVALID_ADDRESS; 56254721Semaste 57254721Semaste if (process_sp && process_sp->CanJIT() && process_sp->IsAlive()) 58254721Semaste { 59254721Semaste Error alloc_error; 60254721Semaste 61254721Semaste ret = process_sp->AllocateMemory(size, lldb::ePermissionsReadable | lldb::ePermissionsWritable, alloc_error); 62254721Semaste 63254721Semaste if (!alloc_error.Success()) 64254721Semaste return LLDB_INVALID_ADDRESS; 65254721Semaste else 66254721Semaste return ret; 67254721Semaste } 68254721Semaste 69254721Semaste for (int iterations = 0; iterations < 16; ++iterations) 70254721Semaste { 71254721Semaste lldb::addr_t candidate = LLDB_INVALID_ADDRESS; 72254721Semaste 73254721Semaste switch (target_sp->GetArchitecture().GetAddressByteSize()) 74254721Semaste { 75254721Semaste case 4: 76254721Semaste { 77263363Semaste uint32_t random_data = rand(); 78254721Semaste candidate = random_data; 79254721Semaste candidate &= ~0xfffull; 80254721Semaste break; 81254721Semaste } 82254721Semaste case 8: 83254721Semaste { 84263363Semaste uint32_t random_low = rand(); 85263363Semaste uint32_t random_high = rand(); 86254721Semaste candidate = random_high; 87254721Semaste candidate <<= 32ull; 88254721Semaste candidate |= random_low; 89254721Semaste candidate &= ~0xfffull; 90254721Semaste break; 91254721Semaste } 92254721Semaste } 93254721Semaste 94254721Semaste if (IntersectsAllocation(candidate, size)) 95254721Semaste continue; 96254721Semaste 97254721Semaste ret = candidate; 98254721Semaste 99254721Semaste return ret; 100254721Semaste } 101254721Semaste 102254721Semaste return ret; 103254721Semaste} 104254721Semaste 105254721SemasteIRMemoryMap::AllocationMap::iterator 106254721SemasteIRMemoryMap::FindAllocation (lldb::addr_t addr, size_t size) 107254721Semaste{ 108254721Semaste if (addr == LLDB_INVALID_ADDRESS) 109254721Semaste return m_allocations.end(); 110254721Semaste 111254721Semaste AllocationMap::iterator iter = m_allocations.lower_bound (addr); 112254721Semaste 113254721Semaste if (iter == m_allocations.end() || 114254721Semaste iter->first > addr) 115254721Semaste { 116254721Semaste if (iter == m_allocations.begin()) 117254721Semaste return m_allocations.end(); 118254721Semaste iter--; 119254721Semaste } 120254721Semaste 121254721Semaste if (iter->first <= addr && iter->first + iter->second.m_size >= addr + size) 122254721Semaste return iter; 123254721Semaste 124254721Semaste return m_allocations.end(); 125254721Semaste} 126254721Semaste 127254721Semastebool 128254721SemasteIRMemoryMap::IntersectsAllocation (lldb::addr_t addr, size_t size) 129254721Semaste{ 130254721Semaste if (addr == LLDB_INVALID_ADDRESS) 131254721Semaste return false; 132254721Semaste 133254721Semaste AllocationMap::iterator iter = m_allocations.lower_bound (addr); 134254721Semaste 135254721Semaste if (iter == m_allocations.end() || 136254721Semaste iter->first > addr) 137254721Semaste { 138254721Semaste if (iter == m_allocations.begin()) 139254721Semaste return false; 140254721Semaste 141254721Semaste iter--; 142254721Semaste } 143254721Semaste 144254721Semaste while (iter != m_allocations.end() && iter->second.m_process_alloc < addr + size) 145254721Semaste { 146254721Semaste if (iter->second.m_process_start + iter->second.m_size > addr) 147254721Semaste return true; 148254721Semaste 149254721Semaste ++iter; 150254721Semaste } 151254721Semaste 152254721Semaste return false; 153254721Semaste} 154254721Semaste 155254721Semastelldb::ByteOrder 156254721SemasteIRMemoryMap::GetByteOrder() 157254721Semaste{ 158254721Semaste lldb::ProcessSP process_sp = m_process_wp.lock(); 159254721Semaste 160254721Semaste if (process_sp) 161254721Semaste return process_sp->GetByteOrder(); 162254721Semaste 163254721Semaste lldb::TargetSP target_sp = m_target_wp.lock(); 164254721Semaste 165254721Semaste if (target_sp) 166254721Semaste return target_sp->GetArchitecture().GetByteOrder(); 167254721Semaste 168254721Semaste return lldb::eByteOrderInvalid; 169254721Semaste} 170254721Semaste 171254721Semasteuint32_t 172254721SemasteIRMemoryMap::GetAddressByteSize() 173254721Semaste{ 174254721Semaste lldb::ProcessSP process_sp = m_process_wp.lock(); 175254721Semaste 176254721Semaste if (process_sp) 177254721Semaste return process_sp->GetAddressByteSize(); 178254721Semaste 179254721Semaste lldb::TargetSP target_sp = m_target_wp.lock(); 180254721Semaste 181254721Semaste if (target_sp) 182254721Semaste return target_sp->GetArchitecture().GetAddressByteSize(); 183254721Semaste 184254721Semaste return UINT32_MAX; 185254721Semaste} 186254721Semaste 187254721SemasteExecutionContextScope * 188254721SemasteIRMemoryMap::GetBestExecutionContextScope() 189254721Semaste{ 190254721Semaste lldb::ProcessSP process_sp = m_process_wp.lock(); 191254721Semaste 192254721Semaste if (process_sp) 193254721Semaste return process_sp.get(); 194254721Semaste 195254721Semaste lldb::TargetSP target_sp = m_target_wp.lock(); 196254721Semaste 197254721Semaste if (target_sp) 198254721Semaste return target_sp.get(); 199254721Semaste 200254721Semaste return NULL; 201254721Semaste} 202254721Semaste 203254721SemasteIRMemoryMap::Allocation::Allocation (lldb::addr_t process_alloc, 204254721Semaste lldb::addr_t process_start, 205254721Semaste size_t size, 206254721Semaste uint32_t permissions, 207254721Semaste uint8_t alignment, 208254721Semaste AllocationPolicy policy) : 209254721Semaste m_process_alloc (process_alloc), 210254721Semaste m_process_start (process_start), 211254721Semaste m_size (size), 212254721Semaste m_permissions (permissions), 213254721Semaste m_alignment (alignment), 214254721Semaste m_policy (policy), 215254721Semaste m_leak (false) 216254721Semaste{ 217254721Semaste switch (policy) 218254721Semaste { 219254721Semaste default: 220254721Semaste assert (0 && "We cannot reach this!"); 221254721Semaste case eAllocationPolicyHostOnly: 222254721Semaste m_data.SetByteSize(size); 223254721Semaste memset(m_data.GetBytes(), 0, size); 224254721Semaste break; 225254721Semaste case eAllocationPolicyProcessOnly: 226254721Semaste break; 227254721Semaste case eAllocationPolicyMirror: 228254721Semaste m_data.SetByteSize(size); 229254721Semaste memset(m_data.GetBytes(), 0, size); 230254721Semaste break; 231254721Semaste } 232254721Semaste} 233254721Semaste 234254721Semastelldb::addr_t 235254721SemasteIRMemoryMap::Malloc (size_t size, uint8_t alignment, uint32_t permissions, AllocationPolicy policy, Error &error) 236254721Semaste{ 237254721Semaste error.Clear(); 238254721Semaste 239254721Semaste lldb::ProcessSP process_sp; 240254721Semaste lldb::addr_t allocation_address = LLDB_INVALID_ADDRESS; 241254721Semaste lldb::addr_t aligned_address = LLDB_INVALID_ADDRESS; 242254721Semaste 243254721Semaste size_t alignment_mask = alignment - 1; 244254721Semaste size_t allocation_size; 245254721Semaste 246254721Semaste if (size == 0) 247254721Semaste allocation_size = alignment; 248254721Semaste else 249254721Semaste allocation_size = (size & alignment_mask) ? ((size + alignment) & (~alignment_mask)) : size; 250254721Semaste 251254721Semaste switch (policy) 252254721Semaste { 253254721Semaste default: 254254721Semaste error.SetErrorToGenericError(); 255254721Semaste error.SetErrorString("Couldn't malloc: invalid allocation policy"); 256254721Semaste return LLDB_INVALID_ADDRESS; 257254721Semaste case eAllocationPolicyHostOnly: 258254721Semaste allocation_address = FindSpace(allocation_size); 259254721Semaste if (allocation_address == LLDB_INVALID_ADDRESS) 260254721Semaste { 261254721Semaste error.SetErrorToGenericError(); 262254721Semaste error.SetErrorString("Couldn't malloc: address space is full"); 263254721Semaste return LLDB_INVALID_ADDRESS; 264254721Semaste } 265254721Semaste break; 266254721Semaste case eAllocationPolicyMirror: 267254721Semaste process_sp = m_process_wp.lock(); 268254721Semaste if (process_sp && process_sp->CanJIT() && process_sp->IsAlive()) 269254721Semaste { 270254721Semaste allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error); 271254721Semaste if (!error.Success()) 272254721Semaste return LLDB_INVALID_ADDRESS; 273254721Semaste } 274254721Semaste else 275254721Semaste { 276254721Semaste policy = eAllocationPolicyHostOnly; 277254721Semaste allocation_address = FindSpace(allocation_size); 278254721Semaste if (allocation_address == LLDB_INVALID_ADDRESS) 279254721Semaste { 280254721Semaste error.SetErrorToGenericError(); 281254721Semaste error.SetErrorString("Couldn't malloc: address space is full"); 282254721Semaste return LLDB_INVALID_ADDRESS; 283254721Semaste } 284254721Semaste } 285254721Semaste break; 286254721Semaste case eAllocationPolicyProcessOnly: 287254721Semaste process_sp = m_process_wp.lock(); 288254721Semaste if (process_sp) 289254721Semaste { 290254721Semaste if (process_sp->CanJIT() && process_sp->IsAlive()) 291254721Semaste { 292254721Semaste allocation_address = process_sp->AllocateMemory(allocation_size, permissions, error); 293254721Semaste if (!error.Success()) 294254721Semaste return LLDB_INVALID_ADDRESS; 295254721Semaste } 296254721Semaste else 297254721Semaste { 298254721Semaste error.SetErrorToGenericError(); 299254721Semaste error.SetErrorString("Couldn't malloc: process doesn't support allocating memory"); 300254721Semaste return LLDB_INVALID_ADDRESS; 301254721Semaste } 302254721Semaste } 303254721Semaste else 304254721Semaste { 305254721Semaste error.SetErrorToGenericError(); 306254721Semaste error.SetErrorString("Couldn't malloc: process doesn't exist, and this memory must be in the process"); 307254721Semaste return LLDB_INVALID_ADDRESS; 308254721Semaste } 309254721Semaste break; 310254721Semaste } 311254721Semaste 312254721Semaste 313254721Semaste lldb::addr_t mask = alignment - 1; 314254721Semaste aligned_address = (allocation_address + mask) & (~mask); 315254721Semaste 316254721Semaste m_allocations[aligned_address] = Allocation(allocation_address, 317254721Semaste aligned_address, 318254721Semaste allocation_size, 319254721Semaste permissions, 320254721Semaste alignment, 321254721Semaste policy); 322254721Semaste 323254721Semaste if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)) 324254721Semaste { 325254721Semaste const char * policy_string; 326254721Semaste 327254721Semaste switch (policy) 328254721Semaste { 329254721Semaste default: 330254721Semaste policy_string = "<invalid policy>"; 331254721Semaste break; 332254721Semaste case eAllocationPolicyHostOnly: 333254721Semaste policy_string = "eAllocationPolicyHostOnly"; 334254721Semaste break; 335254721Semaste case eAllocationPolicyProcessOnly: 336254721Semaste policy_string = "eAllocationPolicyProcessOnly"; 337254721Semaste break; 338254721Semaste case eAllocationPolicyMirror: 339254721Semaste policy_string = "eAllocationPolicyMirror"; 340254721Semaste break; 341254721Semaste } 342254721Semaste 343254721Semaste log->Printf("IRMemoryMap::Malloc (%" PRIu64 ", 0x%" PRIx64 ", 0x%" PRIx64 ", %s) -> 0x%" PRIx64, 344254721Semaste (uint64_t)allocation_size, 345254721Semaste (uint64_t)alignment, 346254721Semaste (uint64_t)permissions, 347254721Semaste policy_string, 348254721Semaste aligned_address); 349254721Semaste } 350254721Semaste 351254721Semaste return aligned_address; 352254721Semaste} 353254721Semaste 354254721Semastevoid 355254721SemasteIRMemoryMap::Leak (lldb::addr_t process_address, Error &error) 356254721Semaste{ 357254721Semaste error.Clear(); 358254721Semaste 359254721Semaste AllocationMap::iterator iter = m_allocations.find(process_address); 360254721Semaste 361254721Semaste if (iter == m_allocations.end()) 362254721Semaste { 363254721Semaste error.SetErrorToGenericError(); 364254721Semaste error.SetErrorString("Couldn't leak: allocation doesn't exist"); 365254721Semaste return; 366254721Semaste } 367254721Semaste 368254721Semaste Allocation &allocation = iter->second; 369254721Semaste 370254721Semaste allocation.m_leak = true; 371254721Semaste} 372254721Semaste 373254721Semastevoid 374254721SemasteIRMemoryMap::Free (lldb::addr_t process_address, Error &error) 375254721Semaste{ 376254721Semaste error.Clear(); 377254721Semaste 378254721Semaste AllocationMap::iterator iter = m_allocations.find(process_address); 379254721Semaste 380254721Semaste if (iter == m_allocations.end()) 381254721Semaste { 382254721Semaste error.SetErrorToGenericError(); 383254721Semaste error.SetErrorString("Couldn't free: allocation doesn't exist"); 384254721Semaste return; 385254721Semaste } 386254721Semaste 387254721Semaste Allocation &allocation = iter->second; 388254721Semaste 389254721Semaste switch (allocation.m_policy) 390254721Semaste { 391254721Semaste default: 392254721Semaste case eAllocationPolicyHostOnly: 393254721Semaste { 394254721Semaste lldb::ProcessSP process_sp = m_process_wp.lock(); 395254721Semaste if (process_sp) 396254721Semaste { 397254721Semaste if (process_sp->CanJIT() && process_sp->IsAlive()) 398254721Semaste process_sp->DeallocateMemory(allocation.m_process_alloc); // FindSpace allocated this for real 399254721Semaste } 400254721Semaste 401254721Semaste break; 402254721Semaste } 403254721Semaste case eAllocationPolicyMirror: 404254721Semaste case eAllocationPolicyProcessOnly: 405254721Semaste { 406254721Semaste lldb::ProcessSP process_sp = m_process_wp.lock(); 407254721Semaste if (process_sp) 408254721Semaste process_sp->DeallocateMemory(allocation.m_process_alloc); 409254721Semaste } 410254721Semaste } 411254721Semaste 412254721Semaste if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)) 413254721Semaste { 414254721Semaste log->Printf("IRMemoryMap::Free (0x%" PRIx64 ") freed [0x%" PRIx64 "..0x%" PRIx64 ")", 415254721Semaste (uint64_t)process_address, 416254721Semaste iter->second.m_process_start, 417254721Semaste iter->second.m_process_start + iter->second.m_size); 418254721Semaste } 419254721Semaste 420254721Semaste m_allocations.erase(iter); 421254721Semaste} 422254721Semaste 423254721Semastevoid 424254721SemasteIRMemoryMap::WriteMemory (lldb::addr_t process_address, const uint8_t *bytes, size_t size, Error &error) 425254721Semaste{ 426254721Semaste error.Clear(); 427254721Semaste 428254721Semaste AllocationMap::iterator iter = FindAllocation(process_address, size); 429254721Semaste 430254721Semaste if (iter == m_allocations.end()) 431254721Semaste { 432254721Semaste lldb::ProcessSP process_sp = m_process_wp.lock(); 433254721Semaste 434254721Semaste if (process_sp) 435254721Semaste { 436254721Semaste process_sp->WriteMemory(process_address, bytes, size, error); 437254721Semaste return; 438254721Semaste } 439254721Semaste 440254721Semaste error.SetErrorToGenericError(); 441254721Semaste error.SetErrorString("Couldn't write: no allocation contains the target range and the process doesn't exist"); 442254721Semaste return; 443254721Semaste } 444254721Semaste 445254721Semaste Allocation &allocation = iter->second; 446254721Semaste 447254721Semaste uint64_t offset = process_address - allocation.m_process_start; 448254721Semaste 449254721Semaste lldb::ProcessSP process_sp; 450254721Semaste 451254721Semaste switch (allocation.m_policy) 452254721Semaste { 453254721Semaste default: 454254721Semaste error.SetErrorToGenericError(); 455254721Semaste error.SetErrorString("Couldn't write: invalid allocation policy"); 456254721Semaste return; 457254721Semaste case eAllocationPolicyHostOnly: 458254721Semaste if (!allocation.m_data.GetByteSize()) 459254721Semaste { 460254721Semaste error.SetErrorToGenericError(); 461254721Semaste error.SetErrorString("Couldn't write: data buffer is empty"); 462254721Semaste return; 463254721Semaste } 464254721Semaste ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size); 465254721Semaste break; 466254721Semaste case eAllocationPolicyMirror: 467254721Semaste if (!allocation.m_data.GetByteSize()) 468254721Semaste { 469254721Semaste error.SetErrorToGenericError(); 470254721Semaste error.SetErrorString("Couldn't write: data buffer is empty"); 471254721Semaste return; 472254721Semaste } 473254721Semaste ::memcpy (allocation.m_data.GetBytes() + offset, bytes, size); 474254721Semaste process_sp = m_process_wp.lock(); 475254721Semaste if (process_sp) 476254721Semaste { 477254721Semaste process_sp->WriteMemory(process_address, bytes, size, error); 478254721Semaste if (!error.Success()) 479254721Semaste return; 480254721Semaste } 481254721Semaste break; 482254721Semaste case eAllocationPolicyProcessOnly: 483254721Semaste process_sp = m_process_wp.lock(); 484254721Semaste if (process_sp) 485254721Semaste { 486254721Semaste process_sp->WriteMemory(process_address, bytes, size, error); 487254721Semaste if (!error.Success()) 488254721Semaste return; 489254721Semaste } 490254721Semaste break; 491254721Semaste } 492254721Semaste 493254721Semaste if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)) 494254721Semaste { 495254721Semaste log->Printf("IRMemoryMap::WriteMemory (0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRId64 ") went to [0x%" PRIx64 "..0x%" PRIx64 ")", 496254721Semaste (uint64_t)process_address, 497254721Semaste (uint64_t)bytes, 498254721Semaste (uint64_t)size, 499254721Semaste (uint64_t)allocation.m_process_start, 500254721Semaste (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size); 501254721Semaste } 502254721Semaste} 503254721Semaste 504254721Semastevoid 505254721SemasteIRMemoryMap::WriteScalarToMemory (lldb::addr_t process_address, Scalar &scalar, size_t size, Error &error) 506254721Semaste{ 507254721Semaste error.Clear(); 508254721Semaste 509254721Semaste if (size == UINT32_MAX) 510254721Semaste size = scalar.GetByteSize(); 511254721Semaste 512254721Semaste if (size > 0) 513254721Semaste { 514254721Semaste uint8_t buf[32]; 515254721Semaste const size_t mem_size = scalar.GetAsMemoryData (buf, size, GetByteOrder(), error); 516254721Semaste if (mem_size > 0) 517254721Semaste { 518254721Semaste return WriteMemory(process_address, buf, mem_size, error); 519254721Semaste } 520254721Semaste else 521254721Semaste { 522254721Semaste error.SetErrorToGenericError(); 523254721Semaste error.SetErrorString ("Couldn't write scalar: failed to get scalar as memory data"); 524254721Semaste } 525254721Semaste } 526254721Semaste else 527254721Semaste { 528254721Semaste error.SetErrorToGenericError(); 529254721Semaste error.SetErrorString ("Couldn't write scalar: its size was zero"); 530254721Semaste } 531254721Semaste return; 532254721Semaste} 533254721Semaste 534254721Semastevoid 535254721SemasteIRMemoryMap::WritePointerToMemory (lldb::addr_t process_address, lldb::addr_t address, Error &error) 536254721Semaste{ 537254721Semaste error.Clear(); 538254721Semaste 539254721Semaste Scalar scalar(address); 540254721Semaste 541254721Semaste WriteScalarToMemory(process_address, scalar, GetAddressByteSize(), error); 542254721Semaste} 543254721Semaste 544254721Semastevoid 545254721SemasteIRMemoryMap::ReadMemory (uint8_t *bytes, lldb::addr_t process_address, size_t size, Error &error) 546254721Semaste{ 547254721Semaste error.Clear(); 548254721Semaste 549254721Semaste AllocationMap::iterator iter = FindAllocation(process_address, size); 550254721Semaste 551254721Semaste if (iter == m_allocations.end()) 552254721Semaste { 553254721Semaste lldb::ProcessSP process_sp = m_process_wp.lock(); 554254721Semaste 555254721Semaste if (process_sp) 556254721Semaste { 557254721Semaste process_sp->ReadMemory(process_address, bytes, size, error); 558254721Semaste return; 559254721Semaste } 560254721Semaste 561254721Semaste lldb::TargetSP target_sp = m_target_wp.lock(); 562254721Semaste 563254721Semaste if (target_sp) 564254721Semaste { 565254721Semaste Address absolute_address(process_address); 566254721Semaste target_sp->ReadMemory(absolute_address, false, bytes, size, error); 567254721Semaste return; 568254721Semaste } 569254721Semaste 570254721Semaste error.SetErrorToGenericError(); 571254721Semaste error.SetErrorString("Couldn't read: no allocation contains the target range, and neither the process nor the target exist"); 572254721Semaste return; 573254721Semaste } 574254721Semaste 575254721Semaste Allocation &allocation = iter->second; 576254721Semaste 577254721Semaste uint64_t offset = process_address - allocation.m_process_start; 578254721Semaste 579254721Semaste lldb::ProcessSP process_sp; 580254721Semaste 581254721Semaste switch (allocation.m_policy) 582254721Semaste { 583254721Semaste default: 584254721Semaste error.SetErrorToGenericError(); 585254721Semaste error.SetErrorString("Couldn't read: invalid allocation policy"); 586254721Semaste return; 587254721Semaste case eAllocationPolicyHostOnly: 588254721Semaste if (!allocation.m_data.GetByteSize()) 589254721Semaste { 590254721Semaste error.SetErrorToGenericError(); 591254721Semaste error.SetErrorString("Couldn't read: data buffer is empty"); 592254721Semaste return; 593254721Semaste } 594254721Semaste ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size); 595254721Semaste break; 596254721Semaste case eAllocationPolicyMirror: 597254721Semaste process_sp = m_process_wp.lock(); 598254721Semaste if (process_sp) 599254721Semaste { 600254721Semaste process_sp->ReadMemory(process_address, bytes, size, error); 601254721Semaste if (!error.Success()) 602254721Semaste return; 603254721Semaste } 604254721Semaste else 605254721Semaste { 606254721Semaste if (!allocation.m_data.GetByteSize()) 607254721Semaste { 608254721Semaste error.SetErrorToGenericError(); 609254721Semaste error.SetErrorString("Couldn't read: data buffer is empty"); 610254721Semaste return; 611254721Semaste } 612254721Semaste ::memcpy (bytes, allocation.m_data.GetBytes() + offset, size); 613254721Semaste } 614254721Semaste break; 615254721Semaste case eAllocationPolicyProcessOnly: 616254721Semaste process_sp = m_process_wp.lock(); 617254721Semaste if (process_sp) 618254721Semaste { 619254721Semaste process_sp->ReadMemory(process_address, bytes, size, error); 620254721Semaste if (!error.Success()) 621254721Semaste return; 622254721Semaste } 623254721Semaste break; 624254721Semaste } 625254721Semaste 626254721Semaste if (lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS)) 627254721Semaste { 628254721Semaste log->Printf("IRMemoryMap::ReadMemory (0x%" PRIx64 ", 0x%" PRIx64 ", 0x%" PRId64 ") came from [0x%" PRIx64 "..0x%" PRIx64 ")", 629254721Semaste (uint64_t)process_address, 630254721Semaste (uint64_t)bytes, 631254721Semaste (uint64_t)size, 632254721Semaste (uint64_t)allocation.m_process_start, 633254721Semaste (uint64_t)allocation.m_process_start + (uint64_t)allocation.m_size); 634254721Semaste } 635254721Semaste} 636254721Semaste 637254721Semastevoid 638254721SemasteIRMemoryMap::ReadScalarFromMemory (Scalar &scalar, lldb::addr_t process_address, size_t size, Error &error) 639254721Semaste{ 640254721Semaste error.Clear(); 641254721Semaste 642254721Semaste if (size > 0) 643254721Semaste { 644254721Semaste DataBufferHeap buf(size, 0); 645254721Semaste ReadMemory(buf.GetBytes(), process_address, size, error); 646254721Semaste 647254721Semaste if (!error.Success()) 648254721Semaste return; 649254721Semaste 650254721Semaste DataExtractor extractor(buf.GetBytes(), buf.GetByteSize(), GetByteOrder(), GetAddressByteSize()); 651254721Semaste 652254721Semaste lldb::offset_t offset = 0; 653254721Semaste 654254721Semaste switch (size) 655254721Semaste { 656254721Semaste default: 657254721Semaste error.SetErrorToGenericError(); 658254721Semaste error.SetErrorStringWithFormat("Couldn't read scalar: unsupported size %" PRIu64, (uint64_t)size); 659254721Semaste return; 660254721Semaste case 1: scalar = extractor.GetU8(&offset); break; 661254721Semaste case 2: scalar = extractor.GetU16(&offset); break; 662254721Semaste case 4: scalar = extractor.GetU32(&offset); break; 663254721Semaste case 8: scalar = extractor.GetU64(&offset); break; 664254721Semaste } 665254721Semaste } 666254721Semaste else 667254721Semaste { 668254721Semaste error.SetErrorToGenericError(); 669254721Semaste error.SetErrorString ("Couldn't read scalar: its size was zero"); 670254721Semaste } 671254721Semaste return; 672254721Semaste} 673254721Semaste 674254721Semastevoid 675254721SemasteIRMemoryMap::ReadPointerFromMemory (lldb::addr_t *address, lldb::addr_t process_address, Error &error) 676254721Semaste{ 677254721Semaste error.Clear(); 678254721Semaste 679254721Semaste Scalar pointer_scalar; 680254721Semaste ReadScalarFromMemory(pointer_scalar, process_address, GetAddressByteSize(), error); 681254721Semaste 682254721Semaste if (!error.Success()) 683254721Semaste return; 684254721Semaste 685254721Semaste *address = pointer_scalar.ULongLong(); 686254721Semaste 687254721Semaste return; 688254721Semaste} 689254721Semaste 690254721Semastevoid 691254721SemasteIRMemoryMap::GetMemoryData (DataExtractor &extractor, lldb::addr_t process_address, size_t size, Error &error) 692254721Semaste{ 693254721Semaste error.Clear(); 694254721Semaste 695254721Semaste if (size > 0) 696254721Semaste { 697254721Semaste AllocationMap::iterator iter = FindAllocation(process_address, size); 698254721Semaste 699254721Semaste if (iter == m_allocations.end()) 700254721Semaste { 701254721Semaste error.SetErrorToGenericError(); 702254721Semaste error.SetErrorStringWithFormat("Couldn't find an allocation containing [0x%" PRIx64 "..0x%" PRIx64 ")", process_address, process_address + size); 703254721Semaste return; 704254721Semaste } 705254721Semaste 706254721Semaste Allocation &allocation = iter->second; 707254721Semaste 708254721Semaste switch (allocation.m_policy) 709254721Semaste { 710254721Semaste default: 711254721Semaste error.SetErrorToGenericError(); 712254721Semaste error.SetErrorString("Couldn't get memory data: invalid allocation policy"); 713254721Semaste return; 714254721Semaste case eAllocationPolicyProcessOnly: 715254721Semaste error.SetErrorToGenericError(); 716254721Semaste error.SetErrorString("Couldn't get memory data: memory is only in the target"); 717254721Semaste return; 718254721Semaste case eAllocationPolicyMirror: 719254721Semaste { 720254721Semaste lldb::ProcessSP process_sp = m_process_wp.lock(); 721254721Semaste 722254721Semaste if (!allocation.m_data.GetByteSize()) 723254721Semaste { 724254721Semaste error.SetErrorToGenericError(); 725254721Semaste error.SetErrorString("Couldn't get memory data: data buffer is empty"); 726254721Semaste return; 727254721Semaste } 728254721Semaste if (process_sp) 729254721Semaste { 730254721Semaste process_sp->ReadMemory(allocation.m_process_start, allocation.m_data.GetBytes(), allocation.m_data.GetByteSize(), error); 731254721Semaste if (!error.Success()) 732254721Semaste return; 733254721Semaste uint64_t offset = process_address - allocation.m_process_start; 734254721Semaste extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize()); 735254721Semaste return; 736254721Semaste } 737254721Semaste } 738254721Semaste case eAllocationPolicyHostOnly: 739254721Semaste if (!allocation.m_data.GetByteSize()) 740254721Semaste { 741254721Semaste error.SetErrorToGenericError(); 742254721Semaste error.SetErrorString("Couldn't get memory data: data buffer is empty"); 743254721Semaste return; 744254721Semaste } 745254721Semaste uint64_t offset = process_address - allocation.m_process_start; 746254721Semaste extractor = DataExtractor(allocation.m_data.GetBytes() + offset, size, GetByteOrder(), GetAddressByteSize()); 747254721Semaste return; 748254721Semaste } 749254721Semaste } 750254721Semaste else 751254721Semaste { 752254721Semaste error.SetErrorToGenericError(); 753254721Semaste error.SetErrorString ("Couldn't get memory data: its size was zero"); 754254721Semaste return; 755254721Semaste } 756254721Semaste} 757254721Semaste 758254721Semaste 759