OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [gdb/] [solib-som.c] - Blame information for rev 476

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 330 jeremybenn
/* Handle SOM shared libraries.
2
 
3
   Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010
4
   Free Software Foundation, Inc.
5
 
6
   This file is part of GDB.
7
 
8
   This program is free software; you can redistribute it and/or modify
9
   it under the terms of the GNU General Public License as published by
10
   the Free Software Foundation; either version 3 of the License, or
11
   (at your option) any later version.
12
 
13
   This program is distributed in the hope that it will be useful,
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
   GNU General Public License for more details.
17
 
18
   You should have received a copy of the GNU General Public License
19
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
 
21
#include "defs.h"
22
#include "symtab.h"
23
#include "bfd.h"
24
#include "symfile.h"
25
#include "objfiles.h"
26
#include "gdbcore.h"
27
#include "target.h"
28
#include "inferior.h"
29
 
30
#include "hppa-tdep.h"
31
#include "solist.h"
32
#include "solib.h"
33
#include "solib-som.h"
34
 
35
#include <sys/utsname.h>
36
#include <string.h>
37
 
38
#undef SOLIB_SOM_DBG 
39
 
40
/* These ought to be defined in some public interface, but aren't.  They
41
   define the meaning of the various bits in the distinguished __dld_flags
42
   variable that is declared in every debuggable a.out on HP-UX, and that
43
   is shared between the debugger and the dynamic linker.
44
 */
45
#define DLD_FLAGS_MAPPRIVATE    0x1
46
#define DLD_FLAGS_HOOKVALID     0x2
47
#define DLD_FLAGS_LISTVALID     0x4
48
#define DLD_FLAGS_BOR_ENABLE    0x8
49
 
50
struct lm_info
51
  {
52
    /* Version of this structure (it is expected to change again in hpux10).  */
53
    unsigned char struct_version;
54
 
55
    /* Binding mode for this library.  */
56
    unsigned char bind_mode;
57
 
58
    /* Version of this library.  */
59
    short library_version;
60
 
61
    /* Start of text address,
62
       link-time text location (length of text area),
63
       end of text address.  */
64
    CORE_ADDR text_addr;
65
    CORE_ADDR text_link_addr;
66
    CORE_ADDR text_end;
67
 
68
    /* Start of data, start of bss and end of data.  */
69
    CORE_ADDR data_start;
70
    CORE_ADDR bss_start;
71
    CORE_ADDR data_end;
72
 
73
    /* Value of linkage pointer (%r19).  */
74
    CORE_ADDR got_value;
75
 
76
    /* Address in target of offset from thread-local register of
77
       start of this thread's data.  I.e., the first thread-local
78
       variable in this shared library starts at *(tsd_start_addr)
79
       from that area pointed to by cr27 (mpsfu_hi).
80
 
81
       We do the indirection as soon as we read it, so from then
82
       on it's the offset itself.  */
83
    CORE_ADDR tsd_start_addr;
84
 
85
    /* Address of the link map entry in the loader.  */
86
    CORE_ADDR lm_addr;
87
  };
88
 
89
/* These addresses should be filled in by som_solib_create_inferior_hook.
90
   They are also used elsewhere in this module.
91
 */
92
typedef struct
93
  {
94
    CORE_ADDR address;
95
    struct unwind_table_entry *unwind;
96
  }
97
addr_and_unwind_t;
98
 
99
/* When adding fields, be sure to clear them in _initialize_som_solib. */
100
static struct
101
  {
102
    int is_valid;
103
    addr_and_unwind_t hook;
104
    addr_and_unwind_t hook_stub;
105
    addr_and_unwind_t load;
106
    addr_and_unwind_t load_stub;
107
    addr_and_unwind_t unload;
108
    addr_and_unwind_t unload2;
109
    addr_and_unwind_t unload_stub;
110
  }
111
dld_cache;
112
 
113
static void
114
som_relocate_section_addresses (struct so_list *so,
115
                                struct target_section *sec)
