[Lldb-commits] [PATCH] D147587: Fix the check in StopInfoBreakpoint for "are we running an expression"

2023-04-04 Thread Jonas Devlieghere via Phabricator via lldb-commits
JDevlieghere accepted this revision.
JDevlieghere added a comment.
This revision is now accepted and ready to land.

LGTM modulo naming preference




Comment at: lldb/include/lldb/Target/Process.h:287-292
+  bool CurrentlyRunningExpression() const {
+// Don't return true if we are no longer running an expression:
+if (m_running_user_expression || m_running_utility_function)
+  return true;
+return false;
+  }

I would prefer `IsRunningExpression` for consistency with other `IsFoo` 
methods. It still conveys that the process is in the process of executing an 
expression. /end bikeshedding


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147587/new/

https://reviews.llvm.org/D147587

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D147587: Fix the check in StopInfoBreakpoint for "are we running an expression"

2023-04-04 Thread Jim Ingham via Phabricator via lldb-commits
jingham created this revision.
jingham added reviewers: JDevlieghere, kastiglione, bulbazord, augusto2112.
Herald added a project: All.
jingham requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

If you hit a breakpoint while running an expression we don't want to run other 
commands that might end up running expressions again because that doesn't 
currently work recursively.  But the code that was checking there was checking 
"WasTheLastResumeForUserExpression" which isn't quite right, since that 
expression might have already completed - because it was part of the handling 
of the breakpoint before we got to the StopInfo.  We are tracking whether we 
are currently running an expression, however, which is the correct thing to 
check.  So I made a function to check that and changed the StopInfoBreakpoint 
to use it.

It's actually pretty hard to get into a situation where this causes problems, 
because the expression has to happen internally in lldb between the stop and 
the fetching of the stop event.  However, that's just what the 
objc_exception_throw frame recognizer does.  Some code that was added to the 
StopInfoBreakpoint turned this "oops I'm running an expression" into a resume - 
which was necessary for some Windows fix, but caused us to fail to stop for the 
objc_exception_throw breakpoint.

So I added a test for the built-in objc_exception_throw built-in recognizer.  
Without the fix the test would fail because we didn't stop at the exception 
throw point.  This also tests that we got all the values right.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D147587

Files:
  lldb/include/lldb/Target/Process.h
  lldb/source/Target/StopInfo.cpp
  lldb/test/API/macosx/objc_exception_recognizer/Makefile
  lldb/test/API/macosx/objc_exception_recognizer/TestObjCRecognizer.py
  lldb/test/API/macosx/objc_exception_recognizer/main.m

