1//===-- InferiorCallPOSIX.cpp ---------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "InferiorCallPOSIX.h"
10#include "lldb/Core/Address.h"
11#include "lldb/Core/Module.h"
12#include "lldb/Expression/DiagnosticManager.h"
13#include "lldb/Host/Config.h"
14#include "lldb/Symbol/SymbolContext.h"
15#include "lldb/Symbol/TypeSystem.h"
16#include "lldb/Target/ExecutionContext.h"
17#include "lldb/Target/Platform.h"
18#include "lldb/Target/Process.h"
19#include "lldb/Target/Target.h"
20#include "lldb/Target/ThreadPlanCallFunction.h"
21#include "lldb/ValueObject/ValueObject.h"
22
23#if LLDB_ENABLE_POSIX
24#include <sys/mman.h>
25#else
26// define them
27#define PROT_NONE 0
28#define PROT_READ 1
29#define PROT_WRITE 2
30#define PROT_EXEC 4
31#endif
32
33using namespace lldb;
34using namespace lldb_private;
35
36bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
37 addr_t addr, addr_t length, unsigned prot,
38 unsigned flags, addr_t fd, addr_t offset) {
39 Thread *thread =
40 process->GetThreadList().GetExpressionExecutionThread().get();
41 if (thread == nullptr)
42 return false;
43
44 ModuleFunctionSearchOptions function_options;
45 function_options.include_symbols = true;
46 function_options.include_inlines = false;
47
48 SymbolContextList sc_list;
49 process->GetTarget().GetImages().FindFunctions(
50 name: ConstString("mmap"), name_type_mask: eFunctionNameTypeFull, options: function_options, sc_list);
51 const uint32_t count = sc_list.GetSize();
52 if (count > 0) {
53 SymbolContext sc;
54 if (sc_list.GetContextAtIndex(idx: 0, sc)) {
55 EvaluateExpressionOptions options;
56 options.SetStopOthers(true);
57 options.SetUnwindOnError(true);
58 options.SetIgnoreBreakpoints(true);
59 options.SetTryAllThreads(true);
60 options.SetDebug(false);
61 options.SetTimeout(process->GetUtilityExpressionTimeout());
62 options.SetTrapExceptions(false);
63
64 addr_t prot_arg;
65 if (prot == eMmapProtNone)
66 prot_arg = PROT_NONE;
67 else {
68 prot_arg = 0;
69 if (prot & eMmapProtExec)
70 prot_arg |= PROT_EXEC;
71 if (prot & eMmapProtRead)
72 prot_arg |= PROT_READ;
73 if (prot & eMmapProtWrite)
74 prot_arg |= PROT_WRITE;
75 }
76
77 Address mmap_addr = sc.GetFunctionOrSymbolAddress();
78 if (mmap_addr.IsValid()) {
79 auto type_system_or_err =
80 process->GetTarget().GetScratchTypeSystemForLanguage(
81 language: eLanguageTypeC);
82 if (!type_system_or_err) {
83 llvm::consumeError(Err: type_system_or_err.takeError());
84 return false;
85 }
86 auto ts = *type_system_or_err;
87 if (!ts)
88 return false;
89 CompilerType void_ptr_type =
90 ts->GetBasicTypeFromAST(basic_type: eBasicTypeVoid).GetPointerType();
91 const ArchSpec arch = process->GetTarget().GetArchitecture();
92 MmapArgList args =
93 process->GetTarget().GetPlatform()->GetMmapArgumentList(
94 arch, addr, length, prot: prot_arg, flags, fd, offset);
95 lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallFunction(
96 *thread, mmap_addr, void_ptr_type, args, options));
97 if (call_plan_sp) {
98 DiagnosticManager diagnostics;
99
100 StackFrame *frame = thread->GetStackFrameAtIndex(idx: 0).get();
101 if (frame) {
102 ExecutionContext exe_ctx;
103 frame->CalculateExecutionContext(exe_ctx);
104 ExpressionResults result = process->RunThreadPlan(
105 exe_ctx, thread_plan_sp&: call_plan_sp, options, diagnostic_manager&: diagnostics);
106 if (result == eExpressionCompleted) {
107
108 allocated_addr =
109 call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(
110 LLDB_INVALID_ADDRESS);
111 if (process->GetAddressByteSize() == 4) {
112 if (allocated_addr == UINT32_MAX)
113 return false;
114 } else if (process->GetAddressByteSize() == 8) {
115 if (allocated_addr == UINT64_MAX)
116 return false;
117 }
118 return true;
119 }
120 }
121 }
122 }
123 }
124 }
125
126 return false;
127}
128
129bool lldb_private::InferiorCallMunmap(Process *process, addr_t addr,
130 addr_t length) {
131 Thread *thread =
132 process->GetThreadList().GetExpressionExecutionThread().get();
133 if (thread == nullptr)
134 return false;
135
136 ModuleFunctionSearchOptions function_options;
137 function_options.include_symbols = true;
138 function_options.include_inlines = false;
139
140 SymbolContextList sc_list;
141 process->GetTarget().GetImages().FindFunctions(
142 name: ConstString("munmap"), name_type_mask: eFunctionNameTypeFull, options: function_options, sc_list);
143 const uint32_t count = sc_list.GetSize();
144 if (count > 0) {
145 SymbolContext sc;
146 if (sc_list.GetContextAtIndex(idx: 0, sc)) {
147 EvaluateExpressionOptions options;
148 options.SetStopOthers(true);
149 options.SetUnwindOnError(true);
150 options.SetIgnoreBreakpoints(true);
151 options.SetTryAllThreads(true);
152 options.SetDebug(false);
153 options.SetTimeout(process->GetUtilityExpressionTimeout());
154 options.SetTrapExceptions(false);
155
156 Address munmap_addr = sc.GetFunctionOrSymbolAddress();
157 if (munmap_addr.IsValid()) {
158 lldb::addr_t args[] = {addr, length};
159 lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallFunction(
160 *thread, munmap_addr, CompilerType(), args, options));
161 if (call_plan_sp) {
162 DiagnosticManager diagnostics;
163
164 StackFrame *frame = thread->GetStackFrameAtIndex(idx: 0).get();
165 if (frame) {
166 ExecutionContext exe_ctx;
167 frame->CalculateExecutionContext(exe_ctx);
168 ExpressionResults result = process->RunThreadPlan(
169 exe_ctx, thread_plan_sp&: call_plan_sp, options, diagnostic_manager&: diagnostics);
170 if (result == eExpressionCompleted) {
171 return true;
172 }
173 }
174 }
175 }
176 }
177 }
178
179 return false;
180}
181

Provided by KDAB

Privacy Policy
Improve your Profiling and Debugging skills
Find out more

source code of lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp