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