GDB (xrefs)
/tmp/gdb-7.10/gdb/solib-dsbt.c
Go to the documentation of this file.
1 /* Handle TIC6X (DSBT) shared libraries for GDB, the GNU Debugger.
2  Copyright (C) 2010-2015 Free Software Foundation, Inc.
3 
4  This file is part of GDB.
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>. */
18 
19 
20 #include "defs.h"
21 #include "inferior.h"
22 #include "gdbcore.h"
23 #include "solib.h"
24 #include "solist.h"
25 #include "objfiles.h"
26 #include "symtab.h"
27 #include "language.h"
28 #include "command.h"
29 #include "gdbcmd.h"
30 #include "elf-bfd.h"
31 #include "gdb_bfd.h"
32 
33 #define GOT_MODULE_OFFSET 4
34 
35 /* Flag which indicates whether internal debug messages should be printed. */
36 static unsigned int solib_dsbt_debug = 0;
37 
38 /* TIC6X pointers are four bytes wide. */
39 enum { TIC6X_PTR_SIZE = 4 };
40 
41 /* Representation of loadmap and related structs for the TIC6X DSBT. */
42 
43 /* External versions; the size and alignment of the fields should be
44  the same as those on the target. When loaded, the placement of
45  the bits in each field will be the same as on the target. */
49 
51 {
52  /* Core address to which the segment is mapped. */
54  /* VMA recorded in the program header. */
56  /* Size of this segment in memory. */
58 };
59 
61  /* Protocol version number, must be zero. */
63  /* A pointer to the DSBT table; the DSBT size and the index of this
64  module. */
68  /* Number of segments in this map. */
70  /* The actual memory map. */
71  struct ext_elf32_dsbt_loadseg segs[1 /* nsegs, actually */];
72 };
73 
74 /* Internal versions; the types are GDB types and the data in each
75  of the fields is (or will be) decoded from the external struct
76  for ease of consumption. */
78 {
79  /* Core address to which the segment is mapped. */
81  /* VMA recorded in the program header. */
83  /* Size of this segment in memory. */
84  long p_memsz;
85 };
86 
88 {
89  /* Protocol version number, must be zero. */
90  int version;
92  /* A pointer to the DSBT table; the DSBT size and the index of this
93  module. */
95  /* Number of segments in this map. */
96  int nsegs;
97  /* The actual memory map. */
98  struct int_elf32_dsbt_loadseg segs[1 /* nsegs, actually */];
99 };
100 
101 /* External link_map and elf32_dsbt_loadaddr struct definitions. */
102 
103 typedef gdb_byte ext_ptr[4];
104 
106 {
107  ext_ptr map; /* struct elf32_dsbt_loadmap *map; */
108 };
109 
111 {
113 
114  /* Absolute file name object was found in. */
115  ext_ptr l_name; /* char *l_name; */
116 
117  /* Dynamic section of the shared object. */
118  ext_ptr l_ld; /* ElfW(Dyn) *l_ld; */
119 
120  /* Chain of loaded objects. */
121  ext_ptr l_next, l_prev; /* struct link_map *l_next, *l_prev; */
122 };
123 
124 /* Link map info to include in an allocated so_list entry */
125 
126 struct lm_info
127 {
128  /* The loadmap, digested into an easier to use form. */
130 };
131 
132 /* Per pspace dsbt specific data. */
133 
134 struct dsbt_info
135 {
136  /* The load map, got value, etc. are not available from the chain
137  of loaded shared objects. ``main_executable_lm_info'' provides
138  a way to get at this information so that it doesn't need to be
139  frequently recomputed. Initialized by dsbt_relocate_main_executable. */
141 
142  /* Load maps for the main executable and the interpreter. These are obtained
143  from ptrace. They are the starting point for getting into the program,
144  and are required to find the solib list with the individual load maps for
145  each module. */
148 
149  /* Cached value for lm_base, below. */
151 
152  /* Link map address for main module. */
154 
159 };
160 
161 /* Per-program-space data key. */
162 static const struct program_space_data *solib_dsbt_pspace_data;
163 
164 static void
165 dsbt_pspace_data_cleanup (struct program_space *pspace, void *arg)
166 {
167  xfree (arg);
168 }
169 
170 /* Get the current dsbt data. If none is found yet, add it now. This
171  function always returns a valid object. */
172 
173 static struct dsbt_info *
175 {
176  struct dsbt_info *info;
177 
178  info = program_space_data (current_program_space, solib_dsbt_pspace_data);
179  if (info != NULL)
180  return info;
181 
182  info = XCNEW (struct dsbt_info);
183  set_program_space_data (current_program_space, solib_dsbt_pspace_data, info);
184 
185  info->lm_base_cache = 0;
186  info->main_lm_addr = 0;
187 
188  return info;
189 }
190 
191 
192 static void
194 {
195  int i;
196 
197  if (map == NULL)
198  printf_filtered ("(null)\n");
199  else if (map->version != 0)
200  printf_filtered (_("Unsupported map version: %d\n"), map->version);
201  else
202  {
203  printf_filtered ("version %d\n", map->version);
204 
205  for (i = 0; i < map->nsegs; i++)
206  printf_filtered ("%s:%s -> %s:%s\n",
208  map->segs[i].p_vaddr),
210  map->segs[i].p_vaddr
211  + map->segs[i].p_memsz),
214  + map->segs[i].p_memsz));
215  }
216 }
217 
218 /* Decode int_elf32_dsbt_loadmap from BUF. */
219 
220 static struct int_elf32_dsbt_loadmap *
222 {
223  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
224  struct ext_elf32_dsbt_loadmap *ext_ldmbuf;
225  struct int_elf32_dsbt_loadmap *int_ldmbuf;
226 
227  int version, seg, nsegs;
228  int int_ldmbuf_size;
229 
230  ext_ldmbuf = (struct ext_elf32_dsbt_loadmap *) buf;
231 
232  /* Extract the version. */
233  version = extract_unsigned_integer (ext_ldmbuf->version,
234  sizeof ext_ldmbuf->version,
235  byte_order);
236  if (version != 0)
237  {
238  /* We only handle version 0. */
239  return NULL;
240  }
241 
242  /* Extract the number of segments. */
243  nsegs = extract_unsigned_integer (ext_ldmbuf->nsegs,
244  sizeof ext_ldmbuf->nsegs,
245  byte_order);
246 
247  if (nsegs <= 0)
248  return NULL;
249 
250  /* Allocate space into which to put information extract from the
251  external loadsegs. I.e, allocate the internal loadsegs. */
252  int_ldmbuf_size = (sizeof (struct int_elf32_dsbt_loadmap)
253  + (nsegs - 1) * sizeof (struct int_elf32_dsbt_loadseg));
254  int_ldmbuf = xmalloc (int_ldmbuf_size);
255 
256  /* Place extracted information in internal structs. */
257  int_ldmbuf->version = version;
258  int_ldmbuf->nsegs = nsegs;
259  for (seg = 0; seg < nsegs; seg++)
260  {
261  int_ldmbuf->segs[seg].addr
262  = extract_unsigned_integer (ext_ldmbuf->segs[seg].addr,
263  sizeof (ext_ldmbuf->segs[seg].addr),
264  byte_order);
265  int_ldmbuf->segs[seg].p_vaddr
266  = extract_unsigned_integer (ext_ldmbuf->segs[seg].p_vaddr,
267  sizeof (ext_ldmbuf->segs[seg].p_vaddr),
268  byte_order);
269  int_ldmbuf->segs[seg].p_memsz
270  = extract_unsigned_integer (ext_ldmbuf->segs[seg].p_memsz,
271  sizeof (ext_ldmbuf->segs[seg].p_memsz),
272  byte_order);
273  }
274 
275  xfree (ext_ldmbuf);
276  return int_ldmbuf;
277 }
278 
279 
280 static struct dsbt_info *get_dsbt_info (void);
281 
282 /* Interrogate the Linux kernel to find out where the program was loaded.
283  There are two load maps; one for the executable and one for the
284  interpreter (only in the case of a dynamically linked executable). */
285 
286 static void
288 {
289  gdb_byte *buf;
290  struct dsbt_info *info = get_dsbt_info ();
291 
293  "exec", &buf))
294  {
295  info->exec_loadmap = NULL;
296  error (_("Error reading DSBT exec loadmap"));
297  }
298  info->exec_loadmap = decode_loadmap (buf);
299  if (solib_dsbt_debug)
301 
303  "interp", &buf))
304  {
305  info->interp_loadmap = NULL;
306  error (_("Error reading DSBT interp loadmap"));
307  }
308  info->interp_loadmap = decode_loadmap (buf);
309  if (solib_dsbt_debug)
311 }
312 
313 /* Given address LDMADDR, fetch and decode the loadmap at that address.
314  Return NULL if there is a problem reading the target memory or if
315  there doesn't appear to be a loadmap at the given address. The
316  allocated space (representing the loadmap) returned by this
317  function may be freed via a single call to xfree. */
318 
319 static struct int_elf32_dsbt_loadmap *
321 {
322  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
323  struct ext_elf32_dsbt_loadmap ext_ldmbuf_partial;
324  struct ext_elf32_dsbt_loadmap *ext_ldmbuf;
325  struct int_elf32_dsbt_loadmap *int_ldmbuf;
326  int ext_ldmbuf_size, int_ldmbuf_size;
327  int version, seg, nsegs;
328 
329  /* Fetch initial portion of the loadmap. */
330  if (target_read_memory (ldmaddr, (gdb_byte *) &ext_ldmbuf_partial,
331  sizeof ext_ldmbuf_partial))
332  {
333  /* Problem reading the target's memory. */
334  return NULL;
335  }
336 
337  /* Extract the version. */
338  version = extract_unsigned_integer (ext_ldmbuf_partial.version,
339  sizeof ext_ldmbuf_partial.version,
340  byte_order);
341  if (version != 0)
342  {
343  /* We only handle version 0. */
344  return NULL;
345  }
346 
347  /* Extract the number of segments. */
348  nsegs = extract_unsigned_integer (ext_ldmbuf_partial.nsegs,
349  sizeof ext_ldmbuf_partial.nsegs,
350  byte_order);
351 
352  if (nsegs <= 0)
353  return NULL;
354 
355  /* Allocate space for the complete (external) loadmap. */
356  ext_ldmbuf_size = sizeof (struct ext_elf32_dsbt_loadmap)
357  + (nsegs - 1) * sizeof (struct ext_elf32_dsbt_loadseg);
358  ext_ldmbuf = xmalloc (ext_ldmbuf_size);
359 
360  /* Copy over the portion of the loadmap that's already been read. */
361  memcpy (ext_ldmbuf, &ext_ldmbuf_partial, sizeof ext_ldmbuf_partial);
362 
363  /* Read the rest of the loadmap from the target. */
364  if (target_read_memory (ldmaddr + sizeof ext_ldmbuf_partial,
365  (gdb_byte *) ext_ldmbuf + sizeof ext_ldmbuf_partial,
366  ext_ldmbuf_size - sizeof ext_ldmbuf_partial))
367  {
368  /* Couldn't read rest of the loadmap. */
369  xfree (ext_ldmbuf);
370  return NULL;
371  }
372 
373  /* Allocate space into which to put information extract from the
374  external loadsegs. I.e, allocate the internal loadsegs. */
375  int_ldmbuf_size = sizeof (struct int_elf32_dsbt_loadmap)
376  + (nsegs - 1) * sizeof (struct int_elf32_dsbt_loadseg);
377  int_ldmbuf = xmalloc (int_ldmbuf_size);
378 
379  /* Place extracted information in internal structs. */
380  int_ldmbuf->version = version;
381  int_ldmbuf->nsegs = nsegs;
382  for (seg = 0; seg < nsegs; seg++)
383  {
384  int_ldmbuf->segs[seg].addr
385  = extract_unsigned_integer (ext_ldmbuf->segs[seg].addr,
386  sizeof (ext_ldmbuf->segs[seg].addr),
387  byte_order);
388  int_ldmbuf->segs[seg].p_vaddr
389  = extract_unsigned_integer (ext_ldmbuf->segs[seg].p_vaddr,
390  sizeof (ext_ldmbuf->segs[seg].p_vaddr),
391  byte_order);
392  int_ldmbuf->segs[seg].p_memsz
393  = extract_unsigned_integer (ext_ldmbuf->segs[seg].p_memsz,
394  sizeof (ext_ldmbuf->segs[seg].p_memsz),
395  byte_order);
396  }
397 
398  xfree (ext_ldmbuf);
399  return int_ldmbuf;
400 }
401 
402 static void dsbt_relocate_main_executable (void);
403 static int enable_break (void);
404 
405 /* Scan for DYNTAG in .dynamic section of ABFD. If DYNTAG is found 1 is
406  returned and the corresponding PTR is set. */
407 
408 static int
409 scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr)
410 {
411  int arch_size, step, sect_size;
412  long dyn_tag;
413  CORE_ADDR dyn_ptr, dyn_addr;
414  gdb_byte *bufend, *bufstart, *buf;
415  Elf32_External_Dyn *x_dynp_32;
416  Elf64_External_Dyn *x_dynp_64;
417  struct bfd_section *sect;
419 
420  if (abfd == NULL)
421  return 0;
422 
423  if (bfd_get_flavour (abfd) != bfd_target_elf_flavour)
424  return 0;
425 
426  arch_size = bfd_get_arch_size (abfd);
427  if (arch_size == -1)
428  return 0;
429 
430  /* Find the start address of the .dynamic section. */
431  sect = bfd_get_section_by_name (abfd, ".dynamic");
432  if (sect == NULL)
433  return 0;
434 
435  for (target_section = current_target_sections->sections;
437  target_section++)
438  if (sect == target_section->the_bfd_section)
439  break;
441  dyn_addr = target_section->addr;
442  else
443  {
444  /* ABFD may come from OBJFILE acting only as a symbol file without being
445  loaded into the target (see add_symbol_file_command). This case is
446  such fallback to the file VMA address without the possibility of
447  having the section relocated to its actual in-memory address. */
448 
449  dyn_addr = bfd_section_vma (abfd, sect);
450  }
451 
452  /* Read in .dynamic from the BFD. We will get the actual value
453  from memory later. */
454  sect_size = bfd_section_size (abfd, sect);
455  buf = bufstart = alloca (sect_size);
456  if (!bfd_get_section_contents (abfd, sect,
457  buf, 0, sect_size))
458  return 0;
459 
460  /* Iterate over BUF and scan for DYNTAG. If found, set PTR and return. */
461  step = (arch_size == 32) ? sizeof (Elf32_External_Dyn)
462  : sizeof (Elf64_External_Dyn);
463  for (bufend = buf + sect_size;
464  buf < bufend;
465  buf += step)
466  {
467  if (arch_size == 32)
468  {
469  x_dynp_32 = (Elf32_External_Dyn *) buf;
470  dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag);
471  dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr);
472  }
473  else
474  {
475  x_dynp_64 = (Elf64_External_Dyn *) buf;
476  dyn_tag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag);
477  dyn_ptr = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_un.d_ptr);
478  }
479  if (dyn_tag == DT_NULL)
480  return 0;
481  if (dyn_tag == dyntag)
482  {
483  /* If requested, try to read the runtime value of this .dynamic
484  entry. */
485  if (ptr)
486  {
487  struct type *ptr_type;
488  gdb_byte ptr_buf[8];
489  CORE_ADDR ptr_addr;
490 
492  ptr_addr = dyn_addr + (buf - bufstart) + arch_size / 8;
493  if (target_read_memory (ptr_addr, ptr_buf, arch_size / 8) == 0)
494  dyn_ptr = extract_typed_address (ptr_buf, ptr_type);
495  *ptr = dyn_ptr;
496  }
497  return 1;
498  }
499  }
500 
501  return 0;
502 }
503 
504 /* If no open symbol file, attempt to locate and open the main symbol
505  file.
506 
507  If FROM_TTYP dereferences to a non-zero integer, allow messages to
508  be printed. This parameter is a pointer rather than an int because
509  open_symbol_file_object is called via catch_errors and
510  catch_errors requires a pointer argument. */
511 
512 static int
513 open_symbol_file_object (void *from_ttyp)
514 {
515  /* Unimplemented. */
516  return 0;
517 }
518 
519 /* Given a loadmap and an address, return the displacement needed
520  to relocate the address. */
521 
522 static CORE_ADDR
524  CORE_ADDR addr)
525 {
526  int seg;
527 
528  for (seg = 0; seg < map->nsegs; seg++)
529  if (map->segs[seg].p_vaddr <= addr
530  && addr < map->segs[seg].p_vaddr + map->segs[seg].p_memsz)
531  return map->segs[seg].addr - map->segs[seg].p_vaddr;
532 
533  return 0;
534 }
535 
536 /* Return the address from which the link map chain may be found. On
537  DSBT, a pointer to the start of the link map will be located at the
538  word found at base of GOT + GOT_MODULE_OFFSET.
539 
540  The base of GOT may be found in a number of ways. Assuming that the
541  main executable has already been relocated,
542  1 The easiest way to find this value is to look up the address of
543  _GLOBAL_OFFSET_TABLE_.
544  2 The other way is to look for tag DT_PLTGOT, which contains the virtual
545  address of Global Offset Table. .*/
546 
547 static CORE_ADDR
548 lm_base (void)
549 {
550  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
551  struct bound_minimal_symbol got_sym;
552  CORE_ADDR addr;
554  struct dsbt_info *info = get_dsbt_info ();
555 
556  /* One of our assumptions is that the main executable has been relocated.
557  Bail out if this has not happened. (Note that post_create_inferior
558  in infcmd.c will call solib_add prior to solib_create_inferior_hook.
559  If we allow this to happen, lm_base_cache will be initialized with
560  a bogus value. */
561  if (info->main_executable_lm_info == 0)
562  return 0;
563 
564  /* If we already have a cached value, return it. */
565  if (info->lm_base_cache)
566  return info->lm_base_cache;
567 
568  got_sym = lookup_minimal_symbol ("_GLOBAL_OFFSET_TABLE_", NULL,
570 
571  if (got_sym.minsym != 0)
572  {
573  addr = BMSYMBOL_VALUE_ADDRESS (got_sym);
574  if (solib_dsbt_debug)
576  "lm_base: get addr %x by _GLOBAL_OFFSET_TABLE_.\n",
577  (unsigned int) addr);
578  }
579  else if (scan_dyntag (DT_PLTGOT, exec_bfd, &addr))
580  {
581  struct int_elf32_dsbt_loadmap *ldm;
582 
584  ldm = info->exec_loadmap;
585  addr += displacement_from_map (ldm, addr);
586  if (solib_dsbt_debug)
588  "lm_base: get addr %x by DT_PLTGOT.\n",
589  (unsigned int) addr);
590  }
591  else
592  {
593  if (solib_dsbt_debug)
595  "lm_base: _GLOBAL_OFFSET_TABLE_ not found.\n");
596  return 0;
597  }
598  addr += GOT_MODULE_OFFSET;
599 
600  if (solib_dsbt_debug)
602  "lm_base: _GLOBAL_OFFSET_TABLE_ + %d = %s\n",
604 
605  if (target_read_memory (addr, buf, sizeof buf) != 0)
606  return 0;
607  info->lm_base_cache = extract_unsigned_integer (buf, sizeof buf, byte_order);
608 
609  if (solib_dsbt_debug)
611  "lm_base: lm_base_cache = %s\n",
612  hex_string_custom (info->lm_base_cache, 8));
613 
614  return info->lm_base_cache;
615 }
616 
617 
618 /* Build a list of `struct so_list' objects describing the shared
619  objects currently loaded in the inferior. This list does not
620  include an entry for the main executable file.
621 
622  Note that we only gather information directly available from the
623  inferior --- we don't examine any of the shared library files
624  themselves. The declaration of `struct so_list' says which fields
625  we provide values for. */
626 
627 static struct so_list *
629 {
630  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
632  struct so_list *sos_head = NULL;
633  struct so_list **sos_next_ptr = &sos_head;
634  struct dsbt_info *info = get_dsbt_info ();
635 
636  /* Make sure that the main executable has been relocated. This is
637  required in order to find the address of the global offset table,
638  which in turn is used to find the link map info. (See lm_base
639  for details.)
640 
641  Note that the relocation of the main executable is also performed
642  by solib_create_inferior_hook, however, in the case of core
643  files, this hook is called too late in order to be of benefit to
644  solib_add. solib_add eventually calls this function,
645  dsbt_current_sos, and also precedes the call to
646  solib_create_inferior_hook. (See post_create_inferior in
647  infcmd.c.) */
648  if (info->main_executable_lm_info == 0 && core_bfd != NULL)
650 
651  /* Locate the address of the first link map struct. */
652  lm_addr = lm_base ();
653 
654  /* We have at least one link map entry. Fetch the the lot of them,
655  building the solist chain. */
656  while (lm_addr)
657  {
658  struct ext_link_map lm_buf;
659  ext_Elf32_Word indexword;
660  CORE_ADDR map_addr;
661  int dsbt_index;
662  int ret;
663 
664  if (solib_dsbt_debug)
666  "current_sos: reading link_map entry at %s\n",
667  hex_string_custom (lm_addr, 8));
668 
669  ret = target_read_memory (lm_addr, (gdb_byte *) &lm_buf, sizeof (lm_buf));
670  if (ret)
671  {
672  warning (_("dsbt_current_sos: Unable to read link map entry."
673  " Shared object chain may be incomplete."));
674  break;
675  }
676 
677  /* Fetch the load map address. */
678  map_addr = extract_unsigned_integer (lm_buf.l_addr.map,
679  sizeof lm_buf.l_addr.map,
680  byte_order);
681 
682  ret = target_read_memory (map_addr + 12, (gdb_byte *) &indexword,
683  sizeof indexword);
684  if (ret)
685  {
686  warning (_("dsbt_current_sos: Unable to read dsbt index."
687  " Shared object chain may be incomplete."));
688  break;
689  }
690  dsbt_index = extract_unsigned_integer (indexword, sizeof indexword,
691  byte_order);
692 
693  /* If the DSBT index is zero, then we're looking at the entry
694  for the main executable. By convention, we don't include
695  this in the list of shared objects. */
696  if (dsbt_index != 0)
697  {
698  int errcode;
699  char *name_buf;
700  struct int_elf32_dsbt_loadmap *loadmap;
701  struct so_list *sop;
702  CORE_ADDR addr;
703 
704  loadmap = fetch_loadmap (map_addr);
705  if (loadmap == NULL)
706  {
707  warning (_("dsbt_current_sos: Unable to fetch load map."
708  " Shared object chain may be incomplete."));
709  break;
710  }
711 
712  sop = xcalloc (1, sizeof (struct so_list));
713  sop->lm_info = xcalloc (1, sizeof (struct lm_info));
714  sop->lm_info->map = loadmap;
715  /* Fetch the name. */
716  addr = extract_unsigned_integer (lm_buf.l_name,
717  sizeof (lm_buf.l_name),
718  byte_order);
719  target_read_string (addr, &name_buf, SO_NAME_MAX_PATH_SIZE - 1,
720  &errcode);
721 
722  if (errcode != 0)
723  warning (_("Can't read pathname for link map entry: %s."),
724  safe_strerror (errcode));
725  else
726  {
727  if (solib_dsbt_debug)
728  fprintf_unfiltered (gdb_stdlog, "current_sos: name = %s\n",
729  name_buf);
730 
731  strncpy (sop->so_name, name_buf, SO_NAME_MAX_PATH_SIZE - 1);
732  sop->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
733  xfree (name_buf);
734  strcpy (sop->so_original_name, sop->so_name);
735  }
736 
737  *sos_next_ptr = sop;
738  sos_next_ptr = &sop->next;
739  }
740  else
741  {
742  info->main_lm_addr = lm_addr;
743  }
744 
745  lm_addr = extract_unsigned_integer (lm_buf.l_next,
746  sizeof (lm_buf.l_next), byte_order);
747  }
748 
749  return sos_head;
750 }
751 
752 /* Return 1 if PC lies in the dynamic symbol resolution code of the
753  run time loader. */
754 
755 static int
757 {
758  struct dsbt_info *info = get_dsbt_info ();
759 
760  return ((pc >= info->interp_text_sect_low && pc < info->interp_text_sect_high)
761  || (pc >= info->interp_plt_sect_low && pc < info->interp_plt_sect_high)
762  || in_plt_section (pc));
763 }
764 
765 /* Print a warning about being unable to set the dynamic linker
766  breakpoint. */
767 
768 static void
770 {
771  warning (_("Unable to find dynamic linker breakpoint function.\n"
772  "GDB will be unable to debug shared library initializers\n"
773  "and track explicitly loaded dynamic code."));
774 }
775 
776 /* Helper function for gdb_bfd_lookup_symbol. */
777 
778 static int
779 cmp_name (asymbol *sym, void *data)
780 {
781  return (strcmp (sym->name, (const char *) data) == 0);
782 }
783 
784 /* The dynamic linkers has, as part of its debugger interface, support
785  for arranging for the inferior to hit a breakpoint after mapping in
786  the shared libraries. This function enables that breakpoint.
787 
788  On the TIC6X, using the shared library (DSBT), GDB can try to place
789  a breakpoint on '_dl_debug_state' to monitor the shared library
790  event. */
791 
792 static int
794 {
795  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
796  asection *interp_sect;
797  struct dsbt_info *info;
798 
799  if (exec_bfd == NULL)
800  return 0;
801 
803  return 0;
804 
805  info = get_dsbt_info ();
806 
807  info->interp_text_sect_low = 0;
808  info->interp_text_sect_high = 0;
809  info->interp_plt_sect_low = 0;
810  info->interp_plt_sect_high = 0;
811 
812  /* Find the .interp section; if not found, warn the user and drop
813  into the old breakpoint at symbol code. */
814  interp_sect = bfd_get_section_by_name (exec_bfd, ".interp");
815  if (interp_sect)
816  {
817  unsigned int interp_sect_size;
818  char *buf;
819  bfd *tmp_bfd = NULL;
820  CORE_ADDR addr;
821  gdb_byte addr_buf[TIC6X_PTR_SIZE];
822  struct int_elf32_dsbt_loadmap *ldm;
823  int ret;
824 
825  /* Read the contents of the .interp section into a local buffer;
826  the contents specify the dynamic linker this program uses. */
827  interp_sect_size = bfd_section_size (exec_bfd, interp_sect);
828  buf = alloca (interp_sect_size);
829  bfd_get_section_contents (exec_bfd, interp_sect,
830  buf, 0, interp_sect_size);
831 
832  /* Now we need to figure out where the dynamic linker was
833  loaded so that we can load its symbols and place a breakpoint
834  in the dynamic linker itself. */
835 
836  TRY
837  {
838  tmp_bfd = solib_bfd_open (buf);
839  }
840  CATCH (ex, RETURN_MASK_ALL)
841  {
842  }
843  END_CATCH
844 
845  if (tmp_bfd == NULL)
846  {
848  return 0;
849  }
850 
852  ldm = info->interp_loadmap;
853 
854  /* Record the relocated start and end address of the dynamic linker
855  text and plt section for dsbt_in_dynsym_resolve_code. */
856  interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
857  if (interp_sect)
858  {
860  = bfd_section_vma (tmp_bfd, interp_sect);
864  = info->interp_text_sect_low
865  + bfd_section_size (tmp_bfd, interp_sect);
866  }
867  interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
868  if (interp_sect)
869  {
870  info->interp_plt_sect_low =
871  bfd_section_vma (tmp_bfd, interp_sect);
872  info->interp_plt_sect_low
874  info->interp_plt_sect_high =
875  info->interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect);
876  }
877 
878  addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name, "_dl_debug_state");
879  if (addr != 0)
880  {
881  if (solib_dsbt_debug)
883  "enable_break: _dl_debug_state (prior to relocation) = %s\n",
884  hex_string_custom (addr, 8));
885  addr += displacement_from_map (ldm, addr);
886 
887  if (solib_dsbt_debug)
889  "enable_break: _dl_debug_state (after relocation) = %s\n",
890  hex_string_custom (addr, 8));
891 
892  /* Now (finally!) create the solib breakpoint. */
894 
895  ret = 1;
896  }
897  else
898  {
899  if (solib_dsbt_debug)
901  "enable_break: _dl_debug_state is not found\n");
902  ret = 0;
903  }
904 
905  /* We're done with the temporary bfd. */
906  gdb_bfd_unref (tmp_bfd);
907 
908  /* We're also done with the loadmap. */
909  xfree (ldm);
910 
911  return ret;
912  }
913 
914  /* Tell the user we couldn't set a dynamic linker breakpoint. */
916 
917  /* Failure return. */
918  return 0;
919 }
920 
921 /* Once the symbols from a shared object have been loaded in the usual
922  way, we are called to do any system specific symbol handling that
923  is needed. */
924 
925 static void
927 {
928 }
929 
930 static void
932 {
933  struct int_elf32_dsbt_loadmap *ldm;
934  struct cleanup *old_chain;
935  struct section_offsets *new_offsets;
936  int changed;
937  struct obj_section *osect;
938  struct dsbt_info *info = get_dsbt_info ();
939 
941  ldm = info->exec_loadmap;
942 
944  info->main_executable_lm_info = xcalloc (1, sizeof (struct lm_info));
945  info->main_executable_lm_info->map = ldm;
946 
947  new_offsets = xcalloc (symfile_objfile->num_sections,
948  sizeof (struct section_offsets));
949  old_chain = make_cleanup (xfree, new_offsets);
950  changed = 0;
951 
953  {
954  CORE_ADDR orig_addr, addr, offset;
955  int osect_idx;
956  int seg;
957 
958  osect_idx = osect - symfile_objfile->sections;
959 
960  /* Current address of section. */
961  addr = obj_section_addr (osect);
962  /* Offset from where this section started. */
963  offset = ANOFFSET (symfile_objfile->section_offsets, osect_idx);
964  /* Original address prior to any past relocations. */
965  orig_addr = addr - offset;
966 
967  for (seg = 0; seg < ldm->nsegs; seg++)
968  {
969  if (ldm->segs[seg].p_vaddr <= orig_addr
970  && orig_addr < ldm->segs[seg].p_vaddr + ldm->segs[seg].p_memsz)
971  {
972  new_offsets->offsets[osect_idx]
973  = ldm->segs[seg].addr - ldm->segs[seg].p_vaddr;
974 
975  if (new_offsets->offsets[osect_idx] != offset)
976  changed = 1;
977  break;
978  }
979  }
980  }
981 
982  if (changed)
983  objfile_relocate (symfile_objfile, new_offsets);
984 
985  do_cleanups (old_chain);
986 
987  /* Now that symfile_objfile has been relocated, we can compute the
988  GOT value and stash it away. */
989 }
990 
991 /* When gdb starts up the inferior, it nurses it along (through the
992  shell) until it is ready to execute it's first instruction. At this
993  point, this function gets called via solib_create_inferior_hook.
994 
995  For the DSBT shared library, the main executable needs to be relocated.
996  The shared library breakpoints also need to be enabled. */
997 
998 static void
1000 {
1001  /* Relocate main executable. */
1003 
1004  /* Enable shared library breakpoints. */
1005  if (!enable_break ())
1006  {
1007  warning (_("shared library handler failed to enable breakpoint"));
1008  return;
1009  }
1010 }
1011 
1012 static void
1014 {
1015  struct dsbt_info *info = get_dsbt_info ();
1016 
1017  info->lm_base_cache = 0;
1018  info->main_lm_addr = 0;
1019  if (info->main_executable_lm_info != 0)
1020  {
1023  info->main_executable_lm_info = 0;
1024  }
1025 }
1026 
1027 static void
1028 dsbt_free_so (struct so_list *so)
1029 {
1030  xfree (so->lm_info->map);
1031  xfree (so->lm_info);
1032 }
1033 
1034 static void
1036  struct target_section *sec)
1037 {
1038  int seg;
1039  struct int_elf32_dsbt_loadmap *map;
1040 
1041  map = so->lm_info->map;
1042 
1043  for (seg = 0; seg < map->nsegs; seg++)
1044  {
1045  if (map->segs[seg].p_vaddr <= sec->addr
1046  && sec->addr < map->segs[seg].p_vaddr + map->segs[seg].p_memsz)
1047  {
1048  CORE_ADDR displ = map->segs[seg].addr - map->segs[seg].p_vaddr;
1049 
1050  sec->addr += displ;
1051  sec->endaddr += displ;
1052  break;
1053  }
1054  }
1055 }
1056 static void
1057 show_dsbt_debug (struct ui_file *file, int from_tty,
1058  struct cmd_list_element *c, const char *value)
1059 {
1060  fprintf_filtered (file, _("solib-dsbt debugging is %s.\n"), value);
1061 }
1062 
1064 
1065 /* Provide a prototype to silence -Wmissing-prototypes. */
1067 
1068 void
1070 {
1072  = register_program_space_data_with_cleanup (NULL, dsbt_pspace_data_cleanup);
1073 
1083 
1084  /* Debug this file's internals. */
1086  &solib_dsbt_debug, _("\
1087 Set internal debugging of shared library code for DSBT ELF."), _("\
1088 Show internal debugging of shared library code for DSBT ELF."), _("\
1089 When non-zero, DSBT solib specific internal debugging is enabled."),
1090  NULL,
1093 }
struct gdbarch * target_gdbarch(void)
Definition: gdbarch.c:5143
static void dsbt_print_loadmap(struct int_elf32_dsbt_loadmap *map)
Definition: solib-dsbt.c:193
ULONGEST extract_unsigned_integer(const gdb_byte *, int, enum bfd_endian)
Definition: findvar.c:84
CORE_ADDR extract_typed_address(const gdb_byte *buf, struct type *type)
Definition: findvar.c:169
CORE_ADDR offsets[1]
Definition: symtab.h:907
void add_setshow_zuinteger_cmd(const char *name, enum command_class theclass, unsigned int *var, const char *set_doc, const char *show_doc, const char *help_doc, cmd_sfunc_ftype *set_func, show_value_ftype *show_func, struct cmd_list_element **set_list, struct cmd_list_element **show_list)
Definition: cli-decode.c:763
bfd_vma CORE_ADDR
Definition: common-types.h:41
CORE_ADDR interp_plt_sect_high
Definition: solib-dsbt.c:158
ext_Elf32_Word version
Definition: solib-dsbt.c:62
static void dsbt_solib_create_inferior_hook(int from_tty)
Definition: solib-dsbt.c:999
void xfree(void *)
Definition: common-utils.c:97
static int cmp_name(asymbol *sym, void *data)
Definition: solib-dsbt.c:779
struct so_list * next
Definition: solist.h:36
struct breakpoint * create_solib_event_breakpoint(struct gdbarch *gdbarch, CORE_ADDR address)
Definition: breakpoint.c:7721
#define BMSYMBOL_VALUE_ADDRESS(symbol)
Definition: symtab.h:393
void warning(const char *fmt,...)
Definition: errors.c:26
LONGEST target_read_alloc(struct target_ops *ops, enum target_object object, const char *annex, gdb_byte **buf_p)
Definition: target.c:1971
const struct builtin_type * builtin_type(struct gdbarch *gdbarch)
Definition: gdbtypes.c:4766
void(* relocate_section_addresses)(struct so_list *so, struct target_section *)
Definition: solist.h:84
static int open_symbol_file_object(void *from_ttyp)
Definition: solib-dsbt.c:513
void(* solib_create_inferior_hook)(int from_tty)
Definition: solist.h:101
struct so_list *(* current_sos)(void)
Definition: solist.h:116
gdb_byte ext_Elf32_Addr[4]
Definition: solib-dsbt.c:47
void objfile_relocate(struct objfile *objfile, const struct section_offsets *new_offsets)
Definition: objfiles.c:836
bfd *(* bfd_open)(char *pathname)
Definition: solist.h:130
static struct dsbt_info * get_dsbt_info(void)
Definition: solib-dsbt.c:174
static int enable_break(void)
Definition: solib-dsbt.c:793
Definition: solist.h:30
#define ALL_OBJFILE_OSECTIONS(objfile, osect)
Definition: objfiles.h:627
#define SO_NAME_MAX_PATH_SIZE
Definition: solist.h:22
CORE_ADDR lm_base_cache
Definition: solib-dsbt.c:150
static CORE_ADDR lm_addr(struct so_list *so)
Definition: nto-tdep.c:262
#define _(String)
Definition: gdb_locale.h:40
struct lm_info * main_executable_lm_info
Definition: solib-dsbt.c:140
#define END_CATCH
int(* open_symbol_file_object)(void *from_ttyp)
Definition: solist.h:123
CORE_ADDR dsbt_table_ptr
Definition: solib-dsbt.c:91
void printf_filtered(const char *format,...)
Definition: utils.c:2388
CORE_ADDR interp_plt_sect_low
Definition: solib-dsbt.c:157
ext_Elf32_Word p_memsz
Definition: solib-dsbt.c:57
#define obj_section_addr(s)
Definition: objfiles.h:135
static int dsbt_in_dynsym_resolve_code(CORE_ADDR pc)
Definition: solib-dsbt.c:756
ext_Elf32_Word nsegs
Definition: solib-dsbt.c:69
struct lm_info * lm_info
Definition: solist.h:42
void(* clear_solib)(void)
Definition: solist.h:98
struct int_elf32_dsbt_loadseg segs[1]
Definition: solib-dsbt.c:98
#define TRY
static struct int_elf32_dsbt_loadmap * decode_loadmap(gdb_byte *buf)
Definition: solib-dsbt.c:221
ext_Elf32_Word dsbt_index
Definition: solib-dsbt.c:67
static void dsbt_special_symbol_handling(void)
Definition: solib-dsbt.c:926
int(* in_dynsym_resolve_code)(CORE_ADDR pc)
Definition: solist.h:127
gdb_byte ext_Elf32_Word[4]
Definition: solib-dsbt.c:48
#define CATCH(EXCEPTION, MASK)
CORE_ADDR interp_text_sect_high
Definition: solib-dsbt.c:156
struct target_ops current_target
void gdb_bfd_unref(struct bfd *abfd)
Definition: gdb_bfd.c:475
void initialize_file_ftype(void)
Definition: defs.h:281
CORE_ADDR gdb_bfd_lookup_symbol(bfd *abfd, int(*match_sym)(asymbol *, void *), void *data)
Definition: solib.c:1629
static void dsbt_relocate_section_addresses(struct so_list *so, struct target_section *sec)
Definition: solib-dsbt.c:1035
#define exec_bfd
Definition: exec.h:32
void fprintf_filtered(struct ui_file *stream, const char *format,...)
Definition: utils.c:2351
#define current_target_sections
Definition: progspace.h:224
static void show_dsbt_debug(struct ui_file *file, int from_tty, struct cmd_list_element *c, const char *value)
Definition: solib-dsbt.c:1057
#define GOT_MODULE_OFFSET
Definition: solib-dsbt.c:33
void fprintf_unfiltered(struct ui_file *stream, const char *format,...)
Definition: utils.c:2361
struct int_elf32_dsbt_loadmap * interp_loadmap
Definition: solib-dsbt.c:147
char so_original_name[SO_NAME_MAX_PATH_SIZE]
Definition: solist.h:49
enum bfd_endian gdbarch_byte_order(struct gdbarch *gdbarch)
Definition: gdbarch.c:1420
struct cleanup * make_cleanup(make_cleanup_ftype *function, void *arg)
Definition: cleanups.c:117
static unsigned int solib_dsbt_debug
Definition: solib-dsbt.c:36
#define ANOFFSET(secoff, whichone)
Definition: symtab.h:910
const char version[]
Definition: version.c:2
Definition: gdbtypes.h:749
char so_name[SO_NAME_MAX_PATH_SIZE]
Definition: solist.h:52
ext_Elf32_Addr p_vaddr
Definition: solib-dsbt.c:55
gdb_byte ext_ptr[4]
Definition: solib-dsbt.c:103
struct target_so_ops dsbt_so_ops
Definition: solib-dsbt.c:1063
initialize_file_ftype _initialize_dsbt_solib
#define symfile_objfile
Definition: progspace.h:216
CORE_ADDR endaddr
Definition: target.h:2260
#define target_has_execution
Definition: target.h:1726
struct cmd_list_element * setdebuglist
Definition: cli-cmds.c:173
struct bfd_section * the_bfd_section
Definition: target.h:2262
void * xmalloc(YYSIZE_T)
struct ui_file * gdb_stdlog
Definition: main.c:73
void(* special_symbol_handling)(void)
Definition: solist.h:107
static void dsbt_get_initial_loadmaps(void)
Definition: solib-dsbt.c:287
CORE_ADDR addr
Definition: target.h:2259
static CORE_ADDR displacement_from_map(struct int_elf32_dsbt_loadmap *map, CORE_ADDR addr)
Definition: solib-dsbt.c:523
Definition: value.c:172
static const struct program_space_data * solib_dsbt_pspace_data
Definition: solib-dsbt.c:162
struct int_elf32_dsbt_loadmap * map
Definition: solib-dsbt.c:129
static int scan_dyntag(int dyntag, bfd *abfd, CORE_ADDR *ptr)
Definition: solib-dsbt.c:409
static void enable_break_failure_warning(void)
Definition: solib-dsbt.c:769
bfd_byte gdb_byte
Definition: common-types.h:38
static CORE_ADDR interp_plt_sect_high
Definition: solib-frv.c:442
struct ext_elf32_dsbt_loadseg segs[1]
Definition: solib-dsbt.c:71
int target_read_memory(CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
Definition: target.c:1393
struct type * builtin_data_ptr
Definition: gdbtypes.h:1533
static int in_plt_section(CORE_ADDR pc)
Definition: objfiles.h:539
static CORE_ADDR lm_base(void)
Definition: solib-dsbt.c:548
struct minimal_symbol * minsym
Definition: minsyms.h:32
CORE_ADDR main_lm_addr
Definition: solib-dsbt.c:153
void(* free_so)(struct so_list *so)
Definition: solist.h:89
char * safe_strerror(int)
int offset
Definition: agent.c:65
static void dsbt_free_so(struct so_list *so)
Definition: solib-dsbt.c:1028
const char * print_core_address(struct gdbarch *gdbarch, CORE_ADDR address)
Definition: utils.c:2764
struct program_space * current_program_space
Definition: progspace.c:35
ext_Elf32_Word dsbt_table_ptr
Definition: solib-dsbt.c:65
ext_Elf32_Word dsbt_size
Definition: solib-dsbt.c:66
CORE_ADDR interp_text_sect_low
Definition: solib-dsbt.c:155
static void dsbt_pspace_data_cleanup(struct program_space *pspace, void *arg)
Definition: solib-dsbt.c:165
struct cmd_list_element * showdebuglist
Definition: cli-cmds.c:175
bfd * core_bfd
Definition: corefile.c:58
gdb_byte ext_Elf32_Half[2]
Definition: solib-dsbt.c:46
static struct so_list * dsbt_current_sos(void)
Definition: solib-dsbt.c:628
static CORE_ADDR interp_text_sect_high
Definition: solib-frv.c:440
struct bound_minimal_symbol lookup_minimal_symbol(const char *name, const char *sfile, struct objfile *objf)
Definition: minsyms.c:163
PTR xcalloc(size_t number, size_t size)
Definition: common-utils.c:71
int target_read_string(CORE_ADDR memaddr, char **string, int len, int *errnop)
Definition: target.c:915
struct int_elf32_dsbt_loadmap * exec_loadmap
Definition: solib-dsbt.c:146
void error(const char *fmt,...)
Definition: errors.c:38
static struct int_elf32_dsbt_loadmap * fetch_loadmap(CORE_ADDR ldmaddr)
Definition: solib-dsbt.c:320
bfd * solib_bfd_open(char *pathname)
Definition: solib.c:481
ext_Elf32_Addr addr
Definition: solib-dsbt.c:53
void do_cleanups(struct cleanup *old_chain)
Definition: cleanups.c:175
static void dsbt_relocate_main_executable(void)
Definition: solib-dsbt.c:931
static void dsbt_clear_solib(void)
Definition: solib-dsbt.c:1013