sgraenitz created this revision. sgraenitz added reviewers: theraven, triplef, mgorny, labath, omjavaid, xiaobai, aleksandr.urakov, zturner. Herald added a project: All. sgraenitz requested review of this revision. Herald added a project: LLDB.
We are planning to add basic ObjC debug support for the GNUstep ObjC runtime on Linux and Windows: https://github.com/gnustep/libobjc2 On Linux much of the desired functionality is there already. It seems accidental in parts, but it's a good early baseline. On Windows nothing works yet. In this first patch I want to add the necessary test infrastructure to utilize the GNUstep runtime in the LLDB test suite. The minimal test demonstrates that it works on Linux. The next goal is to extend the PDB parser and get Windows to this baseline as well. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D146058 Files: 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='Windows and Linux include/link GNUstep libobjc2 for this build') + 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 + if args.objc_gnustep: + assert args.objc_gnustep_dir, "GNUstep libobjc2 runtime for Linux and Windows" + self.objc_gnustep_inc = os.path.join(args.objc_gnustep_dir, 'include') + self.objc_gnustep_lib = os.path.join(args.objc_gnustep_dir, 'lib') 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']) if self.std: args.append('-std={0}'.format(self.std)) + args.extend(['-o', obj]) + args.append(source) + return ('compiling', [source], obj, None, args) def _get_link_command(self): @@ -686,6 +707,12 @@ if sys.platform == 'darwin': args.extend(['-isysroot', self.apple_sdk]) + elif self.objc_gnustep_lib: + args.extend(['-L', self.objc_gnustep_lib, '-lobjc']) + if sys.platform == 'linux': + args.extend(['-Wl,-rpath,' + self.objc_gnustep_lib]) + elif sys.platform == 'win32': + args.extend(['-fuse-ld=lld-link', '-g', '-Xclang', '--dependent-lib=msvcrtd']) return ('linking', self._obj_file_names(), self._exe_file_name(), None, args) Index: lldb/test/Shell/Expr/objc-gnustep-print.m =================================================================== --- /dev/null +++ lldb/test/Shell/Expr/objc-gnustep-print.m @@ -0,0 +1,60 @@ +// REQUIRES: objc-gnustep +// XFAIL: system-windows +// +// RUN: %build %s --compiler=clang --objc-gnustep --output=%t +// RUN: %lldb -b -o "b objc-gnustep-print.m:35" -o "run" -o "p self" -o "p *self" -- %t | FileCheck %s + +#import "objc/runtime.h" + +@protocol NSCoding +@end + +#ifdef __has_attribute +#if __has_attribute(objc_root_class) +__attribute__((objc_root_class)) +#endif +#endif +@interface NSObject <NSCoding> { + id isa; + int refcount; +} +@end +@implementation NSObject +- (id)class { + return object_getClass(self); +} ++ (id)new { + return class_createInstance(self, 0); +} +@end +@interface TestObj : NSObject {} +- (int)ok; +@end +@implementation TestObj +- (int)ok { + return self ? 0 : 1; +} +@end + +// CHECK: (lldb) b objc-gnustep-print.m:35 +// CHECK: Breakpoint {{.*}} at objc-gnustep-print.m +// +// CHECK: (lldb) run +// CHECK: Process {{[0-9]+}} stopped +// CHECK: -[TestObj ok](self=[[SELF_PTR:0x[0-9]+]]{{.*}}) at objc-gnustep-print.m:35 +// +// CHECK: (lldb) p self +// CHECK: (TestObj *) $0 = [[SELF_PTR]] +// +// CHECK: (lldb) p *self +// CHECK: (TestObj) $1 = { +// CHECK: NSObject = { +// CHECK: isa +// CHECK: refcount +// CHECK: } +// CHECK: } + +int main() { + TestObj *testObj = [TestObj new]; + return [testObj ok]; +} Index: lldb/test/CMakeLists.txt =================================================================== --- lldb/test/CMakeLists.txt +++ lldb/test/CMakeLists.txt @@ -25,6 +25,20 @@ file(MAKE_DIRECTORY ${LLDB_TEST_MODULE_CACHE_LLDB}) file(MAKE_DIRECTORY ${LLDB_TEST_MODULE_CACHE_CLANG}) +# Windows and Linux have no built-in ObjC runtime. Let the user provide a path and use GNUstep. +if (UNIX AND NOT APPLE) + find_path(gnustep_install_dir NAMES lib/libobjc.so include/objc/runtime.h) + set(gnustep_info lib/libobjc.so) +elseif (WIN32 AND EXISTS "C:/Program Files (x86)/libobjc/lib/objc.dll" + AND EXISTS "C:/Program Files (x86)/libobjc/include/objc/runtime.h") + set(gnustep_install_dir "C:/Program Files (x86)/libobjc") + set(gnustep_info lib/objc.dll) +endif() +set(LLDB_TEST_OBJC_GNUSTEP_DIR "${gnustep_install_dir}" CACHE PATH "GNUstep libobjc2 path for ObjC tests on Windows and Linux") +if (LLDB_TEST_OBJC_GNUSTEP_DIR) + message(STATUS "Found GNUstep ObjC runtime: ${LLDB_TEST_OBJC_GNUSTEP_DIR}/${gnustep_info}") +endif() + # LLVM_BUILD_MODE is used in lit.site.cfg if (CMAKE_CFG_INTDIR STREQUAL ".") set(LLVM_BUILD_MODE ".")
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits