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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [gdb/] [solib-darwin.c] - Blame information for rev 842

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 227 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
      if (strcmp (sym->name, symname) == 0
162
          && (sym->section->flags & (SEC_CODE | SEC_DATA)) != 0)
163
        {
164
          /* BFD symbols are section relative.  */
165
          symaddr = sym->value + sym->section->vma;
166
          break;
167
        }
168
    }
169
  xfree (symbol_table);
170
 
171
  return symaddr;
172
}
173
 
174
/* Return program interpreter string.  */
175
 
176
static gdb_byte *
177
find_program_interpreter (void)
178
{
179
  gdb_byte *buf = NULL;
180
 
181
  /* If we have an exec_bfd, get the interpreter from the load commands.  */
182
  if (exec_bfd)
183
    {
184
      bfd_mach_o_load_command *cmd;
185
 
186
      if (bfd_mach_o_lookup_command (exec_bfd,
187
                                     BFD_MACH_O_LC_LOAD_DYLINKER, &cmd) == 1)
188
        return cmd->command.dylinker.name_str;
189
    }
190
 
191
  /* If we didn't find it, read from memory.
192
     FIXME: todo.  */
193
  return buf;
194
}
195
 
196
/*  Not used.  I don't see how the main symbol file can be found: the
197
    interpreter name is needed and it is known from the executable file.
198
    Note that darwin-nat.c implements pid_to_exec_file.  */
199
 
200
static int
201
open_symbol_file_object (void *from_ttyp)
202
{
203
  return 0;
204
}
205
 
206
/* Build a list of currently loaded shared objects.  See solib-svr4.c  */
207
 
208
static struct so_list *
209
darwin_current_sos (void)
210
{
211
  struct type *ptr_type = builtin_type (target_gdbarch)->builtin_data_ptr;
212
  int ptr_len = TYPE_LENGTH (ptr_type);
213
  unsigned int image_info_size;
214
  CORE_ADDR lm;
215
  struct so_list *head = NULL;
216
  struct so_list *tail = NULL;
217
  int i;
218
 
219
  /* Be sure image infos are loaded.  */
220
  darwin_load_image_infos ();
221
 
222
  if (!darwin_dyld_version_ok ())
223
    return NULL;
224
 
225
  image_info_size = ptr_len * 3;
226
 
227
  /* Read infos for each solib.
228
     This first entry is ignored as this is the executable itself.  */
229
  for (i = 1; i < dyld_all_image.count; i++)
230
    {
231
      CORE_ADDR info = dyld_all_image.info + i * image_info_size;
232
      char buf[image_info_size];
233
      CORE_ADDR load_addr;
234
      CORE_ADDR path_addr;
235
      char *file_path;
236
      int errcode;
237
      struct darwin_so_list *dnew;
238
      struct so_list *new;
239
      struct cleanup *old_chain;
240
 
241
      /* Read image info from inferior.  */
242
      if (target_read_memory (info, buf, image_info_size))
243
        break;
244
 
245
      load_addr = extract_typed_address (buf, ptr_type);
246
      path_addr = extract_typed_address (buf + ptr_len, ptr_type);
247
 
248
      target_read_string (path_addr, &file_path,
249
                          SO_NAME_MAX_PATH_SIZE - 1, &errcode);
250
      if (errcode)
251
        break;
252
 
253
      /* Create and fill the new so_list element.  */
254
      dnew = XZALLOC (struct darwin_so_list);
255
      new = &dnew->sl;
256
      old_chain = make_cleanup (xfree, dnew);
257
 
258
      new->lm_info = &dnew->li;
259
 
260
      strncpy (new->so_name, file_path, SO_NAME_MAX_PATH_SIZE - 1);
261
      new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
262
      strcpy (new->so_original_name, new->so_name);
263
      xfree (file_path);
264
      new->lm_info->lm_addr = load_addr;
265
 
266
      if (head == NULL)
267
        head = new;
268
      else
269
        tail->next = new;
270
      tail = new;
271
 
272
      discard_cleanups (old_chain);
273
    }
274
 
275
  return head;
276
}
277
 
278
/* Return 1 if PC lies in the dynamic symbol resolution code of the
279
   run time loader.  */
280
 
281
int
282
darwin_in_dynsym_resolve_code (CORE_ADDR pc)
283
{
284
  return 0;
285
}
286
 
287
 
288
/* No special symbol handling.  */
289
 
290
static void
291
darwin_special_symbol_handling (void)
292
{
293
}
294
 
295
/* Shared library startup support.  See documentation in solib-svr4.c  */
296
 
