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
24using namespace llvm;
25using namespace lldb;
26using namespace lldb_private;
27
28#define LLDB_OPTIONS_process_launch
29#include "CommandOptions.inc"
30
31Status 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
149llvm::ArrayRef<OptionDefinition> CommandOptionsProcessLaunch::GetDefinitions() {
150  return llvm::ArrayRef(g_process_launch_options);
151}
152