OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [gdb-7.2/] [gdb-7.2-or32-1.0rc3/] [gdb/] [objc-lang.c] - Blame information for rev 330

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* Objective-C language support routines for GDB, the GNU debugger.
2
 
3
   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
4
   Free Software Foundation, Inc.
5
 
6
   Contributed by Apple Computer, Inc.
7
   Written by Michael Snyder.
8
 
9
   This file is part of GDB.
10
 
11
   This program is free software; you can redistribute it and/or modify
12
   it under the terms of the GNU General Public License as published by
13
   the Free Software Foundation; either version 3 of the License, or
14
   (at your option) any later version.
15
 
16
   This program is distributed in the hope that it will be useful,
17
   but WITHOUT ANY WARRANTY; without even the implied warranty of
18
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
   GNU General Public License for more details.
20
 
21
   You should have received a copy of the GNU General Public License
22
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
23
 
24
#include "defs.h"
25
#include "symtab.h"
26
#include "gdbtypes.h"
27
#include "expression.h"
28
#include "parser-defs.h"
29
#include "language.h"
30
#include "c-lang.h"
31
#include "objc-lang.h"
32
#include "exceptions.h"
33
#include "complaints.h"
34
#include "value.h"
35
#include "symfile.h"
36
#include "objfiles.h"
37
#include "gdb_string.h"         /* for strchr */
38
#include "target.h"             /* for target_has_execution */
39
#include "gdbcore.h"
40
#include "gdbcmd.h"
41
#include "frame.h"
42
#include "gdb_regex.h"
43
#include "regcache.h"
44
#include "block.h"
45
#include "infcall.h"
46
#include "valprint.h"
47
#include "gdb_assert.h"
48
 
49
#include <ctype.h>
50
 
51
struct objc_object {
52
  CORE_ADDR isa;
53
};
54
 
55
struct objc_class {
56
  CORE_ADDR isa;
57
  CORE_ADDR super_class;
58
  CORE_ADDR name;
59
  long version;
60
  long info;
61
  long instance_size;
62
  CORE_ADDR ivars;
63
  CORE_ADDR methods;
64
  CORE_ADDR cache;
65
  CORE_ADDR protocols;
66
};
67
 
68
struct objc_super {
69
  CORE_ADDR receiver;
70
  CORE_ADDR class;
71
};
72
 
73
struct objc_method {
74
  CORE_ADDR name;
75
  CORE_ADDR types;
76
  CORE_ADDR imp;
77
};
78
 
79
static const struct objfile_data *objc_objfile_data;
80
 
81
/* Lookup a structure type named "struct NAME", visible in lexical
82
   block BLOCK.  If NOERR is nonzero, return zero if NAME is not
83
   suitably defined.  */
84
 
85
struct symbol *
86
lookup_struct_typedef (char *name, struct block *block, int noerr)
87
{
88
  struct symbol *sym;
89
 
90
  sym = lookup_symbol (name, block, STRUCT_DOMAIN, 0);
91
 
92
  if (sym == NULL)
93
    {
94
      if (noerr)
95
        return 0;
96
      else
97
        error (_("No struct type named %s."), name);
98
    }
99
  if (TYPE_CODE (SYMBOL_TYPE (sym)) != TYPE_CODE_STRUCT)
100
    {
101
      if (noerr)
102
        return 0;
103
      else
104
        error (_("This context has class, union or enum %s, not a struct."),
105
               name);
106
    }
107
  return sym;
108
}
109
 
110
CORE_ADDR
111
lookup_objc_class (struct gdbarch *gdbarch, char *classname)
112
{
113
  struct type *char_type = builtin_type (gdbarch)->builtin_char;
114
  struct value * function, *classval;
115
 
116
  if (! target_has_execution)
117
    {
118
      /* Can't call into inferior to lookup class.  */
119
      return 0;
120
    }
121
 
122
  if (lookup_minimal_symbol("objc_lookUpClass", 0, 0))
123
    function = find_function_in_inferior("objc_lookUpClass", NULL);
124
  else if (lookup_minimal_symbol ("objc_lookup_class", 0, 0))
125
    function = find_function_in_inferior("objc_lookup_class", NULL);
126
  else
127
    {
128
      complaint (&symfile_complaints, _("no way to lookup Objective-C classes"));
129
      return 0;
130
    }
131
 
132
  classval = value_string (classname, strlen (classname) + 1, char_type);
133
  classval = value_coerce_array (classval);
134
  return (CORE_ADDR) value_as_long (call_function_by_hand (function,
135
                                                           1, &classval));
136
}
137
 
138
CORE_ADDR
139
lookup_child_selector (struct gdbarch *gdbarch, char *selname)
140
{
141
  struct type *char_type = builtin_type (gdbarch)->builtin_char;
142
  struct value * function, *selstring;
143
 
144
  if (! target_has_execution)
145
    {
146
      /* Can't call into inferior to lookup selector.  */
147
      return 0;
148
    }
149
 
150
  if (lookup_minimal_symbol("sel_getUid", 0, 0))
151
    function = find_function_in_inferior("sel_getUid", NULL);
152
  else if (lookup_minimal_symbol ("sel_get_any_uid", 0, 0))
153
    function = find_function_in_inferior("sel_get_any_uid", NULL);
154
  else
155
    {
156
      complaint (&symfile_complaints, _("no way to lookup Objective-C selectors"));
157
      return 0;
158
    }
159
 
160
  selstring = value_coerce_array (value_string (selname,
161
                                                strlen (selname) + 1, char_type));
162
  return value_as_long (call_function_by_hand (function, 1, &selstring));
163
}
164
 
165
struct value *
166
value_nsstring (struct gdbarch *gdbarch, char *ptr, int len)
167
{
168
  struct type *char_type = builtin_type (gdbarch)->builtin_char;
169
  struct value *stringValue[3];
170
  struct value *function, *nsstringValue;
171
  struct symbol *sym;
172
  struct type *type;
173
 
174
  if (!target_has_execution)
175
    return 0;            /* Can't call into inferior to create NSString.  */
176
 
177
  stringValue[2] = value_string(ptr, len, char_type);
178
  stringValue[2] = value_coerce_array(stringValue[2]);
179
  /* _NSNewStringFromCString replaces "istr" after Lantern2A.  */
180
  if (lookup_minimal_symbol("_NSNewStringFromCString", 0, 0))
181
    {
182
      function = find_function_in_inferior("_NSNewStringFromCString", NULL);
183
      nsstringValue = call_function_by_hand(function, 1, &stringValue[2]);
184
    }
185
  else if (lookup_minimal_symbol("istr", 0, 0))
186
    {
187
      function = find_function_in_inferior("istr", NULL);
188
      nsstringValue = call_function_by_hand(function, 1, &stringValue[2]);
189
    }
190
  else if (lookup_minimal_symbol("+[NSString stringWithCString:]", 0, 0))
191
    {
192
      function
193
        = find_function_in_inferior("+[NSString stringWithCString:]", NULL);
194
      type = builtin_type (gdbarch)->builtin_long;
195
 
196
      stringValue[0] = value_from_longest
197
        (type, lookup_objc_class (gdbarch, "NSString"));
198
      stringValue[1] = value_from_longest
199
        (type, lookup_child_selector (gdbarch, "stringWithCString:"));
200
      nsstringValue = call_function_by_hand(function, 3, &stringValue[0]);
201
    }
202
  else
203
    error (_("NSString: internal error -- no way to create new NSString"));
204
 
205
  sym = lookup_struct_typedef("NSString", 0, 1);
206
  if (sym == NULL)
207
    sym = lookup_struct_typedef("NXString", 0, 1);
208
  if (sym == NULL)
209
    type = builtin_type (gdbarch)->builtin_data_ptr;
210
  else
211
    type = lookup_pointer_type(SYMBOL_TYPE (sym));
212
 
213
  deprecated_set_value_type (nsstringValue, type);
214
  return nsstringValue;
215
}
216
 
217
/* Objective-C name demangling.  */
218
 
