OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.1/] [gdb/] [objc-lang.c] - Blame information for rev 252

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

Line No. Rev Author Line
1 227 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
        *cp++ = ' ';            /* replace two '_' with one ' '    */
249
        strcpy(cp, mangled + (cp - demangled) + 2);
250
      }
251
      else {
252
        *cp++ = '(';            /* less easy case: category name */
253
        cp = strchr(cp, '_');
254
        if (!cp)
255
          {
256
            xfree(demangled);   /* not mangled name */
257
            return NULL;
258
          }
259
        *cp++ = ')';
260
        *cp++ = ' ';            /* overwriting 1st char of method name...  */
261
        strcpy(cp, mangled + (cp - demangled)); /* get it back */
262
      }
263
 
264
      while (*cp && *cp == '_')
265
        cp++;                   /* skip any initial underbars in method name */
266
 
267
      for (; *cp; cp++)
268
        if (*cp == '_')
269
          *cp = ':';            /* replace remaining '_' with ':' */
270
 
271
      *cp++ = ']';              /* closing right brace */
272
      *cp++ = 0;         /* string terminator */
273
      return demangled;
274
    }
275
  else
276
    return NULL;        /* Not an objc mangled name.  */
277
}
278
 
279
/* Print the character C on STREAM as part of the contents of a
280
   literal string whose delimiter is QUOTER.  Note that that format
281
   for printing characters and strings is language specific.  */
282
 
283
static void
284
objc_emit_char (int c, struct type *type, struct ui_file *stream, int quoter)
285
{
286
 
287
  c &= 0xFF;                    /* Avoid sign bit follies.  */
288
 
289
  if (PRINT_LITERAL_FORM (c))
290
    {
291
      if (c == '\\' || c == quoter)
292
        {
293
          fputs_filtered ("\\", stream);
294
        }
295
      fprintf_filtered (stream, "%c", c);
296
    }
297
  else
298
    {
299
      switch (c)
300
        {
301
        case '\n':
302
          fputs_filtered ("\\n", stream);
303
          break;
304
        case '\b':
305
          fputs_filtered ("\\b", stream);
306
          break;
307
        case '\t':
308
          fputs_filtered ("\\t", stream);
309
          break;
310
        case '\f':
311
          fputs_filtered ("\\f", stream);
312
          break;
313
        case '\r':
314
          fputs_filtered ("\\r", stream);
315
          break;
316
        case '\033':
317
          fputs_filtered ("\\e", stream);
318
          break;
319
        case '\007':
320
          fputs_filtered ("\\a", stream);
321
          break;
322
        default:
323
          fprintf_filtered (stream, "\\%.3o", (unsigned int) c);
324
          break;
325
        }
326
    }
327
}
328
 
329
static void
330
objc_printchar (int c, struct type *type, struct ui_file *stream)
331
{
332
  fputs_filtered ("'", stream);
333
  objc_emit_char (c, type, stream, '\'');
334
  fputs_filtered ("'", stream);
335
}
336
 
337
/* Print the character string STRING, printing at most LENGTH
338
   characters.  Printing stops early if the number hits print_max;
339
   repeat counts are printed as appropriate.  Print ellipses at the
340
   end if we had to stop before printing LENGTH characters, or if
341
   FORCE_ELLIPSES.  */
342
 
343
static void
344
objc_printstr (struct ui_file *stream, struct type *type,
345
               const gdb_byte *string, unsigned int length,
346
               const char *encoding, int force_ellipses,
347
               const struct value_print_options *options)
348
{
349
  unsigned int i;
350
  unsigned int things_printed = 0;
351
  int in_quotes = 0;
352
  int need_comma = 0;
353
  int width = TYPE_LENGTH (type);
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
    if (addcolon == 0) { /* variable number of args.  */
580
      msglist_len++;
581
      return;
582
    }
583
    p = "";
584
    plen = 0;
585
  } else {
586
    p = str->ptr;
587
    plen = str->length;
588
  }
589
  len = plen + strlen(msglist_sel) + 2;
590
  s = (char *)xmalloc(len);
591
  strcpy(s, msglist_sel);
592
  strncat(s, p, plen);
593
  xfree(msglist_sel);
594
  msglist_sel = s;
595
  if (addcolon) {
596
    s[len-2] = ':';
597
    s[len-1] = 0;
598
    msglist_len++;
599
  } else
600
    s[len-2] = '\0';
601
}
602
 
603
int
604
end_msglist(void)
605
{
606
  int val = msglist_len;
607
  struct selname *sel = selname_chain;
608
  char *p = msglist_sel;
609
  CORE_ADDR selid;
610
 
611
  selname_chain = sel->next;
612
  msglist_len = sel->msglist_len;
613
  msglist_sel = sel->msglist_sel;
614
  selid = lookup_child_selector (parse_gdbarch, p);
615
  if (!selid)
616
    error (_("Can't find selector \"%s\""), p);
617
  write_exp_elt_longcst (selid);
618
  xfree(p);
619
  write_exp_elt_longcst (val);  /* Number of args */
620
  xfree(sel);
621
 
622
  return val;
623
}
624
 
625
/*
626
 * Function: specialcmp (char *a, char *b)
627
 *
628
 * Special strcmp: treats ']' and ' ' as end-of-string.
629
 * Used for qsorting lists of objc methods (either by class or selector).
630
 */
631
 
632
static int
633
specialcmp (char *a, char *b)
634
{
635
  while (*a && *a != ' ' && *a != ']' && *b && *b != ' ' && *b != ']')
636
    {
637
      if (*a != *b)
638
        return *a - *b;
639
      a++, b++;
640
    }
641
  if (*a && *a != ' ' && *a != ']')
642
    return  1;          /* a is longer therefore greater */
643
  if (*b && *b != ' ' && *b != ']')
644
    return -1;          /* a is shorter therefore lesser */
645
  return    0;           /* a and b are identical */
646
}
647
 
648
/*
649
 * Function: compare_selectors (const void *, const void *)
650
 *
651
 * Comparison function for use with qsort.  Arguments are symbols or
652
 * msymbols Compares selector part of objc method name alphabetically.
653
 */
654
 
