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