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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [gdb/] [solib-darwin.c] - Blame information for rev 330

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* Handle Darwin shared libraries for GDB, the GNU Debugger.
2
 
3
   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
4
 
5
   This file is part of GDB.
6
 
7
   This program is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3 of the License, or
10
   (at your option) any later version.
11
 
12
   This program is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
 
20
#include "defs.h"
21
 
22
#include "symtab.h"
23
#include "bfd.h"
24
#include "symfile.h"
25
#include "objfiles.h"
26
#include "gdbcore.h"
27
#include "target.h"
28
#include "inferior.h"
29
#include "regcache.h"
30
#include "gdbthread.h"
31
 
32
#include "gdb_assert.h"
33
 
34
#include "solist.h"
35
#include "solib.h"
36
#include "solib-svr4.h"
37
 
38
#include "bfd-target.h"
39
#include "elf-bfd.h"
40
#include "exec.h"
41
#include "auxv.h"
42
#include "exceptions.h"
43
#include "mach-o.h"
44
 
45
struct gdb_dyld_image_info
46
{
47
  /* Base address (which corresponds to the Mach-O header).  */
48
  CORE_ADDR mach_header;
49
  /* Image file path.  */
50
  CORE_ADDR file_path;
51
  /* st.m_time of image file.  */
52
  unsigned long mtime;
53
};
54
 
55
/* Content of inferior dyld_all_image_infos structure.
56
   See /usr/include/mach-o/dyld_images.h for the documentation.  */
57
struct gdb_dyld_all_image_infos
58
{
59
  /* Version (1).  */
60
  unsigned int version;
61
  /* Number of images.  */
62
  unsigned int count;
63
  /* Image description.  */
64
  CORE_ADDR info;
65
  /* Notifier (function called when a library is added or removed).  */
66
  CORE_ADDR notifier;
67
};
68
 
69
/* Current all_image_infos version.  */
70
#define DYLD_VERSION_MIN 1
71
#define DYLD_VERSION_MAX 7
72
 
73
/* Address of structure dyld_all_image_infos in inferior.  */
74
static CORE_ADDR dyld_all_image_addr;
75
 
76
/* Gdb copy of dyld_all_info_infos.  */
77
static struct gdb_dyld_all_image_infos dyld_all_image;
78
 
79
/* Return non-zero if the version in dyld_all_image is known.  */
80
 
81
static int
82
darwin_dyld_version_ok (void)
83
{
84
  return dyld_all_image.version >= DYLD_VERSION_MIN
85
    && dyld_all_image.version <= DYLD_VERSION_MAX;
86
}
87
 
88
/* Read dyld_all_image from inferior.  */
89
 
90
static void
91
darwin_load_image_infos (void)
92
{
93
  gdb_byte buf[24];
94
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
95
  struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
96
  int len;
97
 
98
  /* If the structure address is not known, don't continue.  */
99
  if (dyld_all_image_addr == 0)
100
    return;
101
 
102
  /* The structure has 4 fields: version (4 bytes), count (4 bytes),
103
     info (pointer) and notifier (pointer).  */
104
  len = 4 + 4 + 2 * ptr_type->length;
105
  gdb_assert (len <= sizeof (buf));
106
  memset (&dyld_all_image, 0, sizeof (dyld_all_image));
107
 
108
  /* Read structure raw bytes from target.  */
109
  if (target_read_memory (dyld_all_image_addr, buf, len))
110
    return;
111
 
112
  /* Extract the fields.  */
113
  dyld_all_image.version = extract_unsigned_integer (buf, 4, byte_order);
114
  if (!darwin_dyld_version_ok ())
115
    return;
116
 
117
  dyld_all_image.count = extract_unsigned_integer (buf + 4, 4, byte_order);
118
  dyld_all_image.info = extract_typed_address (buf + 8, ptr_type);
119
  dyld_all_image.notifier = extract_typed_address
120
    (buf + 8 + ptr_type->length, ptr_type);
121
}
122
 