219
char *
220
objc_demangle (const char *mangled, int options)
221
{
222
  char *demangled, *cp;
223
 
224
  if (mangled[0] == '_' &&
225
     (mangled[1] == 'i' || mangled[1] == 'c') &&
226
      mangled[2] == '_')
227
    {
228
      cp = demangled = xmalloc(strlen(mangled) + 2);
229
 
230
      if (mangled[1] == 'i')
231
        *cp++ = '-';            /* for instance method */
232
      else
233
        *cp++ = '+';            /* for class    method */
234
 
235
      *cp++ = '[';              /* opening left brace  */
236
      strcpy(cp, mangled+3);    /* tack on the rest of the mangled name */
237
 
238
      while (*cp && *cp == '_')
239
        cp++;                   /* skip any initial underbars in class name */
240
 
241
      cp = strchr(cp, '_');
242
      if (!cp)                  /* find first non-initial underbar */
243
        {
244
          xfree(demangled);     /* not mangled name */
245
          return NULL;
246
        }
247
      if (cp[1] == '_')         /* easy case: no category name     */
248
        {
249
          *cp++ = ' ';          /* replace two '_' with one ' '    */
250
          strcpy(cp, mangled + (cp - demangled) + 2);
251
        }
252
      else
253
        {
254
          *cp++ = '(';          /* less easy case: category name */
255
          cp = strchr(cp, '_');
256
          if (!cp)
257
            {
258
              xfree(demangled); /* not mangled name */
259
              return NULL;
260
            }
261
          *cp++ = ')';
262
          *cp++ = ' ';          /* overwriting 1st char of method name...  */
263
          strcpy(cp, mangled + (cp - demangled));       /* get it back */
264
        }
265
 
266
      while (*cp && *cp == '_')
267
        cp++;                   /* skip any initial underbars in method name */
268
 
269
      for (; *cp; cp++)
270
        if (*cp == '_')
271
          *cp = ':';            /* replace remaining '_' with ':' */
272
 
273
      *cp++ = ']';              /* closing right brace */
274
      *cp++ = 0;         /* string terminator */
275
      return demangled;
276
    }
277
  else
278
    return NULL;        /* Not an objc mangled name.  */
279
}
280
 
281
/* Print the character C on STREAM as part of the contents of a
282
   literal string whose delimiter is QUOTER.  Note that that format
283
   for printing characters and strings is language specific.  */
284
 
285
static void
286
objc_emit_char (int c, struct type *type, struct ui_file *stream, int quoter)
287
{
288
  c &= 0xFF;                    /* Avoid sign bit follies.  */
289
 
290
  if (PRINT_LITERAL_FORM (c))
291
    {
292
      if (c == '\\' || c == quoter)
293
        {
294
          fputs_filtered ("\\", stream);
295
        }
296
      fprintf_filtered (stream, "%c", c);
297
    }
298
  else
299
    {
300
      switch (c)
301
        {
302
        case '\n':
303
          fputs_filtered ("\\n", stream);
304
          break;
305
        case '\b':
306
          fputs_filtered ("\\b", stream);
307
          break;
308
        case '\t':
309
          fputs_filtered ("\\t", stream);
310
          break;
311
        case '\f':
312
          fputs_filtered ("\\f", stream);
313
          break;
314
        case '\r':
315
          fputs_filtered ("\\r", stream);
316
          break;
317
        case '\033':
318
          fputs_filtered ("\\e", stream);
319
          break;
320
        case '\007':
321
          fputs_filtered ("\\a", stream);
322
          break;
323
        default:
324
          fprintf_filtered (stream, "\\%.3o", (unsigned int) c);
325
          break;
326
        }
327
    }
328
}
329
 
330
static void
331
objc_printchar (int c, struct type *type, struct ui_file *stream)
332
{
333
  fputs_filtered ("'", stream);
334
  objc_emit_char (c, type, stream, '\'');
335
  fputs_filtered ("'", stream);
336
}
337
 
338
/* Print the character string STRING, printing at most LENGTH
339
   characters.  Printing stops early if the number hits print_max;
340
   repeat counts are printed as appropriate.  Print ellipses at the
341
   end if we had to stop before printing LENGTH characters, or if
342
   FORCE_ELLIPSES.  */
343
 
344
static void
345
objc_printstr (struct ui_file *stream, struct type *type,
346
               const gdb_byte *string, unsigned int length,
347
               const char *encoding, int force_ellipses,
348
               const struct value_print_options *options)
349
{
350
  unsigned int i;
351
  unsigned int things_printed = 0;
352
  int in_quotes = 0;
353
  int need_comma = 0;
354
 
355
  /* If the string was not truncated due to `set print elements', and
356
     the last byte of it is a null, we don't print that, in
357
     traditional C style.  */
358
  if ((!force_ellipses) && length > 0 && string[length-1] == '\0')
359
    length--;
360
 
361
  if (length == 0)
362
    {
363
      fputs_filtered ("\"\"", stream);
364
      return;
365
    }
366
 
367
  for (i = 0; i < length && things_printed < options->print_max; ++i)
368
    {
369
      /* Position of the character we are examining to see whether it
370
         is repeated.  */
371
      unsigned int rep1;
372
      /* Number of repetitions we have detected so far.  */
373
      unsigned int reps;
374
 
375
      QUIT;
376
 
377
      if (need_comma)
378
        {
379
          fputs_filtered (", ", stream);
380
          need_comma = 0;
381
        }
382
 
383
      rep1 = i + 1;
384
      reps = 1;
385
      while (rep1 < length && string[rep1] == string[i])
386
        {
387
          ++rep1;
388
          ++reps;
389
        }
390
 
391
      if (reps > options->repeat_count_threshold)
392
        {
393
          if (in_quotes)
394
            {
395
              if (options->inspect_it)
396
                fputs_filtered ("\\\", ", stream);
397
              else
398
                fputs_filtered ("\", ", stream);
399
              in_quotes = 0;
400
            }
401
          objc_printchar (string[i], type, stream);
402
          fprintf_filtered (stream, " <repeats %u times>", reps);
403
          i = rep1 - 1;
404
          things_printed += options->repeat_count_threshold;
405
          need_comma = 1;
406
        }
407
      else
408
        {
409
          if (!in_quotes)
410
            {
411
              if (options->inspect_it)
412
                fputs_filtered ("\\\"", stream);
413
              else
414
                fputs_filtered ("\"", stream);
415
              in_quotes = 1;
416
            }
417
          objc_emit_char (string[i], type, stream, '"');
418
          ++things_printed;
419
        }
420
    }
421
 
422
  /* Terminate the quotes if necessary.  */
423
  if (in_quotes)
424
    {
425
      if (options->inspect_it)
426
        fputs_filtered ("\\\"", stream);
427
      else
428
        fputs_filtered ("\"", stream);
429
    }
430
 
431
  if (force_ellipses || i < length)
432
    fputs_filtered ("...", stream);
433
}
434
 
435
/* Determine if we are currently in the Objective-C dispatch function.
436
   If so, get the address of the method function that the dispatcher
437
   would call and use that as the function to step into instead. Also
438
   skip over the trampoline for the function (if any).  This is better
439
   for the user since they are only interested in stepping into the
440
   method function anyway.  */
441
static CORE_ADDR
442
objc_skip_trampoline (struct frame_info *frame, CORE_ADDR stop_pc)
443
{
444
  struct gdbarch *gdbarch = get_frame_arch (frame);
445
  CORE_ADDR real_stop_pc;
446
  CORE_ADDR method_stop_pc;
447
 
448
  real_stop_pc = gdbarch_skip_trampoline_code (gdbarch, frame, stop_pc);
449
 
450
  if (real_stop_pc != 0)
451
    find_objc_msgcall (real_stop_pc, &method_stop_pc);
452
  else
453
    find_objc_msgcall (stop_pc, &method_stop_pc);
454
 
455
  if (method_stop_pc)
456
    {
457
      real_stop_pc = gdbarch_skip_trampoline_code
458
                       (gdbarch, frame, method_stop_pc);
459
      if (real_stop_pc == 0)
460
        real_stop_pc = method_stop_pc;
461
    }
462
 
463
  return real_stop_pc;
464
}
465
 
466
 
467
/* Table mapping opcodes into strings for printing operators
468
   and precedences of the operators.  */
469
 