655
static int
656
compare_selectors (const void *a, const void *b)
657
{
658
  char *aname, *bname;
659
 
660
  aname = SYMBOL_PRINT_NAME (*(struct symbol **) a);
661
  bname = SYMBOL_PRINT_NAME (*(struct symbol **) b);
662
  if (aname == NULL || bname == NULL)
663
    error (_("internal: compare_selectors(1)"));
664
 
665
  aname = strchr(aname, ' ');
666
  bname = strchr(bname, ' ');
667
  if (aname == NULL || bname == NULL)
668
    error (_("internal: compare_selectors(2)"));
669
 
670
  return specialcmp (aname+1, bname+1);
671
}
672
 
673
/*
674
 * Function: selectors_info (regexp, from_tty)
675
 *
676
 * Implements the "Info selectors" command.  Takes an optional regexp
677
 * arg.  Lists all objective c selectors that match the regexp.  Works
678
 * by grepping thru all symbols for objective c methods.  Output list
679
 * is sorted and uniqued.
680
 */
681
 
682
static void
683
selectors_info (char *regexp, int from_tty)
684
{
685
  struct objfile        *objfile;
686
  struct minimal_symbol *msymbol;
687
  char                  *name;
688
  char                  *val;
689
  int                    matches = 0;
690
  int                    maxlen  = 0;
691
  int                    ix;
692
  char                   myregexp[2048];
693
  char                   asel[256];
694
  struct symbol        **sym_arr;
695
  int                    plusminus = 0;
696
 
697
  if (regexp == NULL)
698
    strcpy(myregexp, ".*]");    /* Null input, match all objc methods.  */
699
  else
700
    {
701
      if (*regexp == '+' || *regexp == '-')
702
        { /* User wants only class methods or only instance methods.  */
703
          plusminus = *regexp++;
704
          while (*regexp == ' ' || *regexp == '\t')
705
            regexp++;
706
        }
707
      if (*regexp == '\0')
708
        strcpy(myregexp, ".*]");
709
      else
710
        {
711
          strcpy(myregexp, regexp);
712
          if (myregexp[strlen(myregexp) - 1] == '$') /* end of selector */
713
            myregexp[strlen(myregexp) - 1] = ']';    /* end of method name */
714
          else
715
            strcat(myregexp, ".*]");
716
        }
717
    }
718
 
719
  if (regexp != NULL)
720
    {
721
      val = re_comp (myregexp);
722
      if (val != 0)
723
        error (_("Invalid regexp (%s): %s"), val, regexp);
724
    }
725
 
726
  /* First time thru is JUST to get max length and count.  */
727
  ALL_MSYMBOLS (objfile, msymbol)
728
    {
729
      QUIT;
730
      name = SYMBOL_NATURAL_NAME (msymbol);
731
      if (name &&
732
         (name[0] == '-' || name[0] == '+') &&
733
          name[1] == '[')               /* Got a method name.  */
734
        {
735
          /* Filter for class/instance methods.  */
736
          if (plusminus && name[0] != plusminus)
737
            continue;
738
          /* Find selector part.  */
739
          name = (char *) strchr(name+2, ' ');
740
          if (regexp == NULL || re_exec(++name) != 0)
741
            {
742
              char *mystart = name;
743
              char *myend   = (char *) strchr(mystart, ']');
744
 
745
              if (myend && (myend - mystart > maxlen))
746
                maxlen = myend - mystart;       /* Get longest selector.  */
747
              matches++;
748
            }
749
        }
750
    }
751
  if (matches)
752
    {
753
      printf_filtered (_("Selectors matching \"%s\":\n\n"),
754
                       regexp ? regexp : "*");
755
 
756
      sym_arr = alloca (matches * sizeof (struct symbol *));
757
      matches = 0;
758
      ALL_MSYMBOLS (objfile, msymbol)
759
        {
760
          QUIT;
761
          name = SYMBOL_NATURAL_NAME (msymbol);
762
          if (name &&
763
             (name[0] == '-' || name[0] == '+') &&
764
              name[1] == '[')           /* Got a method name.  */
765
            {
766
              /* Filter for class/instance methods.  */
767
              if (plusminus && name[0] != plusminus)
768
                continue;
769
              /* Find selector part.  */
770
              name = (char *) strchr(name+2, ' ');
771
              if (regexp == NULL || re_exec(++name) != 0)
772
                sym_arr[matches++] = (struct symbol *) msymbol;
773
            }
774
        }
775
 
776
      qsort (sym_arr, matches, sizeof (struct minimal_symbol *),
777
             compare_selectors);
778
      /* Prevent compare on first iteration.  */
779
      asel[0] = 0;
780
      for (ix = 0; ix < matches; ix++)   /* Now do the output.  */
781
        {
782
          char *p = asel;
783
 
784
          QUIT;
785
          name = SYMBOL_NATURAL_NAME (sym_arr[ix]);
786
          name = strchr (name, ' ') + 1;
787
          if (p[0] && specialcmp(name, p) == 0)
788
            continue;           /* Seen this one already (not unique).  */
789
 
790
          /* Copy selector part.  */
791
          while (*name && *name != ']')
792
            *p++ = *name++;
793
          *p++ = '\0';
794
          /* Print in columns.  */
795
          puts_filtered_tabular(asel, maxlen + 1, 0);
796
        }
797
      begin_line();
798
    }
799
  else
800
    printf_filtered (_("No selectors matching \"%s\"\n"), regexp ? regexp : "*");
801
}
802
 
803
/*
804
 * Function: compare_classes (const void *, const void *)
805
 *
806
 * Comparison function for use with qsort.  Arguments are symbols or
807
 * msymbols Compares class part of objc method name alphabetically.
808
 */
809
 
810
static int
811
compare_classes (const void *a, const void *b)
812
{
813
  char *aname, *bname;
814
 
815
  aname = SYMBOL_PRINT_NAME (*(struct symbol **) a);
816
  bname = SYMBOL_PRINT_NAME (*(struct symbol **) b);
817
  if (aname == NULL || bname == NULL)
818
    error (_("internal: compare_classes(1)"));
819
 
820
  return specialcmp (aname+1, bname+1);
821
}
822
 