123
/* Link map info to include in an allocated so_list entry.  */
124
 
125
struct lm_info
126
{
127
  /* The target location of lm.  */
128
  CORE_ADDR lm_addr;
129
};
130
 
131
struct darwin_so_list
132
{
133
  /* Common field.  */
134
  struct so_list sl;
135
  /* Darwin specific data.  */
136
  struct lm_info li;
137
};
138
 
139
/* Lookup the value for a specific symbol.  */
140
 
141
static CORE_ADDR
142
lookup_symbol_from_bfd (bfd *abfd, char *symname)
143
{
144
  long storage_needed;
145
  asymbol **symbol_table;
146
  unsigned int number_of_symbols;
147
  unsigned int i;
148
  CORE_ADDR symaddr = 0;
149
 
150
  storage_needed = bfd_get_symtab_upper_bound (abfd);
151
 
152
  if (storage_needed <= 0)
153
    return 0;
154
 
155
  symbol_table = (asymbol **) xmalloc (storage_needed);
156
  number_of_symbols = bfd_canonicalize_symtab (abfd, symbol_table);
157
 
158
  for (i = 0; i < number_of_symbols; i++)
159
    {
160
      asymbol *sym = symbol_table[i];
161
 
162
      if (strcmp (sym->name, symname) == 0
163
          && (sym->section->flags & (SEC_CODE | SEC_DATA)) != 0)
164
        {
165
          /* BFD symbols are section relative.  */
166
          symaddr = sym->value + sym->section->vma;
167
          break;
168
        }
169
    }
170
  xfree (symbol_table);
171
 
172
  return symaddr;
173
}
174
 
175
/* Return program interpreter string.  */
176
 
177
static gdb_byte *
178
find_program_interpreter (void)
179
{
180
  gdb_byte *buf = NULL;
181
 
182
  /* If we have an exec_bfd, get the interpreter from the load commands.  */
183
  if (exec_bfd)
184
    {
185
      bfd_mach_o_load_command *cmd;
186
 
187
      if (bfd_mach_o_lookup_command (exec_bfd,
188
                                     BFD_MACH_O_LC_LOAD_DYLINKER, &cmd) == 1)
189
        return cmd->command.dylinker.name_str;
190
    }
191
 
192
  /* If we didn't find it, read from memory.
193
     FIXME: todo.  */
194
  return buf;
195
}
196
 
197
/*  Not used.  I don't see how the main symbol file can be found: the
198
    interpreter name is needed and it is known from the executable file.
199
    Note that darwin-nat.c implements pid_to_exec_file.  */
200
 
201
static int
202
open_symbol_file_object (void *from_ttyp)
203
{
204
  return 0;
205
}
206
 
207
/* Build a list of currently loaded shared objects.  See solib-svr4.c  */
208
 