116
{
117
  flagword aflag = bfd_get_section_flags(so->abfd, sec->the_bfd_section);
118
 
119
  if (aflag & SEC_CODE)
120
    {
121
      sec->addr    += so->lm_info->text_addr - so->lm_info->text_link_addr;
122
      sec->endaddr += so->lm_info->text_addr - so->lm_info->text_link_addr;
123
    }
124
  else if (aflag & SEC_DATA)
125
    {
126
      sec->addr    += so->lm_info->data_start;
127
      sec->endaddr += so->lm_info->data_start;
128
    }
129
  else
130
    ;
131
}
132
 
133
/* Get HP-UX major release number.  Returns zero if the
134
   release is not known.  */
135
 
136
static int
137
get_hpux_major_release (void)
138
{
139
  static int hpux_major_release = -1;
140
 
141
  if (hpux_major_release == -1)
142
    {
143
      struct utsname x;
144
      char *p;
145
 
146
      uname (&x);
147
      p = strchr (x.release, '.');
148
      hpux_major_release = p ? atoi (p + 1) : 0;
149
    }
150
 
151
  return hpux_major_release;
152
}
153
 
154
/* DL header flag defines.  */
155
#define SHLIB_TEXT_PRIVATE_ENABLE 0x4000
156
 
157
/* The DL header is documented in <shl.h>.  We are only interested
158
   in the flags field to determine whether the executable wants shared
159
   libraries mapped private.  */
160
struct {
161
    short junk[37];
162
    short flags;
163
} dl_header;
164
 
165
/* This hook gets called just before the first instruction in the
166
   inferior process is executed.
167
 
168
   This is our opportunity to set magic flags in the inferior so
169
   that GDB can be notified when a shared library is mapped in and
170
   to tell the dynamic linker that a private copy of the library is
171
   needed (so GDB can set breakpoints in the library).
172
 
173
   __dld_flags is the location of the magic flags; as of this implementation
174
   there are 3 flags of interest:
175
 
176
   bit 0 when set indicates that private copies of the libraries are needed
177
   bit 1 when set indicates that the callback hook routine is valid
178
   bit 2 when set indicates that the dynamic linker should maintain the
179
   __dld_list structure when loading/unloading libraries.
180
 
181
   Note that shared libraries are not mapped in at this time, so we have
182
   run the inferior until the libraries are mapped in.  Typically this
183
   means running until the "_start" is called.  */
184
 