823
/*
824
 * Function: classes_info(regexp, from_tty)
825
 *
826
 * Implements the "info classes" command for objective c classes.
827
 * Lists all objective c classes that match the optional regexp.
828
 * Works by grepping thru the list of objective c methods.  List will
829
 * be sorted and uniqued (since one class may have many methods).
830
 * BUGS: will not list a class that has no methods.
831
 */
832
 
833
static void
834
classes_info (char *regexp, int from_tty)
835
{
836
  struct objfile        *objfile;
837
  struct minimal_symbol *msymbol;
838
  char                  *name;
839
  char                  *val;
840
  int                    matches = 0;
841
  int                    maxlen  = 0;
842
  int                    ix;
843
  char                   myregexp[2048];
844
  char                   aclass[256];
845
  struct symbol        **sym_arr;
846
 
847
  if (regexp == NULL)
848
    strcpy(myregexp, ".* ");    /* Null input: match all objc classes.  */
849
  else
850
    {
851
      strcpy(myregexp, regexp);
852
      if (myregexp[strlen(myregexp) - 1] == '$')
853
        /* In the method name, the end of the class name is marked by ' '.  */
854
        myregexp[strlen(myregexp) - 1] = ' ';
855
      else
856
        strcat(myregexp, ".* ");
857
    }
858
 
859
  if (regexp != NULL)
860
    {
861
      val = re_comp (myregexp);
862
      if (val != 0)
863
        error (_("Invalid regexp (%s): %s"), val, regexp);
864
    }
865
 
866
  /* First time thru is JUST to get max length and count.  */
867
  ALL_MSYMBOLS (objfile, msymbol)
868
    {
869
      QUIT;
870
      name = SYMBOL_NATURAL_NAME (msymbol);
871
      if (name &&
872
         (name[0] == '-' || name[0] == '+') &&
873
          name[1] == '[')                       /* Got a method name.  */
874
        if (regexp == NULL || re_exec(name+2) != 0)
875
          {
876
            /* Compute length of classname part.  */
877
            char *mystart = name + 2;
878
            char *myend   = (char *) strchr(mystart, ' ');
879
 
880
            if (myend && (myend - mystart > maxlen))
881
              maxlen = myend - mystart;
882
            matches++;
883
          }
884
    }
885
  if (matches)
886
    {
887
      printf_filtered (_("Classes matching \"%s\":\n\n"),
888
                       regexp ? regexp : "*");
889
      sym_arr = alloca (matches * sizeof (struct symbol *));
890
      matches = 0;
891
      ALL_MSYMBOLS (objfile, msymbol)
892
        {
893
          QUIT;
894
          name = SYMBOL_NATURAL_NAME (msymbol);
895
          if (name &&
896
             (name[0] == '-' || name[0] == '+') &&
897
              name[1] == '[')                   /* Got a method name.  */
898
            if (regexp == NULL || re_exec(name+2) != 0)
899
                sym_arr[matches++] = (struct symbol *) msymbol;
900
        }
901
 
902
      qsort (sym_arr, matches, sizeof (struct minimal_symbol *),
903
             compare_classes);
904
      /* Prevent compare on first iteration.  */
905
      aclass[0] = 0;
906
      for (ix = 0; ix < matches; ix++)   /* Now do the output.  */
907
        {
908
          char *p = aclass;
909
 
910
          QUIT;
911
          name = SYMBOL_NATURAL_NAME (sym_arr[ix]);
912
          name += 2;
913
          if (p[0] && specialcmp(name, p) == 0)
914
            continue;   /* Seen this one already (not unique).  */
915
 
916
          /* Copy class part of method name.  */
917
          while (*name && *name != ' ')
918
            *p++ = *name++;
919
          *p++ = '\0';
920
          /* Print in columns.  */
921
          puts_filtered_tabular(aclass, maxlen + 1, 0);
922
        }
923
      begin_line();
924
    }
925
  else
926
    printf_filtered (_("No classes matching \"%s\"\n"), regexp ? regexp : "*");
927
}
928
 
929
/*
930
 * Function: find_imps (char *selector, struct symbol **sym_arr)
931
 *
932
 * Input:  a string representing a selector
933
 *         a pointer to an array of symbol pointers
934
 *         possibly a pointer to a symbol found by the caller.
935
 *
936
 * Output: number of methods that implement that selector.  Side
937
 * effects: The array of symbol pointers is filled with matching syms.
938
 *
939
 * By analogy with function "find_methods" (symtab.c), builds a list
940
 * of symbols matching the ambiguous input, so that "decode_line_2"
941
 * (symtab.c) can list them and ask the user to choose one or more.
942
 * In this case the matches are objective c methods
943
 * ("implementations") matching an objective c selector.
944
 *
945
 * Note that it is possible for a normal (c-style) function to have
946
 * the same name as an objective c selector.  To prevent the selector
947
 * from eclipsing the function, we allow the caller (decode_line_1) to
948
 * search for such a function first, and if it finds one, pass it in
949
 * to us.  We will then integrate it into the list.  We also search
950
 * for one here, among the minsyms.
951
 *
952
 * NOTE: if NUM_DEBUGGABLE is non-zero, the sym_arr will be divided
953
 *       into two parts: debuggable (struct symbol) syms, and
954
 *       non_debuggable (struct minimal_symbol) syms.  The debuggable
955
 *       ones will come first, before NUM_DEBUGGABLE (which will thus
956
 *       be the index of the first non-debuggable one).
957
 */
958
 
959
/*
960
 * Function: total_number_of_imps (char *selector);
961
 *
962
 * Input:  a string representing a selector
963
 * Output: number of methods that implement that selector.
964
 *
965
 * By analogy with function "total_number_of_methods", this allows
966
 * decode_line_1 (symtab.c) to detect if there are objective c methods
967
 * matching the input, and to allocate an array of pointers to them
968
 * which can be manipulated by "decode_line_2" (also in symtab.c).
969
 */
970
 