209
static struct so_list *
210
darwin_current_sos (void)
211
{
212
  struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
213
  int ptr_len = TYPE_LENGTH (ptr_type);
214
  unsigned int image_info_size;
215
  CORE_ADDR lm;
216
  struct so_list *head = NULL;
217
  struct so_list *tail = NULL;
218
  int i;
219
 
220
  /* Be sure image infos are loaded.  */
221
  darwin_load_image_infos ();
222
 
223
  if (!darwin_dyld_version_ok ())
224
    return NULL;
225
 
226
  image_info_size = ptr_len * 3;
227
 
228
  /* Read infos for each solib.
229
     This first entry is ignored as this is the executable itself.  */
230
  for (i = 1; i < dyld_all_image.count; i++)
231
    {
232
      CORE_ADDR info = dyld_all_image.info + i * image_info_size;
233
      char buf[image_info_size];
234
      CORE_ADDR load_addr;
235
      CORE_ADDR path_addr;
236
      char *file_path;
237
      int errcode;
238
      struct darwin_so_list *dnew;
239
      struct so_list *new;
240
      struct cleanup *old_chain;
241
 
242
      /* Read image info from inferior.  */
243
      if (target_read_memory (info, buf, image_info_size))
244
        break;
245
 
246
      load_addr = extract_typed_address (buf, ptr_type);
247
      path_addr = extract_typed_address (buf + ptr_len, ptr_type);
248
 
249
      target_read_string (path_addr, &file_path,
250
                          SO_NAME_MAX_PATH_SIZE - 1, &errcode);
251
      if (errcode)
252
        break;
253
 
254
      /* Create and fill the new so_list element.  */
255
      dnew = XZALLOC (struct darwin_so_list);
256
      new = &dnew->sl;
257
      old_chain = make_cleanup (xfree, dnew);
258
 
259
      new->lm_info = &dnew->li;
260
 
261
      strncpy (new->so_name, file_path, SO_NAME_MAX_PATH_SIZE - 1);
262
      new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
263
      strcpy (new->so_original_name, new->so_name);
264
      xfree (file_path);
265
      new->lm_info->lm_addr = load_addr;
266
 
267
      if (head == NULL)
268
        head = new;
269
      else
270
        tail->next = new;
271
      tail = new;
272
 
273
      discard_cleanups (old_chain);
274
    }
275
 
276
  return head;
277
}
278
 
279
/* Return 1 if PC lies in the dynamic symbol resolution code of the
280
   run time loader.  */
281
 
282
int
283
darwin_in_dynsym_resolve_code (CORE_ADDR pc)
284
{
285
  return 0;
286
}
287
 
288
 
289
/* No special symbol handling.  */
290
 
291
static void
292
darwin_special_symbol_handling (void)
293
{
294
}
295
 
296
/* Shared library startup support.  See documentation in solib-svr4.c  */
297
 
298
static void
299
darwin_solib_create_inferior_hook (int from_tty)
300
{
301
  struct minimal_symbol *msymbol;
302
  char **bkpt_namep;
303
  asection *interp_sect;
304
  gdb_byte *interp_name;
305
  CORE_ADDR sym_addr;
306
  CORE_ADDR load_addr = 0;
307
  int load_addr_found = 0;
308
  int loader_found_in_list = 0;
309
  struct so_list *so;
310
  bfd *dyld_bfd = NULL;
311
  struct inferior *inf = current_inferior ();
312
 
313
  /* Find the program interpreter.  */
314
  interp_name = find_program_interpreter ();
315
  if (!interp_name)
316
    return;
317
 
318
  /* Create a bfd for the interpreter.  */
319
  sym_addr = 0;
320
  dyld_bfd = bfd_openr (interp_name, gnutarget);
321
  if (dyld_bfd)
322
    {
323
      bfd *sub;
324
 
325
      sub = bfd_mach_o_fat_extract (dyld_bfd, bfd_object,
326
                                    gdbarch_bfd_arch_info (target_gdbarch));
327
      if (sub)
328
        dyld_bfd = sub;
329
      else
330
        {
331
          bfd_close (dyld_bfd);
332
          dyld_bfd = NULL;
333
        }
334
    }
335
  if (!dyld_bfd)
336
    return;
337
 
338
  if (!inf->attach_flag)
339
    {
340
      /* We find the dynamic linker's base address by examining
341
         the current pc (which should point at the entry point for the
342
         dynamic linker) and subtracting the offset of the entry point.  */
343
      load_addr = (regcache_read_pc (get_current_regcache ())
344
                   - bfd_get_start_address (dyld_bfd));
345
    }
346
  else
347
    {
348
      /* FIXME: todo.
349
         Get address of __DATA.__dyld in exec_bfd, read address at offset 0.
350
      */
351
      return;
352
    }
353
 
354
  /* Now try to set a breakpoint in the dynamic linker.  */
355
  dyld_all_image_addr =
356
    lookup_symbol_from_bfd (dyld_bfd, "_dyld_all_image_infos");
357
 
358
  bfd_close (dyld_bfd);
359
 
360
  if (dyld_all_image_addr == 0)
361
    return;
362
 
363
  dyld_all_image_addr += load_addr;
364
 
365
  darwin_load_image_infos ();
366
 
367
  if (darwin_dyld_version_ok ())
368
    create_solib_event_breakpoint (target_gdbarch, dyld_all_image.notifier);
369
}
370
 