470
static const struct op_print objc_op_print_tab[] =
471
  {
472
    {",",  BINOP_COMMA, PREC_COMMA, 0},
473
    {"=",  BINOP_ASSIGN, PREC_ASSIGN, 1},
474
    {"||", BINOP_LOGICAL_OR, PREC_LOGICAL_OR, 0},
475
    {"&&", BINOP_LOGICAL_AND, PREC_LOGICAL_AND, 0},
476
    {"|",  BINOP_BITWISE_IOR, PREC_BITWISE_IOR, 0},
477
    {"^",  BINOP_BITWISE_XOR, PREC_BITWISE_XOR, 0},
478
    {"&",  BINOP_BITWISE_AND, PREC_BITWISE_AND, 0},
479
    {"==", BINOP_EQUAL, PREC_EQUAL, 0},
480
    {"!=", BINOP_NOTEQUAL, PREC_EQUAL, 0},
481
    {"<=", BINOP_LEQ, PREC_ORDER, 0},
482
    {">=", BINOP_GEQ, PREC_ORDER, 0},
483
    {">",  BINOP_GTR, PREC_ORDER, 0},
484
    {"<",  BINOP_LESS, PREC_ORDER, 0},
485
    {">>", BINOP_RSH, PREC_SHIFT, 0},
486
    {"<<", BINOP_LSH, PREC_SHIFT, 0},
487
    {"+",  BINOP_ADD, PREC_ADD, 0},
488
    {"-",  BINOP_SUB, PREC_ADD, 0},
489
    {"*",  BINOP_MUL, PREC_MUL, 0},
490
    {"/",  BINOP_DIV, PREC_MUL, 0},
491
    {"%",  BINOP_REM, PREC_MUL, 0},
492
    {"@",  BINOP_REPEAT, PREC_REPEAT, 0},
493
    {"-",  UNOP_NEG, PREC_PREFIX, 0},
494
    {"!",  UNOP_LOGICAL_NOT, PREC_PREFIX, 0},
495
    {"~",  UNOP_COMPLEMENT, PREC_PREFIX, 0},
496
    {"*",  UNOP_IND, PREC_PREFIX, 0},
497
    {"&",  UNOP_ADDR, PREC_PREFIX, 0},
498
    {"sizeof ", UNOP_SIZEOF, PREC_PREFIX, 0},
499
    {"++", UNOP_PREINCREMENT, PREC_PREFIX, 0},
500
    {"--", UNOP_PREDECREMENT, PREC_PREFIX, 0},
501
    {NULL, OP_NULL, PREC_NULL, 0}
502
};
503
 
504
const struct language_defn objc_language_defn = {
505
  "objective-c",                /* Language name */
506
  language_objc,
507
  range_check_off,
508
  type_check_off,
509
  case_sensitive_on,
510
  array_row_major,
511
  macro_expansion_c,
512
  &exp_descriptor_standard,
513
  objc_parse,
514
  objc_error,
515
  null_post_parser,
516
  objc_printchar,               /* Print a character constant */
517
  objc_printstr,                /* Function to print string constant */
518
  objc_emit_char,
519
  c_print_type,                 /* Print a type using appropriate syntax */
520
  c_print_typedef,              /* Print a typedef using appropriate syntax */
521
  c_val_print,                  /* Print a value using appropriate syntax */
522
  c_value_print,                /* Print a top-level value */
523
  objc_skip_trampoline,         /* Language specific skip_trampoline */
524
  "self",                       /* name_of_this */
525
  basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
526
  basic_lookup_transparent_type,/* lookup_transparent_type */
527
  objc_demangle,                /* Language specific symbol demangler */
528
  NULL,                         /* Language specific class_name_from_physname */
529
  objc_op_print_tab,            /* Expression operators for printing */
530
  1,                            /* C-style arrays */
531
  0,                             /* String lower bound */
532
  default_word_break_characters,
533
  default_make_symbol_completion_list,
534
  c_language_arch_info,
535
  default_print_array_index,
536
  default_pass_by_reference,
537
  default_get_string,
538
  LANG_MAGIC
539
};
540
 
541
/*
542
 * ObjC:
543
 * Following functions help construct Objective-C message calls
544
 */
545
 
546
struct selname          /* For parsing Objective-C.  */
547
  {
548
    struct selname *next;
549
    char *msglist_sel;
550
    int msglist_len;
551
  };
552
 
553
static int msglist_len;
554
static struct selname *selname_chain;
555
static char *msglist_sel;
556
 
557
void
558
start_msglist(void)
559
{
560
  struct selname *new =
561
    (struct selname *) xmalloc (sizeof (struct selname));
562
 
563
  new->next = selname_chain;
564
  new->msglist_len = msglist_len;
565
  new->msglist_sel = msglist_sel;
566
  msglist_len = 0;
567
  msglist_sel = (char *)xmalloc(1);
568
  *msglist_sel = 0;
569
  selname_chain = new;
570
}
571
 
572
void
573
add_msglist(struct stoken *str, int addcolon)
574
{
575
  char *s, *p;
576
  int len, plen;
577
 
578
  if (str == 0)                  /* Unnamed arg, or...  */
579
    {
580
      if (addcolon == 0) /* variable number of args.  */
581
        {
582
          msglist_len++;
583
          return;
584
        }
585
      p = "";
586
      plen = 0;
587
    }
588
  else
589
    {
590
      p = str->ptr;
591
      plen = str->length;
592
    }
593
  len = plen + strlen(msglist_sel) + 2;
594
  s = (char *)xmalloc(len);
595
  strcpy(s, msglist_sel);
596
  strncat(s, p, plen);
597
  xfree(msglist_sel);
598
  msglist_sel = s;
599
  if (addcolon)
600
    {
601
      s[len-2] = ':';
602
      s[len-1] = 0;
603
      msglist_len++;
604
    }
605
  else
606
    s[len-2] = '\0';
607
}
608
 
609
int
610
end_msglist(void)
611
{
612
  int val = msglist_len;
613
  struct selname *sel = selname_chain;
614
  char *p = msglist_sel;
615
  CORE_ADDR selid;
616
 
617
  selname_chain = sel->next;
618
  msglist_len = sel->msglist_len;
619
  msglist_sel = sel->msglist_sel;
620
  selid = lookup_child_selector (parse_gdbarch, p);
621
  if (!selid)
622
    error (_("Can't find selector \"%s\""), p);
623
  write_exp_elt_longcst (selid);
624
  xfree(p);
625
  write_exp_elt_longcst (val);  /* Number of args */
626
  xfree(sel);
627
 
628
  return val;
629
}
630
 
631
/*
632
 * Function: specialcmp (char *a, char *b)
633
 *
634
 * Special strcmp: treats ']' and ' ' as end-of-string.
635
 * Used for qsorting lists of objc methods (either by class or selector).
636
 */
637
 
638
static int
639
specialcmp (char *a, char *b)
640
{
641
  while (*a && *a != ' ' && *a != ']' && *b && *b != ' ' && *b != ']')
642
    {
643
      if (*a != *b)
644
        return *a - *b;
645
      a++, b++;
646
    }
647
  if (*a && *a != ' ' && *a != ']')
648
    return  1;          /* a is longer therefore greater */
649
  if (*b && *b != ' ' && *b != ']')
650
    return -1;          /* a is shorter therefore lesser */
651
  return    0;           /* a and b are identical */
652
}
653
 
654
/*
655
 * Function: compare_selectors (const void *, const void *)
656
 *
657
 * Comparison function for use with qsort.  Arguments are symbols or
658
 * msymbols Compares selector part of objc method name alphabetically.
659
 */
660
 
661
static int
662
compare_selectors (const void *a, const void *b)
663
{
664
  char *aname, *bname;
665
 
666
  aname = SYMBOL_PRINT_NAME (*(struct symbol **) a);
667
  bname = SYMBOL_PRINT_NAME (*(struct symbol **) b);
668
  if (aname == NULL || bname == NULL)
669
    error (_("internal: compare_selectors(1)"));
670
 
671
  aname = strchr(aname, ' ');
672
  bname = strchr(bname, ' ');
673
  if (aname == NULL || bname == NULL)
674
    error (_("internal: compare_selectors(2)"));
675
 
676
  return specialcmp (aname+1, bname+1);
677
}
678
 
679
/*
680
 * Function: selectors_info (regexp, from_tty)
681
 *
682
 * Implements the "Info selectors" command.  Takes an optional regexp
683
 * arg.  Lists all objective c selectors that match the regexp.  Works
684
 * by grepping thru all symbols for objective c methods.  Output list
685
 * is sorted and uniqued.
686
 */
687
 
