2009-08-10 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 "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   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
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.  */
101   dyld_all_image.version = extract_unsigned_integer (buf, 4, byte_order);
102   if (dyld_all_image.version != DYLD_VERSION)
103     return;
104
105   dyld_all_image.count = extract_unsigned_integer (buf + 4, 4, byte_order);
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
113 struct lm_info
114 {
115   /* The target location of lm.  */
116   CORE_ADDR lm_addr;
117 };
118
119 struct 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.  */
128 static CORE_ADDR
129 lookup_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.  */
162
163 static gdb_byte *
164 find_program_interpreter (void)
165 {
166   gdb_byte *buf = NULL;
167
168   /* If we have an exec_bfd, get the interpreter from the load commands.  */
169   if (exec_bfd)
170     {
171       bfd_mach_o_load_command *cmd;
172       
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;
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.  */
186 static int
187 open_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  */
193 static struct so_list *
194 darwin_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.  */
265 int
266 darwin_in_dynsym_resolve_code (CORE_ADDR pc)
267 {
268   return 0;
269 }
270
271
272 /* No special symbol handling.  */
273 static void
274 darwin_special_symbol_handling (void)
275 {
276 }
277
278 /* Shared library startup support.  See documentation in solib-svr4.c  */
279 static void
280 darwin_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,
310                                     gdbarch_bfd_arch_info (target_gdbarch));
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)
320     return;
321   
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.  */
327       load_addr = (regcache_read_pc (get_current_regcache ())
328                    - bfd_get_start_address (dyld_bfd));
329     }
330   else
331     {
332       /* FIXME: todo.
333          Get address of __DATA.__dyld in exec_bfd, read address at offset 0.
334       */
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);
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)
352     create_solib_event_breakpoint (target_gdbarch, dyld_all_image.notifier);
353 }
354
355 static void
356 darwin_clear_solib (void)
357 {
358   dyld_all_image_addr = 0;
359   dyld_all_image.version = 0;
360 }
361
362 static void
363 darwin_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.  */
369 static void
370 darwin_relocate_section_addresses (struct so_list *so,
371                                    struct target_section *sec)
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
389 static struct symbol *
390 darwin_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
398 static bfd *
399 darwin_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,
415                                 gdbarch_bfd_arch_info (target_gdbarch));
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
426 struct target_so_ops darwin_so_ops;
427
428 void
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 }