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