From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2921 invoked by alias); 23 Jan 2009 15:54:10 -0000 Received: (qmail 2904 invoked by uid 22791); 23 Jan 2009 15:54:06 -0000 X-SWARE-Spam-Status: No, hits=-2.0 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_93 X-Spam-Check-By: sourceware.org Received: from mel.act-europe.fr (HELO mel.act-europe.fr) (212.99.106.210) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 23 Jan 2009 15:54:00 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id 4286629002C for ; Fri, 23 Jan 2009 16:53:57 +0100 (CET) Received: from mel.act-europe.fr ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id iV-pEyC61nBA for ; Fri, 23 Jan 2009 16:53:55 +0100 (CET) Received: from province.act-europe.fr (province.act-europe.fr [10.10.0.214]) by mel.act-europe.fr (Postfix) with ESMTP id DCD66290009 for ; Fri, 23 Jan 2009 16:53:55 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by filtered-province.act-europe.fr (Postfix) with ESMTP id B46C9165CA6 for ; Fri, 23 Jan 2009 16:53:55 +0100 (CET) Received: from province.act-europe.fr ([127.0.0.1]) by localhost (province.act-europe.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id yhkYvhO+3laP for ; Fri, 23 Jan 2009 16:53:55 +0100 (CET) Received: from [IPv6:::1] (province.act-europe.fr [10.10.0.214]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (No client certificate requested) by province.act-europe.fr (Postfix) with ESMTPSA id DD369165CA4 for ; Fri, 23 Jan 2009 16:53:54 +0100 (CET) Message-Id: <2BC5ADA3-B225-4760-822B-C8E31FD999A2@adacore.com> From: Tristan Gingold To: gdb-patches@sourceware.org In-Reply-To: <20090108140918.GA70183@ulanbator.act-europe.fr> Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: quoted-printable Mime-Version: 1.0 (Apple Message framework v930.3) Subject: Ping: [RFA] Add support of shared lib for Darwin Date: Fri, 23 Jan 2009 15:54:00 -0000 References: <20090108140918.GA70183@ulanbator.act-europe.fr> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-01/txt/msg00467.txt.bz2 Just a ping for this patch. (Ulrich has committed his patch). Tristan. On Jan 8, 2009, at 3:09 PM, Tristan Gingold wrote: > Hi, > > this patch is a slightly rewritten version of a previous one. > > It adds support for shared libraries for Darwin. It is based on a > patch from Ulrich (http://sourceware.org/ml/gdb-patches/2008-12/msg00317.= html=20 > ) > which made bfd file opening more flexible. > > Tristan. > > 2009-01-08 Tristan Gingold > > * machoread.c (macho_symfile_read): Read minsymtab also from > shared libraries. > (macho_symfile_read): Try to read dwarf2 frame info from main > object file, but not from OSO files. > (macho_symfile_offsets): Update section names for latest BFD > changes. > * i386-darwin-tdep.c (i386_darwin_init_abi): Call set_solib_ops. > (x86_darwin_init_abi_64): Ditto. > * configure.tgt: Add solib.o solib-darwin.o for Darwin. > > > diff -u -r1.206 configure.tgt > --- configure.tgt 27 Nov 2008 09:23:01 -0000 1.206 > +++ configure.tgt 8 Jan 2009 13:55:06 -0000 > @@ -148,7 +148,7 @@ > i[34567]86-*-darwin*) > # Target: Darwin/i386 > gdb_target_obs=3D"amd64-tdep.o i386-tdep.o i387-tdep.o \ > - i386-darwin-tdep.o" > + i386-darwin-tdep.o solib.o solib-darwin.o" > ;; > i[34567]86-*-dicos*) > # Target: DICOS/i386 > diff -u -r1.2 i386-darwin-tdep.c > --- i386-darwin-tdep.c 3 Jan 2009 05:57:51 -0000 1.2 > +++ i386-darwin-tdep.c 8 Jan 2009 13:55:07 -0000 > @@ -39,6 +39,8 @@ > #include "frame.h" > #include "gdb_assert.h" > #include "i386-darwin-tdep.h" > +#include "solib.h" > +#include "solib-darwin.h" > > /* Offsets into the struct i386_thread_state where we'll find the=20=20 > saved regs. > From and i386-tdep.h. */ > @@ -114,6 +116,8 @@ > tdep->sc_num_regs =3D 16; > > tdep->jb_pc_offset =3D 20; > + > + set_solib_ops (gdbarch, &darwin_so_ops); > } > > static void > @@ -131,6 +135,8 @@ > tdep->sc_num_regs =3D ARRAY_SIZE=20=20 > (amd64_darwin_thread_state_reg_offset); > > tdep->jb_pc_offset =3D 148; > + > + set_solib_ops (gdbarch, &darwin_so_ops); > } > > static enum gdb_osabi > diff -u -r1.2 machoread.c > --- machoread.c 3 Jan 2009 05:57:52 -0000 1.2 > +++ machoread.c 8 Jan 2009 13:55:07 -0000 > @@ -538,7 +538,7 @@ > /* Get symbols from the symbol table only if the file is an=20=20 > executable. > The symbol table of object files is not relocated and is=20=20 > expected to > be in the executable. */ > - if (bfd_get_file_flags (abfd) & EXEC_P) > + if (bfd_get_file_flags (abfd) & (EXEC_P | DYNAMIC)) > { > /* Process the normal symbol table first. */ > storage_needed =3D bfd_get_symtab_upper_bound (objfile->obfd); > @@ -566,6 +566,12 @@ > > install_minimal_symbols (objfile); > > + /* Try to read .eh_frame / .debug_frame. */ > + /* First, locate these sections. We ignore the result status > + as it only checks for debug info. */ > + dwarf2_has_info (objfile); > + dwarf2_build_frame_info (objfile); > + > /* Check for DSYM file. */ > dsym_bfd =3D macho_check_dsym (objfile); > if (dsym_bfd !=3D NULL) > @@ -588,7 +594,7 @@ > /* Now recurse: read dwarf from dsym. */ > symbol_file_add_from_bfd (dsym_bfd, 0, NULL, 0, 0); > > - /* Don't try to read dwarf2 from main file. */ > + /* Don't try to read dwarf2 from main file or shared libraries.=20=20= =20 > */ > return; > } > } > @@ -599,9 +605,8 @@ > dwarf2_build_psymtabs (objfile, mainline); > } > > - /* FIXME: kettenis/20030504: This still needs to be integrated with > - dwarf2read.c in a better way. */ > - dwarf2_build_frame_info (objfile); > + /* Do not try to read .eh_frame/.debug_frame as they are not=20=20 > relocated > + and dwarf2_build_frame_info cannot deal with unrelocated=20=20 > sections. */ > > /* Then the oso. */ > if (oso_vector !=3D NULL) > @@ -661,10 +666,11 @@ > { > const char *bfd_sect_name =3D osect->the_bfd_section->name; > int sect_index =3D osect->the_bfd_section->index; > - > - if (strcmp (bfd_sect_name, "LC_SEGMENT.__TEXT") =3D=3D 0) > - objfile->sect_index_text =3D sect_index; > - else if (strcmp (bfd_sect_name, "LC_SEGMENT.__TEXT.__text")=20=20 > =3D=3D 0) > + > + if (strncmp (bfd_sect_name, "LC_SEGMENT.", 11) =3D=3D 0) > + bfd_sect_name +=3D 11; > + if (strcmp (bfd_sect_name, "__TEXT") =3D=3D 0 > + || strcmp (bfd_sect_name, "__TEXT.__text") =3D=3D 0) > objfile->sect_index_text =3D sect_index; > } > } > --- /dev/null 2009-01-08 14:53:34.000000000 +0100 > +++ solib-darwin.h 2009-01-08 15:01:55.000000000 +0100 > @@ -0,0 +1,28 @@ > +/* Handle shared libraries for GDB, the GNU Debugger. > + > + Copyright (C) 2009 Free Software Foundation, Inc. > + > + This file is part of GDB. > + > + This program is free software; you can redistribute it and/or=20=20 > modify > + it under the terms of the GNU General Public License as=20=20 > published by > + the Free Software Foundation; either version 3 of the License, or > + (at your option) any later version. > + > + This program is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + GNU General Public License for more details. > + > + You should have received a copy of the GNU General Public License > + along with this program. If not, see >. */ > + > +#ifndef SOLIB_DARWIN_H > +#define SOLIB_DARWIN_H > + > +struct objfile; > +struct target_so_ops; > + > +extern struct target_so_ops darwin_so_ops; > + > +#endif /* solib-darwin.h */ > --- /dev/null 2009-01-08 14:53:34.000000000 +0100 > +++ solib-darwin.c 2009-01-08 15:02:07.000000000 +0100 > @@ -0,0 +1,463 @@ > +/* Handle Darwin shared libraries for GDB, the GNU Debugger. > + > + Copyright (C) 2009 Free Software Foundation, Inc. > + > + This file is part of GDB. > + > + This program is free software; you can redistribute it and/or=20=20 > modify > + it under the terms of the GNU General Public License as=20=20 > published by > + the Free Software Foundation; either version 3 of the License, or > + (at your option) any later version. > + > + This program is distributed in the hope that it will be useful, > + but WITHOUT ANY WARRANTY; without even the implied warranty of > + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + GNU General Public License for more details. > + > + You should have received a copy of the GNU General Public License > + along with this program. If not, see >. */ > + > +#include "defs.h" > + > +#include "symtab.h" > +#include "bfd.h" > +#include "symfile.h" > +#include "objfiles.h" > +#include "gdbcore.h" > +#include "target.h" > +#include "inferior.h" > +#include "gdbthread.h" > + > +#include "gdb_assert.h" > + > +#include "solist.h" > +#include "solib.h" > +#include "solib-svr4.h" > + > +#include "bfd-target.h" > +#include "elf-bfd.h" > +#include "exec.h" > +#include "auxv.h" > +#include "exceptions.h" > +#include "mach-o.h" > + > +struct gdb_dyld_image_info > +{ > + /* Base address (which corresponds to the Mach-O header). */ > + CORE_ADDR mach_header; > + /* Image file path. */ > + CORE_ADDR file_path; > + /* st.m_time of image file. */ > + unsigned long mtime; > +}; > + > +/* Content of inferior dyld_all_image_infos structure. */ > +struct gdb_dyld_all_image_infos > +{ > + /* Version (1). */ > + unsigned long version; > + /* Number of images. */ > + unsigned long count; > + /* Image description. */ > + CORE_ADDR info; > + /* Notifier (function called when a library is added or=20=20 > removed). */ > + CORE_ADDR notifier; > +}; > + > +/* Current all_image_infos version. */ > +#define DYLD_VERSION 1 > + > +/* Address of structure dyld_all_image_infos in inferior. */ > +static CORE_ADDR dyld_all_image_addr; > + > +/* Gdb copy of dyld_all_info_infos. */ > +static struct gdb_dyld_all_image_infos dyld_all_image; > + > +/* Read dyld_all_image from inferior. */ > +static void > +darwin_load_image_infos (void) > +{ > + gdb_byte buf[24]; > + struct type *ptr_type =3D builtin_type (target_gdbarch)-=20 > >builtin_data_ptr; > + int len; > + > + len =3D 4 + 4 + 2 * ptr_type->length; > + memset (&dyld_all_image, 0, sizeof (dyld_all_image)); > + > + if (dyld_all_image_addr =3D=3D 0) > + return; > + > + if (target_read_memory (dyld_all_image_addr, buf, len)) > + return; > + > + dyld_all_image.version =3D extract_unsigned_integer (buf, 4); > + if (dyld_all_image.version !=3D DYLD_VERSION) > + return; > + > + dyld_all_image.count =3D extract_unsigned_integer (buf + 4, 4); > + dyld_all_image.info =3D extract_typed_address (buf + 8, ptr_type); > + dyld_all_image.notifier =3D extract_typed_address > + (buf + 8 + ptr_type->length, ptr_type); > +} > + > +/* Link map info to include in an allocated so_list entry */ > + > +struct lm_info > +{ > + /* The target location of lm. */ > + CORE_ADDR lm_addr; > +}; > + > +struct darwin_so_list > +{ > + struct so_list sl; > + struct lm_info li; > +}; > + > +/* Local function prototypes */ > + > +static int match_main (char *); > + > +static CORE_ADDR bfd_lookup_symbol (bfd *, char *); > + > +/* Return non-zero if GDB_SO_NAME and INFERIOR_SO_NAME represent > + the same shared library. */ > + > +static int > +darwin_same (struct so_list *gdb, struct so_list *inferior) > +{ > + return strcmp (gdb->so_original_name, inferior->so_original_name)=20=20 > =3D=3D 0; > +} > + > +/* Lookup the value for a specific symbol. */ > +static CORE_ADDR > +bfd_lookup_symbol (bfd *abfd, char *symname) > +{ > + long storage_needed; > + asymbol **symbol_table; > + unsigned int number_of_symbols; > + unsigned int i; > + CORE_ADDR symaddr =3D 0; > + > + storage_needed =3D bfd_get_symtab_upper_bound (abfd); > + > + if (storage_needed > 0) > + { > + symbol_table =3D (asymbol **) xmalloc (storage_needed); > + number_of_symbols =3D bfd_canonicalize_symtab (abfd,=20=20 > symbol_table); > + > + for (i =3D 0; i < number_of_symbols; i++) > + { > + asymbol *sym =3D symbol_table[i]; > + if (strcmp (sym->name, symname) =3D=3D 0 > + && (sym->section->flags & (SEC_CODE | SEC_DATA)) !=3D 0) > + { > + /* BFD symbols are section relative. */ > + symaddr =3D sym->value + sym->section->vma; > + break; > + } > + } > + xfree (symbol_table); > + } > + > + return symaddr; > +} > + > +/* Return program interpreter string. */ > +static gdb_byte * > +find_program_interpreter (void) > +{ > + gdb_byte *buf =3D NULL; > + > + /* If we have an exec_bfd, use its section table. */ > + if (exec_bfd) > + { > + struct bfd_section *dylinker_sect; > + > + dylinker_sect =3D bfd_get_section_by_name (exec_bfd,=20=20 > "LC_LOAD_DYLINKER"); > + if (dylinker_sect !=3D NULL) > + { > + int sect_size =3D bfd_section_size (exec_bfd, dylinker_sect); > + > + buf =3D xmalloc (sect_size); > + if (bfd_get_section_contents (exec_bfd, dylinker_sect, > + buf, 0, sect_size)) > + return buf; > + xfree (buf); > + } > + } > + > + /* If we didn't find it, read from memory. > + FIXME: todo. */ > + return buf; > +} > + > +/* Not used. I don't see how the main symbol file can be found: the > + interpreter name is needed and it is known from the executable=20=20 > file. > + Note that darwin-nat.c implements pid_to_exec_file. */ > +static int > +open_symbol_file_object (void *from_ttyp) > +{ > + return 0; > +} > + > +/* Build a list of currently loaded shared objects. See solib-=20 > svr4.c */ > +static struct so_list * > +darwin_current_sos (void) > +{ > + struct type *ptr_type =3D builtin_type (target_gdbarch)-=20 > >builtin_data_ptr; > + int ptr_len =3D TYPE_LENGTH (ptr_type); > + unsigned int image_info_size; > + CORE_ADDR lm; > + struct so_list *head =3D NULL; > + struct so_list *tail =3D NULL; > + int i; > + > + /* Be sure image infos are loaded. */ > + darwin_load_image_infos (); > + > + if (dyld_all_image.version !=3D DYLD_VERSION) > + return NULL; > + > + image_info_size =3D ptr_len * 3; > + > + /* Read infos for each solib. */ > + for (i =3D 0; i < dyld_all_image.count; i++) > + { > + CORE_ADDR info =3D dyld_all_image.info + i * image_info_size; > + char buf[image_info_size]; > + CORE_ADDR load_addr; > + CORE_ADDR path_addr; > + char *file_path; > + int errcode; > + struct darwin_so_list *dnew; > + struct so_list *new; > + struct cleanup *old_chain; > + > + /* Read image info from inferior. */ > + if (target_read_memory (info, buf, image_info_size)) > + break; > + > + load_addr =3D extract_typed_address (buf, ptr_type); > + path_addr =3D extract_typed_address (buf + ptr_len, ptr_type); > + > + target_read_string (path_addr, &file_path, > + SO_NAME_MAX_PATH_SIZE - 1, &errcode); > + if (errcode) > + break; > + > + /* Ignore first entry as this is the executable itself. */ > + if (i =3D=3D 0) > + continue; > + > + /* Create and fill the new so_list element. */ > + dnew =3D XZALLOC (struct darwin_so_list); > + new =3D &dnew->sl; > + old_chain =3D make_cleanup (xfree, dnew); > + > + new->lm_info =3D &dnew->li; > + > + strncpy (new->so_name, file_path, SO_NAME_MAX_PATH_SIZE - 1); > + new->so_name[SO_NAME_MAX_PATH_SIZE - 1] =3D '\0'; > + strcpy (new->so_original_name, new->so_name); > + xfree (file_path); > + new->lm_info->lm_addr =3D load_addr; > + > + if (head =3D=3D NULL) > + head =3D new; > + else > + tail->next =3D new; > + tail =3D new; > + > + discard_cleanups (old_chain); > + } > + > + return head; > +} > + > +/* Return 1 if PC lies in the dynamic symbol resolution code of the > + run time loader. */ > +int > +darwin_in_dynsym_resolve_code (CORE_ADDR pc) > +{ > + return 0; > +} > + > + > +/* No special symbol handling. */ > +static void > +darwin_special_symbol_handling (void) > +{ > +} > + > +/* Shared library startup support. See documentation in solib-=20 > svr4.c */ > +static void > +darwin_solib_create_inferior_hook (void) > +{ > + struct minimal_symbol *msymbol; > + char **bkpt_namep; > + asection *interp_sect; > + gdb_byte *interp_name; > + CORE_ADDR sym_addr; > + CORE_ADDR load_addr =3D 0; > + int load_addr_found =3D 0; > + int loader_found_in_list =3D 0; > + struct so_list *so; > + bfd *dyld_bfd =3D NULL; > + struct inferior *inf =3D current_inferior (); > + > + /* First, remove all the solib event breakpoints. Their addresses > + may have changed since the last time we ran the program. */ > + remove_solib_event_breakpoints (); > + > + /* Find the program interpreter. */ > + interp_name =3D find_program_interpreter (); > + if (!interp_name) > + return; > + > + /* Create a bfd for the interpreter. */ > + sym_addr =3D 0; > + dyld_bfd =3D bfd_openr (interp_name, gnutarget); > + if (dyld_bfd) > + { > + bfd *sub; > + sub =3D bfd_mach_o_fat_extract (dyld_bfd, bfd_object, > + gdbarch_bfd_arch_info (current_gdbarch)); > + if (sub) > + dyld_bfd =3D sub; > + else > + { > + bfd_close (dyld_bfd); > + dyld_bfd =3D NULL; > + } > + } > + if (!dyld_bfd) > + { > + xfree (interp_name); > + return; > + } > + > + if (!inf->attach_flag) > + { > + /* We find the dynamic linker's base address by examining > + the current pc (which should point at the entry point for the > + dynamic linker) and subtracting the offset of the entry point. */ > + load_addr =3D (read_pc () - bfd_get_start_address (dyld_bfd)); > + } > + else > + { > + /* FIXME: todo. > + Get address of __DATA.__dyld in exec_bfd, read address at offset 0 > + */ > + xfree (interp_name); > + return; > + } > + > + /* Now try to set a breakpoint in the dynamic linker. */ > + dyld_all_image_addr =3D > + bfd_lookup_symbol (dyld_bfd, "_dyld_all_image_infos"); > + > + bfd_close (dyld_bfd); > + xfree (interp_name); > + > + if (dyld_all_image_addr =3D=3D 0) > + return; > + > + dyld_all_image_addr +=3D load_addr; > + > + darwin_load_image_infos (); > + > + if (dyld_all_image.version =3D=3D DYLD_VERSION) > + create_solib_event_breakpoint (dyld_all_image.notifier); > +} > + > +static void > +darwin_clear_solib (void) > +{ > + dyld_all_image_addr =3D 0; > + dyld_all_image.version =3D 0; > +} > + > +static void > +darwin_free_so (struct so_list *so) > +{ > +} > + > +/* The section table is built from bfd sections using bfd VMAs. > + Relocate these VMAs according to solib info. */ > +static void > +darwin_relocate_section_addresses (struct so_list *so, > + struct section_table *sec) > +{ > + sec->addr +=3D so->lm_info->lm_addr; > + sec->endaddr +=3D so->lm_info->lm_addr; > + > + /* Best effort to set addr_high/addr_low. This is used only by > + 'info sharedlibary'. */ > + if (so->addr_high =3D=3D 0) > + { > + so->addr_low =3D sec->addr; > + so->addr_high =3D sec->endaddr; > + } > + if (sec->endaddr > so->addr_high) > + so->addr_high =3D sec->endaddr; > + if (sec->addr < so->addr_low) > + so->addr_low =3D sec->addr; > +} > +=0C > +static struct symbol * > +darwin_lookup_lib_symbol (const struct objfile *objfile, > + const char *name, > + const char *linkage_name, > + const domain_enum domain) > +{ > + return NULL; > +} > + > +static bfd * > +darwin_bfd_open (char *pathname) > +{ > + char *found_pathname; > + int found_file; > + bfd *abfd; > + bfd *res; > + > + /* Search for shared library file. */ > + found_pathname =3D solib_find (pathname, &found_file); > + if (found_pathname =3D=3D NULL) > + perror_with_name (pathname); > + > + /* Open bfd for shared library. */ > + abfd =3D solib_bfd_fopen (found_pathname, found_file); > + > + res =3D bfd_mach_o_fat_extract (abfd, bfd_object, > + gdbarch_bfd_arch_info (current_gdbarch)); > + if (!res) > + { > + bfd_close (abfd); > + make_cleanup (xfree, found_pathname); > + error (_("`%s': not a shared-library: %s"), > + found_pathname, bfd_errmsg (bfd_get_error ())); > + } > + return res; > +} > + > +extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-=20 > prototypes */ > + > +struct target_so_ops darwin_so_ops; > + > +void > +_initialize_darwin_solib (void) > +{ > + darwin_so_ops.relocate_section_addresses =3D=20=20 > darwin_relocate_section_addresses; > + darwin_so_ops.free_so =3D darwin_free_so; > + darwin_so_ops.clear_solib =3D darwin_clear_solib; > + darwin_so_ops.solib_create_inferior_hook =3D=20=20 > darwin_solib_create_inferior_hook; > + darwin_so_ops.special_symbol_handling =3D=20=20 > darwin_special_symbol_handling; > + darwin_so_ops.current_sos =3D darwin_current_sos; > + darwin_so_ops.open_symbol_file_object =3D open_symbol_file_object; > + darwin_so_ops.in_dynsym_resolve_code =3D=20=20 > darwin_in_dynsym_resolve_code; > + darwin_so_ops.lookup_lib_global_symbol =3D darwin_lookup_lib_symbol; > + darwin_so_ops.same =3D darwin_same; > + darwin_so_ops.bfd_open =3D darwin_bfd_open; > +} >