+ // FIXME: In Phase 1, record _Unwind_GetIP in xh->obj as a part of
+ // the stack trace for this exception. This will only collect Java
+ // frames, but perhaps that is acceptable.
+ // FIXME2: _Unwind_GetIP is nonsensical for SJLJ, being a call-site
+ // index instead of a PC value. We could perhaps arrange for
+ // _Unwind_GetRegionStart to return context->fc->jbuf[1], which
+ // is the address of the handler label for __builtin_longjmp, but
+ // there is no solution for DONT_USE_BUILTIN_SETJMP.
+
+ language_specific_data = (const unsigned char *)
+ _Unwind_GetLanguageSpecificData (context);
+
+ // If no LSDA, then there are no handlers or cleanups.
+ if (! language_specific_data)
+ return _URC_CONTINUE_UNWIND;
+
+ // Parse the LSDA header.
+ p = parse_lsda_header (context, language_specific_data, &info);
+ ip = _Unwind_GetIP (context) - 1;
+ landing_pad = 0;
+ action_record = 0;
+ handler_switch_value = 0;
+
+#ifdef SJLJ_EXCEPTIONS
+ // The given "IP" is an index into the call-site table, with two
+ // exceptions -- -1 means no-action, and 0 means terminate. But
+ // since we're using uleb128 values, we've not got random access
+ // to the array.
+ if ((int) ip <= 0)
+ return _URC_CONTINUE_UNWIND;
+ else
+ {
+ _Unwind_Word cs_lp, cs_action;
+ do
+ {
+ p = read_uleb128 (p, &cs_lp);
+ p = read_uleb128 (p, &cs_action);
+ }
+ while (--ip);
+
+ // Can never have null landing pad for sjlj -- that would have
+ // been indicated by a -1 call site index.
+ landing_pad = cs_lp + 1;
+ if (cs_action)
+ action_record = info.action_table + cs_action - 1;
+ goto found_something;
+ }
+#else
+ // Search the call-site table for the action associated with this IP.
+ while (p < info.action_table)
+ {
+ _Unwind_Ptr cs_start, cs_len, cs_lp;
+ _Unwind_Word cs_action;
+
+ // Note that all call-site encodings are "absolute" displacements.
+ p = read_encoded_value (0, info.call_site_encoding, p, &cs_start);
+ p = read_encoded_value (0, info.call_site_encoding, p, &cs_len);
+ p = read_encoded_value (0, info.call_site_encoding, p, &cs_lp);
+ p = read_uleb128 (p, &cs_action);
+
+ // The table is sorted, so if we've passed the ip, stop.
+ if (ip < info.Start + cs_start)
+ p = info.action_table;
+ else if (ip < info.Start + cs_start + cs_len)
+ {
+ if (cs_lp)
+ landing_pad = info.LPStart + cs_lp;
+ if (cs_action)
+ action_record = info.action_table + cs_action - 1;
+ goto found_something;
+ }
+ }
+#endif // SJLJ_EXCEPTIONS