OSDN Git Service

* simple.c (bfd_simple_get_relocated_section_contents): Add
authordrow <drow>
Tue, 1 Apr 2003 00:12:12 +0000 (00:12 +0000)
committerdrow <drow>
Tue, 1 Apr 2003 00:12:12 +0000 (00:12 +0000)
parameter symbol_table.  Optionally use it instead of the symbol
table from the bfd.  Save and restore output offsets and output
sections  around bfd_get_relocated_section_contents.  Fix a memory
leak.
(simple_save_output_info, simple_restore_output_info): New
functions.
* bfd-in2.h: Regenerate.
* dwarf2.c (read_abbrevs): Use
bfd_simple_get_relocated_section_contents instead of
bfd_get_section_contents.
(decode_line_info): Likewise.
(_bfd_dwarf2_find_nearest_line): Likewise.  Don't call
find_rela_addend.
(find_rela_addend): Remove.
* elfxx-ia64.c (elfNN_ia64_reloc): Weaken sanity check for
debugging sections.
(elfNN_ia64_hash_table_create): Create the hash table with malloc,
not bfd_zalloc.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/dwarf2.c
bfd/elfxx-ia64.c
bfd/simple.c

index 13f14d4..007d400 100644 (file)
@@ -1,3 +1,26 @@
+2003-03-31  Andreas Schwab  <schwab@suse.de>
+           Daniel Jacobowitz  <drow@mvista.com>
+
+       * simple.c (bfd_simple_get_relocated_section_contents): Add
+       parameter symbol_table.  Optionally use it instead of the symbol
+       table from the bfd.  Save and restore output offsets and output
+       sections  around bfd_get_relocated_section_contents.  Fix a memory
+       leak.
+       (simple_save_output_info, simple_restore_output_info): New
+       functions.
+       * bfd-in2.h: Regenerate.
+       * dwarf2.c (read_abbrevs): Use
+       bfd_simple_get_relocated_section_contents instead of
+       bfd_get_section_contents.
+       (decode_line_info): Likewise.
+       (_bfd_dwarf2_find_nearest_line): Likewise.  Don't call
+       find_rela_addend.
+       (find_rela_addend): Remove.
+       * elfxx-ia64.c (elfNN_ia64_reloc): Weaken sanity check for
+       debugging sections.
+       (elfNN_ia64_hash_table_create): Create the hash table with malloc,
+       not bfd_zalloc.
+
 2003-03-31  David Heine  <dlheine@suif.stanford.edu>
 
        * aoutx.h (aout_link_hash_table_create): Use bfd_malloc instead of
index 8960f66..51e2a21 100644 (file)
@@ -4385,7 +4385,7 @@ bfd_link_split_section PARAMS ((bfd *abfd, asection *sec));
 
 /* Extracted from simple.c.  */
 bfd_byte *
-bfd_simple_get_relocated_section_contents PARAMS ((bfd *abfd, asection *sec, bfd_byte *outbuf));
+bfd_simple_get_relocated_section_contents PARAMS ((bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table));
 
 #ifdef __cplusplus
 }
index 521bb71..0bc94b6 100644 (file)
@@ -245,8 +245,6 @@ static bfd_boolean lookup_address_in_line_info_table
 static bfd_boolean lookup_address_in_function_table
   PARAMS ((struct funcinfo *, bfd_vma, struct funcinfo **, const char **));
 static bfd_boolean scan_unit_for_functions PARAMS ((struct comp_unit *));
-static bfd_vma find_rela_addend
-  PARAMS ((bfd *, asection *, bfd_size_type, asymbol**));
 static struct comp_unit *parse_comp_unit
   PARAMS ((bfd *, struct dwarf2_debug *, bfd_vma, unsigned int));
 static bfd_boolean comp_unit_contains_address
@@ -546,13 +544,11 @@ read_abbrevs (abfd, offset, stash)
        }
 
       stash->dwarf_abbrev_size = msec->_raw_size;
-      stash->dwarf_abbrev_buffer = (char*) bfd_alloc (abfd, msec->_raw_size);
+      stash->dwarf_abbrev_buffer
+       = bfd_simple_get_relocated_section_contents (abfd, msec, NULL,
+                                                    stash->syms);
       if (! stash->dwarf_abbrev_buffer)
          return 0;
-
-      if (! bfd_get_section_contents (abfd, msec, stash->dwarf_abbrev_buffer,
-                                     (bfd_vma) 0, msec->_raw_size))
-       return 0;
     }
 
   if (offset >= stash->dwarf_abbrev_size)
