Commit Graph

321 Commits

Author SHA1 Message Date
Jonas Devlieghere 6fa9120080
[lldb] Fix up Objective-C ISA pointers
Support stripping the PAC bits from Objective-C ISA pointers in the
Objective-C runtime plugin.
2022-06-23 14:16:29 -07:00
Jonas Devlieghere d95c406c20
[lldb] Fix off-by-one error in the AppleObjCRuntimeV2 utility function
Fix an off-by-one error in the utility function used to extract the
dynamic class info. This resulted in a buffer overflow in the inferior
which interrupted our utility function.

Differential revision: https://reviews.llvm.org/D128377
2022-06-22 13:57:24 -07:00
Jonas Devlieghere f0d87dfe30
[lldb] Return the correct utility function in AppleObjCRuntimeV2
A copy/paste error in GetClassInfoUtilityFunction resulted in the wrong
utility function being returned: copyRealizedClassList instead of
getRealizedClassList_trylock.

Differential revision: https://reviews.llvm.org/D128378
2022-06-22 13:57:23 -07:00
Jonas Devlieghere c866f8544c
[lldb] Add a setting to specify the preferred dynamic class info extractor o
Add a setting to configure how LLDB parses dynamic Objective-C class
metadata. By default LLDB will choose the most appropriate method for
the target OS.

Differential revision: https://reviews.llvm.org/D128312
2022-06-21 18:51:39 -07:00
Jonas Devlieghere c08f61b45e
[lldb] Instantiate lazily named classes on macOS Ventura.
Recent revisions of the Objective-C runtime changed
objc_debug_class_getNameRaw() in a way that no longer triggers lazy
names to be instantiated. This has the unintended side-effect of making
generic bridged Swift classes, such as _SwiftDeferredNSDictionary<U,V>
to become invisible to the Objective-C runtime.

This patch detects this situation and forces the names to be
instantiated by calling class_getName() and discarding the result before
calling objc_debug_class_getNameRaw() again.

Many thanks to Mike Ash for outlining the solution and Adrian for
authoring the downstream patch.

rdar://95245318

Differential revision: https://reviews.llvm.org/D128306
2022-06-21 18:51:38 -07:00
Jonas Devlieghere fc43703481
[lldb] Use objc_getRealizedClassList_trylock on macOS Ventura and later
In order to avoid stranding the Objective-C runtime lock, we switched
from objc_copyRealizedClassList to its non locking variant
objc_copyRealizedClassList_nolock. Not taking the lock was relatively
safe because we run this expression on one thread only, but it was still
possible that someone was in the middle of modifying this list while we
were trying to read it. Worst case that would result in a crash in the
inferior without side-effects and we'd unwind and try again later.

With the introduction of macOS Ventura, we can use
objc_getRealizedClassList_trylock instead. It has semantics similar to
objc_copyRealizedClassList_nolock, but instead of not locking at all,
the function returns if the lock is already taken, which avoids the
aforementioned crash without stranding the Objective-C runtime lock.
Because LLDB gets to allocate the underlying memory we also avoid
stranding the malloc lock.

rdar://89373233

Differential revision: https://reviews.llvm.org/D127252
2022-06-08 11:34:27 -07:00
Jim Ingham 833882b327 Adapt the ObjC stepping algorithm to deal with "selector-stubs" in clang.
Clang is adding a feature to ObjC code generation, where instead of calling
objc_msgSend directly with an object & selector, it generates a stub that
gets passed only the object and the stub figures out the selector.

This patch adds support for following that dispatch method into the implementation
function.
2022-04-08 17:45:16 -07:00
Jonas Devlieghere 815fa5bf44
[lldb] Remove duplicate "warning:"
Remove "warning:" from the warning message itself. The default event
handler is already emitting the appropriate prefix.
2022-04-06 15:05:27 -07:00
Jason Molenda ee394177e6 Refine memory buffer for importing shared cache objc class list
In https://reviews.llvm.org/D118972 I increased this buffer to be
big enough to import 261,144 classes but this is a lot more than
we currently have, an allocating a too-large buffer can add memory
pressure even if it's only for a short time.  Reduce the size of
this memory buffer to big enough to import 163,840 classes.  I'll
probably move to a scheme where we read the objc classes in chunks,
with a smaller buffer and multiple inferior function calls.

