2009-02-04 Tristan Gingold <gingold@adacore.com>
[external/binutils.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 }