688
static void
689
selectors_info (char *regexp, int from_tty)
690
{
691
  struct objfile        *objfile;
692
  struct minimal_symbol *msymbol;
693
  char                  *name;
694
  char                  *val;
695
  int                    matches = 0;
696
  int                    maxlen  = 0;
697
  int                    ix;
698
  char                   myregexp[2048];
699
  char                   asel[256];
700
  struct symbol        **sym_arr;
701
  int                    plusminus = 0;
702
 
703
  if (regexp == NULL)
704
    strcpy(myregexp, ".*]");    /* Null input, match all objc methods.  */
705
  else
706
    {
707
      if (*regexp == '+' || *regexp == '-')
708
        { /* User wants only class methods or only instance methods.  */
709
          plusminus = *regexp++;
710
          while (*regexp == ' ' || *regexp == '\t')
711
            regexp++;
712
        }
713
      if (*regexp == '\0')
714
        strcpy(myregexp, ".*]");
715
      else
716
        {
717
          strcpy(myregexp, regexp);
718
          if (myregexp[strlen(myregexp) - 1] == '$') /* end of selector */
719
            myregexp[strlen(myregexp) - 1] = ']';    /* end of method name */
720
          else
721
            strcat(myregexp, ".*]");
722
        }
723
    }
724
 
725
  if (regexp != NULL)
726
    {
727
      val = re_comp (myregexp);
728
      if (val != 0)
729
        error (_("Invalid regexp (%s): %s"), val, regexp);
730
    }
731
 
732
  /* First time thru is JUST to get max length and count.  */
733
  ALL_MSYMBOLS (objfile, msymbol)
734
    {
735
      QUIT;
736
      name = SYMBOL_NATURAL_NAME (msymbol);
737
      if (name &&
738
         (name[0] == '-' || name[0] == '+') &&
739
          name[1] == '[')               /* Got a method name.  */
740
        {
741
          /* Filter for class/instance methods.  */
742
          if (plusminus && name[0] != plusminus)
743
            continue;
744
          /* Find selector part.  */
745
          name = (char *) strchr(name+2, ' ');
746
          if (regexp == NULL || re_exec(++name) != 0)
747
            {
748
              char *mystart = name;
749
              char *myend   = (char *) strchr(mystart, ']');
750
 
751
              if (myend && (myend - mystart > maxlen))
752
                maxlen = myend - mystart;       /* Get longest selector.  */
753
              matches++;
754
            }
755
        }
756
    }
757
  if (matches)
758
    {
759
      printf_filtered (_("Selectors matching \"%s\":\n\n"),
760
                       regexp ? regexp : "*");
761
 
762
      sym_arr = alloca (matches * sizeof (struct symbol *));
763
      matches = 0;
764
      ALL_MSYMBOLS (objfile, msymbol)
765
        {
766
          QUIT;
767
          name = SYMBOL_NATURAL_NAME (msymbol);
768
          if (name &&
769
             (name[0] == '-' || name[0] == '+') &&
770
              name[1] == '[')           /* Got a method name.  */
771
            {
772
              /* Filter for class/instance methods.  */
773
              if (plusminus && name[0] != plusminus)
774
                continue;
775
              /* Find selector part.  */
776
              name = (char *) strchr(name+2, ' ');
777
              if (regexp == NULL || re_exec(++name) != 0)
778
                sym_arr[matches++] = (struct symbol *) msymbol;
779
            }
780
        }
781
 
782
      qsort (sym_arr, matches, sizeof (struct minimal_symbol *),
783
             compare_selectors);
784
      /* Prevent compare on first iteration.  */
785
      asel[0] = 0;
786
      for (ix = 0; ix < matches; ix++)   /* Now do the output.  */
787
        {
788
          char *p = asel;
789
 
790
          QUIT;
791
          name = SYMBOL_NATURAL_NAME (sym_arr[ix]);
792
          name = strchr (name, ' ') + 1;
793
          if (p[0] && specialcmp(name, p) == 0)
794
            continue;           /* Seen this one already (not unique).  */
795
 
796
          /* Copy selector part.  */
797
          while (*name && *name != ']')
798
            *p++ = *name++;
799
          *p++ = '\0';
800
          /* Print in columns.  */
801
          puts_filtered_tabular(asel, maxlen + 1, 0);
802
        }
803
      begin_line();
804
    }
805
  else
806
    printf_filtered (_("No selectors matching \"%s\"\n"), regexp ? regexp : "*");
807
}
808
 
809
/*
810
 * Function: compare_classes (const void *, const void *)
811
 *
812
 * Comparison function for use with qsort.  Arguments are symbols or
813
 * msymbols Compares class part of objc method name alphabetically.
814
 */
815
 
816
static int
817
compare_classes (const void *a, const void *b)
818
{
819
  char *aname, *bname;
820
 
821
  aname = SYMBOL_PRINT_NAME (*(struct symbol **) a);
822
  bname = SYMBOL_PRINT_NAME (*(struct symbol **) b);
823
  if (aname == NULL || bname == NULL)
824
    error (_("internal: compare_classes(1)"));
825
 
826
  return specialcmp (aname+1, bname+1);
827
}
828
 
829
/*
830
 * Function: classes_info(regexp, from_tty)
831
 *
832
 * Implements the "info classes" command for objective c classes.
833
 * Lists all objective c classes that match the optional regexp.
834
 * Works by grepping thru the list of objective c methods.  List will
835
 * be sorted and uniqued (since one class may have many methods).
836
 * BUGS: will not list a class that has no methods.
837
 */
838
 
839
static void
840
classes_info (char *regexp, int from_tty)
841
{
842
  struct objfile        *objfile;
843
  struct minimal_symbol *msymbol;
844
  char                  *name;
845
  char                  *val;
846
  int                    matches = 0;
847
  int                    maxlen  = 0;
848
  int                    ix;
849
  char                   myregexp[2048];
850
  char                   aclass[256];
851
  struct symbol        **sym_arr;
852
 
853
  if (regexp == NULL)
854
    strcpy(myregexp, ".* ");    /* Null input: match all objc classes.  */
855
  else
856
    {
857
      strcpy(myregexp, regexp);
858
      if (myregexp[strlen(myregexp) - 1] == '$')
859
        /* In the method name, the end of the class name is marked by ' '.  */
860
        myregexp[strlen(myregexp) - 1] = ' ';
861
      else
862
        strcat(myregexp, ".* ");
863
    }
864
 
865
  if (regexp != NULL)
866
    {
867
      val = re_comp (myregexp);
868
      if (val != 0)
869
        error (_("Invalid regexp (%s): %s"), val, regexp);
870
    }
871
 
872
  /* First time thru is JUST to get max length and count.  */
873
  ALL_MSYMBOLS (objfile, msymbol)
874
    {
875
      QUIT;
876
      name = SYMBOL_NATURAL_NAME (msymbol);
877
      if (name &&
878
         (name[0] == '-' || name[0] == '+') &&
879
          name[1] == '[')                       /* Got a method name.  */
880
        if (regexp == NULL || re_exec(name+2) != 0)
881
          {
882
            /* Compute length of classname part.  */
883
            char *mystart = name + 2;
884
            char *myend   = (char *) strchr(mystart, ' ');
885
 
886
            if (myend && (myend - mystart > maxlen))
887
              maxlen = myend - mystart;
888
            matches++;
889
          }
890
    }
891
  if (matches)
892
    {
893
      printf_filtered (_("Classes matching \"%s\":\n\n"),
894
                       regexp ? regexp : "*");
895
      sym_arr = alloca (matches * sizeof (struct symbol *));
896
      matches = 0;
897
      ALL_MSYMBOLS (objfile, msymbol)
898
        {
899
          QUIT;
900
          name = SYMBOL_NATURAL_NAME (msymbol);
901
          if (name &&
902
             (name[0] == '-' || name[0] == '+') &&
903
              name[1] == '[')                   /* Got a method name.  */
904
            if (regexp == NULL || re_exec(name+2) != 0)
905
                sym_arr[matches++] = (struct symbol *) msymbol;
906
        }
907
 
908
      qsort (sym_arr, matches, sizeof (struct minimal_symbol *),
909
             compare_classes);
910
      /* Prevent compare on first iteration.  */
911
      aclass[0] = 0;
912
      for (ix = 0; ix < matches; ix++)   /* Now do the output.  */
913
        {
914
          char *p = aclass;
915
 
916
          QUIT;
917
          name = SYMBOL_NATURAL_NAME (sym_arr[ix]);
918
          name += 2;
919
          if (p[0] && specialcmp(name, p) == 0)
920
            continue;   /* Seen this one already (not unique).  */
921
 
922
          /* Copy class part of method name.  */
923
          while (*name && *name != ' ')
924
            *p++ = *name++;
925
          *p++ = '\0';
926
          /* Print in columns.  */
927
          puts_filtered_tabular(aclass, maxlen + 1, 0);
928
        }
929
      begin_line();
930
    }
931
  else
932
    printf_filtered (_("No classes matching \"%s\"\n"), regexp ? regexp : "*");
933
}
934
 
