Automatic date update in version.in
[platform/upstream/binutils.git] / gdb / solib-dsbt.c
1 /* Handle TIC6X (DSBT) shared libraries for GDB, the GNU Debugger.
2    Copyright (C) 2010-2014 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.  */
46 typedef gdb_byte ext_Elf32_Half[2];
47 typedef gdb_byte ext_Elf32_Addr[4];
48 typedef gdb_byte ext_Elf32_Word[4];
49
50 struct ext_elf32_dsbt_loadseg
51 {
52   /* Core address to which the segment is mapped.  */
53   ext_Elf32_Addr addr;
54   /* VMA recorded in the program header.  */
55   ext_Elf32_Addr p_vaddr;
56   /* Size of this segment in memory.  */
57   ext_Elf32_Word p_memsz;
58 };
59
60 struct ext_elf32_dsbt_loadmap {
61   /* Protocol version number, must be zero.  */
62   ext_Elf32_Word version;
63   /* A pointer to the DSBT table; the DSBT size and the index of this
64      module.  */
65   ext_Elf32_Word dsbt_table_ptr;
66   ext_Elf32_Word dsbt_size;
67   ext_Elf32_Word dsbt_index;
68   /* Number of segments in this map.  */
69   ext_Elf32_Word nsegs;
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.  */
77 struct int_elf32_dsbt_loadseg
78 {
79   /* Core address to which the segment is mapped.  */
80   CORE_ADDR addr;
81   /* VMA recorded in the program header.  */
82   CORE_ADDR p_vaddr;
83   /* Size of this segment in memory.  */
84   long p_memsz;
85 };
86
87 struct int_elf32_dsbt_loadmap
88 {
89   /* Protocol version number, must be zero.  */
90   int version;
91   CORE_ADDR dsbt_table_ptr;
92   /* A pointer to the DSBT table; the DSBT size and the index of this
93      module.  */
94   int dsbt_size, dsbt_index;
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
105 struct ext_elf32_dsbt_loadaddr
106 {
107   ext_ptr map;                  /* struct elf32_dsbt_loadmap *map; */
108 };
109
110 struct ext_link_map
111 {
112   struct ext_elf32_dsbt_loadaddr l_addr;
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.  */
129   struct int_elf32_dsbt_loadmap *map;
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.  */
140   struct lm_info *main_executable_lm_info;
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.  */
146   struct int_elf32_dsbt_loadmap *exec_loadmap;
147   struct int_elf32_dsbt_loadmap *interp_loadmap;
148
149   /* Cached value for lm_base, below.  */
150   CORE_ADDR lm_base_cache;
151
152   /* Link map address for main module.  */
153   CORE_ADDR main_lm_addr;
154
155   CORE_ADDR interp_text_sect_low;
156   CORE_ADDR interp_text_sect_high;
157   CORE_ADDR interp_plt_sect_low;
158   CORE_ADDR interp_plt_sect_high;
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 *
174 get_dsbt_info (void)
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
193 dsbt_print_loadmap (struct int_elf32_dsbt_loadmap *map)
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",
207                          print_core_address (target_gdbarch (),
208                                              map->segs[i].p_vaddr),
209                          print_core_address (target_gdbarch (),
210                                              map->segs[i].p_vaddr
211                                              + map->segs[i].p_memsz),
212                          print_core_address (target_gdbarch (), map->segs[i].addr),
213                          print_core_address (target_gdbarch (), map->segs[i].addr
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 *
221 decode_loadmap (gdb_byte *buf)
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
287 dsbt_get_initial_loadmaps (void)
288 {
289   gdb_byte *buf;
290   struct dsbt_info *info = get_dsbt_info ();
291
292   if (0 >= target_read_alloc (&current_target, TARGET_OBJECT_FDPIC,
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)
300     dsbt_print_loadmap (info->exec_loadmap);
301
302   if (0 >= target_read_alloc (&current_target, TARGET_OBJECT_FDPIC,
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)
310     dsbt_print_loadmap (info->interp_loadmap);
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 *
320 fetch_loadmap (CORE_ADDR ldmaddr)
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;
418   struct target_section *target_section;
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;
436        target_section < current_target_sections->sections_end;
437        target_section++)
438     if (sect == target_section->the_bfd_section)
439       break;
440   if (target_section < current_target_sections->sections_end)
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
491              ptr_type = builtin_type (target_gdbarch ())->builtin_data_ptr;
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
523 displacement_from_map (struct int_elf32_dsbt_loadmap *map,
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;
553   gdb_byte buf[TIC6X_PTR_SIZE];
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,
569                                    symfile_objfile);
570
571   if (got_sym.minsym != 0)
572     {
573       addr = BMSYMBOL_VALUE_ADDRESS (got_sym);
574       if (solib_dsbt_debug)
575         fprintf_unfiltered (gdb_stdlog,
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
583       dsbt_get_initial_loadmaps ();
584       ldm = info->exec_loadmap;
585       addr += displacement_from_map (ldm, addr);
586       if (solib_dsbt_debug)
587         fprintf_unfiltered (gdb_stdlog,
588                             "lm_base: get addr %x by DT_PLTGOT.\n",
589                             (unsigned int) addr);
590     }
591   else
592     {
593       if (solib_dsbt_debug)
594         fprintf_unfiltered (gdb_stdlog,
595                             "lm_base: _GLOBAL_OFFSET_TABLE_ not found.\n");
596       return 0;
597     }
598   addr += GOT_MODULE_OFFSET;
599
600   if (solib_dsbt_debug)
601     fprintf_unfiltered (gdb_stdlog,
602                         "lm_base: _GLOBAL_OFFSET_TABLE_ + %d = %s\n",
603                         GOT_MODULE_OFFSET, hex_string_custom (addr, 8));
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)
610     fprintf_unfiltered (gdb_stdlog,
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 *
628 dsbt_current_sos (void)
629 {
630   enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
631   CORE_ADDR lm_addr;
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)
649     dsbt_relocate_main_executable ();
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)
665         fprintf_unfiltered (gdb_stdlog,
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
756 dsbt_in_dynsym_resolve_code (CORE_ADDR pc)
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
769 enable_break_failure_warning (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
793 enable_break (void)
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
802   if (!target_has_execution)
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       volatile struct gdb_exception ex;
824       int ret;
825
826       /* Read the contents of the .interp section into a local buffer;
827          the contents specify the dynamic linker this program uses.  */
828       interp_sect_size = bfd_section_size (exec_bfd, interp_sect);
829       buf = alloca (interp_sect_size);
830       bfd_get_section_contents (exec_bfd, interp_sect,
831                                 buf, 0, interp_sect_size);
832
833       /* Now we need to figure out where the dynamic linker was
834          loaded so that we can load its symbols and place a breakpoint
835          in the dynamic linker itself.  */
836
837       TRY_CATCH (ex, RETURN_MASK_ALL)
838         {
839           tmp_bfd = solib_bfd_open (buf);
840         }
841       if (tmp_bfd == NULL)
842         {
843           enable_break_failure_warning ();
844           return 0;
845         }
846
847       dsbt_get_initial_loadmaps ();
848       ldm = info->interp_loadmap;
849
850       /* Record the relocated start and end address of the dynamic linker
851          text and plt section for dsbt_in_dynsym_resolve_code.  */
852       interp_sect = bfd_get_section_by_name (tmp_bfd, ".text");
853       if (interp_sect)
854         {
855           info->interp_text_sect_low
856             = bfd_section_vma (tmp_bfd, interp_sect);
857           info->interp_text_sect_low
858             += displacement_from_map (ldm, info->interp_text_sect_low);
859           info->interp_text_sect_high
860             = info->interp_text_sect_low
861             + bfd_section_size (tmp_bfd, interp_sect);
862         }
863       interp_sect = bfd_get_section_by_name (tmp_bfd, ".plt");
864       if (interp_sect)
865         {
866           info->interp_plt_sect_low =
867             bfd_section_vma (tmp_bfd, interp_sect);
868           info->interp_plt_sect_low
869             += displacement_from_map (ldm, info->interp_plt_sect_low);
870           info->interp_plt_sect_high =
871             info->interp_plt_sect_low + bfd_section_size (tmp_bfd, interp_sect);
872         }
873
874       addr = gdb_bfd_lookup_symbol (tmp_bfd, cmp_name, "_dl_debug_state");
875       if (addr != 0)
876         {
877           if (solib_dsbt_debug)
878             fprintf_unfiltered (gdb_stdlog,
879                                 "enable_break: _dl_debug_state (prior to relocation) = %s\n",
880                                 hex_string_custom (addr, 8));
881           addr += displacement_from_map (ldm, addr);
882
883           if (solib_dsbt_debug)
884             fprintf_unfiltered (gdb_stdlog,
885                                 "enable_break: _dl_debug_state (after relocation) = %s\n",
886                                 hex_string_custom (addr, 8));
887
888           /* Now (finally!) create the solib breakpoint.  */
889           create_solib_event_breakpoint (target_gdbarch (), addr);
890
891           ret = 1;
892         }
893       else
894         {
895           if (solib_dsbt_debug)
896             fprintf_unfiltered (gdb_stdlog,
897                                 "enable_break: _dl_debug_state is not found\n");
898           ret = 0;
899         }
900
901       /* We're done with the temporary bfd.  */
902       gdb_bfd_unref (tmp_bfd);
903
904       /* We're also done with the loadmap.  */
905       xfree (ldm);
906
907       return ret;
908     }
909
910   /* Tell the user we couldn't set a dynamic linker breakpoint.  */
911   enable_break_failure_warning ();
912
913   /* Failure return.  */
914   return 0;
915 }
916
917 /* Once the symbols from a shared object have been loaded in the usual
918    way, we are called to do any system specific symbol handling that
919    is needed.  */
920
921 static void
922 dsbt_special_symbol_handling (void)
923 {
924 }
925
926 static void
927 dsbt_relocate_main_executable (void)
928 {
929   struct int_elf32_dsbt_loadmap *ldm;
930   struct cleanup *old_chain;
931   struct section_offsets *new_offsets;
932   int changed;
933   struct obj_section *osect;
934   struct dsbt_info *info = get_dsbt_info ();
935
936   dsbt_get_initial_loadmaps ();
937   ldm = info->exec_loadmap;
938
939   xfree (info->main_executable_lm_info);
940   info->main_executable_lm_info = xcalloc (1, sizeof (struct lm_info));
941   info->main_executable_lm_info->map = ldm;
942
943   new_offsets = xcalloc (symfile_objfile->num_sections,
944                          sizeof (struct section_offsets));
945   old_chain = make_cleanup (xfree, new_offsets);
946   changed = 0;
947
948   ALL_OBJFILE_OSECTIONS (symfile_objfile, osect)
949     {
950       CORE_ADDR orig_addr, addr, offset;
951       int osect_idx;
952       int seg;
953
954       osect_idx = osect - symfile_objfile->sections;
955
956       /* Current address of section.  */
957       addr = obj_section_addr (osect);
958       /* Offset from where this section started.  */
959       offset = ANOFFSET (symfile_objfile->section_offsets, osect_idx);
960       /* Original address prior to any past relocations.  */
961       orig_addr = addr - offset;
962
963       for (seg = 0; seg < ldm->nsegs; seg++)
964         {
965           if (ldm->segs[seg].p_vaddr <= orig_addr
966               && orig_addr < ldm->segs[seg].p_vaddr + ldm->segs[seg].p_memsz)
967             {
968               new_offsets->offsets[osect_idx]
969                 = ldm->segs[seg].addr - ldm->segs[seg].p_vaddr;
970
971               if (new_offsets->offsets[osect_idx] != offset)
972                 changed = 1;
973               break;
974             }
975         }
976     }
977
978   if (changed)
979     objfile_relocate (symfile_objfile, new_offsets);
980
981   do_cleanups (old_chain);
982
983   /* Now that symfile_objfile has been relocated, we can compute the
984      GOT value and stash it away.  */
985 }
986
987 /* When gdb starts up the inferior, it nurses it along (through the
988    shell) until it is ready to execute it's first instruction.  At this
989    point, this function gets called via solib_create_inferior_hook.
990
991    For the DSBT shared library, the main executable needs to be relocated.
992    The shared library breakpoints also need to be enabled.  */
993
994 static void
995 dsbt_solib_create_inferior_hook (int from_tty)
996 {
997   /* Relocate main executable.  */
998   dsbt_relocate_main_executable ();
999
1000   /* Enable shared library breakpoints.  */
1001   if (!enable_break ())
1002     {
1003       warning (_("shared library handler failed to enable breakpoint"));
1004       return;
1005     }
1006 }
1007
1008 static void
1009 dsbt_clear_solib (void)
1010 {
1011   struct dsbt_info *info = get_dsbt_info ();
1012
1013   info->lm_base_cache = 0;
1014   info->main_lm_addr = 0;
1015   if (info->main_executable_lm_info != 0)
1016     {
1017       xfree (info->main_executable_lm_info->map);
1018       xfree (info->main_executable_lm_info);
1019       info->main_executable_lm_info = 0;
1020     }
1021 }
1022
1023 static void
1024 dsbt_free_so (struct so_list *so)
1025 {
1026   xfree (so->lm_info->map);
1027   xfree (so->lm_info);
1028 }
1029
1030 static void
1031 dsbt_relocate_section_addresses (struct so_list *so,
1032                                  struct target_section *sec)
1033 {
1034   int seg;
1035   struct int_elf32_dsbt_loadmap *map;
1036
1037   map = so->lm_info->map;
1038
1039   for (seg = 0; seg < map->nsegs; seg++)
1040     {
1041       if (map->segs[seg].p_vaddr <= sec->addr
1042           && sec->addr < map->segs[seg].p_vaddr + map->segs[seg].p_memsz)
1043         {
1044           CORE_ADDR displ = map->segs[seg].addr - map->segs[seg].p_vaddr;
1045
1046           sec->addr += displ;
1047           sec->endaddr += displ;
1048           break;
1049         }
1050     }
1051 }
1052 static void
1053 show_dsbt_debug (struct ui_file *file, int from_tty,
1054                  struct cmd_list_element *c, const char *value)
1055 {
1056   fprintf_filtered (file, _("solib-dsbt debugging is %s.\n"), value);
1057 }
1058
1059 struct target_so_ops dsbt_so_ops;
1060
1061 /* Provide a prototype to silence -Wmissing-prototypes.  */
1062 extern initialize_file_ftype _initialize_dsbt_solib;
1063
1064 void
1065 _initialize_dsbt_solib (void)
1066 {
1067   solib_dsbt_pspace_data
1068     = register_program_space_data_with_cleanup (NULL, dsbt_pspace_data_cleanup);
1069
1070   dsbt_so_ops.relocate_section_addresses = dsbt_relocate_section_addresses;
1071   dsbt_so_ops.free_so = dsbt_free_so;
1072   dsbt_so_ops.clear_solib = dsbt_clear_solib;
1073   dsbt_so_ops.solib_create_inferior_hook = dsbt_solib_create_inferior_hook;
1074   dsbt_so_ops.special_symbol_handling = dsbt_special_symbol_handling;
1075   dsbt_so_ops.current_sos = dsbt_current_sos;
1076   dsbt_so_ops.open_symbol_file_object = open_symbol_file_object;
1077   dsbt_so_ops.in_dynsym_resolve_code = dsbt_in_dynsym_resolve_code;
1078   dsbt_so_ops.bfd_open = solib_bfd_open;
1079
1080   /* Debug this file's internals.  */
1081   add_setshow_zuinteger_cmd ("solib-dsbt", class_maintenance,
1082                              &solib_dsbt_debug, _("\
1083 Set internal debugging of shared library code for DSBT ELF."), _("\
1084 Show internal debugging of shared library code for DSBT ELF."), _("\
1085 When non-zero, DSBT solib specific internal debugging is enabled."),
1086                              NULL,
1087                              show_dsbt_debug,
1088                              &setdebuglist, &showdebuglist);
1089 }