This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Explicitly get .dynamic section for "readelf -d"


"readelf -d" cannot display the dynamic segment correctly for some MIPS
targets when there are more than one section in the dynamic segment and
.dynamic section does not come first. This patch fix this bug.


Jie



2004-06-02  Jie Zhang  <zhangjie@magima.com.cn>

        * binutils/readelf.c (get_32bit_dynamic_segment): Explicitly get .dynamic section.
        (get_64bit_dynamic_segment): Likewise.

--- readelf.c.old	2004-06-02 16:47:06.000000000 +0800
+++ readelf.c	2004-06-02 17:21:25.000000000 +0800
@@ -4625,16 +4625,28 @@ get_32bit_dynamic_segment (FILE *file)
 {
   Elf32_External_Dyn *edyn;
   Elf_Internal_Dyn *entry;
+  Elf_Internal_Shdr *sec;
   bfd_size_type i;
 
-  edyn = get_data (NULL, file, dynamic_addr, dynamic_size,
-		   _("dynamic segment"));
+  /* There are some targets, e.g. SGI's ELF, that have more than one section
+     in the DYNAMIC segment. Determine where and how large .dynamic section
+     is now. */
+  for (i = 0, sec = section_headers;
+       i < elf_header.e_shnum;
+       i++, sec++)
+    if (strcmp (SECTION_NAME (sec), ".dynamic") == 0)
+      break;
+
+  if (i == elf_header.e_shnum || sec->sh_size == 0)
+    return 0;
+
+  dynamic_addr = sec->sh_offset;
+
+  edyn = get_data (NULL, file, dynamic_addr, sec->sh_size,
+		   _("dynamic section"));
   if (!edyn)
     return 0;
 
-  /* SGI's ELF has more than one section in the DYNAMIC segment.  Determine
-     how large this .dynamic is now.  We can do this even before the byte
-     swapping since the DT_NULL tag is recognizable.  */
   dynamic_size = 0;
   while (*(Elf32_Word *) edyn[dynamic_size++].d_tag != DT_NULL)
     ;
@@ -4666,16 +4678,28 @@ get_64bit_dynamic_segment (FILE *file)
 {
   Elf64_External_Dyn *edyn;
   Elf_Internal_Dyn *entry;
+  Elf_Internal_Shdr *sec;
   bfd_size_type i;
 
-  edyn = get_data (NULL, file, dynamic_addr, dynamic_size,
-		   _("dynamic segment"));
+  /* There are some targets, e.g. SGI's ELF, that have more than one section
+     in the DYNAMIC segment. Determine where and how large .dynamic section
+     is now. */
+  for (i = 0, sec = section_headers;
+       i < elf_header.e_shnum;
+       i++, sec++)
+    if (strcmp (SECTION_NAME (sec), ".dynamic") == 0)
+      break;
+
+  if (i == elf_header.e_shnum || sec->sh_size == 0)
+    return 0;
+
+  dynamic_addr = sec->sh_offset;
+
+  edyn = get_data (NULL, file, dynamic_addr, sec->sh_size,
+		   _("dynamic section"));
   if (!edyn)
     return 0;
 
-  /* SGI's ELF has more than one section in the DYNAMIC segment.  Determine
-     how large this .dynamic is now.  We can do this even before the byte
-     swapping since the DT_NULL tag is recognizable.  */
   dynamic_size = 0;
   while (*(bfd_vma *) edyn[dynamic_size++].d_tag != DT_NULL)
     ;


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]