935
/*
936
 * Function: find_imps (char *selector, struct symbol **sym_arr)
937
 *
938
 * Input:  a string representing a selector
939
 *         a pointer to an array of symbol pointers
940
 *         possibly a pointer to a symbol found by the caller.
941
 *
942
 * Output: number of methods that implement that selector.  Side
943
 * effects: The array of symbol pointers is filled with matching syms.
944
 *
945
 * By analogy with function "find_methods" (symtab.c), builds a list
946
 * of symbols matching the ambiguous input, so that "decode_line_2"
947
 * (symtab.c) can list them and ask the user to choose one or more.
948
 * In this case the matches are objective c methods
949
 * ("implementations") matching an objective c selector.
950
 *
951
 * Note that it is possible for a normal (c-style) function to have
952
 * the same name as an objective c selector.  To prevent the selector
953
 * from eclipsing the function, we allow the caller (decode_line_1) to
954
 * search for such a function first, and if it finds one, pass it in
955
 * to us.  We will then integrate it into the list.  We also search
956
 * for one here, among the minsyms.
957
 *
958
 * NOTE: if NUM_DEBUGGABLE is non-zero, the sym_arr will be divided
959
 *       into two parts: debuggable (struct symbol) syms, and
960
 *       non_debuggable (struct minimal_symbol) syms.  The debuggable
961
 *       ones will come first, before NUM_DEBUGGABLE (which will thus
962
 *       be the index of the first non-debuggable one).
963
 */
964
 
965
/*
966
 * Function: total_number_of_imps (char *selector);
967
 *
968
 * Input:  a string representing a selector
969
 * Output: number of methods that implement that selector.
970
 *
971
 * By analogy with function "total_number_of_methods", this allows
972
 * decode_line_1 (symtab.c) to detect if there are objective c methods
973
 * matching the input, and to allocate an array of pointers to them
974
 * which can be manipulated by "decode_line_2" (also in symtab.c).
975
 */
976
 
977
char *
978
parse_selector (char *method, char **selector)
979
{
980
  char *s1 = NULL;
981
  char *s2 = NULL;
982
  int found_quote = 0;
983
 
984
  char *nselector = NULL;
985
 
986
  gdb_assert (selector != NULL);
987
 
988
  s1 = method;
989
 
990
  while (isspace (*s1))
991
    s1++;
992
  if (*s1 == '\'')
993
    {
994
      found_quote = 1;
995
      s1++;
996
    }
997
  while (isspace (*s1))
998
    s1++;
999
 
1000
  nselector = s1;
1001
  s2 = s1;
1002
 
1003
  for (;;)
1004
    {
1005
      if (isalnum (*s2) || (*s2 == '_') || (*s2 == ':'))
1006
        *s1++ = *s2;
1007
      else if (isspace (*s2))
1008
        ;
1009
      else if ((*s2 == '\0') || (*s2 == '\''))
1010
        break;
1011
      else
1012
        return NULL;
1013
      s2++;
1014
    }
1015
  *s1++ = '\0';
1016
 
1017
  while (isspace (*s2))
1018
    s2++;
1019
  if (found_quote)
1020
    {
1021
      if (*s2 == '\'')
1022
        s2++;
1023
      while (isspace (*s2))
1024
        s2++;
1025
    }
1026
 
1027
  if (selector != NULL)
1028
    *selector = nselector;
1029
 
1030
  return s2;
1031
}
1032
 
1033
char *
1034
parse_method (char *method, char *type, char **class,
1035
              char **category, char **selector)
1036
{
1037
  char *s1 = NULL;
1038
  char *s2 = NULL;
1039
  int found_quote = 0;
1040
 
1041
  char ntype = '\0';
1042
  char *nclass = NULL;
1043
  char *ncategory = NULL;
1044
  char *nselector = NULL;
1045
 
1046
  gdb_assert (type != NULL);
1047
  gdb_assert (class != NULL);
1048
  gdb_assert (category != NULL);
1049
  gdb_assert (selector != NULL);
1050
 
1051
  s1 = method;
1052
 
1053
  while (isspace (*s1))
1054
    s1++;
1055
  if (*s1 == '\'')
1056
    {
1057
      found_quote = 1;
1058
      s1++;
1059
    }
1060
  while (isspace (*s1))
1061
    s1++;
1062
 
1063
  if ((s1[0] == '+') || (s1[0] == '-'))
1064
    ntype = *s1++;
1065
 
1066
  while (isspace (*s1))
1067
    s1++;
1068
 
1069
  if (*s1 != '[')
1070
    return NULL;
1071
  s1++;
1072
 
1073
  nclass = s1;
1074
  while (isalnum (*s1) || (*s1 == '_'))
1075
    s1++;
1076
 
1077
  s2 = s1;
1078
  while (isspace (*s2))
1079
    s2++;
1080
 
1081
  if (*s2 == '(')
1082
    {
1083
      s2++;
1084
      while (isspace (*s2))
1085
        s2++;
1086
      ncategory = s2;
1087
      while (isalnum (*s2) || (*s2 == '_'))
1088
        s2++;
1089
      *s2++ = '\0';
1090
    }
1091
 
1092
  /* Truncate the class name now that we're not using the open paren.  */
1093
  *s1++ = '\0';
1094
 
1095
  nselector = s2;
1096
  s1 = s2;
1097
 
1098
  for (;;)
1099
    {
1100
      if (isalnum (*s2) || (*s2 == '_') || (*s2 == ':'))
1101
        *s1++ = *s2;
1102
      else if (isspace (*s2))
1103
        ;
1104
      else if (*s2 == ']')
1105
        break;
1106
      else
1107
        return NULL;
1108
      s2++;
1109
    }
1110
  *s1++ = '\0';
1111
  s2++;
1112
 
1113
  while (isspace (*s2))
1114
    s2++;
1115
  if (found_quote)
1116
    {
1117
      if (*s2 != '\'')
1118
        return NULL;
1119
      s2++;
1120
      while (isspace (*s2))
1121
        s2++;
1122
    }
1123
 
1124
  if (type != NULL)
1125
    *type = ntype;
1126
  if (class != NULL)
1127
    *class = nclass;
1128
  if (category != NULL)
1129
    *category = ncategory;
1130
  if (selector != NULL)
1131
    *selector = nselector;
1132
 
1133
  return s2;
1134
}
1135
 
1136
static void
1137
find_methods (struct symtab *symtab, char type,
1138
              const char *class, const char *category,
1139
              const char *selector, struct symbol **syms,
1140
              unsigned int *nsym, unsigned int *ndebug)