Index: lldb/test/API/macosx/objc_exception_recognizer/main.m
===
--- /dev/null
+++ lldb/test/API/macosx/objc_exception_recognizer/main.m
@@ -0,0 +1,37 @@
+#import 
+
+@interface MyException : NSException
+{
+  int extra_info;
+}
+- (NSException *) initWithExtraInfo: (int) info;
+@end
+
+@implementation MyException
+- (NSException *) initWithExtraInfo: (int) info
+{
+  [super initWithName: @"NSException" reason: @"Simple Reason" userInfo: nil];
+  self->extra_info = info;
+  return self;
+}
+@end
+
+int
+main(int argc, char **argv)
+{
+  // Set a breakpoint here for plain exception:
+  @try {
+NSException *plain_exc = [[NSException alloc] initWithName: @"NSException" reason: @"Simple Reason" userInfo: nil];
+[plain_exc raise];
+  }
+  @catch (id anException) {}
+
+  // Set a breakpoint here for MyException:
+  @try {
+MyException *my_exc = [[MyException alloc] initWithExtraInfo: 100];
+[my_exc raise];
+  }
+  @catch (id anException) {}
+
+  return 0;
+}
Index: lldb/test/API/macosx/objc_exception_recognizer/TestObjCRecognizer.py
===
--- /dev/null
+++ lldb/test/API/macosx/objc_exception_recognizer/TestObjCRecognizer.py
@@ -0,0 +1,69 @@
+"""
+Test that the built in ObjC exception throw recognizer works
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+class TestObjCRecognizer(TestBase):
+
+NO_DEBUG_INFO_TESTCASE = True
+
+@skipUnlessDarwin
+def test_exception_recognizer_sub_class(self):
+"""There can be many tests in a test case - describe this test here."""
+self.build()
+self.main_source_file = lldb.SBFileSpec("main.m")
+self.objc_recognizer_test(True)
+
+@skipUnlessDarwin
+def test_exception_recognizer_plain(self):
+"""There can be many tests in a test case - describe this test here."""
+self.build()
+self.main_source_file = lldb.SBFileSpec("main.m")
+self.objc_recognizer_test(False)
+
+def objc_recognizer_test(self, sub_class):
+"""Make sure we stop at the exception and get all the fields out of the recognizer.
+   If sub_class is True, we make a subclass of NSException and throw that."""
+if sub_class:
+bkpt_string = "Set a breakpoint here for MyException"
+else:
+bkpt_string = "Set a breakpoint here for plain exception"
+
+(target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(self,
+   bkpt_string, self.main_source_file)
+
+# Now turn on the ObjC Exception breakpoint and continue to hit it:
+exception_bkpt = target.BreakpointCreateForException(lldb.eLanguageTypeObjC, False, True)
+self.assertTrue(exception_bkpt.GetNumLocations() > 0, "Got some exception locations")
+
+threads = 

[Lldb-commits] [lldb] a78997e - Simplify test.

2023-04-04 Thread Adrian Prantl via lldb-commits

Author: Adrian Prantl
Date: 2023-04-04T15:16:01-07:00
New Revision: a78997e0aa89250a193ff036e7c6e71562e03222

URL: 
https://github.com/llvm/llvm-project/commit/a78997e0aa89250a193ff036e7c6e71562e03222
DIFF: 
https://github.com/llvm/llvm-project/commit/a78997e0aa89250a193ff036e7c6e71562e03222.diff

LOG: Simplify test.

This test doesn't actually depend on being able to launch the process.
This may or may not explain why this test behaves oddly on some of our bots.

Added: 


Modified: 
lldb/packages/Python/lldbsuite/test/lldbutil.py
lldb/test/API/macosx/universal64/TestUniversal64.py

Removed: 




diff  --git a/lldb/packages/Python/lldbsuite/test/lldbutil.py 
b/lldb/packages/Python/lldbsuite/test/lldbutil.py
index 7e64afb3639cd..d174c5af069b8 100644
--- a/lldb/packages/Python/lldbsuite/test/lldbutil.py
+++ b/lldb/packages/Python/lldbsuite/test/lldbutil.py
@@ -811,8 +811,7 @@ def get_crashed_threads(test, process):
 # Helper functions for run_to_{source,name}_breakpoint:
 
 def run_to_breakpoint_make_target(test, exe_name = "a.out", in_cwd = True):
-if in_cwd:
-exe = test.getBuildArtifact(exe_name)
+exe = test.getBuildArtifact(exe_name) if in_cwd else exe_name
 
 # Create the target
 target = test.dbg.CreateTarget(exe)
@@ -827,7 +826,6 @@ def run_to_breakpoint_make_target(test, exe_name = "a.out", 
in_cwd = True):
 
 def run_to_breakpoint_do_run(test, target, bkpt, launch_info = None,
  only_one_thread = True, extra_images = None):
-
 # Launch the process, and do not stop at the entry point.
 if not launch_info:
 launch_info = target.GetLaunchInfo()

diff  --git a/lldb/test/API/macosx/universal64/TestUniversal64.py 
b/lldb/test/API/macosx/universal64/TestUniversal64.py
index d97ebc05176d2..80292c04dd123 100644
--- a/lldb/test/API/macosx/universal64/TestUniversal64.py
+++ b/lldb/test/API/macosx/universal64/TestUniversal64.py
@@ -7,18 +7,11 @@ class Universal64TestCase(TestBase):
 NO_DEBUG_INFO_TESTCASE = True
 
 def do_test(self):
-# Get the executable.
 exe = self.getBuildArtifact("fat.out")
-
-# Create a target.
-self.target = self.dbg.CreateTarget(exe)
-
-# Create a breakpoint on main.
-main_bp = self.target.BreakpointCreateByName("main")
-self.assertTrue(main_bp, VALID_BREAKPOINT)
+target = self.dbg.CreateTarget(exe)
 
 # Make sure the binary and the dSYM are in the image list.
-self.expect("image list ", patterns=['fat.out', 'fat.out.dSYM'])
+self.expect("image list", patterns=['fat.out', 'fat.out.dSYM'])
 
 # The dynamic loader doesn't support fat64 executables so we can't
 # actually launch them here.



___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] 5d77344 - Simplify test script

2023-04-04 Thread Adrian Prantl via lldb-commits

Author: Adrian Prantl
Date: 2023-04-04T15:08:57-07:00
New Revision: 5d77344d9d52a623de93563d9fae47cb0634d699

URL: 
https://github.com/llvm/llvm-project/commit/5d77344d9d52a623de93563d9fae47cb0634d699
DIFF: 
https://github.com/llvm/llvm-project/commit/5d77344d9d52a623de93563d9fae47cb0634d699.diff

LOG: Simplify test script

Added: 


Modified: 
lldb/test/API/lang/c/full_lto_stepping/TestFullLtoStepping.py

Removed: 




diff  --git a/lldb/test/API/lang/c/full_lto_stepping/TestFullLtoStepping.py 
b/lldb/test/API/lang/c/full_lto_stepping/TestFullLtoStepping.py
index 9a553e8afff6e..afd036524bfe5 100644
--- a/lldb/test/API/lang/c/full_lto_stepping/TestFullLtoStepping.py
+++ b/lldb/test/API/lang/c/full_lto_stepping/TestFullLtoStepping.py
@@ -13,14 +13,8 @@ class TestFullLtoStepping(TestBase):
 @skipUnlessDarwin
 def test(self):
 self.build()
-target = self.createTestTarget()
-
-breakpoint = target.BreakpointCreateByName("main")
-self.assertTrue(
-breakpoint and breakpoint.IsValid(),
-"Breakpoint is valid")
+_, _, thread, _ = lldbutil.run_to_name_breakpoint(self, 'main')
 
-_, _, thread, _ = lldbutil.run_to_breakpoint_do_run(self, target, 
breakpoint)
 name = thread.frames[0].GetFunctionName()
 # Check that we start out in main.
 self.assertEqual(name, 'main')



___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D145803: [clang][DebugInfo] Emit DW_AT_type of preferred name if available

2023-04-04 Thread Wolfgang Pieb via Phabricator via lldb-commits
wolfgangp added a comment.

> @probinson Sounds like Sony's solution also changes the `DW_AT_type` to a 
> non-canonical form. Do you still have concerns with the direction of this 
> patch? Would it cause any problems for you downstream?

Sorry for the late reply. Looking at the patch I don't think it will cause us 
any trouble. The 2 solutions should be able to live happily side by side.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D145803/new/

https://reviews.llvm.org/D145803

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D147300: [lldb] Fix build on older FreeBSD

2023-04-04 Thread Brooks Davis via Phabricator via lldb-commits
This revision was automatically updated to reflect the committed changes.
Closed by commit rGc0df412ad2a5: [lldb] Fix build on older FreeBSD (authored by 
brooks).

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147300/new/

https://reviews.llvm.org/D147300

Files:
  lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp


Index: lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp
===
--- lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp
+++ lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp
@@ -11,6 +11,10 @@
 #ifdef __FreeBSD__
 #include 
 
+#ifndef FPE_FLTIDO
+#define FPE_FLTIDO 9
+#endif
+
 #define ADD_SIGCODE(signal_name, signal_value, code_name, code_value, ...) 
\
   static_assert(signal_name == signal_value,   
\
 "Value mismatch for signal number " #signal_name); 
\


Index: lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp
===
--- lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp
+++ lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp
@@ -11,6 +11,10 @@
 #ifdef __FreeBSD__
 #include 
 
+#ifndef FPE_FLTIDO
+#define FPE_FLTIDO 9
+#endif
+
 #define ADD_SIGCODE(signal_name, signal_value, code_name, code_value, ...) \
   static_assert(signal_name == signal_value,   \
 "Value mismatch for signal number " #signal_name); \
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [lldb] c0df412 - [lldb] Fix build on older FreeBSD

2023-04-04 Thread Brooks Davis via lldb-commits

Author: Brooks Davis
Date: 2023-04-04T21:21:45+01:00
New Revision: c0df412ad2a5236a66ff1b608aeddc744b563e79

URL: 
https://github.com/llvm/llvm-project/commit/c0df412ad2a5236a66ff1b608aeddc744b563e79
DIFF: 
https://github.com/llvm/llvm-project/commit/c0df412ad2a5236a66ff1b608aeddc744b563e79.diff

LOG: [lldb] Fix build on older FreeBSD

Commit 392d9eb03af5a1adac66a86939351b22b3e73495 added a dependency on
FPE_FLTIDO which was only defined in FreeBSD main on May 19, 2022 and
is not in all supported releases. Just define it if it's missing as we
could use a debugger compiled on an older system to debug a newer one.

Reviewed by: DavidSpickett, emaste, dim

Differential Revision: https://reviews.llvm.org/D147300

Added: 


Modified: 
lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp

Removed: 




diff  --git a/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp 
b/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp
index f436de0d033e..ebf197339446 100644
--- a/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp
+++ b/lldb/source/Plugins/Process/Utility/FreeBSDSignals.cpp
@@ -11,6 +11,10 @@
 #ifdef __FreeBSD__
 #include 
 
+#ifndef FPE_FLTIDO
+#define FPE_FLTIDO 9
+#endif
+
 #define ADD_SIGCODE(signal_name, signal_value, code_name, code_value, ...) 
\
   static_assert(signal_name == signal_value,   
\
 "Value mismatch for signal number " #signal_name); 
\



___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D147436: [lldb][ClangExpression] Filter out non-root namespaces in FindNamespace

2023-04-04 Thread Adrian Prantl via Phabricator via lldb-commits
aprantl accepted this revision.
aprantl added a comment.
This revision is now accepted and ready to land.

So the new bool flag effectively implements the leading `::` separator in the 
lookup. Seems reasonable!


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D147436/new/

https://reviews.llvm.org/D147436

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D146965: [lldb] Add support for MSP430 in LLDB.

2023-04-04 Thread David Spickett via Phabricator via lldb-commits
DavidSpickett added a comment.

> It is completely bare metal, but the address space is only 16-bit, so would 
> the entire 64 KB of memory count as a core dump?

It's more "world" than "core" but yeah why not. Probably won't need all 64k 
though, see below...

> I can make a test that checks if fallback information even exists and 
> registers have correct data and size, for example.

Yes that would be great. Plus it documents our expectations (or lack of) from 
this third party debug stub.

> What else would you recommend to test for?

Backtrace is the obvious thing, assuming you have implemented any of that yet. 
What you could do is dump the stack from a real device and use the previously 
mentioned fake GDB remote to replay it to lldb.

Other things:

- Stepping
- Breakpoints, hardware and software. Also, do the breakpoints report an 
address after the stop or before.

If the feature mostly relies on the existing msp430 stub being correct, there's 
not much point testing it. For anything where lldb has to make some msp430 
specific decision, see if you can mock up a gdb remote to test it.




Comment at: lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp:127
  llvm::Triple::hexagon, llvm::Triple::mips, llvm::Triple::mips64el,
- llvm::Triple::mipsel, llvm::Triple::systemz},
+ llvm::Triple::mipsel, llvm::Triple::msp430, llvm::Triple::systemz},
 llvm::Triple::Linux);

If this is bare metal why do we have changes to Linux code here? Or is this the 
default platform used when connecting to the msp430 debug stub.

That said, I'm not sure we A: support Hexagon or B: it runs linux either :)


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D146965/new/

https://reviews.llvm.org/D146965

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D146965: [lldb] Add support for MSP430 in LLDB.

2023-04-04 Thread Ilia Kuklin via Phabricator via lldb-commits
kuilpd added a comment.

In D146965#4240075 , @DavidSpickett 
wrote:

> Two things come to mind:
>
> - Core files (though it is embedded so is that even a thing?)

It is completely bare metal, but the address space is only 16-bit, so would the 
entire 64 KB of memory count as a core dump?

> - Mocking an msp430 remote, as we do for example in Target XML tests.

mspdebug (the tool that implements gdb server for MSP430) doesn't have a lot of 
features, doesn't support memory region info or even target.xml with register 
information, so it all comes down to fallback information in LLDB.
I can make a test that checks if fallback information even exists and registers 
have correct data and size, for example.
What else would you recommend to test for?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D146965/new/

https://reviews.llvm.org/D146965

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D146058: [lldb][gnustep] Add basic test and infrastructure for GNUstep ObjC runtime

2023-04-04 Thread Stefan Gränitz via Phabricator via lldb-commits
sgraenitz added a comment.

The modified proposal keeps GNUstep support off by default (even if installed). 
It must be enabled explicitly by passing `-DLLDB_TEST_OBJC_GNUSTEP=On` and it 
can be disabled easily by passing `-DLLDB_TEST_OBJC_GNUSTEP=Off` to CMake. A 
custom install location `/path/to/lib/libobjc.so` can be specified with 
`-DLLDB_TEST_OBJC_GNUSTEP_DIR=/path/to`. Since it involves some extra logic, I 
moved the standard bits into `FindGNUstepObjC.cmake` which should follow 
regular CMake naming conventions (`GNUstepObjC_DIR`, `GNUstepObjC_FOUND`, 
etc.). This might be the foundation for a future GNUstep standard package file.

This version aims to cause minimal friction while allowing to test with GNUstep 
for those who wish. Please find setup instructions in my previous comment 
. If you have any more questions, 
please let me know.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D146058/new/

https://reviews.llvm.org/D146058

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D146058: [lldb][gnustep] Add basic test and infrastructure for GNUstep ObjC runtime

2023-04-04 Thread Stefan Gränitz via Phabricator via lldb-commits
sgraenitz updated this revision to Diff 510732.
sgraenitz added a comment.

Split config in two parts: On/Off and DIR
Move standard find library logic into FindGNUstepObjC.cmake


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D146058/new/

https://reviews.llvm.org/D146058

Files:
  lldb/cmake/modules/FindGNUstepObjC.cmake
  lldb/test/CMakeLists.txt
  lldb/test/Shell/Expr/objc-gnustep-print.m
  lldb/test/Shell/helper/build.py
  lldb/test/Shell/helper/toolchain.py
  lldb/test/Shell/lit.cfg.py
  lldb/test/Shell/lit.site.cfg.py.in

Index: lldb/test/Shell/lit.site.cfg.py.in
===
--- lldb/test/Shell/lit.site.cfg.py.in
+++ lldb/test/Shell/lit.site.cfg.py.in
@@ -16,6 +16,7 @@
 config.target_triple = "@LLVM_TARGET_TRIPLE@"
 config.python_executable = "@Python3_EXECUTABLE@"
 config.have_zlib = @LLVM_ENABLE_ZLIB@
+config.objc_gnustep_dir = "@LLDB_TEST_OBJC_GNUSTEP_DIR@"
 config.lldb_enable_lzma = @LLDB_ENABLE_LZMA@
 config.host_triple = "@LLVM_HOST_TRIPLE@"
 config.lldb_bitness = 64 if @LLDB_IS_64_BITS@ else 32
Index: lldb/test/Shell/lit.cfg.py
===
--- lldb/test/Shell/lit.cfg.py
+++ lldb/test/Shell/lit.cfg.py
@@ -24,7 +24,7 @@
 
 # suffixes: A list of file extensions to treat as test files. This is overriden
 # by individual lit.local.cfg files in the test subdirectories.
-config.suffixes = ['.test', '.cpp', '.s']
+config.suffixes = ['.test', '.cpp', '.s', '.m']
 
 # excludes: A list of directories to exclude from the testsuite. The 'Inputs'
 # subdirectories contain auxiliary inputs for various tests in their parent
@@ -135,6 +135,14 @@
 if config.have_lldb_server:
 config.available_features.add('lldb-server')
 
+if config.objc_gnustep_dir:
+config.available_features.add('objc-gnustep')
+if platform.system() == 'Windows':
+# objc.dll must be in PATH since Windows has no rpath
+config.environment['PATH'] = os.path.pathsep.join((
+os.path.join(config.objc_gnustep_dir, 'lib'),
+config.environment.get('PATH','')))
+
 # NetBSD permits setting dbregs either if one is root
 # or if user_set_dbregs is enabled
 can_set_dbregs = True
Index: lldb/test/Shell/helper/toolchain.py
===
--- lldb/test/Shell/helper/toolchain.py
+++ lldb/test/Shell/helper/toolchain.py
@@ -42,6 +42,8 @@
 build_script_args.append('--tools-dir={0}'.format(config.lldb_tools_dir))
 if config.llvm_libs_dir:
 build_script_args.append('--libs-dir={0}'.format(config.llvm_libs_dir))
+if config.objc_gnustep_dir:
+build_script_args.append('--objc-gnustep-dir="{0}"'.format(config.objc_gnustep_dir))
 
 lldb_init = _get_lldb_init_path(config)
 
Index: lldb/test/Shell/helper/build.py
===
--- lldb/test/Shell/helper/build.py
+++ lldb/test/Shell/helper/build.py
@@ -49,6 +49,18 @@
 action='append',
 help='If specified, a path to search in addition to PATH when --compiler is not an exact path')
 
+parser.add_argument('--objc-gnustep-dir',
+metavar='directory',
+dest='objc_gnustep_dir',
+required=False,
+help='If specified, a path to GNUstep libobjc2 runtime for use on Windows and Linux')
+
+parser.add_argument('--objc-gnustep',
+dest='objc_gnustep',
+action='store_true',
+default=False,
+help='Include and link GNUstep libobjc2 (Windows and Linux only)')
+
 if sys.platform == 'darwin':
 parser.add_argument('--apple-sdk',
 metavar='apple_sdk',
@@ -238,6 +250,10 @@
 self.obj_ext = obj_ext
 self.lib_paths = args.libs_dir
 self.std = args.std
+assert not args.objc_gnustep or args.objc_gnustep_dir, \
+   "--objc-gnustep specified without path to libobjc2"
+self.objc_gnustep_inc = os.path.join(args.objc_gnustep_dir, 'include') if args.objc_gnustep_dir else None
+self.objc_gnustep_lib = os.path.join(args.objc_gnustep_dir, 'lib') if args.objc_gnustep_dir else None
 
 def _exe_file_name(self):
 assert self.mode != 'compile'
@@ -656,15 +672,20 @@
 args.append('-static')
 args.append('-c')
 
-args.extend(['-o', obj])
-args.append(source)
-
 if sys.platform == 'darwin':
 args.extend(['-isysroot', self.apple_sdk])
+elif self.objc_gnustep_inc:
+if source.endswith('.m') or source.endswith('.mm'):
+args.extend(['-fobjc-runtime=gnustep-2.0', '-I', self.objc_gnustep_inc])
+if sys.platform == "win32":
+args.extend(['-Xclang', '-gcodeview', '-Xclang', '--dependent-lib=msvcrtd'])