971
char *
972
parse_selector (char *method, char **selector)
973
{
974
  char *s1 = NULL;
975
  char *s2 = NULL;
976
  int found_quote = 0;
977
 
978
  char *nselector = NULL;
979
 
980
  gdb_assert (selector != NULL);
981
 
982
  s1 = method;
983
 
984
  while (isspace (*s1))
985
    s1++;
986
  if (*s1 == '\'')
987
    {
988
      found_quote = 1;
989
      s1++;
990
    }
991
  while (isspace (*s1))
992
    s1++;
993
 
994
  nselector = s1;
995
  s2 = s1;
996
 
997
  for (;;) {
998
    if (isalnum (*s2) || (*s2 == '_') || (*s2 == ':'))
999
      *s1++ = *s2;
1000
    else if (isspace (*s2))
1001
      ;
1002
    else if ((*s2 == '\0') || (*s2 == '\''))
1003
      break;
1004
    else
1005
      return NULL;
1006
    s2++;
1007
  }
1008
  *s1++ = '\0';
1009
 
1010
  while (isspace (*s2))
1011
    s2++;
1012
  if (found_quote)
1013
    {
1014
      if (*s2 == '\'')
1015
        s2++;
1016
      while (isspace (*s2))
1017
        s2++;
1018
    }
1019
 
1020
  if (selector != NULL)
1021
    *selector = nselector;
1022
 
1023
  return s2;
1024
}
1025
 
1026
char *
1027
parse_method (char *method, char *type, char **class,
1028
              char **category, char **selector)
1029
{
1030
  char *s1 = NULL;
1031
  char *s2 = NULL;
1032
  int found_quote = 0;
1033
 
1034
  char ntype = '\0';
1035
  char *nclass = NULL;
1036
  char *ncategory = NULL;
1037
  char *nselector = NULL;
1038
 
1039
  gdb_assert (type != NULL);
1040
  gdb_assert (class != NULL);
1041
  gdb_assert (category != NULL);
1042
  gdb_assert (selector != NULL);
1043
 
1044
  s1 = method;
1045
 
1046
  while (isspace (*s1))
1047
    s1++;
1048
  if (*s1 == '\'')
1049
    {
1050
      found_quote = 1;
1051
      s1++;
1052
    }
1053
  while (isspace (*s1))
1054
    s1++;
1055
 
1056
  if ((s1[0] == '+') || (s1[0] == '-'))
1057
    ntype = *s1++;
1058
 
1059
  while (isspace (*s1))
1060
    s1++;
1061
 
1062
  if (*s1 != '[')
1063
    return NULL;
1064
  s1++;
1065
 
1066
  nclass = s1;
1067
  while (isalnum (*s1) || (*s1 == '_'))
1068
    s1++;
1069
 
1070
  s2 = s1;
1071
  while (isspace (*s2))
1072
    s2++;
1073
 
1074
  if (*s2 == '(')
1075
    {
1076
      s2++;
1077
      while (isspace (*s2))
1078
        s2++;
1079
      ncategory = s2;
1080
      while (isalnum (*s2) || (*s2 == '_'))
1081
        s2++;
1082
      *s2++ = '\0';
1083
    }
1084
 
1085
  /* Truncate the class name now that we're not using the open paren.  */
1086
  *s1++ = '\0';
1087
 
1088
  nselector = s2;
1089
  s1 = s2;
1090
 
1091
  for (;;) {
1092
    if (isalnum (*s2) || (*s2 == '_') || (*s2 == ':'))
1093
      *s1++ = *s2;
1094
    else if (isspace (*s2))
1095
      ;
1096
    else if (*s2 == ']')
1097
      break;
1098
    else
1099
      return NULL;
1100
    s2++;
1101
  }
1102
  *s1++ = '\0';
1103
  s2++;
1104
 
1105
  while (isspace (*s2))
1106
    s2++;
1107
  if (found_quote)
1108
    {
1109
      if (*s2 != '\'')
1110
        return NULL;
1111
      s2++;
1112
      while (isspace (*s2))
1113
        s2++;
1114
    }
1115
 
1116
  if (type != NULL)
1117
    *type = ntype;
1118
  if (class != NULL)
1119
    *class = nclass;
1120
  if (category != NULL)
1121
    *category = ncategory;
1122
  if (selector != NULL)
1123
    *selector = nselector;
1124
 
1125
  return s2;
1126
}
1127
 
1128
static void
1129
find_methods (struct symtab *symtab, char type,
1130
              const char *class, const char *category,
1131
              const char *selector, struct symbol **syms,
1132
              unsigned int *nsym, unsigned int *ndebug)
1133
{
1134
  struct objfile *objfile = NULL;
1135
  struct minimal_symbol *msymbol = NULL;
1136
  struct block *block = NULL;
1137
  struct symbol *sym = NULL;
1138
 
1139
  char *symname = NULL;
1140
 
1141
  char ntype = '\0';
1142
  char *nclass = NULL;
1143
  char *ncategory = NULL;
1144
  char *nselector = NULL;
1145
 
1146
  unsigned int csym = 0;
1147
  unsigned int cdebug = 0;
1148
 
1149
  static char *tmp = NULL;
1150
  static unsigned int tmplen = 0;
1151
 
1152
  gdb_assert (nsym != NULL);
1153
  gdb_assert (ndebug != NULL);
1154
 
1155
  if (symtab)
1156
    block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (symtab), STATIC_BLOCK);
1157
 
1158
  ALL_OBJFILES (objfile)