185
static void
186
som_solib_create_inferior_hook (int from_tty)
187
{
188
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
189
  struct minimal_symbol *msymbol;
190
  unsigned int dld_flags, status, have_endo;
191
  asection *shlib_info;
192
  char buf[4];
193
  CORE_ADDR anaddr;
194
 
195
  if (symfile_objfile == NULL)
196
    return;
197
 
198
  /* First see if the objfile was dynamically linked.  */
199
  shlib_info = bfd_get_section_by_name (symfile_objfile->obfd, "$SHLIB_INFO$");
200
  if (!shlib_info)
201
    return;
202
 
203
  /* It's got a $SHLIB_INFO$ section, make sure it's not empty.  */
204
  if (bfd_section_size (symfile_objfile->obfd, shlib_info) == 0)
205
    return;
206
 
207
  /* Read the DL header.  */
208
  bfd_get_section_contents (symfile_objfile->obfd, shlib_info,
209
                            (char *) &dl_header, 0, sizeof (dl_header));
210
 
211
  have_endo = 0;
212
  /* Slam the pid of the process into __d_pid.
213
 
214
     We used to warn when this failed, but that warning is only useful
215
     on very old HP systems (hpux9 and older).  The warnings are an
216
     annoyance to users of modern systems and foul up the testsuite as
217
     well.  As a result, the warnings have been disabled.  */
218
  msymbol = lookup_minimal_symbol ("__d_pid", NULL, symfile_objfile);
219
  if (msymbol == NULL)
220
    goto keep_going;
221
 
222
  anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
223
  store_unsigned_integer (buf, 4, byte_order, PIDGET (inferior_ptid));
224
  status = target_write_memory (anaddr, buf, 4);
225
  if (status != 0)
226
    {
227
      warning (_("\
228
Unable to write __d_pid.\n\
229
Suggest linking with /opt/langtools/lib/end.o.\n\
230
GDB will be unable to track shl_load/shl_unload calls"));
231
      goto keep_going;
232
    }
233
 
234
  /* Get the value of _DLD_HOOK (an export stub) and put it in __dld_hook;
235
     This will force the dynamic linker to call __d_trap when significant
236
     events occur.
237
 
238
     Note that the above is the pre-HP-UX 9.0 behaviour.  At 9.0 and above,
239
     the dld provides an export stub named "__d_trap" as well as the
240
     function named "__d_trap" itself, but doesn't provide "_DLD_HOOK".
241
     We'll look first for the old flavor and then the new.
242
   */
243
  msymbol = lookup_minimal_symbol ("_DLD_HOOK", NULL, symfile_objfile);
244
  if (msymbol == NULL)
245
    msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile);
246
  if (msymbol == NULL)
247
    {
248
      warning (_("\
249
Unable to find _DLD_HOOK symbol in object file.\n\
250
Suggest linking with /opt/langtools/lib/end.o.\n\
251
GDB will be unable to track shl_load/shl_unload calls"));
252
      goto keep_going;
253
    }
254
  anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
255
  dld_cache.hook.address = anaddr;
256
 
257
  /* Grrr, this might not be an export symbol!  We have to find the
258
     export stub.  */
259
  msymbol = hppa_lookup_stub_minimal_symbol (SYMBOL_LINKAGE_NAME (msymbol),
260
                                             EXPORT);
261
  if (msymbol != NULL)
262
    {
263
      anaddr = SYMBOL_VALUE (msymbol);
264
      dld_cache.hook_stub.address = anaddr;
265
    }
266
  store_unsigned_integer (buf, 4, byte_order, anaddr);
267
 
268
  msymbol = lookup_minimal_symbol ("__dld_hook", NULL, symfile_objfile);
269
  if (msymbol == NULL)
270
    {
271
      warning (_("\
272
Unable to find __dld_hook symbol in object file.\n\
273
Suggest linking with /opt/langtools/lib/end.o.\n\
274
GDB will be unable to track shl_load/shl_unload calls"));
275
      goto keep_going;
276
    }
277
  anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
278
  status = target_write_memory (anaddr, buf, 4);
279
 
280
  /* Now set a shlib_event breakpoint at __d_trap so we can track
281
     significant shared library events.  */
282
  msymbol = lookup_minimal_symbol ("__d_trap", NULL, symfile_objfile);
283
  if (msymbol == NULL)
284
    {
285
      warning (_("\
286
Unable to find __dld_d_trap symbol in object file.\n\
287
Suggest linking with /opt/langtools/lib/end.o.\n\
288
GDB will be unable to track shl_load/shl_unload calls"));
289
      goto keep_going;
290
    }
291
  create_solib_event_breakpoint (target_gdbarch,
292
                                 SYMBOL_VALUE_ADDRESS (msymbol));
293
 
294
  /* We have all the support usually found in end.o, so we can track
295
     shl_load and shl_unload calls.  */
296
  have_endo = 1;
297
 
298
keep_going:
299
 
300
  /* Get the address of __dld_flags, if no such symbol exists, then we can
301
     not debug the shared code.  */
302
  msymbol = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
303
  if (msymbol == NULL)
304
    {
305
      error (_("Unable to find __dld_flags symbol in object file."));
306
    }
307
 
308
  anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
309
 
310
  /* Read the current contents.  */
311
  status = target_read_memory (anaddr, buf, 4);
312
  if (status != 0)
313
    error (_("Unable to read __dld_flags."));
314
  dld_flags = extract_unsigned_integer (buf, 4, byte_order);
315
 
316
  /* If the libraries were not mapped private on HP-UX 11 and later, warn
317
     the user.  On HP-UX 10 and earlier, there is no easy way to specify
318
     that shared libraries should be privately mapped.  So, we just force
319
     private mapping.  */
320
  if (get_hpux_major_release () >= 11
321
      && (dl_header.flags & SHLIB_TEXT_PRIVATE_ENABLE) == 0
322
      && (dld_flags & DLD_FLAGS_MAPPRIVATE) == 0)
323
    warning
324
      (_("Private mapping of shared library text was not specified\n"
325
         "by the executable; setting a breakpoint in a shared library which\n"
326
         "is not privately mapped will not work.  See the HP-UX 11i v3 chatr\n"
327
         "manpage for methods to privately map shared library text."));
328
 
329
  /* Turn on the flags we care about.  */
330
  if (get_hpux_major_release () < 11)
331
    dld_flags |= DLD_FLAGS_MAPPRIVATE;
332
  if (have_endo)
333
    dld_flags |= DLD_FLAGS_HOOKVALID;
334
  store_unsigned_integer (buf, 4, byte_order, dld_flags);
335
  status = target_write_memory (anaddr, buf, 4);
336
  if (status != 0)
337
    error (_("Unable to write __dld_flags."));
338
 
339
  /* Now find the address of _start and set a breakpoint there.
340
     We still need this code for two reasons:
341
 
342
     * Not all sites have /opt/langtools/lib/end.o, so it's not always
343
     possible to track the dynamic linker's events.
344
 
345
     * At this time no events are triggered for shared libraries
346
     loaded at startup time (what a crock).  */
347
 
348
  msymbol = lookup_minimal_symbol ("_start", NULL, symfile_objfile);
349
  if (msymbol == NULL)
350
    error (_("Unable to find _start symbol in object file."));
351
 
352
  anaddr = SYMBOL_VALUE_ADDRESS (msymbol);
353
 
354
  /* Make the breakpoint at "_start" a shared library event breakpoint.  */
355
  create_solib_event_breakpoint (target_gdbarch, anaddr);
356
 
357
  clear_symtab_users ();
358
}
359
 
360
static void
361
som_special_symbol_handling (void)
362
{
363
}
364
 
365
static void
366
som_solib_desire_dynamic_linker_symbols (void)
367
{
368
  struct objfile *objfile;
369
  struct unwind_table_entry *u;
370
  struct minimal_symbol *dld_msymbol;
371
 
372
  /* Do we already know the value of these symbols?  If so, then
373
     we've no work to do.
374
 
375
     (If you add clauses to this test, be sure to likewise update the
376
     test within the loop.)
377
   */
378
  if (dld_cache.is_valid)
379
    return;
380
 
381
  ALL_OBJFILES (objfile)
382
  {
383
    dld_msymbol = lookup_minimal_symbol ("shl_load", NULL, objfile);
384
    if (dld_msymbol != NULL)
385
      {
386
        dld_cache.load.address = SYMBOL_VALUE (dld_msymbol);
387
        dld_cache.load.unwind = find_unwind_entry (dld_cache.load.address);
388
      }
389
 
390
    dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_load",
391
                                                          objfile);
392
    if (dld_msymbol != NULL)
393
      {
394
        if (MSYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline)
395
          {
396
            u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol));
397
            if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT))
398
              {
399
                dld_cache.load_stub.address = SYMBOL_VALUE (dld_msymbol);
400
                dld_cache.load_stub.unwind = u;
401
              }
402
          }
403
      }
404
 
405
    dld_msymbol = lookup_minimal_symbol ("shl_unload", NULL, objfile);
406
    if (dld_msymbol != NULL)
407
      {
408
        dld_cache.unload.address = SYMBOL_VALUE (dld_msymbol);
409
        dld_cache.unload.unwind = find_unwind_entry (dld_cache.unload.address);
410
 
411
        /* ??rehrauer: I'm not sure exactly what this is, but it appears
412
           that on some HPUX 10.x versions, there's two unwind regions to
413
           cover the body of "shl_unload", the second being 4 bytes past
414
           the end of the first.  This is a large hack to handle that
415
           case, but since I don't seem to have any legitimate way to
416
           look for this thing via the symbol table...
417
         */
418
        if (dld_cache.unload.unwind != NULL)
419
          {
420
            u = find_unwind_entry (dld_cache.unload.unwind->region_end + 4);
421
            if (u != NULL)
422
              {
423
                dld_cache.unload2.address = u->region_start;
424
                dld_cache.unload2.unwind = u;
425
              }
426
          }
427
      }
428
 
429
    dld_msymbol = lookup_minimal_symbol_solib_trampoline ("shl_unload",
430
                                                          objfile);
431
    if (dld_msymbol != NULL)
432
      {
433
        if (MSYMBOL_TYPE (dld_msymbol) == mst_solib_trampoline)
434
          {
435
            u = find_unwind_entry (SYMBOL_VALUE (dld_msymbol));
436
            if ((u != NULL) && (u->stub_unwind.stub_type == EXPORT))
437
              {
438
                dld_cache.unload_stub.address = SYMBOL_VALUE (dld_msymbol);
439
                dld_cache.unload_stub.unwind = u;
440
              }
441
          }
442
      }
443
 
444
    /* Did we find everything we were looking for?  If so, stop. */
445
    if ((dld_cache.load.address != 0)
446
        && (dld_cache.load_stub.address != 0)
447
        && (dld_cache.unload.address != 0)
448
        && (dld_cache.unload_stub.address != 0))
449
      {
450
        dld_cache.is_valid = 1;
451
        break;
452
      }
453
  }
454
 
455
  dld_cache.hook.unwind = find_unwind_entry (dld_cache.hook.address);
456
  dld_cache.hook_stub.unwind = find_unwind_entry (dld_cache.hook_stub.address);
457
 
458
  /* We're prepared not to find some of these symbols, which is why
459
     this function is a "desire" operation, and not a "require".
460
   */
461
}
462
 
463
static int
464
som_in_dynsym_resolve_code (CORE_ADDR pc)
465
{
466
  struct unwind_table_entry *u_pc;
467
 
468
  /* Are we in the dld itself?
469
 
470
     ??rehrauer: Large hack -- We'll assume that any address in a
471
     shared text region is the dld's text.  This would obviously
472
     fall down if the user attached to a process, whose shlibs
473
     weren't mapped to a (writeable) private region.  However, in
474
     that case the debugger probably isn't able to set the fundamental
475
     breakpoint in the dld callback anyways, so this hack should be
476
     safe.
477
   */
478
  if ((pc & (CORE_ADDR) 0xc0000000) == (CORE_ADDR) 0xc0000000)
479
    return 1;
480
 
481
  /* Cache the address of some symbols that are part of the dynamic
482
     linker, if not already known.
483
   */
484
  som_solib_desire_dynamic_linker_symbols ();
485
 
486
  /* Are we in the dld callback?  Or its export stub? */
487
  u_pc = find_unwind_entry (pc);
488
  if (u_pc == NULL)
489
    return 0;
490
 
491
  if ((u_pc == dld_cache.hook.unwind) || (u_pc == dld_cache.hook_stub.unwind))
492
    return 1;
493
 
494
  /* Or the interface of the dld (i.e., "shl_load" or friends)? */
495
  if ((u_pc == dld_cache.load.unwind)
496
      || (u_pc == dld_cache.unload.unwind)
497
      || (u_pc == dld_cache.unload2.unwind)
498
      || (u_pc == dld_cache.load_stub.unwind)
499
      || (u_pc == dld_cache.unload_stub.unwind))
500
    return 1;
501
 
502
  /* Apparently this address isn't part of the dld's text. */
503
  return 0;
504
}
505
 
506
static void
507
som_clear_solib (void)
508
{
509
}
510
 
511
struct dld_list {
512
  char name[4];
513
  char info[4];
514
  char text_addr[4];
515
  char text_link_addr[4];
516
  char text_end[4];
517
  char data_start[4];
518
  char bss_start[4];
519
  char data_end[4];
520
  char got_value[4];
521
  char next[4];
522
  char tsd_start_addr_ptr[4];
523
};
524
 
525
static CORE_ADDR
526
link_map_start (void)
527
{
528
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
529
  struct minimal_symbol *sym;
530
  CORE_ADDR addr;
531
  char buf[4];
532
  unsigned int dld_flags;
533
 
534
  sym = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
535
  if (!sym)
536
    error (_("Unable to find __dld_flags symbol in object file."));
537
  addr = SYMBOL_VALUE_ADDRESS (sym);
538
  read_memory (addr, buf, 4);
539
  dld_flags = extract_unsigned_integer (buf, 4, byte_order);
540
  if ((dld_flags & DLD_FLAGS_LISTVALID) == 0)
541
    error (_("__dld_list is not valid according to __dld_flags."));
542
 
543
  sym = lookup_minimal_symbol ("__dld_list", NULL, NULL);
544
  if (!sym)
545
    {
546
      /* Older crt0.o files (hpux8) don't have __dld_list as a symbol,
547
         but the data is still available if you know where to look.  */
548
      sym = lookup_minimal_symbol ("__dld_flags", NULL, NULL);
549
      if (!sym)
550
        {
551
          error (_("Unable to find dynamic library list."));
552
          return 0;
553
        }
554
      addr = SYMBOL_VALUE_ADDRESS (sym) - 8;
555
    }
556
  else
557
    addr = SYMBOL_VALUE_ADDRESS (sym);
558
 
559
  read_memory (addr, buf, 4);
560
  addr = extract_unsigned_integer (buf, 4, byte_order);
561
  if (addr == 0)
562
    return 0;
563
 
564
  read_memory (addr, buf, 4);
565
  return extract_unsigned_integer (buf, 4, byte_order);
566
}
567
 
568
/* Does this so's name match the main binary? */
569
static int
570
match_main (const char *name)
571
{
572
  return strcmp (name, symfile_objfile->name) == 0;
573
}
574
 
575
static struct so_list *
576
som_current_sos (void)
577
{
578
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
579
  CORE_ADDR lm;
580
  struct so_list *head = 0;
581
  struct so_list **link_ptr = &head;
582
 
583
  for (lm = link_map_start (); lm; )
584
    {
585
      char *namebuf;
586
      CORE_ADDR addr;
587
      struct so_list *new;
588
      struct cleanup *old_chain;
589
      int errcode;
590
      struct dld_list dbuf;
591
      char tsdbuf[4];
592
 
593
      new = (struct so_list *) xmalloc (sizeof (struct so_list));
594
      old_chain = make_cleanup (xfree, new);
595
 
596
      memset (new, 0, sizeof (*new));
597
      new->lm_info = xmalloc (sizeof (struct lm_info));
598
      make_cleanup (xfree, new->lm_info);
599
 
600
      read_memory (lm, (gdb_byte *)&dbuf, sizeof (struct dld_list));
601
 
602
      addr = extract_unsigned_integer ((gdb_byte *)&dbuf.name,
603
                                       sizeof (dbuf.name), byte_order);
604
      target_read_string (addr, &namebuf, SO_NAME_MAX_PATH_SIZE - 1, &errcode);
605
      if (errcode != 0)
606
        warning (_("Can't read pathname for load map: %s."),
607
                 safe_strerror (errcode));
608
      else
609
        {
610
          strncpy (new->so_name, namebuf, SO_NAME_MAX_PATH_SIZE - 1);
611
          new->so_name[SO_NAME_MAX_PATH_SIZE - 1] = '\0';
612
          xfree (namebuf);
613
          strcpy (new->so_original_name, new->so_name);
614
        }
615
 
616
        if (new->so_name[0] && !match_main (new->so_name))
617
          {
618
            struct lm_info *lmi = new->lm_info;
619
            unsigned int tmp;
620
 
621
            lmi->lm_addr = lm;
622
 
623
#define EXTRACT(_fld) \
624
  extract_unsigned_integer ((gdb_byte *)&dbuf._fld, \
625
                            sizeof (dbuf._fld), byte_order);
626
 
627
            lmi->text_addr = EXTRACT (text_addr);
628
            tmp = EXTRACT (info);
629
            lmi->library_version = (tmp >> 16) & 0xffff;
630
            lmi->bind_mode = (tmp >> 8) & 0xff;
631
            lmi->struct_version = tmp & 0xff;
632
            lmi->text_link_addr = EXTRACT (text_link_addr);
633
            lmi->text_end = EXTRACT (text_end);
634
            lmi->data_start = EXTRACT (data_start);
635
            lmi->bss_start = EXTRACT (bss_start);
636
            lmi->data_end = EXTRACT (data_end);
637
            lmi->got_value = EXTRACT (got_value);
638
            tmp = EXTRACT (tsd_start_addr_ptr);
639
            read_memory (tmp, tsdbuf, 4);
640
            lmi->tsd_start_addr
641
              = extract_unsigned_integer (tsdbuf, 4, byte_order);
642
 
643
#ifdef SOLIB_SOM_DBG
644
            printf ("\n+ library \"%s\" is described at %s\n", new->so_name,
645
                    paddress (target_gdbarch, lm));
646
            printf ("  'version' is %d\n", new->lm_info->struct_version);
647
            printf ("  'bind_mode' is %d\n", new->lm_info->bind_mode);
648
            printf ("  'library_version' is %d\n",
649
                    new->lm_info->library_version);
650
            printf ("  'text_addr' is %s\n",
651
                    paddress (target_gdbarch, new->lm_info->text_addr));
652
            printf ("  'text_link_addr' is %s\n",
653
                    paddress (target_gdbarch, new->lm_info->text_link_addr));
654
            printf ("  'text_end' is %s\n",
655
                    paddress (target_gdbarch, new->lm_info->text_end));
656
            printf ("  'data_start' is %s\n",
657
                    paddress (target_gdbarch, new->lm_info->data_start));
658
            printf ("  'bss_start' is %s\n",
659
                    paddress (target_gdbarch, new->lm_info->bss_start));
660
            printf ("  'data_end' is %s\n",
661
                    paddress (target_gdbarch, new->lm_info->data_end));
662
            printf ("  'got_value' is %s\n",
663
                    paddress (target_gdbarch, new->lm_info->got_value));
664
            printf ("  'tsd_start_addr' is %s\n",
665
                    paddress (target_gdbarch, new->lm_info->tsd_start_addr));
666
#endif
667
 
668
            new->addr_low = lmi->text_addr;
669
            new->addr_high = lmi->text_end;
670
 
671
            /* Link the new object onto the list.  */
672
            new->next = NULL;
673
            *link_ptr = new;
674
            link_ptr = &new->next;
675
          }
676
        else
677
          {
678
            free_so (new);
679
          }
680
 
681
      lm = EXTRACT (next);
682
      discard_cleanups (old_chain);
683
#undef EXTRACT
684
    }
685
 
686
  /* TODO: The original somsolib code has logic to detect and eliminate
687
     duplicate entries.  Do we need that?  */
688
 
689
  return head;
690
}
691
 
692
static int
693
som_open_symbol_file_object (void *from_ttyp)
694
{
695
  enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
696
  CORE_ADDR lm, l_name;
697
  char *filename;
698
  int errcode;
699
  int from_tty = *(int *)from_ttyp;
700
  char buf[4];
701
 
702
  if (symfile_objfile)
703
    if (!query (_("Attempt to reload symbols from process? ")))
704
      return 0;
705
 
706
  /* First link map member should be the executable.  */
707
  if ((lm = link_map_start ()) == 0)
708
    return 0;    /* failed somehow... */
709
 
710
  /* Read address of name from target memory to GDB.  */
711
  read_memory (lm + offsetof (struct dld_list, name), buf, 4);
712
 
713
  /* Convert the address to host format.  Assume that the address is
714
     unsigned.  */
715
  l_name = extract_unsigned_integer (buf, 4, byte_order);
716
 
717
  if (l_name == 0)
718
    return 0;            /* No filename.  */
719
 
720
  /* Now fetch the filename from target memory.  */
721
  target_read_string (l_name, &filename, SO_NAME_MAX_PATH_SIZE - 1, &errcode);
722
 
723
  if (errcode)
724
    {
725
      warning (_("failed to read exec filename from attached file: %s"),
726
               safe_strerror (errcode));
727
      return 0;
728
    }
729
 
730
  make_cleanup (xfree, filename);
731
  /* Have a pathname: read the symbol file.  */
732
  symbol_file_add_main (filename, from_tty);
733
 
734
  return 1;
735
}
736
 
737
static void
738
som_free_so (struct so_list *so)
739
{
740
  xfree (so->lm_info);
741
}
742
 
743
static CORE_ADDR
744
som_solib_thread_start_addr (struct so_list *so)
745
{
746
  return so->lm_info->tsd_start_addr;
747
}
748
 
749
/* Return the GOT value for the shared library in which ADDR belongs.  If
750
   ADDR isn't in any known shared library, return zero.  */
751
 
752
static CORE_ADDR
753
som_solib_get_got_by_pc (CORE_ADDR addr)
754
{
755
  struct so_list *so_list = master_so_list ();
756
  CORE_ADDR got_value = 0;
757
 
758
  while (so_list)
759
    {
760
      if (so_list->lm_info->text_addr <= addr
761
          && so_list->lm_info->text_end > addr)
762
        {
763
          got_value = so_list->lm_info->got_value;
764
          break;
765
        }
766
      so_list = so_list->next;
767
    }
768
  return got_value;
769
}
770
 
771
/* Return the address of the handle of the shared library in which ADDR belongs.
772
   If ADDR isn't in any known shared library, return zero.  */
773
/* this function is used in initialize_hp_cxx_exception_support in
774
   hppa-hpux-tdep.c  */
775
 
776
static CORE_ADDR
777
som_solib_get_solib_by_pc (CORE_ADDR addr)
778
{
779
  struct so_list *so_list = master_so_list ();
780
 
781
  while (so_list)
782
    {
783
      if (so_list->lm_info->text_addr <= addr
784
          && so_list->lm_info->text_end > addr)
785
        {
786
          break;
787
        }
788
      so_list = so_list->next;
789
    }
790
  if (so_list)
791
    return so_list->lm_info->lm_addr;
792
  else
793
    return 0;
794
}
795
 
796
 
797
static struct target_so_ops som_so_ops;
798
 
799
extern initialize_file_ftype _initialize_som_solib; /* -Wmissing-prototypes */
800
 
801
void
802
_initialize_som_solib (void)
803
{
804
  som_so_ops.relocate_section_addresses = som_relocate_section_addresses;
805
  som_so_ops.free_so = som_free_so;
806
  som_so_ops.clear_solib = som_clear_solib;
807
  som_so_ops.solib_create_inferior_hook = som_solib_create_inferior_hook;
808
  som_so_ops.special_symbol_handling = som_special_symbol_handling;
809
  som_so_ops.current_sos = som_current_sos;
810
  som_so_ops.open_symbol_file_object = som_open_symbol_file_object;
811
  som_so_ops.in_dynsym_resolve_code = som_in_dynsym_resolve_code;
812
  som_so_ops.bfd_open = solib_bfd_open;
813
}
814
 
815
void
816
som_solib_select (struct gdbarch *gdbarch)
817
{
818
  struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
819
 
820
  set_solib_ops (gdbarch, &som_so_ops);
821
  tdep->solib_thread_start_addr = som_solib_thread_start_addr;
822
  tdep->solib_get_got_by_pc = som_solib_get_got_by_pc;
823
  tdep->solib_get_solib_by_pc = som_solib_get_solib_by_pc;
824
}
825
 
826
/* The rest of these functions are not part of the solib interface; they
827
   are used by somread.c or hppa-hpux-tdep.c */
828
 
829
int
830
som_solib_section_offsets (struct objfile *objfile,
831
                           struct section_offsets *offsets)
832
{
833
  struct so_list *so_list = master_so_list ();
834
 
835
  while (so_list)
836
    {
837
      /* Oh what a pain!  We need the offsets before so_list->objfile
838
         is valid.  The BFDs will never match.  Make a best guess.  */
839
      if (strstr (objfile->name, so_list->so_name))
840
        {
841
          asection *private_section;
842
 
843
          /* The text offset is easy.  */
844
          offsets->offsets[SECT_OFF_TEXT (objfile)]
845
            = (so_list->lm_info->text_addr
846
               - so_list->lm_info->text_link_addr);
847
          offsets->offsets[SECT_OFF_RODATA (objfile)]
848
            = ANOFFSET (offsets, SECT_OFF_TEXT (objfile));
849
 
850
          /* We should look at presumed_dp in the SOM header, but
851
             that's not easily available.  This should be OK though.  */
852
          private_section = bfd_get_section_by_name (objfile->obfd,
853
                                                     "$PRIVATE$");
854
          if (!private_section)
855
            {
856
              warning (_("Unable to find $PRIVATE$ in shared library!"));
857
              offsets->offsets[SECT_OFF_DATA (objfile)] = 0;
858
              offsets->offsets[SECT_OFF_BSS (objfile)] = 0;
859
              return 1;
860
            }
861
          offsets->offsets[SECT_OFF_DATA (objfile)]
862
            = (so_list->lm_info->data_start - private_section->vma);
863
          offsets->offsets[SECT_OFF_BSS (objfile)]
864
            = ANOFFSET (offsets, SECT_OFF_DATA (objfile));
865
          return 1;
866
        }
867
      so_list = so_list->next;
868
    }
869
  return 0;
870
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.