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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [gdb/] [solib-som.c] - Blame information for rev 866

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

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

powered by: WebSVN 2.1.0

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