@@ -1023,21 +1019,15 @@ decode_line_info (unit, stash)
        }
 
       stash->dwarf_line_size = msec->_raw_size;
-      stash->dwarf_line_buffer = (char *) bfd_alloc (abfd, msec->_raw_size);
+      stash->dwarf_line_buffer
+       = bfd_simple_get_relocated_section_contents (abfd, msec, NULL,
+                                                    stash->syms);
       if (! stash->dwarf_line_buffer)
        return 0;
-
-      if (! bfd_get_section_contents (abfd, msec, stash->dwarf_line_buffer,
-                                     (bfd_vma) 0, msec->_raw_size))
-       return 0;
-
-      /* FIXME: We ought to apply the relocs against this section before
-        we process it...  */
     }
 
-  /* Since we are using un-relocated data, it is possible to get a bad value
-     for the line_offset.  Validate it here so that we won't get a segfault
-     below.  */
+  /* It is possible to get a bad value for the line_offset.  Validate
+     it here so that we won't get a segfault below.  */
   if (unit->line_offset >= stash->dwarf_line_size)
     {
       (*_bfd_error_handler) (_("Dwarf Error: Line offset (%lu) greater than or equal to .debug_line size (%lu)."),
@@ -1529,60 +1519,6 @@ scan_unit_for_functions (unit)
   return TRUE;
 }
 
-/* Look for a RELA relocation to be applied on OFFSET of section SEC,
-   and return the addend if such a relocation is found.  Since this is
-   only used to find relocations referring to the .debug_abbrev
-   section, we make sure the relocation refers to this section, but
-   this is not strictly necessary, and it can probably be safely
-   removed if needed.  However, it is important to note that this
-   function only returns the addend, it doesn't serve the purpose of
-   applying a generic relocation.
-
-   If no suitable relocation is found, or if it is not a real RELA
-   relocation, this function returns 0.  */
-
-static bfd_vma
-find_rela_addend (abfd, sec, offset, syms)
-     bfd* abfd;
-     asection* sec;
-     bfd_size_type offset;
-     asymbol** syms;
-{
-  long reloc_size = bfd_get_reloc_upper_bound (abfd, sec);
-  arelent **relocs = NULL;
-  long reloc_count, relc;
-
-  if (reloc_size <= 0)
-    return 0;
-
-  relocs = (arelent **) bfd_malloc ((bfd_size_type) reloc_size);
-  if (relocs == NULL)
-    return 0;
-
-  reloc_count = bfd_canonicalize_reloc (abfd, sec, relocs, syms);
-
-  if (reloc_count <= 0)
-    {
-      free (relocs);
-      return 0;
-    }
-
-  for (relc = 0; relc < reloc_count; relc++)
-    if (relocs[relc]->address == offset
-       && (*relocs[relc]->sym_ptr_ptr)->flags & BSF_SECTION_SYM
-       && strcmp ((*relocs[relc]->sym_ptr_ptr)->name,
-                  ".debug_abbrev") == 0)
-      {
-       bfd_vma addend = (relocs[relc]->howto->partial_inplace
-                         ? 0 : relocs[relc]->addend);
-       free (relocs);
-       return addend;
-      }
-
-  free (relocs);
-  return 0;
-}
-
 /* Parse a DWARF2 compilation unit starting at INFO_PTR.  This
    includes the compilation unit header that proceeds the DIE's, but
    does not include the length field that preceeds each compilation
@@ -1610,7 +1546,6 @@ parse_comp_unit (abfd, stash, unit_length, offset_size)
   char *info_ptr = stash->info_ptr;
   char *end_ptr = info_ptr + unit_length;
   bfd_size_type amt;
-  bfd_size_type off;
 
   version = read_2_bytes (abfd, info_ptr);
   info_ptr += 2;
@@ -1619,12 +1554,6 @@ parse_comp_unit (abfd, stash, unit_length, offset_size)
     abbrev_offset = read_4_bytes (abfd, info_ptr);
   else
     abbrev_offset = read_8_bytes (abfd, info_ptr);
-  /* The abbrev offset is generally a relocation pointing to
-     .debug_abbrev+offset.  On RELA targets, we have to find the
-     relocation and extract the addend to obtain the actual
-     abbrev_offset, so do it here.  */
-  off = info_ptr - stash->sec_info_ptr;
-  abbrev_offset += find_rela_addend (abfd, stash->sec, off, stash->syms);
   info_ptr += offset_size;
   addr_size = read_1_byte (abfd, info_ptr);
   info_ptr += 1;
@@ -1947,8 +1876,8 @@ _bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
 
          start = stash->info_ptr_end - stash->info_ptr;
 
-         if (! bfd_get_section_contents (abfd, msec, stash->info_ptr + start,
-                                         (bfd_vma) 0, size))
+         if ((bfd_simple_get_relocated_section_contents
+              (abfd, msec, stash->info_ptr + start, symbols)) == NULL)
            continue;
 
          stash->info_ptr_end = stash->info_ptr + start + size;
@@ -1961,21 +1890,6 @@ _bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
       stash->syms = symbols;
     }
 