1141
{
1142
  struct objfile *objfile = NULL;
1143
  struct minimal_symbol *msymbol = NULL;
1144
  struct block *block = NULL;
1145
  struct symbol *sym = NULL;
1146
 
1147
  char *symname = NULL;
1148
 
1149
  char ntype = '\0';
1150
  char *nclass = NULL;
1151
  char *ncategory = NULL;
1152
  char *nselector = NULL;
1153
 
1154
  unsigned int csym = 0;
1155
  unsigned int cdebug = 0;
1156
 
1157
  static char *tmp = NULL;
1158
  static unsigned int tmplen = 0;
1159
 
1160
  gdb_assert (nsym != NULL);
1161
  gdb_assert (ndebug != NULL);
1162
 
1163
  if (symtab)
1164
    block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
1165
 
1166
  ALL_OBJFILES (objfile)
1167
    {
1168
      unsigned int *objc_csym;
1169
 
1170
      /* The objfile_csym variable counts the number of ObjC methods
1171
         that this objfile defines.  We save that count as a private
1172
         objfile data.  If we have already determined that this objfile
1173
         provides no ObjC methods, we can skip it entirely.  */
1174
 
1175
      unsigned int objfile_csym = 0;
1176
 
1177
      objc_csym = objfile_data (objfile, objc_objfile_data);
1178
      if (objc_csym != NULL && *objc_csym == 0)
1179
        /* There are no ObjC symbols in this objfile.  Skip it entirely.  */
1180
        continue;
1181
 
1182
      ALL_OBJFILE_MSYMBOLS (objfile, msymbol)
1183
        {
1184
          struct gdbarch *gdbarch = get_objfile_arch (objfile);
1185
          CORE_ADDR pc = SYMBOL_VALUE_ADDRESS (msymbol);
1186
 
1187
          QUIT;
1188
 
1189
          /* Check the symbol name first as this can be done entirely without
1190
             sending any query to the target.  */
1191
          symname = SYMBOL_NATURAL_NAME (msymbol);
1192
          if (symname == NULL)
1193
            continue;
1194
 
1195
          if ((symname[0] != '-' && symname[0] != '+') || (symname[1] != '['))
1196
            /* Not a method name.  */
1197
            continue;
1198
 
1199
          /* The minimal symbol might point to a function descriptor;
1200
             resolve it to the actual code address instead.  */
1201
          pc = gdbarch_convert_from_func_ptr_addr (gdbarch, pc,
1202
                                                   &current_target);
1203
 
1204
          if (symtab)
1205
            if (pc < BLOCK_START (block) || pc >= BLOCK_END (block))
1206
              /* Not in the specified symtab.  */
1207
              continue;
1208
 
1209
          /* Now that thinks are a bit sane, clean up the symname.  */
1210
          while ((strlen (symname) + 1) >= tmplen)
1211
            {
1212
              tmplen = (tmplen == 0) ? 1024 : tmplen * 2;
1213
              tmp = xrealloc (tmp, tmplen);
1214
            }
1215
          strcpy (tmp, symname);
1216
 
1217
          if (parse_method (tmp, &ntype, &nclass, &ncategory, &nselector) == NULL)
1218
            continue;
1219
 
1220
          objfile_csym++;
1221
 
1222
          if ((type != '\0') && (ntype != type))
1223
            continue;
1224
 
1225
          if ((class != NULL)
1226
              && ((nclass == NULL) || (strcmp (class, nclass) != 0)))
1227
            continue;
1228
 
1229
          if ((category != NULL) &&
1230
              ((ncategory == NULL) || (strcmp (category, ncategory) != 0)))
1231
            continue;
1232
 
1233
          if ((selector != NULL) &&
1234
              ((nselector == NULL) || (strcmp (selector, nselector) != 0)))
1235
            continue;
1236
 
1237
          sym = find_pc_function (pc);
1238
          if (sym != NULL)
1239
            {
1240
              const char *newsymname = SYMBOL_NATURAL_NAME (sym);
1241
 
1242
              if (strcmp (symname, newsymname) == 0)
1243
                {
1244
                  /* Found a high-level method sym: swap it into the
1245
                     lower part of sym_arr (below num_debuggable).  */
1246
                  if (syms != NULL)
1247
                    {
1248
                      syms[csym] = syms[cdebug];
1249
                      syms[cdebug] = sym;
1250
                    }
1251
                  csym++;
1252
                  cdebug++;
1253
                }
1254
              else
1255
                {
1256
                  warning (
1257
"debugging symbol \"%s\" does not match minimal symbol (\"%s\"); ignoring",
1258
                           newsymname, symname);
1259
                  if (syms != NULL)
1260
                    syms[csym] = (struct symbol *) msymbol;
1261
                  csym++;
1262
                }
1263
            }
1264
          else
1265
            {
1266
              /* Found a non-debuggable method symbol.  */
1267
              if (syms != NULL)
1268
                syms[csym] = (struct symbol *) msymbol;
1269
              csym++;
1270
            }
1271
        }
1272
      if (objc_csym == NULL)
1273
        {
1274
          objc_csym = obstack_alloc (&objfile->objfile_obstack,
1275
                                     sizeof (*objc_csym));
1276
          *objc_csym = objfile_csym;
1277
          set_objfile_data (objfile, objc_objfile_data, objc_csym);
1278
        }
1279
      else
1280
        /* Count of ObjC methods in this objfile should be constant.  */
1281
        gdb_assert (*objc_csym == objfile_csym);
1282
    }
1283
 
1284
  if (nsym != NULL)
1285
    *nsym = csym;
1286
  if (ndebug != NULL)
1287
    *ndebug = cdebug;
1288
}
1289
 
1290
char *find_imps (struct symtab *symtab, struct block *block,
1291
                 char *method, struct symbol **syms,
1292
                 unsigned int *nsym, unsigned int *ndebug)
1293
{
1294
  char type = '\0';
1295
  char *class = NULL;
1296
  char *category = NULL;
1297
  char *selector = NULL;
1298
 
1299
  unsigned int csym = 0;
1300
  unsigned int cdebug = 0;
1301
 
1302
  unsigned int ncsym = 0;
1303
  unsigned int ncdebug = 0;
1304
 
1305
  char *buf = NULL;
1306
  char *tmp = NULL;
1307
 
1308
  gdb_assert (nsym != NULL);
1309
  gdb_assert (ndebug != NULL);
1310
 
1311
  if (nsym != NULL)
1312
    *nsym = 0;
1313
  if (ndebug != NULL)
1314
    *ndebug = 0;
1315
 
1316
  buf = (char *) alloca (strlen (method) + 1);
1317
  strcpy (buf, method);
1318
  tmp = parse_method (buf, &type, &class, &category, &selector);
1319
 
1320
  if (tmp == NULL)
1321
    {
1322
      struct symbol *sym = NULL;
1323
      struct minimal_symbol *msym = NULL;
1324
 
1325
      strcpy (buf, method);
1326
      tmp = parse_selector (buf, &selector);
1327
 
1328
      if (tmp == NULL)
1329
        return NULL;
1330
 
1331
      sym = lookup_symbol (selector, block, VAR_DOMAIN, 0);
1332
      if (sym != NULL)
1333
        {
1334
          if (syms)
1335
            syms[csym] = sym;
1336
          csym++;
1337
          cdebug++;
1338
        }
1339
 
1340
      if (sym == NULL)
1341
        msym = lookup_minimal_symbol (selector, 0, 0);
1342
 
1343
      if (msym != NULL)
1344
        {
1345
          if (syms)
1346
            syms[csym] = (struct symbol *)msym;
1347
          csym++;
1348
        }
1349
    }
1350
 
1351
  if (syms != NULL)
1352
    find_methods (symtab, type, class, category, selector,
1353
                  syms + csym, &ncsym, &ncdebug);
1354
  else
1355
    find_methods (symtab, type, class, category, selector,
1356
                  NULL, &ncsym, &ncdebug);
1357
 
1358
  /* If we didn't find any methods, just return.  */
1359
  if (ncsym == 0 && ncdebug == 0)
1360
    return method;
1361
 
1362
  /* Take debug symbols from the second batch of symbols and swap them
1363
   * with debug symbols from the first batch.  Repeat until either the
1364
   * second section is out of debug symbols or the first section is
1365
   * full of debug symbols.  Either way we have all debug symbols
1366
   * packed to the beginning of the buffer.
1367
   */
1368
 
1369
  if (syms != NULL)
1370
    {
1371
      while ((cdebug < csym) && (ncdebug > 0))
1372
        {
1373
          struct symbol *s = NULL;
1374
          /* First non-debugging symbol.  */
1375
          unsigned int i = cdebug;
1376
          /* Last of second batch of debug symbols.  */
1377
          unsigned int j = csym + ncdebug - 1;
1378
 
1379
          s = syms[j];
1380
          syms[j] = syms[i];
1381
          syms[i] = s;
1382
 
1383
          /* We've moved a symbol from the second debug section to the
1384
             first one.  */
1385
          cdebug++;
1386
          ncdebug--;
1387
        }
1388
    }
1389
 
1390
  csym += ncsym;
1391
  cdebug += ncdebug;
1392
 
1393
  if (nsym != NULL)
1394
    *nsym = csym;
1395
  if (ndebug != NULL)
1396
    *ndebug = cdebug;
1397
 
1398
  if (syms == NULL)
1399
    return method + (tmp - buf);
1400
 
1401
  if (csym > 1)
1402
    {
1403
      /* Sort debuggable symbols.  */
1404
      if (cdebug > 1)
1405
        qsort (syms, cdebug, sizeof (struct minimal_symbol *),
1406
               compare_classes);
1407
 
1408
      /* Sort minimal_symbols.  */
1409
      if ((csym - cdebug) > 1)
1410
        qsort (&syms[cdebug], csym - cdebug,
1411
               sizeof (struct minimal_symbol *), compare_classes);
1412
    }
1413
  /* Terminate the sym_arr list.  */
1414
  syms[csym] = 0;
1415
 
1416
  return method + (tmp - buf);
1417
}
1418
 