1159
    {
1160
      unsigned int *objc_csym;
1161
 
1162
      /* The objfile_csym variable counts the number of ObjC methods
1163
         that this objfile defines.  We save that count as a private
1164
         objfile data.  If we have already determined that this objfile
1165
         provides no ObjC methods, we can skip it entirely.  */
1166
 
1167
      unsigned int objfile_csym = 0;
1168
 
1169
      objc_csym = objfile_data (objfile, objc_objfile_data);
1170
      if (objc_csym != NULL && *objc_csym == 0)
1171
        /* There are no ObjC symbols in this objfile.  Skip it entirely.  */
1172
        continue;
1173
 
1174
      ALL_OBJFILE_MSYMBOLS (objfile, msymbol)
1175
        {
1176
          struct gdbarch *gdbarch = get_objfile_arch (objfile);
1177
          CORE_ADDR pc = SYMBOL_VALUE_ADDRESS (msymbol);
1178
 
1179
          QUIT;
1180
 
1181
          /* The minimal symbol might point to a function descriptor;
1182
             resolve it to the actual code address instead.  */
1183
          pc = gdbarch_convert_from_func_ptr_addr (gdbarch, pc,
1184
                                                   &current_target);
1185
 
1186
          if (symtab)
1187
            if (pc < BLOCK_START (block) || pc >= BLOCK_END (block))
1188
              /* Not in the specified symtab.  */
1189
              continue;
1190
 
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
          while ((strlen (symname) + 1) >= tmplen)
1200
            {
1201
              tmplen = (tmplen == 0) ? 1024 : tmplen * 2;
1202
              tmp = xrealloc (tmp, tmplen);
1203
            }
1204
          strcpy (tmp, symname);
1205
 
1206
          if (parse_method (tmp, &ntype, &nclass, &ncategory, &nselector) == NULL)
1207
            continue;
1208
 
1209
          objfile_csym++;
1210
 
1211
          if ((type != '\0') && (ntype != type))
1212
            continue;
1213
 
1214
          if ((class != NULL)
1215
              && ((nclass == NULL) || (strcmp (class, nclass) != 0)))
1216
            continue;
1217
 
1218
          if ((category != NULL) &&
1219
              ((ncategory == NULL) || (strcmp (category, ncategory) != 0)))
1220
            continue;
1221
 
1222
          if ((selector != NULL) &&
1223
              ((nselector == NULL) || (strcmp (selector, nselector) != 0)))
1224
            continue;
1225
 
1226
          sym = find_pc_function (pc);
1227
          if (sym != NULL)
1228
            {
1229
              const char *newsymname = SYMBOL_NATURAL_NAME (sym);
1230
 
1231
              if (strcmp (symname, newsymname) == 0)
1232
                {
1233
                  /* Found a high-level method sym: swap it into the
1234
                     lower part of sym_arr (below num_debuggable).  */
1235
                  if (syms != NULL)
1236
                    {
1237
                      syms[csym] = syms[cdebug];
1238
                      syms[cdebug] = sym;
1239
                    }
1240
                  csym++;
1241
                  cdebug++;
1242
                }
1243
              else
1244
                {
1245
                  warning (
1246
"debugging symbol \"%s\" does not match minimal symbol (\"%s\"); ignoring",
1247
                           newsymname, symname);
1248
                  if (syms != NULL)
1249
                    syms[csym] = (struct symbol *) msymbol;
1250
                  csym++;
1251
                }
1252
            }
1253
          else
1254
            {
1255
              /* Found a non-debuggable method symbol.  */
1256
              if (syms != NULL)
1257
                syms[csym] = (struct symbol *) msymbol;
1258
              csym++;
1259
            }
1260
        }
1261
      if (objc_csym == NULL)
1262
        {
1263
          objc_csym = obstack_alloc (&objfile->objfile_obstack,
1264
                                     sizeof (*objc_csym));
1265
          *objc_csym = objfile_csym;
1266
          set_objfile_data (objfile, objc_objfile_data, objc_csym);
1267
        }
1268
      else
1269
        /* Count of ObjC methods in this objfile should be constant.  */
1270
        gdb_assert (*objc_csym == objfile_csym);
1271
    }
1272
 
1273
  if (nsym != NULL)
1274
    *nsym = csym;
1275
  if (ndebug != NULL)
1276
    *ndebug = cdebug;
1277
}
1278
 
1279
char *find_imps (struct symtab *symtab, struct block *block,
1280
                 char *method, struct symbol **syms,
1281
                 unsigned int *nsym, unsigned int *ndebug)
1282
{
1283
  char type = '\0';
1284
  char *class = NULL;
1285
  char *category = NULL;
1286
  char *selector = NULL;
1287
 
1288
  unsigned int csym = 0;
1289
  unsigned int cdebug = 0;
1290
 
1291
  unsigned int ncsym = 0;
1292
  unsigned int ncdebug = 0;
1293
 
1294
  char *buf = NULL;
1295
  char *tmp = NULL;
1296
 
1297
  gdb_assert (nsym != NULL);
1298
  gdb_assert (ndebug != NULL);
1299
 
1300
  if (nsym != NULL)
1301
    *nsym = 0;
1302
  if (ndebug != NULL)
1303
    *ndebug = 0;
1304
 
1305
  buf = (char *) alloca (strlen (method) + 1);
1306
  strcpy (buf, method);
1307
  tmp = parse_method (buf, &type, &class, &category, &selector);
1308
 
1309
  if (tmp == NULL) {
1310
 
1311
    struct symbol *sym = NULL;
1312
    struct minimal_symbol *msym = NULL;
1313
 
1314
    strcpy (buf, method);
1315
    tmp = parse_selector (buf, &selector);
1316
 
1317
    if (tmp == NULL)
1318
      return NULL;
1319
 
1320
    sym = lookup_symbol (selector, block, VAR_DOMAIN, 0);
1321
    if (sym != NULL)
1322
      {
1323
        if (syms)
1324
          syms[csym] = sym;
1325
        csym++;
1326
        cdebug++;
1327
      }
1328
 
1329
    if (sym == NULL)
1330
      msym = lookup_minimal_symbol (selector, 0, 0);
1331
 
1332
    if (msym != NULL)
1333
      {
1334
        if (syms)
1335
          syms[csym] = (struct symbol *)msym;
1336
        csym++;
1337
      }
1338
  }
1339
 
1340
  if (syms != NULL)
1341
    find_methods (symtab, type, class, category, selector,
1342
                  syms + csym, &ncsym, &ncdebug);
1343
  else
1344
    find_methods (symtab, type, class, category, selector,
1345
                  NULL, &ncsym, &ncdebug);
1346
 
1347
  /* If we didn't find any methods, just return.  */
1348
  if (ncsym == 0 && ncdebug == 0)
1349
    return method;
1350
 
1351
  /* Take debug symbols from the second batch of symbols and swap them
1352
   * with debug symbols from the first batch.  Repeat until either the
1353
   * second section is out of debug symbols or the first section is
1354
   * full of debug symbols.  Either way we have all debug symbols
1355
   * packed to the beginning of the buffer.
1356
   */
1357
 
1358
  if (syms != NULL)
1359
    {
1360
      while ((cdebug < csym) && (ncdebug > 0))
1361
        {
1362
          struct symbol *s = NULL;
1363
          /* First non-debugging symbol.  */
1364
          unsigned int i = cdebug;
1365
          /* Last of second batch of debug symbols.  */
1366
          unsigned int j = csym + ncdebug - 1;
1367
 
1368
          s = syms[j];
1369
          syms[j] = syms[i];
1370
          syms[i] = s;
1371
 
1372
          /* We've moved a symbol from the second debug section to the
1373
             first one.  */
1374
          cdebug++;
1375
          ncdebug--;
1376
        }
1377
    }
1378
 
1379
  csym += ncsym;
1380
  cdebug += ncdebug;
1381
 
1382
  if (nsym != NULL)
1383
    *nsym = csym;
1384
  if (ndebug != NULL)
1385
    *ndebug = cdebug;
1386
 
1387
  if (syms == NULL)
1388
    return method + (tmp - buf);
1389
 
1390
  if (csym > 1)
1391
    {
1392
      /* Sort debuggable symbols.  */
1393
      if (cdebug > 1)
1394
        qsort (syms, cdebug, sizeof (struct minimal_symbol *),
1395
               compare_classes);
1396
 
1397
      /* Sort minimal_symbols.  */
1398
      if ((csym - cdebug) > 1)
1399
        qsort (&syms[cdebug], csym - cdebug,
1400
               sizeof (struct minimal_symbol *), compare_classes);
1401
    }
1402
  /* Terminate the sym_arr list.  */
1403
  syms[csym] = 0;
1404
 
1405
  return method + (tmp - buf);
1406
}
1407
 