rdar://91275493
2022-04-05 12:49:40 -07:00
Jonas Devlieghere 73714a3c60
[lldb] Fix undefined behavior: left shift of negative value
Fix undefined behavior in AppleObjCRuntimeV2 where we were left shifting
a signed value. This also removes redundant casts of unobfuscated to
uint64_t which it already is.

rdar://91242879

Differential revision: https://reviews.llvm.org/D123098
2022-04-05 09:37:31 -07:00
Jonas Devlieghere 9a88c2b639
[lldb] Fixup tagged pointers ISAs
This patch upstreams support for tagger pointer ISAs.
2022-03-23 09:59:34 -07:00
Jonas Devlieghere 2fc38b2b7b
[lldb] Report debugger diagnostics as events
Report warnings and errors through events instead of printing directly
the to the debugger's error stream. By using events, IDEs such as Xcode
can report these issues in the UI instead of having them show up in the
debugger console.

The new diagnostic events are handled by the default event loop. If a
diagnostic is reported while nobody is listening for the new event
types, it is printed directly to the debugger's error stream.

Differential revision: https://reviews.llvm.org/D121511
2022-03-16 08:33:01 -07:00
Jonas Devlieghere 527d2c5867
[lldb] Fix AppleObjCRuntime log channels
The log channel was changed from Types to Commands in
a007a6d84471bb956abe10974cac3066799f583f:

-    Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_TYPES));
+    Log *log = GetLog(LLDBLog::Process | LLDBLog::Commands);
2022-03-15 14:47:33 -07:00
Shafik Yaghmour 80a11e0803 [LLDB] Replace use of double underscore in identifiers
Identifiers with __ anywhere are reserved. I picked this up via the
bugprone-reserved-identifier clang-tidy check but -Wreserved-identifier will
also flag these uses as well.

Differential Revision: https://reviews.llvm.org/D119915
2022-02-16 11:54:45 -08:00
Jason Molenda a37c38176a Increase memory buffer for scanning objc classes on darwin systems
iOS systems are getting near this limit; double itfrom a 150kb
buffer to a 300kb buffer, which is freed after processing the
list of classes.

rdar://88454594
Differential Revision: https://reviews.llvm.org/D118972
2022-02-04 23:53:27 -08:00
Pavel Labath c34698a811 [lldb] Rename Logging.h to LLDBLog.h and clean up includes
Most of our code was including Log.h even though that is not where the
"lldb" log channel is defined (Log.h defines the generic logging
infrastructure). This worked because Log.h included Logging.h, even
though it should.

After the recent refactor, it became impossible the two files include
each other in this direction (the opposite inclusion is needed), so this
patch removes the workaround that was put in place and cleans up all
files to include the right thing. It also renames the file to LLDBLog to
better reflect its purpose.
2022-02-03 14:47:01 +01:00
Pavel Labath a007a6d844 [lldb] Convert "LLDB" log channel to the new API 2022-02-02 14:13:08 +01:00
Jonas Devlieghere d230848a85 [lldb] Print an error message when we're reading libobjc.A.dylib from memory
Use libobjc.A.dylib as a sentinel to detect situations where we're
reading libraries from process memory instead of the shared cache.

Differential revision: https://reviews.llvm.org/D117623
2022-01-18 17:23:38 -08:00
Jonas Devlieghere 10eb32f45d [lldb] Improve 'lang objc tagged-pointer info' command
Don't try to get a class descriptor for a pointer that doesn't look like
a tagged pointer. Also print addresses as fixed-width hex and update the
test.
2021-11-05 13:19:00 -07:00
Jonas Devlieghere f9e6be5cc1 [lldb] Update tagged pointer command output and test.
- Use formatv to print the addresses.
 - Add check for 0x0 which is treated as an invalid address.
 - Use a an address that's less likely to be interpreted as a real
   tagged pointer.
2021-11-03 15:04:36 -07:00
Jonas Devlieghere 50b40b0518 [lldb] Improve error reporting in `lang objc tagged-pointer info`
Improve error handling for the lang objc tagged-pointer info. Rather
than failing silently, report an error if we couldn't convert an
argument to an address or resolve the class descriptor.

  (lldb) lang objc tagged-pointer info 0xbb6404c47a587764
  error: could not get class descriptor for 0xbb6404c47a587764

  (lldb) lang objc tagged-pointer info n1
  error: could not convert 'n1' to a valid address