1419
static void
1420
print_object_command (char *args, int from_tty)
1421
{
1422
  struct value *object, *function, *description;
1423
  CORE_ADDR string_addr, object_addr;
1424
  int i = 0;
1425
  gdb_byte c = 0;
1426
 
1427
  if (!args || !*args)
1428
    error (
1429
"The 'print-object' command requires an argument (an Objective-C object)");
1430
 
1431
  {
1432
    struct expression *expr = parse_expression (args);
1433
    struct cleanup *old_chain =
1434
      make_cleanup (free_current_contents, &expr);
1435
    int pc = 0;
1436
 
1437
    object = evaluate_subexp (builtin_type (expr->gdbarch)->builtin_data_ptr,
1438
                              expr, &pc, EVAL_NORMAL);
1439
    do_cleanups (old_chain);
1440
  }
1441
 
1442
  /* Validate the address for sanity.  */
1443
  object_addr = value_as_long (object);
1444
  read_memory (object_addr, &c, 1);
1445
 
1446
  function = find_function_in_inferior ("_NSPrintForDebugger", NULL);
1447
  if (function == NULL)
1448
    error (_("Unable to locate _NSPrintForDebugger in child process"));
1449
 
1450
  description = call_function_by_hand (function, 1, &object);
1451
 
1452
  string_addr = value_as_long (description);
1453
  if (string_addr == 0)
1454
    error (_("object returns null description"));
1455
 
1456
  read_memory (string_addr + i++, &c, 1);
1457
  if (c != 0)
1458
    do
1459
      { /* Read and print characters up to EOS.  */
1460
        QUIT;
1461
        printf_filtered ("%c", c);
1462
        read_memory (string_addr + i++, &c, 1);
1463
      } while (c != 0);
1464
  else
1465
    printf_filtered(_("<object returns empty description>"));
1466
  printf_filtered ("\n");
1467
}
1468
 
1469
/* The data structure 'methcalls' is used to detect method calls (thru
1470
 * ObjC runtime lib functions objc_msgSend, objc_msgSendSuper, etc.),
1471
 * and ultimately find the method being called.
1472
 */
1473
 
1474
struct objc_methcall {
1475
  char *name;
1476
 /* Return instance method to be called.  */
1477
  int (*stop_at) (CORE_ADDR, CORE_ADDR *);
1478
  /* Start of pc range corresponding to method invocation.  */
1479
  CORE_ADDR begin;
1480
  /* End of pc range corresponding to method invocation.  */
1481
  CORE_ADDR end;
1482
};
1483
 
1484
static int resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc);
1485
static int resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc);
1486
static int resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc);
1487
static int resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc);
1488
 
1489
static struct objc_methcall methcalls[] = {
1490
  { "_objc_msgSend", resolve_msgsend, 0, 0},
1491
  { "_objc_msgSend_stret", resolve_msgsend_stret, 0, 0},
1492
  { "_objc_msgSendSuper", resolve_msgsend_super, 0, 0},
1493
  { "_objc_msgSendSuper_stret", resolve_msgsend_super_stret, 0, 0},
1494
  { "_objc_getClass", NULL, 0, 0},
1495
  { "_objc_getMetaClass", NULL, 0, 0}
1496
};
1497
 
1498
#define nmethcalls (sizeof (methcalls) / sizeof (methcalls[0]))
1499
 
1500
/* The following function, "find_objc_msgsend", fills in the data
1501
 * structure "objc_msgs" by finding the addresses of each of the
1502
 * (currently four) functions that it holds (of which objc_msgSend is
1503
 * the first).  This must be called each time symbols are loaded, in
1504
 * case the functions have moved for some reason.
1505
 */
1506
 
1507
static void
1508
find_objc_msgsend (void)
1509
{
1510
  unsigned int i;
1511
 
1512
  for (i = 0; i < nmethcalls; i++)
1513
    {
1514
      struct minimal_symbol *func;
1515
 
1516
      /* Try both with and without underscore.  */
1517
      func = lookup_minimal_symbol (methcalls[i].name, NULL, NULL);
1518
      if ((func == NULL) && (methcalls[i].name[0] == '_'))
1519
        {
1520
          func = lookup_minimal_symbol (methcalls[i].name + 1, NULL, NULL);
1521
        }
1522
      if (func == NULL)
1523
        {
1524
          methcalls[i].begin = 0;
1525
          methcalls[i].end = 0;
1526
          continue;
1527
        }
1528
 
1529
      methcalls[i].begin = SYMBOL_VALUE_ADDRESS (func);
1530
      do {
1531
        methcalls[i].end = SYMBOL_VALUE_ADDRESS (++func);
1532
      } while (methcalls[i].begin == methcalls[i].end);
1533
    }
1534
}
1535
 
1536
/* find_objc_msgcall (replaces pc_off_limits)
1537
 *
1538
 * ALL that this function now does is to determine whether the input
1539
 * address ("pc") is the address of one of the Objective-C message
1540
 * dispatch functions (mainly objc_msgSend or objc_msgSendSuper), and
1541
 * if so, it returns the address of the method that will be called.
1542
 *
1543
 * The old function "pc_off_limits" used to do a lot of other things
1544
 * in addition, such as detecting shared library jump stubs and
1545
 * returning the address of the shlib function that would be called.
1546
 * That functionality has been moved into the gdbarch_skip_trampoline_code and
1547
 * IN_SOLIB_TRAMPOLINE macros, which are resolved in the target-
1548
 * dependent modules.
1549
 */
1550
 
1551
struct objc_submethod_helper_data {
1552
  int (*f) (CORE_ADDR, CORE_ADDR *);
1553
  CORE_ADDR pc;
1554
  CORE_ADDR *new_pc;
1555
};
1556
 
1557
static int
1558
find_objc_msgcall_submethod_helper (void * arg)
1559
{
1560
  struct objc_submethod_helper_data *s =
1561
    (struct objc_submethod_helper_data *) arg;
1562
 
1563
  if (s->f (s->pc, s->new_pc) == 0)
1564
    return 1;
1565
  else
1566
    return 0;
1567
}
1568
 
1569
static int
1570
find_objc_msgcall_submethod (int (*f) (CORE_ADDR, CORE_ADDR *),
1571
                             CORE_ADDR pc,
1572
                             CORE_ADDR *new_pc)
1573
{
1574
  struct objc_submethod_helper_data s;
1575
 
1576
  s.f = f;
1577
  s.pc = pc;
1578
  s.new_pc = new_pc;
1579
 
1580
  if (catch_errors (find_objc_msgcall_submethod_helper,
1581
                    (void *) &s,
1582
                    "Unable to determine target of Objective-C method call (ignoring):\n",
1583
                    RETURN_MASK_ALL) == 0)
1584
    return 1;
1585
  else
1586
    return 0;
1587
}
1588
 
1589
int
1590
find_objc_msgcall (CORE_ADDR pc, CORE_ADDR *new_pc)
1591
{
1592
  unsigned int i;
1593
 
1594
  find_objc_msgsend ();
1595
  if (new_pc != NULL)
1596
    {
1597
      *new_pc = 0;
1598
    }
1599
 
1600
  for (i = 0; i < nmethcalls; i++)
1601
    if ((pc >= methcalls[i].begin) && (pc < methcalls[i].end))
1602
      {
1603
        if (methcalls[i].stop_at != NULL)
1604
          return find_objc_msgcall_submethod (methcalls[i].stop_at,
1605
                                              pc, new_pc);
1606
        else
1607
          return 0;
1608
      }
1609
 
1610
  return 0;
1611
}
1612
 
1613
extern initialize_file_ftype _initialize_objc_language; /* -Wmissing-prototypes */
1614
 
1615
void
1616
_initialize_objc_language (void)
1617
{
1618
  add_language (&objc_language_defn);
1619
  add_info ("selectors", selectors_info,    /* INFO SELECTORS command.  */
1620
            _("All Objective-C selectors, or those matching REGEXP."));
1621
  add_info ("classes", classes_info,        /* INFO CLASSES   command.  */
1622
            _("All Objective-C classes, or those matching REGEXP."));
1623
  add_com ("print-object", class_vars, print_object_command,
1624
           _("Ask an Objective-C object to print itself."));
1625
  add_com_alias ("po", "print-object", class_vars, 1);
1626
}
1627
 