1408
static void
1409
print_object_command (char *args, int from_tty)
1410
{
1411
  struct value *object, *function, *description;
1412
  CORE_ADDR string_addr, object_addr;
1413
  int i = 0;
1414
  gdb_byte c = 0;
1415
 
1416
  if (!args || !*args)
1417
    error (
1418
"The 'print-object' command requires an argument (an Objective-C object)");
1419
 
1420
  {
1421
    struct expression *expr = parse_expression (args);
1422
    struct cleanup *old_chain =
1423
      make_cleanup (free_current_contents, &expr);
1424
    int pc = 0;
1425
 
1426
    object = evaluate_subexp (builtin_type (expr->gdbarch)->builtin_data_ptr,
1427
                              expr, &pc, EVAL_NORMAL);
1428
    do_cleanups (old_chain);
1429
  }
1430
 
1431
  /* Validate the address for sanity.  */
1432
  object_addr = value_as_long (object);
1433
  read_memory (object_addr, &c, 1);
1434
 
1435
  function = find_function_in_inferior ("_NSPrintForDebugger", NULL);
1436
  if (function == NULL)
1437
    error (_("Unable to locate _NSPrintForDebugger in child process"));
1438
 
1439
  description = call_function_by_hand (function, 1, &object);
1440
 
1441
  string_addr = value_as_long (description);
1442
  if (string_addr == 0)
1443
    error (_("object returns null description"));
1444
 
1445
  read_memory (string_addr + i++, &c, 1);
1446
  if (c != 0)
1447
    do
1448
      { /* Read and print characters up to EOS.  */
1449
        QUIT;
1450
        printf_filtered ("%c", c);
1451
        read_memory (string_addr + i++, &c, 1);
1452
      } while (c != 0);
1453
  else
1454
    printf_filtered(_("<object returns empty description>"));
1455
  printf_filtered ("\n");
1456
}
1457
 
1458
/* The data structure 'methcalls' is used to detect method calls (thru
1459
 * ObjC runtime lib functions objc_msgSend, objc_msgSendSuper, etc.),
1460
 * and ultimately find the method being called.
1461
 */
1462
 
1463
struct objc_methcall {
1464
  char *name;
1465
 /* Return instance method to be called.  */
1466
  int (*stop_at) (CORE_ADDR, CORE_ADDR *);
1467
  /* Start of pc range corresponding to method invocation.  */
1468
  CORE_ADDR begin;
1469
  /* End of pc range corresponding to method invocation.  */
1470
  CORE_ADDR end;
1471
};
1472
 
1473
static int resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc);
1474
static int resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc);
1475
static int resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc);
1476
static int resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc);
1477
 
1478
static struct objc_methcall methcalls[] = {
1479
  { "_objc_msgSend", resolve_msgsend, 0, 0},
1480
  { "_objc_msgSend_stret", resolve_msgsend_stret, 0, 0},
1481
  { "_objc_msgSendSuper", resolve_msgsend_super, 0, 0},
1482
  { "_objc_msgSendSuper_stret", resolve_msgsend_super_stret, 0, 0},
1483
  { "_objc_getClass", NULL, 0, 0},
1484
  { "_objc_getMetaClass", NULL, 0, 0}
1485
};
1486
 
1487
#define nmethcalls (sizeof (methcalls) / sizeof (methcalls[0]))
1488
 
1489
/* The following function, "find_objc_msgsend", fills in the data
1490
 * structure "objc_msgs" by finding the addresses of each of the
1491
 * (currently four) functions that it holds (of which objc_msgSend is
1492
 * the first).  This must be called each time symbols are loaded, in
1493
 * case the functions have moved for some reason.
1494
 */
1495
 
1496
static void
1497
find_objc_msgsend (void)
1498
{
1499
  unsigned int i;
1500
  for (i = 0; i < nmethcalls; i++) {
1501
 
1502
    struct minimal_symbol *func;
1503
 
1504
    /* Try both with and without underscore.  */
1505
    func = lookup_minimal_symbol (methcalls[i].name, NULL, NULL);
1506
    if ((func == NULL) && (methcalls[i].name[0] == '_')) {
1507
      func = lookup_minimal_symbol (methcalls[i].name + 1, NULL, NULL);
1508
    }
1509
    if (func == NULL) {
1510
      methcalls[i].begin = 0;
1511
      methcalls[i].end = 0;
1512
      continue;
1513
    }
1514
 
1515
    methcalls[i].begin = SYMBOL_VALUE_ADDRESS (func);
1516
    do {
1517
      methcalls[i].end = SYMBOL_VALUE_ADDRESS (++func);
1518
    } while (methcalls[i].begin == methcalls[i].end);
1519
  }
1520
}
1521
 
