1/* Provide legacy r_debug and link_map support for SVR4-like native targets. 2 3 Copyright (C) 2000, 2001, 2006, 2007 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#include "gdbcore.h" 22#include "solib-svr4.h" 23 24#ifdef HAVE_LINK_H 25 26#ifdef HAVE_NLIST_H 27/* nlist.h needs to be included before link.h on some older *BSD systems. */ 28#include <nlist.h> 29#endif 30 31#include <link.h> 32 33/* Fetch (and possibly build) an appropriate link_map_offsets structure 34 for native targets using struct definitions from link.h. */ 35 36static struct link_map_offsets * 37legacy_svr4_fetch_link_map_offsets (void) 38{ 39 static struct link_map_offsets lmo; 40 static struct link_map_offsets *lmp = 0; 41#if defined (HAVE_STRUCT_LINK_MAP32) 42 static struct link_map_offsets lmo32; 43 static struct link_map_offsets *lmp32 = 0; 44#endif 45 46#ifndef offsetof 47#define offsetof(TYPE, MEMBER) ((unsigned long) &((TYPE *)0)->MEMBER) 48#endif 49#define fieldsize(TYPE, MEMBER) (sizeof (((TYPE *)0)->MEMBER)) 50 51 if (lmp == 0) 52 { 53 lmp = &lmo; 54 55#ifdef HAVE_STRUCT_LINK_MAP_WITH_L_MEMBERS 56 lmo.r_version_offset = offsetof (struct r_debug, r_version); 57 lmo.r_version_size = fieldsize (struct r_debug, r_version); 58 lmo.r_map_offset = offsetof (struct r_debug, r_map); 59 lmo.r_ldsomap_offset = -1; 60 61 lmo.link_map_size = sizeof (struct link_map); 62 63 lmo.l_addr_offset = offsetof (struct link_map, l_addr); 64 lmo.l_next_offset = offsetof (struct link_map, l_next); 65 lmo.l_ld_offset = offsetof (struct link_map, l_ld); 66 lmo.l_prev_offset = offsetof (struct link_map, l_prev); 67 lmo.l_name_offset = offsetof (struct link_map, l_name); 68#else /* !defined(HAVE_STRUCT_LINK_MAP_WITH_L_MEMBERS) */ 69#ifdef HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS 70 lmo.link_map_size = sizeof (struct link_map); 71 72 lmo.l_addr_offset = offsetof (struct link_map, lm_addr); 73 lmo.l_next_offset = offsetof (struct link_map, lm_next); 74 /* FIXME: Is this the right field name, or is it available at all? */ 75 lmo.l_ld_offset = offsetof (struct link_map, lm_ld); 76 lmo.l_name_offset = offsetof (struct link_map, lm_name); 77#else /* !defined(HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS) */ 78#if HAVE_STRUCT_SO_MAP_WITH_SOM_MEMBERS 79 lmo.link_map_size = sizeof (struct so_map); 80 81 lmo.l_addr_offset = offsetof (struct so_map, som_addr); 82 lmo.l_next_offset = offsetof (struct so_map, som_next); 83 lmo.l_name_offset = offsetof (struct so_map, som_path); 84 /* FIXME: Is the address of the dynamic table available? */ 85 lmo.l_ld_offset = -1; 86#endif /* HAVE_STRUCT_SO_MAP_WITH_SOM_MEMBERS */ 87#endif /* HAVE_STRUCT_LINK_MAP_WITH_LM_MEMBERS */ 88#endif /* HAVE_STRUCT_LINK_MAP_WITH_L_MEMBERS */ 89 } 90 91#if defined (HAVE_STRUCT_LINK_MAP32) 92 if (lmp32 == 0) 93 { 94 lmp32 = &lmo32; 95 96 lmo32.r_version_offset = offsetof (struct r_debug32, r_version); 97 lmo32.r_version_size = fieldsize (struct r_debug32, r_version); 98 lmo32.r_map_offset = offsetof (struct r_debug32, r_map); 99 lmo32.r_ldsomap_offset = -1; 100 101 lmo32.link_map_size = sizeof (struct link_map32); 102 103 lmo32.l_addr_offset = offsetof (struct link_map32, l_addr); 104 lmo32.l_next_offset = offsetof (struct link_map32, l_next); 105 lmo32.l_prev_offset = offsetof (struct link_map32, l_prev); 106 lmo32.l_name_offset = offsetof (struct link_map32, l_name); 107 } 108#endif /* defined (HAVE_STRUCT_LINK_MAP32) */ 109 110#if defined (HAVE_STRUCT_LINK_MAP32) 111 if (exec_bfd != NULL) 112 { 113 if (bfd_get_arch_size (exec_bfd) == 32) 114 return lmp32; 115 } 116 if (gdbarch_ptr_bit (current_gdbarch) == 32) 117 return lmp32; 118#endif 119 return lmp; 120} 121 122#endif /* HAVE_LINK_H */ 123 124extern initialize_file_ftype _initialize_svr4_lm; /* -Wmissing-prototypes */ 125 126void 127_initialize_svr4_lm (void) 128{ 129#ifdef HAVE_LINK_H 130 legacy_svr4_fetch_link_map_offsets_hook = legacy_svr4_fetch_link_map_offsets; 131#endif /* HAVE_LINK_H */ 132} 133