Differential revision: https://reviews.llvm.org/D112945
2021-11-02 14:25:42 -07:00
Pavel Labath 49481b5380 Remove ConstString from Language, LanguageRuntime, SystemRuntime and SymbolFile plugin names 2021-10-27 08:25:44 +02:00
Jonas Devlieghere 957a5e9874 [lldb] Fix nullptr dereference in AppleObjCRuntimeV2
Fix a potential nullptr dereference in AppleObjCRuntimeV2 by checking
the result of GetClassInfoUtilityFunction and returning a failure if
it's null.

The DynamicClassInfoExtractor was already doign the right thing, but the
SharedCacheClassInfoExtractor was missing this check.
2021-10-18 23:30:31 -07:00
Pavel Labath a3939e159f [lldb] Return StringRef from PluginInterface::GetPluginName
There is no reason why this function should be returning a ConstString.

While modifying these files, I also fixed several instances where
GetPluginName and GetPluginNameStatic were returning different strings.

I am not changing the return type of GetPluginNameStatic in this patch, as that
would necessitate additional changes, and this patch is big enough as it is.

Differential Revision: https://reviews.llvm.org/D111877
2021-10-18 10:14:42 +02:00
Alfsonso Gregory 3fe771bf02 [LLDB] Fix objc_clsopt_v16_t struct
The objc_clsopt_v16_t struct does not match up with the macOS/iOS15
dyld_shared_cache ObjC runtime structures. A struct field was seemingly
omitted.

Differential revision: https://reviews.llvm.org/D110477
2021-10-04 08:55:09 -07:00
Pavel Labath b03126768a [lldb] Remove PluginInterface::GetPluginVersion
In all these years, we haven't found a use for this function (it has
zero callers). Lets just remove the boilerplate.

Differential Revision: https://reviews.llvm.org/D109600
2021-09-13 10:29:00 +02:00
Jonas Devlieghere d1d4f36556 [lldb] Make sure there's a value for the key before dereferencing.
Make sure there's a value for the shared_cache_base_address key exists
in the dictionary before trying to dereference the value.

rdar://76894476
2021-09-08 13:46:09 -07:00
Fred Riss 9ed7416aaf [lldb] Try harder to find the __NSCFBoolean addresses
It looks like recent CoreFoundation builds strip the non-public symbol
that we were looking for to find the 2 boolean "classes". The public
symbol is of course there, and it contains the address of the private
one. If we don't find the private symbol directly, go through a memory
read at the public symbol's location instead.
2021-08-06 13:04:29 -07:00
Jonas Devlieghere fd2433e139 [lldb] Replace default bodies of special member functions with = default;
Replace default bodies of special member functions with = default;

$ run-clang-tidy.py -header-filter='lldb' -checks='-*,modernize-use-equals-default' -fix ,

https://clang.llvm.org/extra/clang-tidy/checks/modernize-use-equals-default.html

Differential revision: https://reviews.llvm.org/D104041
2021-07-02 11:31:16 -07:00
Jonas Devlieghere 71be4db05b [lldb] Check for the mangled symbol name for objc_copyRealizedClassList_nolock
When we check whether the Objective-C SPI is available, we need to check
for the mangled symbol name. Unlike `objc_copyRealizedClassList`, which
is C exported, the `nolock` variant is not.

Differential revision: https://reviews.llvm.org/D105136
2021-06-29 10:58:35 -07:00
Jonas Devlieghere ffc0533855 [lldb] Use the non-locking variant of objc_copyRealizedClassList
Avoid standing the Objective-C runtime lock by calling
objc_copyRealizedClassList_nolock instead of objc_copyRealizedClassList.

We already guarantee that no other threads can run while we're running
this utility expression, similar to when we parse the data ourselves
from the gdb_objc_realized_classes struct.

Worst case this will crash if the list is getting edited, which won't do
any harm and we'll just try again later.

Differential revision: https://reviews.llvm.org/D104951
2021-06-25 15:02:49 -07:00
Jonas Devlieghere fc71a5c6e8 [lldb] Support new objective-c hash table layout
Update LLDB for thew new Objective-C hash table layout in the dyld
shared cache found in macOS Monterey.

