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