1522
/* find_objc_msgcall (replaces pc_off_limits)
1523
 *
1524
 * ALL that this function now does is to determine whether the input
1525
 * address ("pc") is the address of one of the Objective-C message
1526
 * dispatch functions (mainly objc_msgSend or objc_msgSendSuper), and
1527
 * if so, it returns the address of the method that will be called.
1528
 *
1529
 * The old function "pc_off_limits" used to do a lot of other things
1530
 * in addition, such as detecting shared library jump stubs and
1531
 * returning the address of the shlib function that would be called.
1532
 * That functionality has been moved into the gdbarch_skip_trampoline_code and
1533
 * IN_SOLIB_TRAMPOLINE macros, which are resolved in the target-
1534
 * dependent modules.
1535
 */
1536
 
1537
struct objc_submethod_helper_data {
1538
  int (*f) (CORE_ADDR, CORE_ADDR *);
1539
  CORE_ADDR pc;
1540
  CORE_ADDR *new_pc;
1541
};
1542
 
1543
static int
1544
find_objc_msgcall_submethod_helper (void * arg)
1545
{
1546
  struct objc_submethod_helper_data *s =
1547
    (struct objc_submethod_helper_data *) arg;
1548
 
1549
  if (s->f (s->pc, s->new_pc) == 0)
1550
    return 1;
1551
  else
1552
    return 0;
1553
}
1554
 
1555
static int
1556
find_objc_msgcall_submethod (int (*f) (CORE_ADDR, CORE_ADDR *),
1557
                             CORE_ADDR pc,
1558
                             CORE_ADDR *new_pc)
1559
{
1560
  struct objc_submethod_helper_data s;
1561
 
1562
  s.f = f;
1563
  s.pc = pc;
1564
  s.new_pc = new_pc;
1565
 
1566
  if (catch_errors (find_objc_msgcall_submethod_helper,
1567
                    (void *) &s,
1568
                    "Unable to determine target of Objective-C method call (ignoring):\n",
1569
                    RETURN_MASK_ALL) == 0)
1570
    return 1;
1571
  else
1572
    return 0;
1573
}
1574
 
1575
int
1576
find_objc_msgcall (CORE_ADDR pc, CORE_ADDR *new_pc)
1577
{
1578
  unsigned int i;
1579
 
1580
  find_objc_msgsend ();
1581
  if (new_pc != NULL)
1582
    {
1583
      *new_pc = 0;
1584
    }
1585
 
1586
  for (i = 0; i < nmethcalls; i++)
1587
    if ((pc >= methcalls[i].begin) && (pc < methcalls[i].end))
1588
      {
1589
        if (methcalls[i].stop_at != NULL)
1590
          return find_objc_msgcall_submethod (methcalls[i].stop_at,
1591
                                              pc, new_pc);
1592
        else
1593
          return 0;
1594
      }
1595
 
1596
  return 0;
1597
}
1598
 
1599
extern initialize_file_ftype _initialize_objc_language; /* -Wmissing-prototypes */
1600
 
1601
void
1602
_initialize_objc_language (void)
1603
{
1604
  add_language (&objc_language_defn);
1605
  add_info ("selectors", selectors_info,    /* INFO SELECTORS command.  */
1606
            _("All Objective-C selectors, or those matching REGEXP."));
1607
  add_info ("classes", classes_info,        /* INFO CLASSES   command.  */
1608
            _("All Objective-C classes, or those matching REGEXP."));
1609
  add_com ("print-object", class_vars, print_object_command,
1610
           _("Ask an Objective-C object to print itself."));
1611
  add_com_alias ("po", "print-object", class_vars, 1);
1612
}
1613
 
1614
static void
1615
read_objc_method (struct gdbarch *gdbarch, CORE_ADDR addr,
1616
                  struct objc_method *method)
1617
{
1618
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1619
  method->name  = read_memory_unsigned_integer (addr + 0, 4, byte_order);
1620
  method->types = read_memory_unsigned_integer (addr + 4, 4, byte_order);
1621
  method->imp   = read_memory_unsigned_integer (addr + 8, 4, byte_order);
1622
}
1623
 
1624
static unsigned long
1625
read_objc_methlist_nmethods (struct gdbarch *gdbarch, CORE_ADDR addr)
1626
{
1627
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1628
  return read_memory_unsigned_integer (addr + 4, 4, byte_order);
1629
}
1630
 
1631
static void
1632
read_objc_methlist_method (struct gdbarch *gdbarch, CORE_ADDR addr,
1633
                           unsigned long num, struct objc_method *method)
1634
{
1635
  gdb_assert (num < read_objc_methlist_nmethods (gdbarch, addr));
1636
  read_objc_method (gdbarch, addr + 8 + (12 * num), method);
1637
}
1638
 
1639
static void
1640
read_objc_object (struct gdbarch *gdbarch, CORE_ADDR addr,
1641
                  struct objc_object *object)
1642
{
1643
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1644
  object->isa = read_memory_unsigned_integer (addr, 4, byte_order);
1645
}
1646
 
1647
static void
1648
read_objc_super (struct gdbarch *gdbarch, CORE_ADDR addr,
1649
                 struct objc_super *super)
1650
{
1651
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1652
  super->receiver = read_memory_unsigned_integer (addr, 4, byte_order);
1653
  super->class = read_memory_unsigned_integer (addr + 4, 4, byte_order);
1654
};
1655
 
1656
static void
1657
read_objc_class (struct gdbarch *gdbarch, CORE_ADDR addr,
1658
                 struct objc_class *class)
1659
{
1660
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1661
  class->isa = read_memory_unsigned_integer (addr, 4, byte_order);
1662
  class->super_class = read_memory_unsigned_integer (addr + 4, 4, byte_order);
1663
  class->name = read_memory_unsigned_integer (addr + 8, 4, byte_order);
1664
  class->version = read_memory_unsigned_integer (addr + 12, 4, byte_order);
1665
  class->info = read_memory_unsigned_integer (addr + 16, 4, byte_order);
1666
  class->instance_size = read_memory_unsigned_integer (addr + 18, 4, byte_order);
1667
  class->ivars = read_memory_unsigned_integer (addr + 24, 4, byte_order);
1668
  class->methods = read_memory_unsigned_integer (addr + 28, 4, byte_order);
1669
  class->cache = read_memory_unsigned_integer (addr + 32, 4, byte_order);
1670
  class->protocols = read_memory_unsigned_integer (addr + 36, 4, byte_order);
1671
}
1672
 