rdar://72863911
2021-06-11 10:26:16 -07:00
Jonas Devlieghere 9494c510af [lldb] Use C++11 default member initializers
This converts a default constructor's member initializers into C++11
default member initializers. This patch was automatically generated with
clang-tidy and the modernize-use-default-member-init check.

$ run-clang-tidy.py -header-filter='lldb' -checks='-*,modernize-use-default-member-init' -fix

This is a mass-refactoring patch and this commit will be added to
.git-blame-ignore-revs.

Differential revision: https://reviews.llvm.org/D103483
2021-06-09 09:43:13 -07:00
Raphael Isemann 76e47d4887 [lldb][NFC] Use C++ versions of the deprecated C standard library headers
The C headers are deprecated so as requested in D102845, this is replacing them
all with their (not deprecated) C++ equivalent.

Reviewed By: shafik

Differential Revision: https://reviews.llvm.org/D103084
2021-05-26 12:46:12 +02:00
Raphael Isemann bbea361039 [lldb][NFC] Remove all uses of StringRef::withNullAsEmpty in LLDB
A long time ago LLDB wanted to start using StringRef instead of
C-Strings/ConstString but was blocked by the fact that the StringRef constructor
that takes a C-string was asserting that the C-string isn't a nullptr. To
workaround this, D24697 introduced a special function called `withNullAsEmpty`
and that's what LLDB (and only LLDB) started to use to build StringRefs from
C-strings.

A bit later it seems that `withNullAsEmpty` was declared too awkward to use and
instead the assert in the StringRef constructor got removed (see D24904). The
rest of LLDB was then converted to StringRef by just calling the now perfectly
usable implicit constructor.

However, all the calls to `withNullAsEmpty` just remained and are now just
strange artefacts in the code base that just look out of place. It's also
curiously a LLDB-exclusive function and no other project ever called it since
it's introduction half a decade ago.

This patch removes all uses of `withNullAsEmpty`. The follow up will be to
remove the function from StringRef.

Reviewed By: JDevlieghere