297
static void
298
darwin_solib_create_inferior_hook (int from_tty)
299
{
300
  struct minimal_symbol *msymbol;
301
  char **bkpt_namep;
302
  asection *interp_sect;
303
  gdb_byte *interp_name;
304
  CORE_ADDR sym_addr;
305
  CORE_ADDR load_addr = 0;
306
  int load_addr_found = 0;
307
  int loader_found_in_list = 0;
308
  struct so_list *so;
309
  bfd *dyld_bfd = NULL;
310
  struct inferior *inf = current_inferior ();
311
 
312
  /* First, remove all the solib event breakpoints.  Their addresses
313
     may have changed since the last time we ran the program.  */
314
  remove_solib_event_breakpoints ();
315
 
316
  /* Find the program interpreter.  */
317
  interp_name = find_program_interpreter ();
318
  if (!interp_name)
319
    return;
320
 
321
  /* Create a bfd for the interpreter.  */
322
  sym_addr = 0;
323
  dyld_bfd = bfd_openr (interp_name, gnutarget);
324
  if (dyld_bfd)
325
    {
326
      bfd *sub;
327
      sub = bfd_mach_o_fat_extract (dyld_bfd, bfd_object,
328
                                    gdbarch_bfd_arch_info (target_gdbarch));
329
      if (sub)
330
        dyld_bfd = sub;
331
      else
332
        {
333
          bfd_close (dyld_bfd);
334
          dyld_bfd = NULL;
335
        }
336
    }
337
  if (!dyld_bfd)
338
    return;
339
 
340
  if (!inf->attach_flag)
341
    {
342
      /* We find the dynamic linker's base address by examining
343
         the current pc (which should point at the entry point for the
344
         dynamic linker) and subtracting the offset of the entry point.  */
345
      load_addr = (regcache_read_pc (get_current_regcache ())
346
                   - bfd_get_start_address (dyld_bfd));
347
    }
348
  else
349
    {
350
      /* FIXME: todo.
351
         Get address of __DATA.__dyld in exec_bfd, read address at offset 0.
352
      */
353
      return;
354
    }
355
 
356
  /* Now try to set a breakpoint in the dynamic linker.  */
357
  dyld_all_image_addr =
358
    lookup_symbol_from_bfd (dyld_bfd, "_dyld_all_image_infos");
359
 
360
  bfd_close (dyld_bfd);
361
 
362
  if (dyld_all_image_addr == 0)
363
    return;
364
 
365
  dyld_all_image_addr += load_addr;
366
 
367
  darwin_load_image_infos ();
368
 
369
  if (darwin_dyld_version_ok ())
370
    create_solib_event_breakpoint (target_gdbarch, dyld_all_image.notifier);
371
}
372
 
373
static void
374
darwin_clear_solib (void)
375
{
376
  dyld_all_image_addr = 0;
377
  dyld_all_image.version = 0;
378
}
379
 
380
static void
381
darwin_free_so (struct so_list *so)
382
{
383
}
384
 
385
/* The section table is built from bfd sections using bfd VMAs.
386
   Relocate these VMAs according to solib info.  */
387
 
388
static void
389
darwin_relocate_section_addresses (struct so_list *so,
390
                                   struct target_section *sec)
391
{
392
  sec->addr += so->lm_info->lm_addr;
393
  sec->endaddr += so->lm_info->lm_addr;
394
 
395
  /* Best effort to set addr_high/addr_low.  This is used only by
396
     'info sharedlibary'.  */
397
  if (so->addr_high == 0)
398
    {
399
      so->addr_low = sec->addr;
400
      so->addr_high = sec->endaddr;
401
    }
402
  if (sec->endaddr > so->addr_high)
403
    so->addr_high = sec->endaddr;
404
  if (sec->addr < so->addr_low)
405
    so->addr_low = sec->addr;
406
}
407
 
408
static struct symbol *
409
darwin_lookup_lib_symbol (const struct objfile *objfile,
410
                          const char *name,
411
                          const char *linkage_name,
412
                          const domain_enum domain)
413
{
414
  return NULL;
415
}
416
 
417
static bfd *
418
darwin_bfd_open (char *pathname)
419
{
420
  char *found_pathname;
421
  int found_file;
422
  bfd *abfd;
423
  bfd *res;
424
 
425
  /* Search for shared library file.  */
426
  found_pathname = solib_find (pathname, &found_file);
427
  if (found_pathname == NULL)
428
    perror_with_name (pathname);
429
 
430
  /* Open bfd for shared library.  */
431
  abfd = solib_bfd_fopen (found_pathname, found_file);
432
 
433
  res = bfd_mach_o_fat_extract (abfd, bfd_object,
434
                                gdbarch_bfd_arch_info (target_gdbarch));
435
  if (!res)
436
    {
437
      bfd_close (abfd);
438
      make_cleanup (xfree, found_pathname);
439
      error (_("`%s': not a shared-library: %s"),
440
             found_pathname, bfd_errmsg (bfd_get_error ()));
441
    }
442
  return res;
443
}
444
 
445
struct target_so_ops darwin_so_ops;
446
 
447
void
448
_initialize_darwin_solib (void)
449
{
450
  darwin_so_ops.relocate_section_addresses = darwin_relocate_section_addresses;
451
  darwin_so_ops.free_so = darwin_free_so;
452
  darwin_so_ops.clear_solib = darwin_clear_solib;
453
  darwin_so_ops.solib_create_inferior_hook = darwin_solib_create_inferior_hook;
454
  darwin_so_ops.special_symbol_handling = darwin_special_symbol_handling;
455
  darwin_so_ops.current_sos = darwin_current_sos;
456
  darwin_so_ops.open_symbol_file_object = open_symbol_file_object;
457
  darwin_so_ops.in_dynsym_resolve_code = darwin_in_dynsym_resolve_code;
458
  darwin_so_ops.lookup_lib_global_symbol = darwin_lookup_lib_symbol;
459
  darwin_so_ops.bfd_open = darwin_bfd_open;
460
}

powered by: WebSVN 2.1.0

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