diff options
Diffstat (limited to 'gdb')
-rw-r--r-- | gdb/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/solib-svr4.c | 48 |
2 files changed, 36 insertions, 19 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 84cc94d..17adcac 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2007-08-22 Daniel Jacobowitz <dan@codesourcery.com> + + * solib-svr4.c (scan_dyntag): Only read target memory when necessary. + Fix formatting. + (elf_locate_base): Look for DT_MIPS_RLD_MAP first. Expand comments. + (elf_lookup_lib_symbol): Fix formatting. + 2007-08-21 Michael Snyder <msnyder@access-company.com> * dbxread.c (read_dbx_symtab): Guard null deref. diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c index 6391827..d6b075b 100644 --- a/gdb/solib-svr4.c +++ b/gdb/solib-svr4.c @@ -354,7 +354,7 @@ scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr) int arch_size, step, sect_size; long dyn_tag; CORE_ADDR dyn_ptr, dyn_addr; - gdb_byte *bufend, *buf; + gdb_byte *bufend, *bufstart, *buf; Elf32_External_Dyn *x_dynp_32; Elf64_External_Dyn *x_dynp_64; struct bfd_section *sect; @@ -371,16 +371,13 @@ scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr) return 0; dyn_addr = bfd_section_vma (abfd, sect); - /* Read in .dynamic section, silently ignore errors. */ + /* Read in .dynamic from the BFD. We will get the actual value + from memory later. */ sect_size = bfd_section_size (abfd, sect); - buf = alloca (sect_size); - if (target_read_memory (dyn_addr, buf, sect_size)) - { - /* If target_read_memory fails, try reading the BFD file. */ - if (!bfd_get_section_contents (abfd, sect, - buf, 0, sect_size)) - return 0; - } + buf = bufstart = alloca (sect_size); + if (!bfd_get_section_contents (abfd, sect, + buf, 0, sect_size)) + return 0; /* Iterate over BUF and scan for DYNTAG. If found, set PTR and return. */ step = (arch_size == 32) ? sizeof (Elf32_External_Dyn) @@ -395,7 +392,7 @@ scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr) dyn_tag = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_tag); dyn_ptr = bfd_h_get_32 (abfd, (bfd_byte *) x_dynp_32->d_un.d_ptr); } - else + else { x_dynp_64 = (Elf64_External_Dyn *) buf; dyn_tag = bfd_h_get_64 (abfd, (bfd_byte *) x_dynp_64->d_tag); @@ -405,9 +402,20 @@ scan_dyntag (int dyntag, bfd *abfd, CORE_ADDR *ptr) return 0; if (dyn_tag == dyntag) { + /* If requested, try to read the runtime value of this .dynamic + entry. */ if (ptr) - *ptr = dyn_ptr; - return 1; + { + gdb_byte ptr_buf[8]; + CORE_ADDR ptr_addr; + + ptr_addr = dyn_addr + (buf - bufstart) + arch_size / 8; + if (target_read_memory (ptr_addr, ptr_buf, arch_size / 8) == 0) + dyn_ptr = extract_typed_address (ptr_buf, + builtin_type_void_data_ptr); + *ptr = dyn_ptr; + } + return 1; } } @@ -445,11 +453,9 @@ elf_locate_base (void) struct minimal_symbol *msymbol; CORE_ADDR dyn_ptr; - /* Find DT_DEBUG. */ - if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr)) - return dyn_ptr; - - /* Find DT_MIPS_RLD_MAP. */ + /* Look for DT_MIPS_RLD_MAP first. MIPS executables use this + instead of DT_DEBUG, although they sometimes contain an unused + DT_DEBUG. */ if (scan_dyntag (DT_MIPS_RLD_MAP, exec_bfd, &dyn_ptr)) { gdb_byte *pbuf; @@ -462,6 +468,10 @@ elf_locate_base (void) return extract_typed_address (pbuf, builtin_type_void_data_ptr); } + /* Find DT_DEBUG. */ + if (scan_dyntag (DT_DEBUG, exec_bfd, &dyn_ptr)) + return dyn_ptr; + /* This may be a static executable. Look for the symbol conventionally named _r_debug, as a last resort. */ msymbol = lookup_minimal_symbol ("_r_debug", NULL, symfile_objfile); @@ -1549,7 +1559,7 @@ elf_lookup_lib_symbol (const struct objfile *objfile, || scan_dyntag (DT_SYMBOLIC, objfile->obfd, NULL) != 1) return NULL; - return lookup_global_symbol_from_objfile + return lookup_global_symbol_from_objfile (objfile, name, linkage_name, domain, symtab); } |