Differential Revision: https://reviews.llvm.org/D102597
2021-05-18 09:41:20 +02:00
Martin Storsjö 127322ddeb [lldb] Silence GCC warnings about control reaching the end of non-void functions. NFC.
Also remove a superfluous semicolon after the braces for a switch
statement (that wasn't warned about).

Differential Revision: https://reviews.llvm.org/D100447
2021-04-14 11:54:45 +03:00
Jonas Devlieghere 801cea2ce9 [lldb] Fix else-after-return in AppleObjCRuntimeV2 (NFC)
Use early returns to associate the error message with the corresponding
condition and eliminate some else-after-returns in the process.
2021-04-06 10:07:22 -07:00
Jim Ingham be0ced03ba Revert "Revert "Add support for fetching signed values from tagged pointers.""
This reverts commit 602ab188a7.

The patch replicated an lldbassert for a certain type of NSNumber for tagged
pointers.  This really shouldn't be an assert since we don't do anything wrong
with these numbers, we just don't print a summary.  So this patch changed the
lldbassert to a log message in reverting the revert.
2021-04-05 18:18:26 -07:00
Jason Molenda 602ab188a7 Revert "Add support for fetching signed values from tagged pointers."
This reverts commit 4d9039c8dc.

This is causing the greendragon bots to fail most of the time when
running TestNSDictionarySynthetic.py.  Reverting until Jim has a chance
to look at this on Monday.  Running the commands from that test from
the command line, it fails 10-13% of the time on my desktop.

This is a revert of Jim's changes in https://reviews.llvm.org/D99694
2021-04-04 01:47:35 -07:00
Jonas Devlieghere cf51bf77b0 [lldb] Account for objc_debug_class_getNameRaw returning NULL
On macOS Catalina, calling objc_debug_class_getNameRaw on some of the
ISA pointers returns NULL, causing us to crash and unwind before reading
all the Objective-C classes. This does not happen on macOS Big Sur.
Account for that possibility and skip the class when that happens.
2021-04-01 19:58:28 -07:00
Jim Ingham 4d9039c8dc Add support for fetching signed values from tagged pointers.
The ObjC runtime offers both signed & unsigned tagged pointer value
accessors to tagged pointer providers, but lldb's tagged pointer
code only implemented the unsigned one.  This patch adds an
emulation of the signed one.

The motivation for doing this is that NSNumbers use the signed
accessor (they are always signed) and we need to follow that in our
summary provider or we will get incorrect values for negative
NSNumbers.

The data-formatter-objc test file had NSNumber examples (along with lots of other
goodies) but the NSNumber values weren't tested.  So I also added
checks for those values to the test.

I also did a quick audit of the other types in that main.m file, and
it looks like pretty much all the other values are either intermediates
or are tested.

Differential Revision: https://reviews.llvm.org/D99694
2021-04-01 10:59:25 -07:00
Jonas Devlieghere bf8cbfa65f [lldb] Move UpdateISAToDescriptorMap into ClassInfoExtractor (NFC)
Move UpdateISAToDescriptorMap into ClassInfoExtractor so that all the
formerly public functions can be private and remain an implementation
detail of the extractor.

Differential revision: https://reviews.llvm.org/D99448
2021-03-29 09:23:44 -07:00
Jonas Devlieghere 24baaad945 [lldb] Remove UpdateISAToDescriptorMapFromMemory
Remove UpdateISAToDescriptorMapFromMemory because it's dead code.
2021-03-26 15:40:36 -07:00
Jonas Devlieghere 645764f3aa [lldb] Add consistency between reading the dynamic and shared cache class info
This adds the consistency I promised in D99315 between how we read the
class info from the Objective-C runtime and the shared cache. (NFC)

Differential revision: https://reviews.llvm.org/D99446
2021-03-26 15:19:21 -07:00
Jonas Devlieghere 077aa10253 [lldb] Support lazily named classes in the Objective-C classes
Generic classes in Swift have their name instantiated on request, since
the vast majority never need it, and it just wastes time and memory.
This results in LLDB being unable to determine the dynamic type of these
Swift objects.

The main issues is that lazily named classes are not added to the
gdb_objc_realized_classes hashtable. This means the class count in the
table doesn't change when a class is realized and LLDB doesn't know it
needs to re-parse the class info. But even if it did, the classes are
not in the hash table.

The first change in this patch is that we read
objc_debug_realized_class_generation_count and re-parse the class info
when the count changes.

The second change in this patch is that we use
objc_copyRealizedClassList (if available) to get all realized classes
from the runtime.

Unfortunately, objc_copyRealizedClassList calls _dyld_objc_class_count
in its implementation. As we know, the Objective-C parsing code might
get called before dyld is fully initialized, resulting in crashes or
even a stranded lock. Therefore we only use objc_copyRealizedClassList
when we know it's safe to do so by checking libSystemInitialized in
dyld_all_image_infos.

As a result, it's possible that the first time we read the Objective-C
runtime we are forced to use gdb_objc_realized_classes. This should be
fine, as there should be no lazily named classes at this point.
Subsequent queries will detect the change in realized class generation
count and use objc_copyRealizedClassList.

This patch keeps the old behavior when objc_copyRealizedClassList or
objc_debug_realized_class_generation_count are not available.

Differential revision: https://reviews.llvm.org/D99315
2021-03-26 13:34:08 -07:00
Fred Riss c4fee95746 [lldb/ObjC] Make the NonPointerIsaCache initialization lazy
The objc_debug_isa_class_mask magic value that the objc runtime vends
is now initialized using a static initializer instead of a constant
value. The runtime plugin itself will be initialized before the value
is computed and as a result, the cache will get the wrong value.

Making the creation of the NonPointerIsaCache fully lazy fixes this.
2021-03-24 20:08:06 -07:00
Jonas Devlieghere ff29fdfe4e [lldb] Format AppleObjCRuntimeV2 (NFC) 2021-03-24 20:08:06 -07:00
Jonas Devlieghere db8b1598b7 [lldb] Inline objc_opt->version >= 14 to avoid dealing with bool type 2021-03-02 16:41:44 -08:00
Jonas Devlieghere c85d47f7b8 [lldb] Add more logging to __lldb_apple_objc_v2_get_dynamic_class_info 2021-03-02 16:24:59 -08:00
Adrian Prantl 057efa9916 Make the error condition in Value::ValueType explicit (NFC)
The comment for ValueType claims that all values <1 are errors, but
not all switch statements take this into account. This patch
introduces an explicit Error case and deletes all default: cases, so
we get warned about incomplete switch coverage.

https://reviews.llvm.org/D96537
2021-02-12 16:12:31 -08:00