@@ -47,6 +47,7 @@ limitations under the License.
4747#define BREAKPOINT_TARGET 0x02
4848#define BREAKPOINT_NOTIFICATION 0x04
4949#define BREAKPOINT_TARGET_END 0x08
50+ #define BREAKPOINT_LLDB_NOTIFICATION 0x10
5051
5152#define PERSIST_END_EXCEPTION 0x0F22
5253
@@ -409,7 +410,7 @@ size_t Debugger::GetReturnAddress() {
409410#ifdef ARM64
410411 return GetRegister (LR);
411412#else
412- void *ra;
413+ void *ra = NULL ;
413414 RemoteRead ((void *)GetRegister (RSP), &ra, child_ptr_size);
414415 return (size_t )ra;
415416#endif
@@ -713,7 +714,10 @@ void Debugger::AddBreakpoint(void *address, int type) {
713714 for (auto it = breakpoints.rbegin (); it != breakpoints.rend (); ++it) {
714715 if ((*it)->address == address) {
715716 (*it)->type |= type;
716- if (((*it)->type & BREAKPOINT_NOTIFICATION) && ((*it)->type & BREAKPOINT_TARGET)) {
717+ if ((((*it)->type & BREAKPOINT_NOTIFICATION) ||
718+ ((*it)->type & BREAKPOINT_LLDB_NOTIFICATION))
719+ && ((*it)->type & BREAKPOINT_TARGET))
720+ {
717721 FATAL (" Target method must not be the same as _dyld_debugger_notification" );
718722 }
719723
@@ -1278,26 +1282,20 @@ void Debugger::OnModuleLoaded(void *module, char *module_name) {
12781282void Debugger::HandleDyld (void *module ) {
12791283 dyld_address = module ;
12801284
1281- m_dyld_debugger_notification = GetSymbolAddress (module , (char *)" __dyld_debugger_notification" );
1282- AddBreakpoint (m_dyld_debugger_notification, BREAKPOINT_NOTIFICATION);
1283-
1284- #ifdef ARM64
1285- // For arm we just mov pc, lr on BREAKPOINT_NOTIFICATION
1286- #else
1287- // This save us the recurring TRAP FLAG breakpoint on BREAKPOINT_NOTIFICATION.
1288- unsigned char ret = 0xC3 ;
1289- RemoteWrite ((void *)((uint64_t )m_dyld_debugger_notification+1 ), (void *)&ret, 1 );
1290- #endif
1285+ void *dyld_debugger_notification = GetSymbolAddress (module , (char *)" __dyld_debugger_notification" );
1286+ if (dyld_debugger_notification) {
1287+ AddBreakpoint (dyld_debugger_notification, BREAKPOINT_NOTIFICATION);
1288+ } else {
1289+ dyld_debugger_notification = GetSymbolAddress (module , (char *)" _lldb_image_notifier" );
1290+ if (!dyld_debugger_notification) FATAL (" Couldn't find __dyld_debugger_notification or _lldb_image_notifier" );
1291+ AddBreakpoint (dyld_debugger_notification, BREAKPOINT_LLDB_NOTIFICATION);
1292+ }
12911293}
12921294
1293- void Debugger::OnDyldImageNotifier (size_t mode, unsigned long infoCount, uint64_t machHeaders[]) {
1294- uint64_t *image_info_array = new uint64_t [infoCount];
1295- size_t image_info_array_size = sizeof (uint64_t ) * infoCount;
1296- RemoteRead (machHeaders, (void *)image_info_array, image_info_array_size);
1297-
1295+ void Debugger::OnImageNotifier (size_t mode, unsigned long infoCount, uint64_t * headers) {
12981296 if (mode == 1 ) { /* dyld_image_removing */
12991297 for (unsigned long i = 0 ; i < infoCount; ++i) {
1300- OnModuleUnloaded ((void *)image_info_array [i]);
1298+ OnModuleUnloaded ((void *)headers [i]);
13011299 }
13021300 } else {
13031301 dyld_all_image_infos all_image_infos = mach_target->GetAllImageInfos ();
@@ -1319,8 +1317,8 @@ void Debugger::OnDyldImageNotifier(size_t mode, unsigned long infoCount, uint64_
13191317 void *mach_header_addr = (void *)all_image_info_array[i].imageLoadAddress ;
13201318 if (mode == 2 ) { /* dyld_notify_remove_all */
13211319 OnModuleUnloaded (mach_header_addr);
1322- } else if (std::find (image_info_array, image_info_array + infoCount, (uint64_t )mach_header_addr)
1323- != image_info_array + infoCount) {
1320+ } else if (std::find (headers, headers + infoCount, (uint64_t )mach_header_addr)
1321+ != headers + infoCount) {
13241322 /* dyld_image_adding */
13251323 mach_target->ReadCString ((uint64_t )all_image_info_array[i].imageFilePath , PATH_MAX, path);
13261324 char *base_name = strrchr ((char *)path, ' /' );
@@ -1331,10 +1329,35 @@ void Debugger::OnDyldImageNotifier(size_t mode, unsigned long infoCount, uint64_
13311329
13321330 delete [] all_image_info_array;
13331331 }
1332+ }
1333+
1334+ void Debugger::OnDyldImageNotifier (size_t mode, unsigned long infoCount, uint64_t machHeaders[]) {
1335+ uint64_t *image_info_array = new uint64_t [infoCount];
1336+ size_t image_info_array_size = sizeof (uint64_t ) * infoCount;
1337+ RemoteRead (machHeaders, (void *)image_info_array, image_info_array_size);
1338+
1339+ OnImageNotifier (mode, infoCount, image_info_array);
1340+
1341+ delete [] image_info_array;
1342+ }
1343+
1344+ void Debugger::OnLldbImageNotifier (size_t mode, unsigned long infoCount, size_t infos) {
1345+ uint64_t *header_array = new uint64_t [infoCount];
1346+ uint64_t *image_info_array = new uint64_t [infoCount * 3 ];
1347+
1348+ RemoteRead ((void *)infos, (void *)image_info_array, 3 * sizeof (uint64_t ) * infoCount);
1349+
1350+ for (size_t i = 0 ; i < infoCount; i++) {
1351+ header_array[i] = image_info_array[i * 3 ];
1352+ }
1353+
1354+ OnImageNotifier (mode, infoCount, header_array);
13341355
1356+ delete [] header_array;
13351357 delete [] image_info_array;
13361358}
13371359
1360+
13381361void Debugger::OnProcessCreated () {
13391362 if (trace_debug_events) {
13401363 SAY (" Debugger: Process created or attached\n " );
@@ -1374,8 +1397,12 @@ int Debugger::HandleDebuggerBreakpoint() {
13741397 OnDyldImageNotifier (GetRegister (ArgumentToRegister (0 )),
13751398 (unsigned long )GetRegister (ArgumentToRegister (1 )),
13761399 (uint64_t *)GetRegister (ArgumentToRegister (2 )));
1377-
13781400 return BREAKPOINT_NOTIFICATION;
1401+ } else if (breakpoint->type & BREAKPOINT_LLDB_NOTIFICATION) {
1402+ OnLldbImageNotifier (GetRegister (ArgumentToRegister (0 )),
1403+ (unsigned long )GetRegister (ArgumentToRegister (1 )),
1404+ GetRegister (ArgumentToRegister (2 )));
1405+ return BREAKPOINT_LLDB_NOTIFICATION;
13791406 }
13801407
13811408 breakpoints.erase (iter);
@@ -1438,12 +1465,19 @@ void Debugger::HandleExceptionInternal(MachException *raised_mach_exception) {
14381465 if (breakpoint_type & BREAKPOINT_TARGET_END) {
14391466 handle_exception_status = DEBUGGER_TARGET_END;
14401467 }
1468+ if ((breakpoint_type & BREAKPOINT_NOTIFICATION) ||
1469+ (breakpoint_type & BREAKPOINT_LLDB_NOTIFICATION))
1470+ {
1471+ // simulate return
14411472#ifdef ARM64
1442- if (breakpoint_type & BREAKPOINT_NOTIFICATION) {
1443- SetRegister (ARCH_PC, GetRegister (LR));
1444- return ;
1445- }
1473+ SetRegister (ARCH_PC, GetRegister (LR));
1474+ return ;
1475+ #else
1476+ size_t ret_address = GetReturnAddress ();
1477+ SetRegister (ARCH_SP, GetRegister (ARCH_SP) + child_ptr_size);
1478+ SetRegister (ARCH_PC, ret_address);
14461479#endif
1480+ }
14471481
14481482 if (breakpoint_type != BREAKPOINT_UNKNOWN) {
14491483 return ;
0 commit comments