1673
static CORE_ADDR
1674
find_implementation_from_class (struct gdbarch *gdbarch,
1675
                                CORE_ADDR class, CORE_ADDR sel)
1676
{
1677
  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
1678
  CORE_ADDR subclass = class;
1679
 
1680
  while (subclass != 0)
1681
    {
1682
 
1683
      struct objc_class class_str;
1684
      unsigned mlistnum = 0;
1685
 
1686
      read_objc_class (gdbarch, subclass, &class_str);
1687
 
1688
      for (;;)
1689
        {
1690
          CORE_ADDR mlist;
1691
          unsigned long nmethods;
1692
          unsigned long i;
1693
 
1694
          mlist = read_memory_unsigned_integer (class_str.methods +
1695
                                                (4 * mlistnum),
1696
                                                4, byte_order);
1697
          if (mlist == 0)
1698
            break;
1699
 
1700
          nmethods = read_objc_methlist_nmethods (gdbarch, mlist);
1701
 
1702
          for (i = 0; i < nmethods; i++)
1703
            {
1704
              struct objc_method meth_str;
1705
              read_objc_methlist_method (gdbarch, mlist, i, &meth_str);
1706
 
1707
#if 0
1708
              fprintf (stderr,
1709
                       "checking method 0x%lx against selector 0x%lx\n",
1710
                       meth_str.name, sel);
1711
#endif
1712
 
1713
              if (meth_str.name == sel)
1714
                /* FIXME: hppa arch was doing a pointer dereference
1715
                   here. There needs to be a better way to do that.  */
1716
                return meth_str.imp;
1717
            }
1718
          mlistnum++;
1719
        }
1720
      subclass = class_str.super_class;
1721
    }
1722
 
1723
  return 0;
1724
}
1725
 
1726
static CORE_ADDR
1727
find_implementation (struct gdbarch *gdbarch,
1728
                     CORE_ADDR object, CORE_ADDR sel)
1729
{
1730
  struct objc_object ostr;
1731
 
1732
  if (object == 0)
1733
    return 0;
1734
  read_objc_object (gdbarch, object, &ostr);
1735
  if (ostr.isa == 0)
1736
    return 0;
1737
 
1738
  return find_implementation_from_class (gdbarch, ostr.isa, sel);
1739
}
1740
 
1741
static int
1742
resolve_msgsend (CORE_ADDR pc, CORE_ADDR *new_pc)
1743
{
1744
  struct frame_info *frame = get_current_frame ();
1745
  struct gdbarch *gdbarch = get_frame_arch (frame);
1746
  struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1747
 
1748
  CORE_ADDR object;
1749
  CORE_ADDR sel;
1750
  CORE_ADDR res;
1751
 
1752
  object = gdbarch_fetch_pointer_argument (gdbarch, frame, 0, ptr_type);
1753
  sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1754
 
1755
  res = find_implementation (gdbarch, object, sel);
1756
  if (new_pc != 0)
1757
    *new_pc = res;
1758
  if (res == 0)
1759
    return 1;
1760
  return 0;
1761
}
1762
 
1763
static int
1764
resolve_msgsend_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
1765
{
1766
  struct frame_info *frame = get_current_frame ();
1767
  struct gdbarch *gdbarch = get_frame_arch (frame);
1768
  struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1769
 
1770
  CORE_ADDR object;
1771
  CORE_ADDR sel;
1772
  CORE_ADDR res;
1773
 
1774
  object = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1775
  sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 2, ptr_type);
1776
 
1777
  res = find_implementation (gdbarch, object, sel);
1778
  if (new_pc != 0)
1779
    *new_pc = res;
1780
  if (res == 0)
1781
    return 1;
1782
  return 0;
1783
}
1784
 
1785
static int
1786
resolve_msgsend_super (CORE_ADDR pc, CORE_ADDR *new_pc)
1787
{
1788
  struct frame_info *frame = get_current_frame ();
1789
  struct gdbarch *gdbarch = get_frame_arch (frame);
1790
  struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1791
 
1792
  struct objc_super sstr;
1793
 
1794
  CORE_ADDR super;
1795
  CORE_ADDR sel;
1796
  CORE_ADDR res;
1797
 
1798
  super = gdbarch_fetch_pointer_argument (gdbarch, frame, 0, ptr_type);
1799
  sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1800
 
1801
  read_objc_super (gdbarch, super, &sstr);
1802
  if (sstr.class == 0)
1803
    return 0;
1804
 
1805
  res = find_implementation_from_class (gdbarch, sstr.class, sel);
1806
  if (new_pc != 0)
1807
    *new_pc = res;
1808
  if (res == 0)
1809
    return 1;
1810
  return 0;
1811
}
1812
 
1813
static int
1814
resolve_msgsend_super_stret (CORE_ADDR pc, CORE_ADDR *new_pc)
1815
{
1816
  struct frame_info *frame = get_current_frame ();
1817
  struct gdbarch *gdbarch = get_frame_arch (frame);
1818
  struct type *ptr_type = builtin_type (gdbarch)->builtin_func_ptr;
1819
 
1820
  struct objc_super sstr;
1821
 
1822
  CORE_ADDR super;
1823
  CORE_ADDR sel;
1824
  CORE_ADDR res;
1825
 
1826
  super = gdbarch_fetch_pointer_argument (gdbarch, frame, 1, ptr_type);
1827
  sel = gdbarch_fetch_pointer_argument (gdbarch, frame, 2, ptr_type);
1828
 
1829
  read_objc_super (gdbarch, super, &sstr);
1830
  if (sstr.class == 0)
1831
    return 0;
1832
 
1833
  res = find_implementation_from_class (gdbarch, sstr.class, sel);
1834
  if (new_pc != 0)
1835
    *new_pc = res;
1836
  if (res == 0)
1837
    return 1;
1838
  return 0;
1839
}
1840
 
1841
void
1842
_initialize_objc_lang (void)
1843
{
1844
  objc_objfile_data = register_objfile_data ();
1845
}

powered by: WebSVN 2.1.0

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