-  /* FIXME: There is a problem with the contents of the
-     .debug_info section.  The 'low' and 'high' addresses of the
-     comp_units are computed by relocs against symbols in the
-     .text segment.  We need these addresses in order to determine
-     the nearest line number, and so we have to resolve the
-     relocs.  There is a similar problem when the .debug_line
-     section is processed as well (e.g., there may be relocs
-     against the operand of the DW_LNE_set_address operator).
-
-     Unfortunately getting hold of the reloc information is hard...
-
-     For now, this means that disassembling object files (as
-     opposed to fully executables) does not always work as well as
-     we would like.  */
-
   /* A null info_ptr indicates that there is no dwarf2 info
      (or that an error occured while setting up the stash).  */
   if (! stash->info_ptr)
@@ -2042,10 +1956,10 @@ _bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
                {
                  if (comp_unit_contains_address (each, addr))
                    return comp_unit_find_nearest_line (each, addr,
-                                                      filename_ptr,
-                                                      functionname_ptr,
-                                                      linenumber_ptr,
-                                                      stash);
+                                                       filename_ptr,
+                                                       functionname_ptr,
+                                                       linenumber_ptr,
+                                                       stash);
                }
              else
                {
index c423057..3c8ec9e 100644 (file)
@@ -357,6 +357,10 @@ elfNN_ia64_reloc (abfd, reloc, sym, data, input_section,
       reloc->address += input_section->output_offset;
       return bfd_reloc_ok;
     }
+
+  if (input_section->flags & SEC_DEBUGGING)
+    return bfd_reloc_continue;
+
   *error_message = "Unsupported call to elfNN_ia64_reloc";
   return bfd_reloc_notsupported;
 }
@@ -1788,19 +1792,24 @@ elfNN_ia64_hash_table_create (abfd)
 {
   struct elfNN_ia64_link_hash_table *ret;
 
-  ret = bfd_zalloc (abfd, (bfd_size_type) sizeof (*ret));
+  ret = bfd_zmalloc ((bfd_size_type) sizeof (*ret));
   if (!ret)
     return 0;
+
   if (!_bfd_elf_link_hash_table_init (&ret->root, abfd,
                                      elfNN_ia64_new_elf_hash_entry))
     {
-      bfd_release (abfd, ret);
+      free (ret);
       return 0;
     }
 
   if (!elfNN_ia64_local_hash_table_init (&ret->loc_hash_table, abfd,
                                         elfNN_ia64_new_loc_hash_entry))
-    return 0;
+    {
+      free (ret);
+      return 0;
+    }
+
   return &ret->root.root;
 }
 
index 30f9be0..a91d118 100644 (file)
@@ -42,8 +42,14 @@ static bfd_boolean simple_dummy_reloc_dangerous
 static bfd_boolean simple_dummy_unattached_reloc
   PARAMS ((struct bfd_link_info *, const char *, bfd *, asection *, bfd_vma));
 
+static void simple_save_output_info
+  PARAMS ((bfd *, asection *, PTR));
+
+static void simple_restore_output_info
+  PARAMS ((bfd *, asection *, PTR));
+
 bfd_byte * bfd_simple_get_relocated_section_contents
-  PARAMS ((bfd *, asection *, bfd_byte *));
+  PARAMS ((bfd *, asection *, bfd_byte *, asymbol **));
 
 static bfd_boolean
 simple_dummy_warning (link_info, warning, symbol, abfd, section, address)
@@ -105,17 +111,48 @@ simple_dummy_unattached_reloc (link_info, name, abfd, section, address)
   return TRUE;
 }
 
