15ffd83dbSDimitry Andric //===-- InferiorCallPOSIX.cpp ---------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "InferiorCallPOSIX.h"
100b57cec5SDimitry Andric #include "lldb/Core/Address.h"
11349cc55cSDimitry Andric #include "lldb/Core/Module.h"
120b57cec5SDimitry Andric #include "lldb/Core/ValueObject.h"
130b57cec5SDimitry Andric #include "lldb/Expression/DiagnosticManager.h"
140b57cec5SDimitry Andric #include "lldb/Host/Config.h"
150b57cec5SDimitry Andric #include "lldb/Symbol/SymbolContext.h"
16349cc55cSDimitry Andric #include "lldb/Symbol/TypeSystem.h"
170b57cec5SDimitry Andric #include "lldb/Target/ExecutionContext.h"
180b57cec5SDimitry Andric #include "lldb/Target/Platform.h"
190b57cec5SDimitry Andric #include "lldb/Target/Process.h"
200b57cec5SDimitry Andric #include "lldb/Target/Target.h"
210b57cec5SDimitry Andric #include "lldb/Target/ThreadPlanCallFunction.h"
220b57cec5SDimitry Andric
23480093f4SDimitry Andric #if LLDB_ENABLE_POSIX
240b57cec5SDimitry Andric #include <sys/mman.h>
250b57cec5SDimitry Andric #else
260b57cec5SDimitry Andric // define them
270b57cec5SDimitry Andric #define PROT_NONE 0
280b57cec5SDimitry Andric #define PROT_READ 1
290b57cec5SDimitry Andric #define PROT_WRITE 2
300b57cec5SDimitry Andric #define PROT_EXEC 4
310b57cec5SDimitry Andric #endif
320b57cec5SDimitry Andric
330b57cec5SDimitry Andric using namespace lldb;
340b57cec5SDimitry Andric using namespace lldb_private;
350b57cec5SDimitry Andric
InferiorCallMmap(Process * process,addr_t & allocated_addr,addr_t addr,addr_t length,unsigned prot,unsigned flags,addr_t fd,addr_t offset)360b57cec5SDimitry Andric bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
370b57cec5SDimitry Andric addr_t addr, addr_t length, unsigned prot,
380b57cec5SDimitry Andric unsigned flags, addr_t fd, addr_t offset) {
390b57cec5SDimitry Andric Thread *thread =
400b57cec5SDimitry Andric process->GetThreadList().GetExpressionExecutionThread().get();
410b57cec5SDimitry Andric if (thread == nullptr)
420b57cec5SDimitry Andric return false;
430b57cec5SDimitry Andric
44349cc55cSDimitry Andric ModuleFunctionSearchOptions function_options;
45349cc55cSDimitry Andric function_options.include_symbols = true;
46349cc55cSDimitry Andric function_options.include_inlines = false;
47349cc55cSDimitry Andric
480b57cec5SDimitry Andric SymbolContextList sc_list;
499dba64beSDimitry Andric process->GetTarget().GetImages().FindFunctions(
50349cc55cSDimitry Andric ConstString("mmap"), eFunctionNameTypeFull, function_options, sc_list);
519dba64beSDimitry Andric const uint32_t count = sc_list.GetSize();
520b57cec5SDimitry Andric if (count > 0) {
530b57cec5SDimitry Andric SymbolContext sc;
540b57cec5SDimitry Andric if (sc_list.GetContextAtIndex(0, sc)) {
550b57cec5SDimitry Andric const uint32_t range_scope =
560b57cec5SDimitry Andric eSymbolContextFunction | eSymbolContextSymbol;
570b57cec5SDimitry Andric const bool use_inline_block_range = false;
580b57cec5SDimitry Andric EvaluateExpressionOptions options;
590b57cec5SDimitry Andric options.SetStopOthers(true);
600b57cec5SDimitry Andric options.SetUnwindOnError(true);
610b57cec5SDimitry Andric options.SetIgnoreBreakpoints(true);
620b57cec5SDimitry Andric options.SetTryAllThreads(true);
630b57cec5SDimitry Andric options.SetDebug(false);
640b57cec5SDimitry Andric options.SetTimeout(process->GetUtilityExpressionTimeout());
650b57cec5SDimitry Andric options.SetTrapExceptions(false);
660b57cec5SDimitry Andric
670b57cec5SDimitry Andric addr_t prot_arg;
680b57cec5SDimitry Andric if (prot == eMmapProtNone)
690b57cec5SDimitry Andric prot_arg = PROT_NONE;
700b57cec5SDimitry Andric else {
710b57cec5SDimitry Andric prot_arg = 0;
720b57cec5SDimitry Andric if (prot & eMmapProtExec)
730b57cec5SDimitry Andric prot_arg |= PROT_EXEC;
740b57cec5SDimitry Andric if (prot & eMmapProtRead)
750b57cec5SDimitry Andric prot_arg |= PROT_READ;
760b57cec5SDimitry Andric if (prot & eMmapProtWrite)
770b57cec5SDimitry Andric prot_arg |= PROT_WRITE;
780b57cec5SDimitry Andric }
790b57cec5SDimitry Andric
800b57cec5SDimitry Andric AddressRange mmap_range;
810b57cec5SDimitry Andric if (sc.GetAddressRange(range_scope, 0, use_inline_block_range,
820b57cec5SDimitry Andric mmap_range)) {
839dba64beSDimitry Andric auto type_system_or_err =
849dba64beSDimitry Andric process->GetTarget().GetScratchTypeSystemForLanguage(
859dba64beSDimitry Andric eLanguageTypeC);
869dba64beSDimitry Andric if (!type_system_or_err) {
879dba64beSDimitry Andric llvm::consumeError(type_system_or_err.takeError());
889dba64beSDimitry Andric return false;
899dba64beSDimitry Andric }
90*bdd1243dSDimitry Andric auto ts = *type_system_or_err;
91*bdd1243dSDimitry Andric if (!ts)
92*bdd1243dSDimitry Andric return false;
939dba64beSDimitry Andric CompilerType void_ptr_type =
94*bdd1243dSDimitry Andric ts->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
950b57cec5SDimitry Andric const ArchSpec arch = process->GetTarget().GetArchitecture();
960b57cec5SDimitry Andric MmapArgList args =
970b57cec5SDimitry Andric process->GetTarget().GetPlatform()->GetMmapArgumentList(
980b57cec5SDimitry Andric arch, addr, length, prot_arg, flags, fd, offset);
990b57cec5SDimitry Andric lldb::ThreadPlanSP call_plan_sp(
1000b57cec5SDimitry Andric new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(),
1019dba64beSDimitry Andric void_ptr_type, args, options));
1020b57cec5SDimitry Andric if (call_plan_sp) {
1030b57cec5SDimitry Andric DiagnosticManager diagnostics;
1040b57cec5SDimitry Andric
1050b57cec5SDimitry Andric StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
1060b57cec5SDimitry Andric if (frame) {
1070b57cec5SDimitry Andric ExecutionContext exe_ctx;
1080b57cec5SDimitry Andric frame->CalculateExecutionContext(exe_ctx);
1090b57cec5SDimitry Andric ExpressionResults result = process->RunThreadPlan(
1100b57cec5SDimitry Andric exe_ctx, call_plan_sp, options, diagnostics);
1110b57cec5SDimitry Andric if (result == eExpressionCompleted) {
1120b57cec5SDimitry Andric
1130b57cec5SDimitry Andric allocated_addr =
1140b57cec5SDimitry Andric call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(
1150b57cec5SDimitry Andric LLDB_INVALID_ADDRESS);
1160b57cec5SDimitry Andric if (process->GetAddressByteSize() == 4) {
1170b57cec5SDimitry Andric if (allocated_addr == UINT32_MAX)
1180b57cec5SDimitry Andric return false;
1190b57cec5SDimitry Andric } else if (process->GetAddressByteSize() == 8) {
1200b57cec5SDimitry Andric if (allocated_addr == UINT64_MAX)
1210b57cec5SDimitry Andric return false;
1220b57cec5SDimitry Andric }
1230b57cec5SDimitry Andric return true;
1240b57cec5SDimitry Andric }
1250b57cec5SDimitry Andric }
1260b57cec5SDimitry Andric }
1270b57cec5SDimitry Andric }
1280b57cec5SDimitry Andric }
1290b57cec5SDimitry Andric }
1300b57cec5SDimitry Andric
1310b57cec5SDimitry Andric return false;
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric
InferiorCallMunmap(Process * process,addr_t addr,addr_t length)1340b57cec5SDimitry Andric bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
1350b57cec5SDimitry Andric addr_t length) {
1360b57cec5SDimitry Andric Thread *thread =
1370b57cec5SDimitry Andric process->GetThreadList().GetExpressionExecutionThread().get();
1380b57cec5SDimitry Andric if (thread == nullptr)
1390b57cec5SDimitry Andric return false;
1400b57cec5SDimitry Andric
141349cc55cSDimitry Andric ModuleFunctionSearchOptions function_options;
142349cc55cSDimitry Andric function_options.include_symbols = true;
143349cc55cSDimitry Andric function_options.include_inlines = false;
144349cc55cSDimitry Andric
1450b57cec5SDimitry Andric SymbolContextList sc_list;
1469dba64beSDimitry Andric process->GetTarget().GetImages().FindFunctions(
147349cc55cSDimitry Andric ConstString("munmap"), eFunctionNameTypeFull, function_options, sc_list);
1489dba64beSDimitry Andric const uint32_t count = sc_list.GetSize();
1490b57cec5SDimitry Andric if (count > 0) {
1500b57cec5SDimitry Andric SymbolContext sc;
1510b57cec5SDimitry Andric if (sc_list.GetContextAtIndex(0, sc)) {
1520b57cec5SDimitry Andric const uint32_t range_scope =
1530b57cec5SDimitry Andric eSymbolContextFunction | eSymbolContextSymbol;
1540b57cec5SDimitry Andric const bool use_inline_block_range = false;
1550b57cec5SDimitry Andric EvaluateExpressionOptions options;
1560b57cec5SDimitry Andric options.SetStopOthers(true);
1570b57cec5SDimitry Andric options.SetUnwindOnError(true);
1580b57cec5SDimitry Andric options.SetIgnoreBreakpoints(true);
1590b57cec5SDimitry Andric options.SetTryAllThreads(true);
1600b57cec5SDimitry Andric options.SetDebug(false);
1610b57cec5SDimitry Andric options.SetTimeout(process->GetUtilityExpressionTimeout());
1620b57cec5SDimitry Andric options.SetTrapExceptions(false);
1630b57cec5SDimitry Andric
1640b57cec5SDimitry Andric AddressRange munmap_range;
1650b57cec5SDimitry Andric if (sc.GetAddressRange(range_scope, 0, use_inline_block_range,
1660b57cec5SDimitry Andric munmap_range)) {
1670b57cec5SDimitry Andric lldb::addr_t args[] = {addr, length};
1680b57cec5SDimitry Andric lldb::ThreadPlanSP call_plan_sp(
1690b57cec5SDimitry Andric new ThreadPlanCallFunction(*thread, munmap_range.GetBaseAddress(),
1700b57cec5SDimitry Andric CompilerType(), args, options));
1710b57cec5SDimitry Andric if (call_plan_sp) {
1720b57cec5SDimitry Andric DiagnosticManager diagnostics;
1730b57cec5SDimitry Andric
1740b57cec5SDimitry Andric StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
1750b57cec5SDimitry Andric if (frame) {
1760b57cec5SDimitry Andric ExecutionContext exe_ctx;
1770b57cec5SDimitry Andric frame->CalculateExecutionContext(exe_ctx);
1780b57cec5SDimitry Andric ExpressionResults result = process->RunThreadPlan(
1790b57cec5SDimitry Andric exe_ctx, call_plan_sp, options, diagnostics);
1800b57cec5SDimitry Andric if (result == eExpressionCompleted) {
1810b57cec5SDimitry Andric return true;
1820b57cec5SDimitry Andric }
1830b57cec5SDimitry Andric }
1840b57cec5SDimitry Andric }
1850b57cec5SDimitry Andric }
1860b57cec5SDimitry Andric }
1870b57cec5SDimitry Andric }
1880b57cec5SDimitry Andric
1890b57cec5SDimitry Andric return false;
1900b57cec5SDimitry Andric }
191