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