+struct saved_output_info
+{
+  bfd_vma offset;
+  asection *section;
+};
+
+static void
+simple_save_output_info (abfd, section, ptr)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     asection *section;
+     PTR ptr;
+{
+  struct saved_output_info *output_info = (struct saved_output_info *) ptr;
+  output_info[section->index].offset = section->output_offset;
+  output_info[section->index].section = section->output_section;
+  section->output_offset = 0;
+  section->output_section = section;
+}
+
+static void
+simple_restore_output_info (abfd, section, ptr)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     asection *section;
+     PTR ptr;
+{
+  struct saved_output_info *output_info = (struct saved_output_info *) ptr;
+  section->output_offset = output_info[section->index].offset;
+  section->output_section = output_info[section->index].section;
+}
+
 /*
 FUNCTION
        bfd_simple_relocate_secton
 
 SYNOPSIS
-       bfd_byte *bfd_simple_get_relocated_section_contents (bfd *abfd, asection *sec, bfd_byte *outbuf);
+       bfd_byte *bfd_simple_get_relocated_section_contents (bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table);
 
 DESCRIPTION
-       Returns the relocated contents of section @var{sec}.  Only symbols
-       from @var{abfd} and the output offsets assigned to sections in
-       @var{abfd} are used.  The result will be stored at @var{outbuf}
+       Returns the relocated contents of section @var{sec}.  The symbols in
+       @var{symbol_table} will be used, or the symbols from @var{abfd} if
+       @var{symbol_table} is NULL.  The output offsets for all sections will
+       be temporarily reset to 0.  The result will be stored at @var{outbuf}
        or allocated with @code{bfd_malloc} if @var{outbuf} is @code{NULL}.
 
        Generally all sections in @var{abfd} should have their
@@ -126,17 +163,18 @@ DESCRIPTION
 */
 
 bfd_byte *
-bfd_simple_get_relocated_section_contents (abfd, sec, outbuf)
+bfd_simple_get_relocated_section_contents (abfd, sec, outbuf, symbol_table)
      bfd *abfd;
      asection *sec;
      bfd_byte *outbuf;
+     asymbol **symbol_table;
 {
   struct bfd_link_info link_info;
   struct bfd_link_order link_order;
   struct bfd_link_callbacks callbacks;
   bfd_byte *contents, *data;
   int storage_needed;
-  asymbol **symbol_table;
+  PTR saved_offsets;
 
   if (! (sec->flags & SEC_RELOC))
     {
@@ -183,11 +221,36 @@ bfd_simple_get_relocated_section_contents (abfd, sec, outbuf)
        return NULL;
       outbuf = data;
     }
-  bfd_link_add_symbols (abfd, &link_info);
 
-  storage_needed = bfd_get_symtab_upper_bound (abfd);
-  symbol_table = (asymbol **) bfd_malloc (storage_needed);
-  bfd_canonicalize_symtab (abfd, symbol_table);
+  /* The sections in ABFD may already have output sections and offsets set.
+     Because this function is primarily for debug sections, and GCC uses the
+     knowledge that debug sections will generally have VMA 0 when emiting
+     relocations between DWARF-2 sections (which are supposed to be
+     section-relative offsets anyway), we need to reset the output offsets
+     to zero.  We also need to arrange for section->output_section->vma plus
+     section->output_offset to equal section->vma, which we do by setting
+     section->output_section to point back to section.  Save the original
+     output offset and output section to restore later.  */
+  saved_offsets = malloc (sizeof (struct saved_output_info)
+                         * abfd->section_count);
+  if (saved_offsets == NULL)
+    {
+      if (data)
+       free (data);
+      return NULL;
+    }
+  bfd_map_over_sections (abfd, simple_save_output_info, saved_offsets);
+
+  if (symbol_table == NULL)
+    {
+      bfd_link_add_symbols (abfd, &link_info);
+
+      storage_needed = bfd_get_symtab_upper_bound (abfd);
+      symbol_table = (asymbol **) bfd_malloc (storage_needed);
+      bfd_canonicalize_symtab (abfd, symbol_table);
+    }
+  else
+    storage_needed = 0;
 
   contents = bfd_get_relocated_section_contents (abfd,
                                                 &link_info,
@@ -198,6 +261,12 @@ bfd_simple_get_relocated_section_contents (abfd, sec, outbuf)
   if (contents == NULL && data != NULL)
     free (data);
 
+  if (storage_needed != 0)
+    free (symbol_table);
+
+  bfd_map_over_sections (abfd, simple_restore_output_info, saved_offsets);
+  free (saved_offsets);
+
   /* Foul hack to prevent bfd_section_size aborts.  This flag only controls
      that macro (and the related size macros), selecting between _raw_size
      and _cooked_size.  Debug sections won't change size while we're only
@@ -208,6 +277,5 @@ bfd_simple_get_relocated_section_contents (abfd, sec, outbuf)
 
   bfd_link_hash_table_free (abfd, link_info.hash);
 
-  free (symbol_table);
   return contents;
 }