1628
static void
1629
read_objc_method (struct gdbarch *gdbarch, CORE_ADDR addr,
1630
                  struct objc_method *method)
1631
{
1632
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1633
 
1634
  method->name  = read_memory_unsigned_integer (addr + 0, 4, byte_order);
1635
  method->types = read_memory_unsigned_integer (addr + 4, 4, byte_order);
1636
  method->imp   = read_memory_unsigned_integer (addr + 8, 4, byte_order);
1637
}
1638
 
1639
static unsigned long
1640
read_objc_methlist_nmethods (struct gdbarch *gdbarch, CORE_ADDR addr)
1641
{
1642
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1643
 
1644
  return read_memory_unsigned_integer (addr + 4, 4, byte_order);
1645
}
1646
 
1647
static void
1648
read_objc_methlist_method (struct gdbarch *gdbarch, CORE_ADDR addr,
1649
                           unsigned long num, struct objc_method *method)
1650
{
1651
  gdb_assert (num < read_objc_methlist_nmethods (gdbarch, addr));
1652
  read_objc_method (gdbarch, addr + 8 + (12 * num), method);
1653
}
1654
 
1655
static void
1656
read_objc_object (struct gdbarch *gdbarch, CORE_ADDR addr,
1657
                  struct objc_object *object)
1658
{
1659
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1660
 
1661
  object->isa = read_memory_unsigned_integer (addr, 4, byte_order);
1662
}
1663
 
1664
static void
1665
read_objc_super (struct gdbarch *gdbarch, CORE_ADDR addr,
1666
                 struct objc_super *super)
1667
{
1668
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1669
 
1670
  super->receiver = read_memory_unsigned_integer (addr, 4, byte_order);
1671
  super->class = read_memory_unsigned_integer (addr + 4, 4, byte_order);
1672
};
1673
 
1674
static void
1675
read_objc_class (struct gdbarch *gdbarch, CORE_ADDR addr,
1676
                 struct objc_class *class)
1677
{
1678
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1679
 
1680
  class->isa = read_memory_unsigned_integer (addr, 4, byte_order);
1681
  class->super_class = read_memory_unsigned_integer (addr + 4, 4, byte_order);
1682
  class->name = read_memory_unsigned_integer (addr + 8, 4, byte_order);
1683
  class->version = read_memory_unsigned_integer (addr + 12, 4, byte_order);
1684
  class->info = read_memory_unsigned_integer (addr + 16, 4, byte_order);
1685
  class->instance_size = read_memory_unsigned_integer (addr + 18, 4, byte_order);
1686
  class->ivars = read_memory_unsigned_integer (addr + 24, 4, byte_order);
1687
  class->methods = read_memory_unsigned_integer (addr + 28, 4, byte_order);
1688
  class->cache = read_memory_unsigned_integer (addr + 32, 4, byte_order);
1689
  class->protocols = read_memory_unsigned_integer (addr + 36, 4, byte_order);
1690
}
1691
 
1692
static CORE_ADDR
1693
find_implementation_from_class (struct gdbarch *gdbarch,
1694
                                CORE_ADDR class, CORE_ADDR sel)
1695
{
1696
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1697
  CORE_ADDR subclass = class;
1698
 
1699
  while (subclass != 0)
1700
    {
1701
 
1702
      struct objc_class class_str;
1703
      unsigned mlistnum = 0;
1704
 
1705
      read_objc_class (gdbarch, subclass, &class_str);
1706
 
1707
      for (;;)
1708
        {
1709
          CORE_ADDR mlist;
1710
          unsigned long nmethods;
1711
          unsigned long i;
1712
 
1713
          mlist = read_memory_unsigned_integer (class_str.methods +
1714
                                                (4 * mlistnum),
1715
                                                4, byte_order);
1716
          if (mlist == 0)
1717
            break;
1718
 
1719
          nmethods = read_objc_methlist_nmethods (gdbarch, mlist);
1720
 
1721
          for (i = 0; i < nmethods; i++)
1722
            {
1723
              struct objc_method meth_str;
1724
 
1725
              read_objc_methlist_method (gdbarch, mlist, i, &meth_str);
1726
#if 0
1727
              fprintf (stderr,
1728
                       "checking method 0x%lx against selector 0x%lx\n",
1729
                       meth_str.name, sel);
1730
#endif
1731
 
1732
              if (meth_str.name == sel)
1733
                /* FIXME: hppa arch was doing a pointer dereference
1734
                   here. There needs to be a better way to do that.  */
1735
                return meth_str.imp;
1736
            }
1737
          mlistnum++;
1738
        }
1739
      subclass = class_str.super_class;
1740
    }
1741
 
1742
  return 0;
1743
}
1744
 
1745
static CORE_ADDR
1746
find_implementation (struct gdbarch *gdbarch,
1747
                     CORE_ADDR object, CORE_ADDR sel)
1748
{
1749
  struct objc_object ostr;
1750
 
1751
  if (object == 0)
1752
    return 0;
1753
  read_objc_object (gdbarch, object, &ostr);
1754
  if (ostr.isa == 0)
1755
    return 0;
1756
 
1757
  return find_implementation_from_class (gdbarch, ostr.isa, sel);
1758
}
1759
 
1760
static int
1761
resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc)
1762
{
1763
  struct frame_info *frame = get_current_frame ();
1764
  struct gdbarch *gdbarch = get_frame_arch (frame);
1765
  struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1766
 
1767
  CORE_ADDR object;
1768
  CORE_ADDR sel;
1769
  CORE_ADDR res;
1770
 
1771
  object = gdbarch_fetch_pointer_argument (gdbarch, frame, 0, ptr_type);
1772
  sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1773
 
1774
  res = find_implementation (gdbarch, object, sel);
1775
  if (new_pc != 0)
1776
    *new_pc = res;
1777
  if (res == 0)
1778
    return 1;
1779
  return 0;
1780
}
1781
 
1782
static int
1783
resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
1784
{
1785
  struct frame_info *frame = get_current_frame ();
1786
  struct gdbarch *gdbarch = get_frame_arch (frame);
1787
  struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1788
 
1789
  CORE_ADDR object;
1790
  CORE_ADDR sel;
1791
  CORE_ADDR res;
1792
 
1793
  object = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1794
  sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 2, ptr_type);
1795
 
1796
  res = find_implementation (gdbarch, object, sel);
1797
  if (new_pc != 0)
1798
    *new_pc = res;
1799
  if (res == 0)
1800
    return 1;
1801
  return 0;
1802
}
1803
 
1804
static int
1805
resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc)
1806
{
1807
  struct frame_info *frame = get_current_frame ();
1808
  struct gdbarch *gdbarch = get_frame_arch (frame);
1809
  struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1810
 
1811
  struct objc_super sstr;
1812
 
1813
  CORE_ADDR super;
1814
  CORE_ADDR sel;
1815
  CORE_ADDR res;
1816
 
1817
  super = gdbarch_fetch_pointer_argument (gdbarch, frame, 0, ptr_type);
1818
  sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1819
 
1820
  read_objc_super (gdbarch, super, &sstr);
1821
  if (sstr.class == 0)
1822
    return 0;
1823
 
1824
  res = find_implementation_from_class (gdbarch, sstr.class, sel);
1825
  if (new_pc != 0)
1826
    *new_pc = res;
1827
  if (res == 0)
1828
    return 1;
1829
  return 0;
1830
}
1831
 
1832
static int
1833
resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
1834
{
1835
  struct frame_info *frame = get_current_frame ();
1836
  struct gdbarch *gdbarch = get_frame_arch (frame);
1837
  struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1838
 
1839
  struct objc_super sstr;
1840
 
1841
  CORE_ADDR super;
1842
  CORE_ADDR sel;
1843
  CORE_ADDR res;
1844
 
1845
  super = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1846
  sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 2, ptr_type);
1847
 
1848
  read_objc_super (gdbarch, super, &sstr);
1849
  if (sstr.class == 0)
1850
    return 0;
1851
 
1852
  res = find_implementation_from_class (gdbarch, sstr.class, sel);
1853
  if (new_pc != 0)
1854
    *new_pc = res;
1855
  if (res == 0)
1856
    return 1;
1857
  return 0;
1858
}
1859
 
1860
void
1861
_initialize_objc_lang (void)
1862
{
1863
  objc_objfile_data = register_objfile_data ();
1864
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.