xref: /freebsd-src/contrib/llvm-project/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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