GDB (API)
|
00001 /* nto-tdep.c - general QNX Neutrino target functionality. 00002 00003 Copyright (C) 2003-2013 Free Software Foundation, Inc. 00004 00005 Contributed by QNX Software Systems Ltd. 00006 00007 This file is part of GDB. 00008 00009 This program is free software; you can redistribute it and/or modify 00010 it under the terms of the GNU General Public License as published by 00011 the Free Software Foundation; either version 3 of the License, or 00012 (at your option) any later version. 00013 00014 This program is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 GNU General Public License for more details. 00018 00019 You should have received a copy of the GNU General Public License 00020 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 00021 00022 #include "defs.h" 00023 #include "gdb_stat.h" 00024 #include "gdb_string.h" 00025 #include "nto-tdep.h" 00026 #include "top.h" 00027 #include "inferior.h" 00028 #include "gdbarch.h" 00029 #include "bfd.h" 00030 #include "elf-bfd.h" 00031 #include "solib-svr4.h" 00032 #include "gdbcore.h" 00033 #include "objfiles.h" 00034 00035 #include <string.h> 00036 00037 #ifdef __CYGWIN__ 00038 #include <sys/cygwin.h> 00039 #endif 00040 00041 #ifdef __CYGWIN__ 00042 static char default_nto_target[] = "C:\\QNXsdk\\target\\qnx6"; 00043 #elif defined(__sun__) || defined(linux) 00044 static char default_nto_target[] = "/opt/QNXsdk/target/qnx6"; 00045 #else 00046 static char default_nto_target[] = ""; 00047 #endif 00048 00049 struct nto_target_ops current_nto_target; 00050 00051 static char * 00052 nto_target (void) 00053 { 00054 char *p = getenv ("QNX_TARGET"); 00055 00056 #ifdef __CYGWIN__ 00057 static char buf[PATH_MAX]; 00058 if (p) 00059 cygwin_conv_path (CCP_WIN_A_TO_POSIX, p, buf, PATH_MAX); 00060 else 00061 cygwin_conv_path (CCP_WIN_A_TO_POSIX, default_nto_target, buf, PATH_MAX); 00062 return buf; 00063 #else 00064 return p ? p : default_nto_target; 00065 #endif 00066 } 00067 00068 /* Take a string such as i386, rs6000, etc. and map it onto CPUTYPE_X86, 00069 CPUTYPE_PPC, etc. as defined in nto-share/dsmsgs.h. */ 00070 int 00071 nto_map_arch_to_cputype (const char *arch) 00072 { 00073 if (!strcmp (arch, "i386") || !strcmp (arch, "x86")) 00074 return CPUTYPE_X86; 00075 if (!strcmp (arch, "rs6000") || !strcmp (arch, "powerpc")) 00076 return CPUTYPE_PPC; 00077 if (!strcmp (arch, "mips")) 00078 return CPUTYPE_MIPS; 00079 if (!strcmp (arch, "arm")) 00080 return CPUTYPE_ARM; 00081 if (!strcmp (arch, "sh")) 00082 return CPUTYPE_SH; 00083 return CPUTYPE_UNKNOWN; 00084 } 00085 00086 int 00087 nto_find_and_open_solib (char *solib, unsigned o_flags, char **temp_pathname) 00088 { 00089 char *buf, *arch_path, *nto_root, *endian; 00090 const char *base; 00091 const char *arch; 00092 int arch_len, len, ret; 00093 #define PATH_FMT \ 00094 "%s/lib:%s/usr/lib:%s/usr/photon/lib:%s/usr/photon/dll:%s/lib/dll" 00095 00096 nto_root = nto_target (); 00097 if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name, "i386") == 0) 00098 { 00099 arch = "x86"; 00100 endian = ""; 00101 } 00102 else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name, 00103 "rs6000") == 0 00104 || strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name, 00105 "powerpc") == 0) 00106 { 00107 arch = "ppc"; 00108 endian = "be"; 00109 } 00110 else 00111 { 00112 arch = gdbarch_bfd_arch_info (target_gdbarch ())->arch_name; 00113 endian = gdbarch_byte_order (target_gdbarch ()) 00114 == BFD_ENDIAN_BIG ? "be" : "le"; 00115 } 00116 00117 /* In case nto_root is short, add strlen(solib) 00118 so we can reuse arch_path below. */ 00119 00120 arch_len = (strlen (nto_root) + strlen (arch) + strlen (endian) + 2 00121 + strlen (solib)); 00122 arch_path = alloca (arch_len); 00123 xsnprintf (arch_path, arch_len, "%s/%s%s", nto_root, arch, endian); 00124 00125 len = strlen (PATH_FMT) + strlen (arch_path) * 5 + 1; 00126 buf = alloca (len); 00127 xsnprintf (buf, len, PATH_FMT, arch_path, arch_path, arch_path, arch_path, 00128 arch_path); 00129 00130 base = lbasename (solib); 00131 ret = openp (buf, OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, base, o_flags, 00132 temp_pathname); 00133 if (ret < 0 && base != solib) 00134 { 00135 xsnprintf (arch_path, arch_len, "/%s", solib); 00136 ret = open (arch_path, o_flags, 0); 00137 if (temp_pathname) 00138 { 00139 if (ret >= 0) 00140 *temp_pathname = gdb_realpath (arch_path); 00141 else 00142 *temp_pathname = NULL; 00143 } 00144 } 00145 return ret; 00146 } 00147 00148 void 00149 nto_init_solib_absolute_prefix (void) 00150 { 00151 char buf[PATH_MAX * 2], arch_path[PATH_MAX]; 00152 char *nto_root, *endian; 00153 const char *arch; 00154 00155 nto_root = nto_target (); 00156 if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name, "i386") == 0) 00157 { 00158 arch = "x86"; 00159 endian = ""; 00160 } 00161 else if (strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name, 00162 "rs6000") == 0 00163 || strcmp (gdbarch_bfd_arch_info (target_gdbarch ())->arch_name, 00164 "powerpc") == 0) 00165 { 00166 arch = "ppc"; 00167 endian = "be"; 00168 } 00169 else 00170 { 00171 arch = gdbarch_bfd_arch_info (target_gdbarch ())->arch_name; 00172 endian = gdbarch_byte_order (target_gdbarch ()) 00173 == BFD_ENDIAN_BIG ? "be" : "le"; 00174 } 00175 00176 xsnprintf (arch_path, sizeof (arch_path), "%s/%s%s", nto_root, arch, endian); 00177 00178 xsnprintf (buf, sizeof (buf), "set solib-absolute-prefix %s", arch_path); 00179 execute_command (buf, 0); 00180 } 00181 00182 char ** 00183 nto_parse_redirection (char *pargv[], const char **pin, const char **pout, 00184 const char **perr) 00185 { 00186 char **argv; 00187 char *in, *out, *err, *p; 00188 int argc, i, n; 00189 00190 for (n = 0; pargv[n]; n++); 00191 if (n == 0) 00192 return NULL; 00193 in = ""; 00194 out = ""; 00195 err = ""; 00196 00197 argv = xcalloc (n + 1, sizeof argv[0]); 00198 argc = n; 00199 for (i = 0, n = 0; n < argc; n++) 00200 { 00201 p = pargv[n]; 00202 if (*p == '>') 00203 { 00204 p++; 00205 if (*p) 00206 out = p; 00207 else 00208 out = pargv[++n]; 00209 } 00210 else if (*p == '<') 00211 { 00212 p++; 00213 if (*p) 00214 in = p; 00215 else 00216 in = pargv[++n]; 00217 } 00218 else if (*p++ == '2' && *p++ == '>') 00219 { 00220 if (*p == '&' && *(p + 1) == '1') 00221 err = out; 00222 else if (*p) 00223 err = p; 00224 else 00225 err = pargv[++n]; 00226 } 00227 else 00228 argv[i++] = pargv[n]; 00229 } 00230 *pin = in; 00231 *pout = out; 00232 *perr = err; 00233 return argv; 00234 } 00235 00236 /* The struct lm_info, lm_addr, and nto_truncate_ptr are copied from 00237 solib-svr4.c to support nto_relocate_section_addresses 00238 which is different from the svr4 version. */ 00239 00240 /* Link map info to include in an allocated so_list entry */ 00241 00242 struct lm_info 00243 { 00244 /* Pointer to copy of link map from inferior. The type is char * 00245 rather than void *, so that we may use byte offsets to find the 00246 various fields without the need for a cast. */ 00247 gdb_byte *lm; 00248 00249 /* Amount by which addresses in the binary should be relocated to 00250 match the inferior. This could most often be taken directly 00251 from lm, but when prelinking is involved and the prelink base 00252 address changes, we may need a different offset, we want to 00253 warn about the difference and compute it only once. */ 00254 CORE_ADDR l_addr; 00255 00256 /* The target location of lm. */ 00257 CORE_ADDR lm_addr; 00258 }; 00259 00260 00261 static CORE_ADDR 00262 lm_addr (struct so_list *so) 00263 { 00264 if (so->lm_info->l_addr == (CORE_ADDR)-1) 00265 { 00266 struct link_map_offsets *lmo = nto_fetch_link_map_offsets (); 00267 struct type *ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr; 00268 00269 so->lm_info->l_addr = 00270 extract_typed_address (so->lm_info->lm + lmo->l_addr_offset, ptr_type); 00271 } 00272 return so->lm_info->l_addr; 00273 } 00274 00275 static CORE_ADDR 00276 nto_truncate_ptr (CORE_ADDR addr) 00277 { 00278 if (gdbarch_ptr_bit (target_gdbarch ()) == sizeof (CORE_ADDR) * 8) 00279 /* We don't need to truncate anything, and the bit twiddling below 00280 will fail due to overflow problems. */ 00281 return addr; 00282 else 00283 return addr & (((CORE_ADDR) 1 << gdbarch_ptr_bit (target_gdbarch ())) - 1); 00284 } 00285 00286 static Elf_Internal_Phdr * 00287 find_load_phdr (bfd *abfd) 00288 { 00289 Elf_Internal_Phdr *phdr; 00290 unsigned int i; 00291 00292 if (!elf_tdata (abfd)) 00293 return NULL; 00294 00295 phdr = elf_tdata (abfd)->phdr; 00296 for (i = 0; i < elf_elfheader (abfd)->e_phnum; i++, phdr++) 00297 { 00298 if (phdr->p_type == PT_LOAD && (phdr->p_flags & PF_X)) 00299 return phdr; 00300 } 00301 return NULL; 00302 } 00303 00304 void 00305 nto_relocate_section_addresses (struct so_list *so, struct target_section *sec) 00306 { 00307 /* Neutrino treats the l_addr base address field in link.h as different than 00308 the base address in the System V ABI and so the offset needs to be 00309 calculated and applied to relocations. */ 00310 Elf_Internal_Phdr *phdr = find_load_phdr (sec->the_bfd_section->owner); 00311 unsigned vaddr = phdr ? phdr->p_vaddr : 0; 00312 00313 sec->addr = nto_truncate_ptr (sec->addr + lm_addr (so) - vaddr); 00314 sec->endaddr = nto_truncate_ptr (sec->endaddr + lm_addr (so) - vaddr); 00315 } 00316 00317 /* This is cheating a bit because our linker code is in libc.so. If we 00318 ever implement lazy linking, this may need to be re-examined. */ 00319 int 00320 nto_in_dynsym_resolve_code (CORE_ADDR pc) 00321 { 00322 if (in_plt_section (pc)) 00323 return 1; 00324 return 0; 00325 } 00326 00327 void 00328 nto_dummy_supply_regset (struct regcache *regcache, char *regs) 00329 { 00330 /* Do nothing. */ 00331 } 00332 00333 enum gdb_osabi 00334 nto_elf_osabi_sniffer (bfd *abfd) 00335 { 00336 if (nto_is_nto_target) 00337 return nto_is_nto_target (abfd); 00338 return GDB_OSABI_UNKNOWN; 00339 } 00340 00341 static const char *nto_thread_state_str[] = 00342 { 00343 "DEAD", /* 0 0x00 */ 00344 "RUNNING", /* 1 0x01 */ 00345 "READY", /* 2 0x02 */ 00346 "STOPPED", /* 3 0x03 */ 00347 "SEND", /* 4 0x04 */ 00348 "RECEIVE", /* 5 0x05 */ 00349 "REPLY", /* 6 0x06 */ 00350 "STACK", /* 7 0x07 */ 00351 "WAITTHREAD", /* 8 0x08 */ 00352 "WAITPAGE", /* 9 0x09 */ 00353 "SIGSUSPEND", /* 10 0x0a */ 00354 "SIGWAITINFO", /* 11 0x0b */ 00355 "NANOSLEEP", /* 12 0x0c */ 00356 "MUTEX", /* 13 0x0d */ 00357 "CONDVAR", /* 14 0x0e */ 00358 "JOIN", /* 15 0x0f */ 00359 "INTR", /* 16 0x10 */ 00360 "SEM", /* 17 0x11 */ 00361 "WAITCTX", /* 18 0x12 */ 00362 "NET_SEND", /* 19 0x13 */ 00363 "NET_REPLY" /* 20 0x14 */ 00364 }; 00365 00366 char * 00367 nto_extra_thread_info (struct thread_info *ti) 00368 { 00369 if (ti && ti->private 00370 && ti->private->state < ARRAY_SIZE (nto_thread_state_str)) 00371 return (char *)nto_thread_state_str [ti->private->state]; 00372 return ""; 00373 } 00374 00375 void 00376 nto_initialize_signals (void) 00377 { 00378 /* We use SIG45 for pulses, or something, so nostop, noprint 00379 and pass them. */ 00380 signal_stop_update (gdb_signal_from_name ("SIG45"), 0); 00381 signal_print_update (gdb_signal_from_name ("SIG45"), 0); 00382 signal_pass_update (gdb_signal_from_name ("SIG45"), 1); 00383 00384 /* By default we don't want to stop on these two, but we do want to pass. */ 00385 #if defined(SIGSELECT) 00386 signal_stop_update (SIGSELECT, 0); 00387 signal_print_update (SIGSELECT, 0); 00388 signal_pass_update (SIGSELECT, 1); 00389 #endif 00390 00391 #if defined(SIGPHOTON) 00392 signal_stop_update (SIGPHOTON, 0); 00393 signal_print_update (SIGPHOTON, 0); 00394 signal_pass_update (SIGPHOTON, 1); 00395 #endif 00396 }