1 //===-- CommandOptionsProcessLaunch.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 "CommandOptionsProcessLaunch.h"
10 
11 #include "lldb/Host/FileSystem.h"
12 #include "lldb/Host/HostInfo.h"
13 #include "lldb/Host/OptionParser.h"
14 #include "lldb/Interpreter/CommandCompletions.h"
15 #include "lldb/Interpreter/CommandObject.h"
16 #include "lldb/Interpreter/CommandOptionArgumentTable.h"
17 #include "lldb/Interpreter/OptionArgParser.h"
18 #include "lldb/Target/ExecutionContext.h"
19 #include "lldb/Target/Platform.h"
20 #include "lldb/Target/Target.h"
21 
22 #include "llvm/ADT/ArrayRef.h"
23 
24 using namespace llvm;
25 using namespace lldb;
26 using namespace lldb_private;
27 
28 #define LLDB_OPTIONS_process_launch
29 #include "CommandOptions.inc"
30 
31 Status CommandOptionsProcessLaunch::SetOptionValue(
32     uint32_t option_idx, llvm::StringRef option_arg,
33     ExecutionContext *execution_context) {
34   Status error;
35   const int short_option = g_process_launch_options[option_idx].short_option;
36 
37   TargetSP target_sp =
38       execution_context ? execution_context->GetTargetSP() : TargetSP();
39   switch (short_option) {
40   case 's': // Stop at program entry point
41     launch_info.GetFlags().Set(eLaunchFlagStopAtEntry);
42     break;
43   case 'm': // Stop at user entry point
44     target_sp->CreateBreakpointAtUserEntry(error);
45     break;
46   case 'i': // STDIN for read only
47   {
48     FileAction action;
49     if (action.Open(STDIN_FILENO, FileSpec(option_arg), true, false))
50       launch_info.AppendFileAction(action);
51     break;
52   }
53 
54   case 'o': // Open STDOUT for write only
55   {
56     FileAction action;
57     if (action.Open(STDOUT_FILENO, FileSpec(option_arg), false, true))
58       launch_info.AppendFileAction(action);
59     break;
60   }
61 
62   case 'e': // STDERR for write only
63   {
64     FileAction action;
65     if (action.Open(STDERR_FILENO, FileSpec(option_arg), false, true))
66       launch_info.AppendFileAction(action);
67     break;
68   }
69 
70   case 'P': // Process plug-in name
71     launch_info.SetProcessPluginName(option_arg);
72     break;
73 
74   case 'n': // Disable STDIO
75   {
76     FileAction action;
77     const FileSpec dev_null(FileSystem::DEV_NULL);
78     if (action.Open(STDIN_FILENO, dev_null, true, false))
79       launch_info.AppendFileAction(action);
80     if (action.Open(STDOUT_FILENO, dev_null, false, true))
81       launch_info.AppendFileAction(action);
82     if (action.Open(STDERR_FILENO, dev_null, false, true))
83       launch_info.AppendFileAction(action);
84     break;
85   }
86 
87   case 'w':
88     launch_info.SetWorkingDirectory(FileSpec(option_arg));
89     break;
90 
91   case 't': // Open process in new terminal window
92     launch_info.GetFlags().Set(eLaunchFlagLaunchInTTY);
93     break;
94 
95   case 'a': {
96     PlatformSP platform_sp =
97         target_sp ? target_sp->GetPlatform() : PlatformSP();
98     launch_info.GetArchitecture() =
99         Platform::GetAugmentedArchSpec(platform_sp.get(), option_arg);
100   } break;
101 
102   case 'A': // Disable ASLR.
103   {
104     bool success;
105     const bool disable_aslr_arg =
106         OptionArgParser::ToBoolean(option_arg, true, &success);
107     if (success)
108       disable_aslr = disable_aslr_arg ? eLazyBoolYes : eLazyBoolNo;
109     else
110       error.SetErrorStringWithFormat(
111           "Invalid boolean value for disable-aslr option: '%s'",
112           option_arg.empty() ? "<null>" : option_arg.str().c_str());
113     break;
114   }
115 
116   case 'X': // shell expand args.
117   {
118     bool success;
119     const bool expand_args =
120         OptionArgParser::ToBoolean(option_arg, true, &success);
121     if (success)
122       launch_info.SetShellExpandArguments(expand_args);
123     else
124       error.SetErrorStringWithFormat(
125           "Invalid boolean value for shell-expand-args option: '%s'",
126           option_arg.empty() ? "<null>" : option_arg.str().c_str());
127     break;
128   }
129 
130   case 'c':
131     if (!option_arg.empty())
132       launch_info.SetShell(FileSpec(option_arg));
133     else
134       launch_info.SetShell(HostInfo::GetDefaultShell());
135     break;
136 
137   case 'E':
138     launch_info.GetEnvironment().insert(option_arg);
139     break;
140 
141   default:
142     error.SetErrorStringWithFormat("unrecognized short option character '%c'",
143                                    short_option);
144     break;
145   }
146   return error;
147 }
148 
149 llvm::ArrayRef<OptionDefinition> CommandOptionsProcessLaunch::GetDefinitions() {
150   return llvm::ArrayRef(g_process_launch_options);
151 }
152