180814287SRaphael Isemann //===-- InferiorCallPOSIX.cpp ---------------------------------------------===//
2933f6f61SPeter Collingbourne //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6933f6f61SPeter Collingbourne //
7933f6f61SPeter Collingbourne //===----------------------------------------------------------------------===//
8933f6f61SPeter Collingbourne 
999f9aa02SPeter Collingbourne #include "InferiorCallPOSIX.h"
1000049b8bSMatt Kopec #include "lldb/Core/Address.h"
11*c020be17SJonas Devlieghere #include "lldb/Core/Module.h"
1299f9aa02SPeter Collingbourne #include "lldb/Core/StreamFile.h"
13ef651600SJim Ingham #include "lldb/Core/ValueObject.h"
14579e70c9SSean Callanan #include "lldb/Expression/DiagnosticManager.h"
15579e70c9SSean Callanan #include "lldb/Host/Config.h"
1699f9aa02SPeter Collingbourne #include "lldb/Symbol/SymbolContext.h"
17*c020be17SJonas Devlieghere #include "lldb/Symbol/TypeSystem.h"
1899f9aa02SPeter Collingbourne #include "lldb/Target/ExecutionContext.h"
1996ad3de5SRobert Flack #include "lldb/Target/Platform.h"
2099f9aa02SPeter Collingbourne #include "lldb/Target/Process.h"
2199f9aa02SPeter Collingbourne #include "lldb/Target/Target.h"
2299f9aa02SPeter Collingbourne #include "lldb/Target/ThreadPlanCallFunction.h"
2399f9aa02SPeter Collingbourne 
243011d55fSJonas Devlieghere #if LLDB_ENABLE_POSIX
2599f9aa02SPeter Collingbourne #include <sys/mman.h>
26b2f1fb29SVirgile Bello #else
27b2f1fb29SVirgile Bello // define them
28b2f1fb29SVirgile Bello #define PROT_NONE 0
29b2f1fb29SVirgile Bello #define PROT_READ 1
30b2f1fb29SVirgile Bello #define PROT_WRITE 2
31b2f1fb29SVirgile Bello #define PROT_EXEC 4
32b2f1fb29SVirgile Bello #endif
3399f9aa02SPeter Collingbourne 
3499f9aa02SPeter Collingbourne using namespace lldb;
3599f9aa02SPeter Collingbourne using namespace lldb_private;
3699f9aa02SPeter Collingbourne 
InferiorCallMmap(Process * process,addr_t & allocated_addr,addr_t addr,addr_t length,unsigned prot,unsigned flags,addr_t fd,addr_t offset)37b9c1b51eSKate Stone bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
38b9c1b51eSKate Stone                                     addr_t addr, addr_t length, unsigned prot,
39b9c1b51eSKate Stone                                     unsigned flags, addr_t fd, addr_t offset) {
40b9c1b51eSKate Stone   Thread *thread =
41b9c1b51eSKate Stone       process->GetThreadList().GetExpressionExecutionThread().get();
42248a1305SKonrad Kleine   if (thread == nullptr)
43f72ce3a2SJim Ingham     return false;
4499f9aa02SPeter Collingbourne 
45*c020be17SJonas Devlieghere   ModuleFunctionSearchOptions function_options;
46*c020be17SJonas Devlieghere   function_options.include_symbols = true;
47*c020be17SJonas Devlieghere   function_options.include_inlines = false;
48*c020be17SJonas Devlieghere 
4999f9aa02SPeter Collingbourne   SymbolContextList sc_list;
501ad655e2SAdrian Prantl   process->GetTarget().GetImages().FindFunctions(
51*c020be17SJonas Devlieghere       ConstString("mmap"), eFunctionNameTypeFull, function_options, sc_list);
521ad655e2SAdrian Prantl   const uint32_t count = sc_list.GetSize();
53b9c1b51eSKate Stone   if (count > 0) {
5499f9aa02SPeter Collingbourne     SymbolContext sc;
55b9c1b51eSKate Stone     if (sc_list.GetContextAtIndex(0, sc)) {
56b9c1b51eSKate Stone       const uint32_t range_scope =
57b9c1b51eSKate Stone           eSymbolContextFunction | eSymbolContextSymbol;
5899f9aa02SPeter Collingbourne       const bool use_inline_block_range = false;
596fbc48bcSJim Ingham       EvaluateExpressionOptions options;
606fbc48bcSJim Ingham       options.SetStopOthers(true);
616fbc48bcSJim Ingham       options.SetUnwindOnError(true);
626fbc48bcSJim Ingham       options.SetIgnoreBreakpoints(true);
636fbc48bcSJim Ingham       options.SetTryAllThreads(true);
646fbc48bcSJim Ingham       options.SetDebug(false);
654c03ea14SAdrian Prantl       options.SetTimeout(process->GetUtilityExpressionTimeout());
66728384a0SStephane Sezer       options.SetTrapExceptions(false);
6799f9aa02SPeter Collingbourne 
6837c40af7SEd Maste       addr_t prot_arg;
6999f9aa02SPeter Collingbourne       if (prot == eMmapProtNone)
7099f9aa02SPeter Collingbourne         prot_arg = PROT_NONE;
7199f9aa02SPeter Collingbourne       else {
7299f9aa02SPeter Collingbourne         prot_arg = 0;
7399f9aa02SPeter Collingbourne         if (prot & eMmapProtExec)
7499f9aa02SPeter Collingbourne           prot_arg |= PROT_EXEC;
7599f9aa02SPeter Collingbourne         if (prot & eMmapProtRead)
7699f9aa02SPeter Collingbourne           prot_arg |= PROT_READ;
7799f9aa02SPeter Collingbourne         if (prot & eMmapProtWrite)
7899f9aa02SPeter Collingbourne           prot_arg |= PROT_WRITE;
7999f9aa02SPeter Collingbourne       }
8099f9aa02SPeter Collingbourne 
8199f9aa02SPeter Collingbourne       AddressRange mmap_range;
82b9c1b51eSKate Stone       if (sc.GetAddressRange(range_scope, 0, use_inline_block_range,
83b9c1b51eSKate Stone                              mmap_range)) {
841b385a18SAlex Langford         auto type_system_or_err =
851b385a18SAlex Langford             process->GetTarget().GetScratchTypeSystemForLanguage(
861b385a18SAlex Langford                 eLanguageTypeC);
871b385a18SAlex Langford         if (!type_system_or_err) {
881b385a18SAlex Langford           llvm::consumeError(type_system_or_err.takeError());
891b385a18SAlex Langford           return false;
901b385a18SAlex Langford         }
911b385a18SAlex Langford         CompilerType void_ptr_type =
921b385a18SAlex Langford             type_system_or_err->GetBasicTypeFromAST(eBasicTypeVoid)
931b385a18SAlex Langford                 .GetPointerType();
9437c40af7SEd Maste         const ArchSpec arch = process->GetTarget().GetArchitecture();
9537c40af7SEd Maste         MmapArgList args =
9637c40af7SEd Maste             process->GetTarget().GetPlatform()->GetMmapArgumentList(
9737c40af7SEd Maste                 arch, addr, length, prot_arg, flags, fd, offset);
98b9c1b51eSKate Stone         lldb::ThreadPlanSP call_plan_sp(
99b9c1b51eSKate Stone             new ThreadPlanCallFunction(*thread, mmap_range.GetBaseAddress(),
1001b385a18SAlex Langford                                        void_ptr_type, args, options));
101b9c1b51eSKate Stone         if (call_plan_sp) {
102579e70c9SSean Callanan           DiagnosticManager diagnostics;
103923886ceSJim Ingham 
104b57e4a1bSJason Molenda           StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
105b9c1b51eSKate Stone           if (frame) {
10699f9aa02SPeter Collingbourne             ExecutionContext exe_ctx;
10799f9aa02SPeter Collingbourne             frame->CalculateExecutionContext(exe_ctx);
108b9c1b51eSKate Stone             ExpressionResults result = process->RunThreadPlan(
109b9c1b51eSKate Stone                 exe_ctx, call_plan_sp, options, diagnostics);
110b9c1b51eSKate Stone             if (result == eExpressionCompleted) {
111ef651600SJim Ingham 
112b9c1b51eSKate Stone               allocated_addr =
113b9c1b51eSKate Stone                   call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(
114b9c1b51eSKate Stone                       LLDB_INVALID_ADDRESS);
115b9c1b51eSKate Stone               if (process->GetAddressByteSize() == 4) {
11699f9aa02SPeter Collingbourne                 if (allocated_addr == UINT32_MAX)
11799f9aa02SPeter Collingbourne                   return false;
118b9c1b51eSKate Stone               } else if (process->GetAddressByteSize() == 8) {
11900049b8bSMatt Kopec                 if (allocated_addr == UINT64_MAX)
12000049b8bSMatt Kopec                   return false;
12100049b8bSMatt Kopec               }
12299f9aa02SPeter Collingbourne               return true;
12399f9aa02SPeter Collingbourne             }
12499f9aa02SPeter Collingbourne           }
12599f9aa02SPeter Collingbourne         }
12699f9aa02SPeter Collingbourne       }
12799f9aa02SPeter Collingbourne     }
12899f9aa02SPeter Collingbourne   }
12999f9aa02SPeter Collingbourne 
13099f9aa02SPeter Collingbourne   return false;
13199f9aa02SPeter Collingbourne }
13299f9aa02SPeter Collingbourne 
InferiorCallMunmap(Process * process,addr_t addr,addr_t length)133b9c1b51eSKate Stone bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
134b9c1b51eSKate Stone                                       addr_t length) {
135b9c1b51eSKate Stone   Thread *thread =
136b9c1b51eSKate Stone       process->GetThreadList().GetExpressionExecutionThread().get();
137248a1305SKonrad Kleine   if (thread == nullptr)
138bbfa68b0SJohnny Chen     return false;
13999f9aa02SPeter Collingbourne 
140*c020be17SJonas Devlieghere   ModuleFunctionSearchOptions function_options;
141*c020be17SJonas Devlieghere   function_options.include_symbols = true;
142*c020be17SJonas Devlieghere   function_options.include_inlines = false;
143*c020be17SJonas Devlieghere 
14499f9aa02SPeter Collingbourne   SymbolContextList sc_list;
1451ad655e2SAdrian Prantl   process->GetTarget().GetImages().FindFunctions(
146*c020be17SJonas Devlieghere       ConstString("munmap"), eFunctionNameTypeFull, function_options, sc_list);
1471ad655e2SAdrian Prantl   const uint32_t count = sc_list.GetSize();
148b9c1b51eSKate Stone   if (count > 0) {
14999f9aa02SPeter Collingbourne     SymbolContext sc;
150b9c1b51eSKate Stone     if (sc_list.GetContextAtIndex(0, sc)) {
151b9c1b51eSKate Stone       const uint32_t range_scope =
152b9c1b51eSKate Stone           eSymbolContextFunction | eSymbolContextSymbol;
15399f9aa02SPeter Collingbourne       const bool use_inline_block_range = false;
1546fbc48bcSJim Ingham       EvaluateExpressionOptions options;
1556fbc48bcSJim Ingham       options.SetStopOthers(true);
1566fbc48bcSJim Ingham       options.SetUnwindOnError(true);
1576fbc48bcSJim Ingham       options.SetIgnoreBreakpoints(true);
1586fbc48bcSJim Ingham       options.SetTryAllThreads(true);
1596fbc48bcSJim Ingham       options.SetDebug(false);
1604c03ea14SAdrian Prantl       options.SetTimeout(process->GetUtilityExpressionTimeout());
161728384a0SStephane Sezer       options.SetTrapExceptions(false);
16299f9aa02SPeter Collingbourne 
16399f9aa02SPeter Collingbourne       AddressRange munmap_range;
164b9c1b51eSKate Stone       if (sc.GetAddressRange(range_scope, 0, use_inline_block_range,
165b9c1b51eSKate Stone                              munmap_range)) {
166a464f3d4SSean Callanan         lldb::addr_t args[] = {addr, length};
167579e70c9SSean Callanan         lldb::ThreadPlanSP call_plan_sp(
168b9c1b51eSKate Stone             new ThreadPlanCallFunction(*thread, munmap_range.GetBaseAddress(),
169b9c1b51eSKate Stone                                        CompilerType(), args, options));
170b9c1b51eSKate Stone         if (call_plan_sp) {
171579e70c9SSean Callanan           DiagnosticManager diagnostics;
172923886ceSJim Ingham 
173b57e4a1bSJason Molenda           StackFrame *frame = thread->GetStackFrameAtIndex(0).get();
174b9c1b51eSKate Stone           if (frame) {
17599f9aa02SPeter Collingbourne             ExecutionContext exe_ctx;
17699f9aa02SPeter Collingbourne             frame->CalculateExecutionContext(exe_ctx);
177b9c1b51eSKate Stone             ExpressionResults result = process->RunThreadPlan(
178b9c1b51eSKate Stone                 exe_ctx, call_plan_sp, options, diagnostics);
179b9c1b51eSKate Stone             if (result == eExpressionCompleted) {
18099f9aa02SPeter Collingbourne               return true;
18199f9aa02SPeter Collingbourne             }
18299f9aa02SPeter Collingbourne           }
18399f9aa02SPeter Collingbourne         }
18499f9aa02SPeter Collingbourne       }
18599f9aa02SPeter Collingbourne     }
18699f9aa02SPeter Collingbourne   }
18799f9aa02SPeter Collingbourne 
18899f9aa02SPeter Collingbourne   return false;
18999f9aa02SPeter Collingbourne }
190