371
static void
372
darwin_clear_solib (void)
373
{
374
  dyld_all_image_addr = 0;
375
  dyld_all_image.version = 0;
376
}
377
 
378
static void
379
darwin_free_so (struct so_list *so)
380
{
381
}
382
 
383
/* The section table is built from bfd sections using bfd VMAs.
384
   Relocate these VMAs according to solib info.  */
385
 
386
static void
387
darwin_relocate_section_addresses (struct so_list *so,
388
                                   struct target_section *sec)
389
{
390
  sec->addr += so->lm_info->lm_addr;
391
  sec->endaddr += so->lm_info->lm_addr;
392
 
393
  /* Best effort to set addr_high/addr_low.  This is used only by
394
     'info sharedlibary'.  */
395
  if (so->addr_high == 0)
396
    {
397
      so->addr_low = sec->addr;
398
      so->addr_high = sec->endaddr;
399
    }
400
  if (sec->endaddr > so->addr_high)
401
    so->addr_high = sec->endaddr;
402
  if (sec->addr < so->addr_low)
403
    so->addr_low = sec->addr;
404
}
405
 
406
static struct symbol *
407
darwin_lookup_lib_symbol (const struct objfile *objfile,
408
                          const char *name,
409
                          const domain_enum domain)
410
{
411
  return NULL;
412
}
413
 
414
static bfd *
415
darwin_bfd_open (char *pathname)
416
{
417
  char *found_pathname;
418
  int found_file;
419
  bfd *abfd;
420
  bfd *res;
421
 
422
  /* Search for shared library file.  */
423
  found_pathname = solib_find (pathname, &found_file);
424
  if (found_pathname == NULL)
425
    perror_with_name (pathname);
426
 
427
  /* Open bfd for shared library.  */
428
  abfd = solib_bfd_fopen (found_pathname, found_file);
429
 
430
  res = bfd_mach_o_fat_extract (abfd, bfd_object,
431
                                gdbarch_bfd_arch_info (target_gdbarch));
432
  if (!res)
433
    {
434
      bfd_close (abfd);
435
      make_cleanup (xfree, found_pathname);
436
      error (_("`%s': not a shared-library: %s"),
437
             found_pathname, bfd_errmsg (bfd_get_error ()));
438
    }
439
  return res;
440
}
441
 
442
struct target_so_ops darwin_so_ops;
443
 
444
void
445
_initialize_darwin_solib (void)
446
{
447
  darwin_so_ops.relocate_section_addresses = darwin_relocate_section_addresses;
448
  darwin_so_ops.free_so = darwin_free_so;
449
  darwin_so_ops.clear_solib = darwin_clear_solib;
450
  darwin_so_ops.solib_create_inferior_hook = darwin_solib_create_inferior_hook;
451
  darwin_so_ops.special_symbol_handling = darwin_special_symbol_handling;
452
  darwin_so_ops.current_sos = darwin_current_sos;
453
  darwin_so_ops.open_symbol_file_object = open_symbol_file_object;
454
  darwin_so_ops.in_dynsym_resolve_code = darwin_in_dynsym_resolve_code;
455
  darwin_so_ops.lookup_lib_global_symbol = darwin_lookup_lib_symbol;
456
  darwin_so_ops.bfd_open = darwin_bfd_open;
457
}

powered by: WebSVN 2.1.0

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