]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
2007-09-27 Roland McGrath <roland@redhat.com>
authorRoland McGrath <roland@redhat.com>
Thu, 27 Sep 2007 07:31:33 +0000 (07:31 +0000)
committerRoland McGrath <roland@redhat.com>
Thu, 27 Sep 2007 07:31:33 +0000 (07:31 +0000)
* alpha_retval.c: Use dwarf_attr_integrate and dwarf_hasattr_integrate.
* i386_retval.c: Likewise.
* ia64_retval.c: Likewise.
* ppc64_retval.c: Likewise.
* ppc_retval.c: Likewise.
* s390_retval.c: Likewise.
* sparc_retval.c: Likewise.
* x86_64_retval.c: Likewise.

27 files changed:
NEWS
backends/ChangeLog
backends/alpha_retval.c
backends/i386_retval.c
backends/ia64_retval.c
backends/ppc64_retval.c
backends/ppc_retval.c
backends/s390_retval.c
backends/sparc_retval.c
backends/x86_64_retval.c
libdwfl/ChangeLog
libdwfl/dwfl_module_addrsym.c
libelf/ChangeLog
libelf/Makefile.am
libelf/elf_getdata.c
libelf/gelf.h
libelf/gelf_getnote.c [new file with mode: 0644]
libelf/gelf_xlate.c
libelf/libelf.map
libelf/libelfP.h
libelf/note_xlate.h [new file with mode: 0644]
src/ChangeLog
src/readelf.c
tests/ChangeLog
tests/Makefile.am
tests/run-addrname-test.sh
tests/testfile41.bz2 [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 4eb1ead8b2d043c3330d7f8380aa5ef0851754c6..d257c1fd393cfc2d71bf2d9927d2a287589ed324 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,8 @@
+Version 0.130:
+
+readelf: -p option can take an argument like -x for one section,
+        or no argument (as before) for all SHF_STRINGS sections
+
 Version 0.129:
 
 readelf: new options --hex-dump (or -x), --strings (or -p)
index 159e6dc1773f6b2aca8b311c99a8716b02520359..9c51f98649d661d0cce31c8f5eeb19cea7055e52 100644 (file)
@@ -1,3 +1,14 @@
+2007-09-27  Roland McGrath  <roland@redhat.com>
+
+       * alpha_retval.c: Use dwarf_attr_integrate and dwarf_hasattr_integrate.
+       * i386_retval.c: Likewise.
+       * ia64_retval.c: Likewise.
+       * ppc64_retval.c: Likewise.
+       * ppc_retval.c: Likewise.
+       * s390_retval.c: Likewise.
+       * sparc_retval.c: Likewise.
+       * x86_64_retval.c: Likewise.
+
 2007-08-23  Roland McGrath  <roland@redhat.com>
 
        * x86_64_regs.c (x86_64_register_info): Put %rflags in "integer" set.
index 09f8bb4c20314957c1c3935b9bee7c9333a9bd22..57ba867b5249a88c6296faf7dcb54961f319ccef 100644 (file)
@@ -1,5 +1,5 @@
 /* Function return value location for Alpha ELF ABI.
-   Copyright (C) 2005 Red Hat, Inc.
+   Copyright (C) 2005, 2007 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -66,7 +66,8 @@ alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
      which is the type of the return value.  */
 
   Dwarf_Attribute attr_mem;
-  Dwarf_Attribute *attr = dwarf_attr (functypedie, DW_AT_type, &attr_mem);
+  Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
+                                               &attr_mem);
   if (attr == NULL)
     /* The function has no return value, like a `void' function in C.  */
     return 0;
@@ -80,7 +81,7 @@ alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
         || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
         || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
     {
-      attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
+      attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
       typedie = dwarf_formref_die (attr, &die_mem);
       tag = dwarf_tag (typedie);
     }
@@ -91,9 +92,9 @@ alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
       return -1;
 
     case DW_TAG_subrange_type:
-      if (! dwarf_hasattr (typedie, DW_AT_byte_size))
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
        {
-         attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
+         attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
          typedie = dwarf_formref_die (attr, &die_mem);
          tag = dwarf_tag (typedie);
        }
@@ -105,8 +106,8 @@ alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     case DW_TAG_ptr_to_member_type:
       {
        Dwarf_Word size;
-       if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size,
-                                        &attr_mem), &size) != 0)
+       if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+                                                  &attr_mem), &size) != 0)
          {
            if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
              size = 8;
@@ -116,8 +117,9 @@ alpha_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
        if (tag == DW_TAG_base_type)
          {
            Dwarf_Word encoding;
-           if (dwarf_formudata (dwarf_attr (typedie, DW_AT_encoding,
-                                            &attr_mem), &encoding) != 0)
+           if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+                                                      &attr_mem),
+                                &encoding) != 0)
              return -1;
 
            *locp = loc_fpreg;
index cfd50579d01441107ca74942055070a2eccab028..c3bab10876db985fb936994eb125e55fc3849786 100644 (file)
@@ -1,5 +1,5 @@
 /* Function return value location for Linux/i386 ABI.
-   Copyright (C) 2005 Red Hat, Inc.
+   Copyright (C) 2005, 2007 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -66,7 +66,8 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
      which is the type of the return value.  */
 
   Dwarf_Attribute attr_mem;
-  Dwarf_Attribute *attr = dwarf_attr (functypedie, DW_AT_type, &attr_mem);
+  Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
+                                               &attr_mem);
   if (attr == NULL)
     /* The function has no return value, like a `void' function in C.  */
     return 0;
@@ -80,7 +81,7 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
         || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
         || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
     {
-      attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
+      attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
       typedie = dwarf_formref_die (attr, &die_mem);
       tag = dwarf_tag (typedie);
     }
@@ -91,9 +92,9 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
       return -1;
 
     case DW_TAG_subrange_type:
-      if (! dwarf_hasattr (typedie, DW_AT_byte_size))
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
        {
-         attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
+         attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
          typedie = dwarf_formref_die (attr, &die_mem);
          tag = dwarf_tag (typedie);
        }
@@ -105,8 +106,8 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     case DW_TAG_ptr_to_member_type:
       {
        Dwarf_Word size;
-       if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size,
-                                        &attr_mem), &size) != 0)
+       if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+                                                  &attr_mem), &size) != 0)
          {
            if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
              size = 4;
@@ -116,8 +117,9 @@ i386_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
        if (tag == DW_TAG_base_type)
          {
            Dwarf_Word encoding;
-           if (dwarf_formudata (dwarf_attr (typedie, DW_AT_encoding,
-                                            &attr_mem), &encoding) != 0)
+           if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+                                                      &attr_mem),
+                                &encoding) != 0)
              return -1;
            if (encoding == DW_ATE_float)
              {
index 4100328c76aad141b586e10efba9bb65b80832f7..238cd9efeb2ed068864f71c8c5559866d745bcba 100644 (file)
@@ -1,5 +1,5 @@
 /* Function return value location for IA64 ABI.
-   Copyright (C) 2006 Red Hat, Inc.
+   Copyright (C) 2006, 2007 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -119,8 +119,8 @@ hfa_type (Dwarf_Die *typedie, const Dwarf_Op **locp, int fpregs_used)
        return -1;
 
       Dwarf_Word encoding;
-      if (dwarf_formudata (dwarf_attr (typedie, DW_AT_encoding,
-                                      &attr_mem), &encoding) != 0)
+      if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+                                                &attr_mem), &encoding) != 0)
        return -1;
 
       switch (encoding)
@@ -174,8 +174,9 @@ hfa_type (Dwarf_Die *typedie, const Dwarf_Op **locp, int fpregs_used)
              case DW_TAG_member:;
                Dwarf_Die child_type_mem;
                Dwarf_Die *child_typedie
-                 = dwarf_formref_die (dwarf_attr (&child_mem, DW_AT_type,
-                                                  &attr_mem),
+                 = dwarf_formref_die (dwarf_attr_integrate (&child_mem,
+                                                            DW_AT_type,
+                                                            &attr_mem),
                                       &child_type_mem);
                if (tag == DW_TAG_union_type)
                  {
@@ -207,10 +208,10 @@ hfa_type (Dwarf_Die *typedie, const Dwarf_Op **locp, int fpregs_used)
        break;
 
       Dwarf_Die base_type_mem;
-      Dwarf_Die *base_typedie = dwarf_formref_die (dwarf_attr (typedie,
-                                                              DW_AT_type,
-                                                              &attr_mem),
-                                                  &base_type_mem);
+      Dwarf_Die *base_typedie
+       = dwarf_formref_die (dwarf_attr_integrate (typedie, DW_AT_type,
+                                                  &attr_mem),
+                            &base_type_mem);
 
       int used = hfa_type (base_typedie, locp, 0);
       if (used < 0 || used > 8)
@@ -235,7 +236,8 @@ ia64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
      which is the type of the return value.  */
 
   Dwarf_Attribute attr_mem;
-  Dwarf_Attribute *attr = dwarf_attr (functypedie, DW_AT_type, &attr_mem);
+  Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
+                                               &attr_mem);
   if (attr == NULL)
     /* The function has no return value, like a `void' function in C.  */
     return 0;
@@ -261,9 +263,9 @@ ia64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
       return -1;
 
     case DW_TAG_subrange_type:
-      if (! dwarf_hasattr (typedie, DW_AT_byte_size))
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
        {
-         attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
+         attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
          typedie = dwarf_formref_die (attr, &die_mem);
          tag = dwarf_tag (typedie);
        }
@@ -273,8 +275,8 @@ ia64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     case DW_TAG_enumeration_type:
     case DW_TAG_pointer_type:
     case DW_TAG_ptr_to_member_type:
-      if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size,
-                                      &attr_mem), &size) != 0)
+      if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+                                                &attr_mem), &size) != 0)
        {
          if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
            size = 8;
@@ -284,8 +286,9 @@ ia64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
       if (tag == DW_TAG_base_type)
        {
          Dwarf_Word encoding;
-         if (dwarf_formudata (dwarf_attr (typedie, DW_AT_encoding,
-                                          &attr_mem), &encoding) != 0)
+         if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+                                                    &attr_mem),
+                              &encoding) != 0)
            return -1;
 
          switch (encoding)
@@ -343,8 +346,8 @@ ia64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     case DW_TAG_class_type:
     case DW_TAG_union_type:
     case DW_TAG_array_type:
-      if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size,
-                                      &attr_mem), &size) != 0)
+      if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+                                                &attr_mem), &size) != 0)
        return -1;
 
       /* If this qualifies as an homogeneous floating-point aggregate
index 7f5e6f83d7785c7798c60b4e29d9ac7fa2094fe1..454897cccfa1fc75b2e455f2385b3c093580e928 100644 (file)
@@ -1,5 +1,5 @@
 /* Function return value location for Linux/PPC64 ABI.
-   Copyright (C) 2005, 2006 Red Hat, Inc.
+   Copyright (C) 2005, 2006, 2007 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -69,7 +69,8 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
      which is the type of the return value.  */
 
   Dwarf_Attribute attr_mem;
-  Dwarf_Attribute *attr = dwarf_attr (functypedie, DW_AT_type, &attr_mem);
+  Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
+                                               &attr_mem);
   if (attr == NULL)
     /* The function has no return value, like a `void' function in C.  */
     return 0;
@@ -83,7 +84,7 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
         || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
         || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
     {
-      attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
+      attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
       typedie = dwarf_formref_die (attr, &die_mem);
       tag = dwarf_tag (typedie);
     }
@@ -95,9 +96,9 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
       return -1;
 
     case DW_TAG_subrange_type:
-      if (! dwarf_hasattr (typedie, DW_AT_byte_size))
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
        {
-         attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
+         attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
          typedie = dwarf_formref_die (attr, &die_mem);
          tag = dwarf_tag (typedie);
        }
@@ -107,8 +108,8 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     case DW_TAG_enumeration_type:
     case DW_TAG_pointer_type:
     case DW_TAG_ptr_to_member_type:
-      if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size,
-                                      &attr_mem), &size) != 0)
+      if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+                                                &attr_mem), &size) != 0)
        {
          if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
            size = 8;
@@ -118,8 +119,9 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
       if (tag == DW_TAG_base_type)
        {
          Dwarf_Word encoding;
-         if (dwarf_formudata (dwarf_attr (typedie, DW_AT_encoding,
-                                          &attr_mem), &encoding) != 0)
+         if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+                                                    &attr_mem),
+                              &encoding) != 0)
            return -1;
 
          if (encoding == DW_ATE_float || encoding == DW_ATE_complex_float)
@@ -150,20 +152,22 @@ ppc64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
 
     case DW_TAG_string_type:
     case DW_TAG_array_type:
-      if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size,
-                                      &attr_mem), &size) == 0
+      if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+                                                &attr_mem), &size) == 0
          && size <= 8)
        {
          if (tag == DW_TAG_array_type)
            {
              /* Check if it's a character array.  */
-             attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
+             attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
              typedie = dwarf_formref_die (attr, &die_mem);
              tag = dwarf_tag (typedie);
              if (tag != DW_TAG_base_type)
                goto aggregate;
-             if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size,
-                                              &attr_mem), &size) != 0)
+             if (dwarf_formudata (dwarf_attr_integrate (typedie,
+                                                        DW_AT_byte_size,
+                                                        &attr_mem),
+                                  &size) != 0)
                return -1;
              if (size != 1)
                goto aggregate;
index b8d86aca46c93fc82499c3b2d0a13fd65c50071e..fa0e303cbd0d72cf65f8c1e65ea679b4cd24d92c 100644 (file)
@@ -1,5 +1,5 @@
 /* Function return value location for Linux/PPC ABI.
-   Copyright (C) 2005, 2006 Red Hat, Inc.
+   Copyright (C) 2005, 2006, 2007 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -71,7 +71,8 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
      which is the type of the return value.  */
 
   Dwarf_Attribute attr_mem;
-  Dwarf_Attribute *attr = dwarf_attr (functypedie, DW_AT_type, &attr_mem);
+  Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
+                                               &attr_mem);
   if (attr == NULL)
     /* The function has no return value, like a `void' function in C.  */
     return 0;
@@ -85,7 +86,7 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
         || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
         || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
     {
-      attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
+      attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
       typedie = dwarf_formref_die (attr, &die_mem);
       tag = dwarf_tag (typedie);
     }
@@ -97,9 +98,9 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
       return -1;
 
     case DW_TAG_subrange_type:
-      if (! dwarf_hasattr (typedie, DW_AT_byte_size))
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
        {
-         attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
+         attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
          typedie = dwarf_formref_die (attr, &die_mem);
          tag = dwarf_tag (typedie);
        }
@@ -109,8 +110,8 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     case DW_TAG_enumeration_type:
     case DW_TAG_pointer_type:
     case DW_TAG_ptr_to_member_type:
-      if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size,
-                                      &attr_mem), &size) != 0)
+      if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+                                                &attr_mem), &size) != 0)
        {
          if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
            size = 4;
@@ -122,8 +123,10 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
          if (tag == DW_TAG_base_type)
            {
              Dwarf_Word encoding;
-             if (dwarf_formudata (dwarf_attr (typedie, DW_AT_encoding,
-                                              &attr_mem), &encoding) != 0)
+             if (dwarf_formudata (dwarf_attr_integrate (typedie,
+                                                        DW_AT_encoding,
+                                                        &attr_mem),
+                                  &encoding) != 0)
                return -1;
              if (encoding == DW_ATE_float)
                {
@@ -145,8 +148,8 @@ ppc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     case DW_TAG_union_type:
     case DW_TAG_array_type:
       if (SVR4_STRUCT_RETURN
-         && dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size,
-                                      &attr_mem), &size) == 0
+         && dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+                                                   &attr_mem), &size) == 0
          && size > 0 && size <= 8)
        goto intreg;
       goto aggregate;
index 6c4308288d172daf7439774ecad3428f82ff5705..15bd97bfcd4fd1ca652e2d87d3c76149bf504617 100644 (file)
@@ -1,5 +1,5 @@
 /* Function return value location for S/390 ABI.
-   Copyright (C) 2006 Red Hat, Inc.
+   Copyright (C) 2006, 2007 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -67,7 +67,8 @@ s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
      which is the type of the return value.  */
 
   Dwarf_Attribute attr_mem;
-  Dwarf_Attribute *attr = dwarf_attr (functypedie, DW_AT_type, &attr_mem);
+  Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
+                                               &attr_mem);
   if (attr == NULL)
     /* The function has no return value, like a `void' function in C.  */
     return 0;
@@ -81,7 +82,7 @@ s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
         || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
         || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
     {
-      attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
+      attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
       typedie = dwarf_formref_die (attr, &die_mem);
       tag = dwarf_tag (typedie);
     }
@@ -93,7 +94,7 @@ s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
       return -1;
 
     case DW_TAG_subrange_type:
-      if (! dwarf_hasattr (typedie, DW_AT_byte_size))
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
        {
          attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
          typedie = dwarf_formref_die (attr, &die_mem);
@@ -122,8 +123,9 @@ s390_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
        if (tag == DW_TAG_base_type)
          {
            Dwarf_Word encoding;
-           if (dwarf_formudata (dwarf_attr (typedie, DW_AT_encoding,
-                                            &attr_mem), &encoding) != 0)
+           if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+                                                      &attr_mem),
+                                &encoding) != 0)
              return -1;
            if (encoding == DW_ATE_float && size <= 8)
              {
index cfde0d2fb8ffc37c4430cd3b8d3fe69a5cb48c6f..7cd3827387d8241fabf73443f07d71f83f6ff1eb 100644 (file)
@@ -1,5 +1,5 @@
 /* Function return value location for SPARC.
-   Copyright (C) 2006 Red Hat, Inc.
+   Copyright (C) 2006, 2007 Red Hat, Inc.
 
    This program is Open Source software; you can redistribute it and/or
    modify it under the terms of the Open Software License version 1.0 as
@@ -59,7 +59,8 @@ sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
      which is the type of the return value.  */
 
   Dwarf_Attribute attr_mem;
-  Dwarf_Attribute *attr = dwarf_attr (functypedie, DW_AT_type, &attr_mem);
+  Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
+                                               &attr_mem);
   if (attr == NULL)
     /* The function has no return value, like a `void' function in C.  */
     return 0;
@@ -73,7 +74,7 @@ sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
         || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
         || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
     {
-      attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
+      attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
       typedie = dwarf_formref_die (attr, &die_mem);
       tag = dwarf_tag (typedie);
     }
@@ -85,9 +86,9 @@ sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
       return -1;
 
     case DW_TAG_subrange_type:
-      if (! dwarf_hasattr (typedie, DW_AT_byte_size))
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
        {
-         attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
+         attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
          typedie = dwarf_formref_die (attr, &die_mem);
          tag = dwarf_tag (typedie);
        }
@@ -97,8 +98,8 @@ sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     case DW_TAG_enumeration_type:
     case DW_TAG_pointer_type:
     case DW_TAG_ptr_to_member_type:
-      if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size,
-                                      &attr_mem), &size) != 0)
+      if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+                                                &attr_mem), &size) != 0)
        {
          uint8_t asize;
          Dwarf_Die cudie;
@@ -111,8 +112,9 @@ sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
       if (tag == DW_TAG_base_type)
        {
          Dwarf_Word encoding;
-         if (dwarf_formudata (dwarf_attr (typedie, DW_AT_encoding,
-                                          &attr_mem), &encoding) != 0)
+         if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+                                                    &attr_mem),
+                              &encoding) != 0)
            return -1;
          if (encoding == DW_ATE_float)
            {
@@ -140,8 +142,8 @@ sparc_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     case DW_TAG_class_type:
     case DW_TAG_union_type:
     case DW_TAG_array_type:
-      if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size,
-                                      &attr_mem), &size) == 0
+      if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+                                                &attr_mem), &size) == 0
          && size > 0 && size <= 8)
        goto intreg;
       goto aggregate;
index 1920abf91f538aac9b050463c50b57a9cb57cbd8..3109431e05c0252ef7f80a18918b9d9770b55003 100644 (file)
@@ -1,5 +1,5 @@
 /* Function return value location for Linux/x86-64 ABI.
-   Copyright (C) 2005 Red Hat, Inc.
+   Copyright (C) 2005, 2007 Red Hat, Inc.
    This file is part of Red Hat elfutils.
 
    Red Hat elfutils is free software; you can redistribute it and/or modify
@@ -80,7 +80,8 @@ x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
      which is the type of the return value.  */
 
   Dwarf_Attribute attr_mem;
-  Dwarf_Attribute *attr = dwarf_attr (functypedie, DW_AT_type, &attr_mem);
+  Dwarf_Attribute *attr = dwarf_attr_integrate (functypedie, DW_AT_type,
+                                               &attr_mem);
   if (attr == NULL)
     /* The function has no return value, like a `void' function in C.  */
     return 0;
@@ -94,7 +95,7 @@ x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
         || tag == DW_TAG_const_type || tag == DW_TAG_volatile_type
         || tag == DW_TAG_restrict_type || tag == DW_TAG_mutable_type)
     {
-      attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
+      attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
       typedie = dwarf_formref_die (attr, &die_mem);
       tag = dwarf_tag (typedie);
     }
@@ -106,9 +107,9 @@ x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
       return -1;
 
     case DW_TAG_subrange_type:
-      if (! dwarf_hasattr (typedie, DW_AT_byte_size))
+      if (! dwarf_hasattr_integrate (typedie, DW_AT_byte_size))
        {
-         attr = dwarf_attr (typedie, DW_AT_type, &attr_mem);
+         attr = dwarf_attr_integrate (typedie, DW_AT_type, &attr_mem);
          typedie = dwarf_formref_die (attr, &die_mem);
          tag = dwarf_tag (typedie);
        }
@@ -118,8 +119,8 @@ x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     case DW_TAG_enumeration_type:
     case DW_TAG_pointer_type:
     case DW_TAG_ptr_to_member_type:
-      if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size,
-                                      &attr_mem), &size) != 0)
+      if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+                                                &attr_mem), &size) != 0)
        {
          if (tag == DW_TAG_pointer_type || tag == DW_TAG_ptr_to_member_type)
            size = 8;
@@ -129,8 +130,9 @@ x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
       if (tag == DW_TAG_base_type)
        {
          Dwarf_Word encoding;
-         if (dwarf_formudata (dwarf_attr (typedie, DW_AT_encoding,
-                                          &attr_mem), &encoding) != 0)
+         if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_encoding,
+                                                    &attr_mem),
+                              &encoding) != 0)
            return -1;
 
          switch (encoding)
@@ -179,8 +181,8 @@ x86_64_return_value_location (Dwarf_Die *functypedie, const Dwarf_Op **locp)
     case DW_TAG_class_type:
     case DW_TAG_union_type:
     case DW_TAG_array_type:
-      if (dwarf_formudata (dwarf_attr (typedie, DW_AT_byte_size,
-                                      &attr_mem), &size) != 0)
+      if (dwarf_formudata (dwarf_attr_integrate (typedie, DW_AT_byte_size,
+                                                &attr_mem), &size) != 0)
        return -1;
       if (size > 16)
        goto large;
index a5177aca5a3d70c6fa681f8518ade860e022f13f..3a99753b4c46760901ca7ceeab5ded21f7525c21 100644 (file)
@@ -1,3 +1,8 @@
+2007-09-11  Roland McGrath  <roland@redhat.com>
+
+       * dwfl_module_addrsym.c: Prefer a later global symbol at the same
+       address if its st_size is smaller.
+
 2007-08-13  Roland McGrath  <roland@redhat.com>
 
        * dwfl_module_addrsym.c: Add dead initializer for stupid compiler.
index 52dbb3d88896b135ac2a93bf64cbfc56307d2562..f16de116c93d495e770cb70531f9c9aaba786c70 100644 (file)
@@ -131,28 +131,40 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
             and is closer to ADDR or is global when it was local.  */
          if (name[0] != '\0'
              && GELF_ST_TYPE (sym.st_info) != STT_SECTION
-             && GELF_ST_TYPE (sym.st_info) != STT_FILE
-             && (closest_name == NULL
+             && GELF_ST_TYPE (sym.st_info) != STT_FILE)
+           {
+             if (closest_name == NULL
                  || closest_sym->st_value < sym.st_value
                  || (GELF_ST_BIND (closest_sym->st_info)
-                     < GELF_ST_BIND (sym.st_info))))
-           {
-             if (sym.st_size != 0)
+                     < GELF_ST_BIND (sym.st_info)))
+               {
+                 if (sym.st_size != 0)
+                   {
+                     *closest_sym = sym;
+                     closest_shndx = shndx;
+                     closest_name = name;
+                   }
+                 else if (same_section (&sym, shndx))
+                   {
+                     /* Handwritten assembly symbols sometimes have no
+                        st_size.  If no symbol with proper size includes
+                        the address, we'll use the closest one that is in
+                        the same section as ADDR.  */
+                     sizeless_sym = sym;
+                     sizeless_shndx = shndx;
+                     sizeless_name = name;
+                   }
+               }
+             /* When the beginning of its range is no closer,
+                the end of its range might be.  */
+             else if (sym.st_size != 0
+                      && closest_sym->st_value == sym.st_value
+                      && closest_sym->st_size > sym.st_size)
                {
                  *closest_sym = sym;
                  closest_shndx = shndx;
                  closest_name = name;
                }
-             else if (same_section (&sym, shndx))
-               {
-                 /* Handwritten assembly symbols sometimes have no st_size.
-                    If no symbol with proper size includes the address,
-                    we'll use the closest one that is in the same section
-                    as ADDR.  */
-                 sizeless_sym = sym;
-                 sizeless_shndx = shndx;
-                 sizeless_name = name;
-               }
            }
        }
     }
index 4962c30aa4c0328c4a6b363f9200d1d4fa57012a..c879aedec52eb91032cae11000d20f51160baa35 100644 (file)
@@ -1,3 +1,18 @@
+2007-08-24  Roland McGrath  <roland@redhat.com>
+
+       * gelf_getnote.c: New file.
+       * Makefile.am (libelf_a_SOURCES): Add it.
+       * gelf.h: Declare gelf_getnote.
+       * libelf.map (ELFUTILS_1.3): Add gelf_getnote.
+
+       * libelfP.h (NOTE_ALIGN): New macro.
+       * note_xlate.h: New file.
+       * Makefile.am (noinst_HEADERS): Add it.
+       * gelf_xlate.c: Include it.
+       (__elf_xfctstom): Use elf_cvt_note.
+       * elf_getdata.c (shtype_map, __libelf_type_align): Handle SHT_NOTE.
+       (__libelf_set_rawdata): Likewise.
+
 2007-08-19  Roland McGrath  <roland@redhat.com>
 
        * gelf_update_auxv.c: New file.
index 3e8322e94145ef43037c545053ba486e9f44d18f..3e52bcec755c5f24fa6d7aeecb55d503182af774 100644 (file)
@@ -84,6 +84,7 @@ libelf_a_SOURCES = elf_version.c elf_hash.c elf_error.c elf_fill.c \
                   gelf_getmove.c gelf_update_move.c \
                   gelf_getsyminfo.c gelf_update_syminfo.c \
                   gelf_getauxv.c gelf_update_auxv.c \
+                  gelf_getnote.c \
                   gelf_xlatetof.c gelf_xlatetom.c \
                   nlist.c \
                   gelf_getsymshndx.c gelf_update_symshndx.c \
@@ -133,7 +134,7 @@ uninstall: uninstall-am
 endif
 
 noinst_HEADERS = elf.h abstract.h common.h exttypes.h gelf_xlate.h libelfP.h \
-                version_xlate.h gnuhash_xlate.h dl-hash.h
+                version_xlate.h gnuhash_xlate.h note_xlate.h dl-hash.h
 EXTRA_DIST = libelf.map
 
 CLEANFILES = $(am_libelf_pic_a_OBJECTS) *.gcno *.gcda libelf.so.$(VERSION)
index 9d4b83e47b1a2fc0a73b34578e5e756298eb1933..ae5b41df0d0a0ea0bbfd81dc224aadb302b7b3fc 100644 (file)
@@ -86,6 +86,7 @@ static const Elf_Type shtype_map[EV_NUM - 1][TYPEIDX (SHT_HISUNW) + 1] =
       [SHT_PREINIT_ARRAY] = ELF_T_ADDR,
       [SHT_GROUP] = ELF_T_WORD,
       [SHT_SYMTAB_SHNDX] = ELF_T_WORD,
+      [SHT_NOTE] = ELF_T_NHDR,
       [TYPEIDX (SHT_GNU_verdef)] = ELF_T_VDEF,
       [TYPEIDX (SHT_GNU_verneed)] = ELF_T_VNEED,
       [TYPEIDX (SHT_GNU_versym)] = ELF_T_HALF,
@@ -116,6 +117,7 @@ const uint_fast8_t __libelf_type_aligns[EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM]
       [ELF_T_VNAUX] = __alignof__ (ElfW2(Bits,Vernaux)),                     \
       [ELF_T_MOVE] = __alignof__ (ElfW2(Bits,Move)),                         \
       [ELF_T_LIB] = __alignof__ (ElfW2(Bits,Lib)),                           \
+      [ELF_T_NHDR] = __alignof__ (ElfW2(Bits,Nhdr)),                         \
     }
     [EV_CURRENT - 1] =
     {
@@ -238,7 +240,7 @@ __libelf_set_rawdata (Elf_Scn *scn)
       else
        {
          Elf_Type t = shtype_map[LIBELF_EV_IDX][TYPEIDX (type)];
-         if (t == ELF_T_VDEF
+         if (t == ELF_T_VDEF || t == ELF_T_NHDR
              || (t == ELF_T_GNUHASH && elf->class == ELFCLASS64))
            entsize = 1;
          else
index b985c1c0c3d3531a744c69a66c0713fa712933ae..9f81b7e97f75d164027f7ecc03db86c30cf26f04 100644 (file)
@@ -335,6 +335,14 @@ extern GElf_auxv_t *gelf_getauxv (Elf_Data *__data, int __ndx,
 extern int gelf_update_auxv (Elf_Data *__data, int __ndx, GElf_auxv_t *__src);
 
 
+/* Get note header at the given offset into the data, and the offsets of
+   the note's name and descriptor data.  Returns the offset of the next
+   note header, or 0 for an invalid offset or corrupt note header.  */
+extern size_t gelf_getnote (Elf_Data *__data, size_t __offset,
+                           GElf_Nhdr *__result,
+                           size_t *__name_offset, size_t *__desc_offset);
+
+
 /* Retrieve uninterpreted chunk of the file contents.  */
 extern char *gelf_rawchunk (Elf *__elf, GElf_Off __offset, GElf_Word __size);
 
diff --git a/libelf/gelf_getnote.c b/libelf/gelf_getnote.c
new file mode 100644 (file)
index 0000000..e490018
--- /dev/null
@@ -0,0 +1,119 @@
+/* Get note information at the supplied offset.
+   Copyright (C) 2007 Red Hat, Inc.
+   This file is part of Red Hat elfutils.
+
+   Red Hat elfutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by the
+   Free Software Foundation; version 2 of the License.
+
+   Red Hat elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with Red Hat elfutils; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+   In addition, as a special exception, Red Hat, Inc. gives You the
+   additional right to link the code of Red Hat elfutils with code licensed
+   under any Open Source Initiative certified open source license
+   (http://www.opensource.org/licenses/index.php) which requires the
+   distribution of source code with any binary distribution and to
+   distribute linked combinations of the two.  Non-GPL Code permitted under
+   this exception must only link to the code of Red Hat elfutils through
+   those well defined interfaces identified in the file named EXCEPTION
+   found in the source code files (the "Approved Interfaces").  The files
+   of Non-GPL Code may instantiate templates or use macros or inline
+   functions from the Approved Interfaces without causing the resulting
+   work to be covered by the GNU General Public License.  Only Red Hat,
+   Inc. may make changes or additions to the list of Approved Interfaces.
+   Red Hat's grant of this exception is conditioned upon your not adding
+   any new exceptions.  If you wish to add a new Approved Interface or
+   exception, please contact Red Hat.  You must obey the GNU General Public
+   License in all respects for all of the Red Hat elfutils code and other
+   code used in conjunction with Red Hat elfutils except the Non-GPL Code
+   covered by this exception.  If you modify this file, you may extend this
+   exception to your version of the file, but you are not obligated to do
+   so.  If you do not wish to provide this exception without modification,
+   you must delete this exception statement from your version and license
+   this file solely under the GPL without exception.
+
+   Red Hat elfutils is an included package of the Open Invention Network.
+   An included package of the Open Invention Network is a package for which
+   Open Invention Network licensees cross-license their patents.  No patent
+   license is granted, either expressly or impliedly, by designation as an
+   included package.  Should you wish to participate in the Open Invention
+   Network licensing program, please visit www.openinventionnetwork.com
+   <http://www.openinventionnetwork.com>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <gelf.h>
+#include <string.h>
+
+#include "libelfP.h"
+
+size_t
+gelf_getnote (data, offset, result, name_offset, desc_offset)
+     Elf_Data *data;
+     size_t offset;
+     GElf_Nhdr *result;
+     size_t *name_offset;
+     size_t *desc_offset;
+{
+  if (data == NULL)
+    return 0;
+
+  if (unlikely (data->d_type != ELF_T_NHDR))
+    {
+      __libelf_seterrno (ELF_E_INVALID_HANDLE);
+      return 0;
+    }
+
+  /* It's easy to handle this type.  It has the same size for 32 and
+     64 bit objects.  */
+  assert (sizeof (GElf_Nhdr) == sizeof (Elf32_Nhdr));
+  assert (sizeof (GElf_Nhdr) == sizeof (Elf64_Nhdr));
+
+  rwlock_rdlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  /* The data is already in the correct form.  Just make sure the
+     offset is OK.  */
+  if (unlikely (offset + sizeof (GElf_Nhdr) > data->d_size))
+    {
+      __libelf_seterrno (ELF_E_OFFSET_RANGE);
+      offset = 0;
+    }
+  else
+    {
+      const GElf_Nhdr *n = data->d_buf + offset;
+      offset += sizeof *n;
+
+      GElf_Word namesz = NOTE_ALIGN (n->n_namesz);
+      GElf_Word descsz = NOTE_ALIGN (n->n_descsz);
+
+      if (unlikely (data->d_size - offset < namesz))
+       offset = 0;
+      else
+       {
+         *name_offset = offset;
+         offset += namesz;
+         if (unlikely (data->d_size - offset < descsz))
+           offset = 0;
+         else
+           {
+             *desc_offset = offset;
+             offset += descsz;
+             *result = *n;
+           }
+       }
+    }
+
+  rwlock_unlock (((Elf_Data_Scn *) data)->s->elf->lock);
+
+  return offset;
+}
index 080474fdca2d24565d23a493fc551a62eb842ee3..a4134c30b3eb04b5648ebbe246759a425b429edb 100644 (file)
@@ -185,6 +185,7 @@ union unaligned
    do not contain records of only one type.  */
 #include "version_xlate.h"
 #include "gnuhash_xlate.h"
+#include "note_xlate.h"
 
 
 /* Now the externally visible table with the function pointers.  */
@@ -213,7 +214,7 @@ const xfct_t __elf_xfctstom[EV_NUM - 1][EV_NUM - 1][ELFCLASSNUM - 1][ELF_T_NUM]
        [ELF_T_VDAUX]   = elf_cvt_Verdef,                                     \
        [ELF_T_VNEED]   = elf_cvt_Verneed,                                    \
        [ELF_T_VNAUX]   = elf_cvt_Verneed,                                    \
-       [ELF_T_NHDR]    = ElfW2(Bits, cvt_Nhdr),                              \
+       [ELF_T_NHDR]    = elf_cvt_note,                                       \
        [ELF_T_SYMINFO] = ElfW2(Bits, cvt_Syminfo),                           \
        [ELF_T_MOVE]    = ElfW2(Bits, cvt_Move),                              \
        [ELF_T_LIB]     = ElfW2(Bits, cvt_Lib),                               \
index bc597c6fee377e23d1b3d9861018f4f74345f3aa..9453c4383ae4eae5cc23849d2782c2e189431640 100644 (file)
@@ -122,4 +122,5 @@ ELFUTILS_1.3 {
   global:
     gelf_getauxv;
     gelf_update_auxv;
+    gelf_getnote;
 };
index f06252d71f00edf91500cea9e571396b31fb5988..291206cac316ffc444890bbbb2a2079416f12e20 100644 (file)
@@ -574,4 +574,7 @@ extern uint32_t __libelf_crc32 (uint32_t crc, unsigned char *buf, size_t len)
       }                                                                              \
   } while (0)
 
+/* Align offset to 4 bytes as needed for note name and descriptor data.  */
+#define NOTE_ALIGN(n)  (((n) + 3) & -4U)
+
 #endif  /* libelfP.h */
diff --git a/libelf/note_xlate.h b/libelf/note_xlate.h
new file mode 100644 (file)
index 0000000..6e8b78c
--- /dev/null
@@ -0,0 +1,80 @@
+/* Conversion functions for notes.
+   Copyright (C) 2007 Red Hat, Inc.
+   This file is part of Red Hat elfutils.
+
+   Red Hat elfutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by the
+   Free Software Foundation; version 2 of the License.
+
+   Red Hat elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with Red Hat elfutils; if not, write to the Free Software Foundation,
+   Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301 USA.
+
+   In addition, as a special exception, Red Hat, Inc. gives You the
+   additional right to link the code of Red Hat elfutils with code licensed
+   under any Open Source Initiative certified open source license
+   (http://www.opensource.org/licenses/index.php) which requires the
+   distribution of source code with any binary distribution and to
+   distribute linked combinations of the two.  Non-GPL Code permitted under
+   this exception must only link to the code of Red Hat elfutils through
+   those well defined interfaces identified in the file named EXCEPTION
+   found in the source code files (the "Approved Interfaces").  The files
+   of Non-GPL Code may instantiate templates or use macros or inline
+   functions from the Approved Interfaces without causing the resulting
+   work to be covered by the GNU General Public License.  Only Red Hat,
+   Inc. may make changes or additions to the list of Approved Interfaces.
+   Red Hat's grant of this exception is conditioned upon your not adding
+   any new exceptions.  If you wish to add a new Approved Interface or
+   exception, please contact Red Hat.  You must obey the GNU General Public
+   License in all respects for all of the Red Hat elfutils code and other
+   code used in conjunction with Red Hat elfutils except the Non-GPL Code
+   covered by this exception.  If you modify this file, you may extend this
+   exception to your version of the file, but you are not obligated to do
+   so.  If you do not wish to provide this exception without modification,
+   you must delete this exception statement from your version and license
+   this file solely under the GPL without exception.
+
+   Red Hat elfutils is an included package of the Open Invention Network.
+   An included package of the Open Invention Network is a package for which
+   Open Invention Network licensees cross-license their patents.  No patent
+   license is granted, either expressly or impliedly, by designation as an
+   included package.  Should you wish to participate in the Open Invention
+   Network licensing program, please visit www.openinventionnetwork.com
+   <http://www.openinventionnetwork.com>.  */
+
+static void
+elf_cvt_note (void *dest, const void *src, size_t len, int encode)
+{
+  assert (sizeof (Elf32_Nhdr) == sizeof (Elf64_Nhdr));
+
+  while (len > 0)
+    {
+      (1 ? Elf32_cvt_Nhdr : Elf64_cvt_Nhdr) (dest, src, sizeof (Elf32_Nhdr),
+                                            encode);
+      const Elf32_Nhdr *n = encode ? src : dest;
+      Elf32_Word namesz = NOTE_ALIGN (n->n_namesz);
+      Elf32_Word descsz = NOTE_ALIGN (n->n_descsz);
+
+      len -= sizeof *n;
+      src += sizeof *n;
+      dest += sizeof *n;
+
+      if (namesz > len)
+       break;
+      len -= namesz;
+      if (descsz > len)
+       break;
+      len -= descsz;
+
+      if (src != dest)
+       memcpy (dest, src, namesz + descsz);
+
+      src += namesz + descsz;
+      dest += namesz + descsz;
+    }
+}
index 2c51f472bfd8bf1602b214045e4e05498db095de..0d92d721247cecbda986083a9490a4ccaaa9dc5f 100644 (file)
@@ -1,3 +1,20 @@
+2007-09-10  Roland McGrath  <roland@redhat.com>
+
+       * readelf.c (options): Give -p optional argument, alias --string-dump.
+       (string_sections, string_sections_tail): New static variables.
+       (parse_opt): Set them when -p has an argument.
+       (print_string_section): New function, broken out of ...
+       (print_strings): ... here.  Call it.
+       (dump_data_section): New function, broken out of ...
+       (dump_data): ... here.  Call it.
+       (for_each_section_argument): New function, broken out of ...
+       (dump_data): ... here.  Call it.
+       (dump_strings): New function.
+
+2007-08-31  Roland McGrath  <roland@redhat.com>
+
+       * readelf.c (print_strings): Typo fix.
+
 2007-08-23  Roland McGrath  <roland@redhat.com>
 
        * readelf.c (printf_with_wrap): Function removed.
index 747309597f9dcdda82ee3930417cb572b1de871e..bb79e28b6fbed1977e2160e16c14844f42f06dc2 100644 (file)
@@ -87,8 +87,9 @@ static const struct argp_option options[] =
     N_("Display architecture specific information (if any)"), 0 },
   { "hex-dump", 'x', "SECTION", 0,
     N_("Dump the uninterpreted contents of SECTION, by number or name"), 0 },
-  { "strings", 'p', NULL, 0,
-    N_("Print contents of sections marked as containing only strings"), 0 },
+  { "strings", 'p', "SECTION", OPTION_ARG_OPTIONAL,
+    N_("Print string contents of sections"), 0 },
+  { "string-dump", 'p', NULL, OPTION_ALIAS | OPTION_HIDDEN, NULL, 0 },
 
   { NULL, 0, NULL, 0, N_("Output control:"), 0 },
 
@@ -173,6 +174,10 @@ static enum section_e
 static struct section_argument *dump_data_sections;
 static struct section_argument **dump_data_sections_tail = &dump_data_sections;
 
+/* Select string dumping of sections.  */
+static struct section_argument *string_sections;
+static struct section_argument **string_sections_tail = &string_sections;
+
 struct section_argument
 {
   struct section_argument *next;
@@ -208,6 +213,7 @@ static void handle_hash (Ebl *ebl);
 static void handle_notes (Ebl *ebl, GElf_Ehdr *ehdr);
 static void print_liblist (Ebl *ebl);
 static void dump_data (Ebl *ebl);
+static void dump_strings (Ebl *ebl);
 static void print_strings (Ebl *ebl);
 
 
@@ -326,10 +332,6 @@ parse_opt (int key, char *arg,
       print_symbol_table = true;
       any_control_option = true;
       break;
-    case 'p':
-      print_string_sections = true;
-      any_control_option = true;
-      break;
     case 'V':
       print_version_info = true;
       any_control_option = true;
@@ -367,13 +369,23 @@ parse_opt (int key, char *arg,
        }
       any_control_option = true;
       break;
+    case 'p':
+      any_control_option = true;
+      if (arg == NULL)
+       {
+         print_string_sections = true;
+         break;
+       }
+      /* Fall through.  */
     case 'x':
       {
        struct section_argument *a = xmalloc (sizeof *a);
        a->arg = arg;
        a->next = NULL;
-       *dump_data_sections_tail = a;
-       dump_data_sections_tail = &a->next;
+       struct section_argument ***tailp
+         = key == 'x' ? &dump_data_sections_tail : &string_sections_tail;
+       **tailp = a;
+       *tailp = &a->next;
       }
       any_control_option = true;
       break;
@@ -542,6 +554,8 @@ process_elf_file (Elf *elf, const char *prefix, const char *fname,
     print_liblist (ebl);
   if (dump_data_sections != NULL)
     dump_data (ebl);
+  if (string_sections != NULL)
+    dump_strings (ebl);
   if (print_debug_sections != 0)
     print_debug (ebl, ehdr);
   if (print_notes)
@@ -5694,15 +5708,76 @@ hex_dump (const uint8_t *data, size_t len)
 }
 
 static void
-dump_data (Ebl *ebl)
+dump_data_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
+{
+  if (shdr->sh_size == 0 || shdr->sh_type == SHT_NOBITS)
+    printf (gettext ("\nSection [%Zu] '%s' has no data to dump.\n"),
+           elf_ndxscn (scn), name);
+  else
+    {
+      Elf_Data *data = elf_rawdata (scn, NULL);
+      if (data == NULL)
+       error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
+              elf_ndxscn (scn), name, elf_errmsg (-1));
+      else
+       {
+         printf (gettext ("\nHex dump of section [%Zu] '%s', %" PRIu64
+                          " bytes at offset %#0" PRIx64 ":\n"),
+                 elf_ndxscn (scn), name,
+                 shdr->sh_size, shdr->sh_offset);
+         hex_dump (data->d_buf, data->d_size);
+       }
+    }
+}
+
+static void
+print_string_section (Elf_Scn *scn, const GElf_Shdr *shdr, const char *name)
+{
+  if (shdr->sh_size == 0)
+    printf (gettext ("\nSection [%Zu] '%s' is empty.\n"),
+           elf_ndxscn (scn), name);
+
+  Elf_Data *data = elf_rawdata (scn, NULL);
+  if (data == NULL)
+    error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
+          elf_ndxscn (scn), name, elf_errmsg (-1));
+  else
+    {
+      printf (gettext ("\nString section [%Zu] '%s' contains %" PRIu64
+                      " bytes at offset %#0" PRIx64 ":\n"),
+             elf_ndxscn (scn), name,
+             shdr->sh_size, shdr->sh_offset);
+
+      const char *start = data->d_buf;
+      const char *const limit = start + data->d_size;
+      do
+       {
+         const char *end = memchr (start, '\0', limit - start);
+         const size_t pos = start - (const char *) data->d_buf;
+         if (unlikely (end == NULL))
+           {
+             printf ("  [%6Zx]- %.*s\n",
+                     pos, (int) (limit - start), start);
+             break;
+           }
+         printf ("  [%6Zx]  %s\n", pos, start);
+         start = end + 1;
+       } while (start < limit);
+    }
+}
+
+static void
+for_each_section_argument (Elf *elf, const struct section_argument *list,
+                          void (*dump) (Elf_Scn *scn, const GElf_Shdr *shdr,
+                                        const char *name))
 {
   /* Get the section header string table index.  */
   size_t shstrndx;
-  if (elf_getshstrndx (ebl->elf, &shstrndx) < 0)
+  if (elf_getshstrndx (elf, &shstrndx) < 0)
     error (EXIT_FAILURE, 0,
           gettext ("cannot get section header string table index"));
 
-  for (struct section_argument *a = dump_data_sections; a != NULL; a = a->next)
+  for (const struct section_argument *a = list; a != NULL; a = a->next)
     {
       Elf_Scn *scn;
       GElf_Shdr shdr_mem;
@@ -5712,7 +5787,7 @@ dump_data (Ebl *ebl)
       unsigned long int shndx = strtoul (a->arg, &endp, 0);
       if (endp != a->arg && *endp == '\0')
        {
-         scn = elf_getscn (ebl->elf, shndx);
+         scn = elf_getscn (elf, shndx);
          if (scn == NULL)
            {
              error (0, 0, gettext ("\nsection [%lu] does not exist"), shndx);
@@ -5722,17 +5797,17 @@ dump_data (Ebl *ebl)
          if (gelf_getshdr (scn, &shdr_mem) == NULL)
            error (EXIT_FAILURE, 0, gettext ("cannot get section header: %s"),
                   elf_errmsg (-1));
-         name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
+         name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
        }
       else
        {
          /* Need to look up the section by name.  */
          scn = NULL;
-         while ((scn = elf_nextscn (ebl->elf, scn)) != NULL)
+         while ((scn = elf_nextscn (elf, scn)) != NULL)
            {
              if (gelf_getshdr (scn, &shdr_mem) == NULL)
                continue;
-             name = elf_strptr (ebl->elf, shstrndx, shdr_mem.sh_name);
+             name = elf_strptr (elf, shstrndx, shdr_mem.sh_name);
              if (name == NULL)
                continue;
              if (!strcmp (name, a->arg))
@@ -5746,27 +5821,22 @@ dump_data (Ebl *ebl)
            }
        }
 
-      if (shdr_mem.sh_size == 0 || shdr_mem.sh_type == SHT_NOBITS)
-       printf (gettext ("\nSection [%Zu] '%s' has no data to dump.\n"),
-               elf_ndxscn (scn), name);
-      else
-       {
-         Elf_Data *data = elf_rawdata (scn, NULL);
-         if (data == NULL)
-           error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
-                  elf_ndxscn (scn), name, elf_errmsg (-1));
-         else
-           {
-             printf (gettext ("\nHex dump of section [%Zu] '%s', %" PRIu64
-                              " bytes at offset %#0" PRIx64 ":\n"),
-                     elf_ndxscn (scn), name,
-                     shdr_mem.sh_size, shdr_mem.sh_offset);
-             hex_dump (data->d_buf, data->d_size);
-           }
-       }
+      (*dump) (scn, &shdr_mem, name);
     }
 }
 
+static void
+dump_data (Ebl *ebl)
+{
+  for_each_section_argument (ebl->elf, dump_data_sections, &dump_data_section);
+}
+
+static void
+dump_strings (Ebl *ebl)
+{
+  for_each_section_argument (ebl->elf, string_sections, &print_string_section);
+}
+
 static void
 print_strings (Ebl *ebl)
 {
@@ -5793,35 +5863,6 @@ print_strings (Ebl *ebl)
       if (name == NULL)
        continue;
 
-      if (shdr_mem.sh_size == 0)
-       printf (gettext ("\nSection [%Zu] '%s' is empty.\n"),
-               elf_ndxscn (scn), name);
-
-      Elf_Data *data = elf_rawdata (scn, NULL);
-      if (data == NULL)
-       error (0, 0, gettext ("cannot get data for section [%Zu] '%s': %s"),
-              elf_ndxscn (scn), name, elf_errmsg (-1));
-      else
-       {
-         printf (gettext ("\nString section [%Zu] '%s' contains %" PRIu64
-                          " bytes at offset %#0" PRIx64 ":\n"),
-                 elf_ndxscn (scn), name,
-                 shdr_mem.sh_size, shdr_mem.sh_offset);
-
-         const char *start = data->d_buf;
-         const char *const limit = start + data->d_size;
-         do
-           {
-             const char *end = memchr (start, '\0', limit - start);
-             const size_t pos = start - (const char *) data->d_buf;
-             if (unlikely (end == NULL))
-               {
-                 printf ("  [%6Zx]- %.*s\n", pos, (int) (end - start), start);
-                 break;
-               }
-             printf ("  [%6Zx]  %s\n", pos, start);
-             start = end + 1;
-           } while (start < limit);
-       }
+      print_string_section (scn, &shdr_mem, name);
     }
 }
index adfcb2c7557733726ed7f6785feb54f6eb527de8..e854a6be04fb298337c961fd7ae36b62c22b9450 100644 (file)
@@ -1,3 +1,9 @@
+2007-09-11  Roland McGrath  <roland@redhat.com>
+
+       * run-addrname-test.sh: Add a new case.
+       * testfile41.bz2: New data file.
+       * Makefile.am (EXTRA_DIST): Add it.
+
 2007-08-23  Roland McGrath  <roland@redhat.com>
 
        * run-allregs.sh: Update expected x86-64 output for %rflags.
index decefe77e47f36a5a98dd3129a51ca4a7d5ef5ef..eb34e438c49707628be7bd171c112a0b2ebc58b6 100644 (file)
@@ -127,7 +127,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
             testfile34.bz2 testfile35.bz2 testfile35.debug.bz2 \
             testfile36.bz2 testfile36.debug.bz2 \
             testfile37.bz2 testfile37.debug.bz2 \
-            testfile38.bz2 testfile39.bz2 testfile40.bz2 testfile40.debug.bz2
+            testfile38.bz2 testfile39.bz2 testfile40.bz2 testfile40.debug.bz2 \
+            testfile41.bz2
 
 installed_TESTS_ENVIRONMENT = libdir=$(DESTDIR)$(libdir) \
                              bindir=$(DESTDIR)$(bindir) \
index 59290b393ace1ab1c6d43277c0dcf36b07152a81..ce47fe101ca50818c972758340f5181a87c197c4 100755 (executable)
@@ -25,7 +25,7 @@
 
 . $srcdir/test-subr.sh
 
-testfiles testfile34 testfile38
+testfiles testfile34 testfile38 testfile41
 
 testrun_compare ../src/addr2line -f -e testfile34 \
                                 0x08048074 0x08048075 0x08048076 \
@@ -55,4 +55,11 @@ t3_global_after_0+0x1
 ??:0
 EOF
 
+testrun_compare ../src/addr2line -S -e testfile41 0x1 0x104 <<\EOF
+small_global_at_large_global+0x1
+??:0
+small_global_first_at_large_global+0x1
+??:0
+EOF
+
 exit 0
diff --git a/tests/testfile41.bz2 b/tests/testfile41.bz2
new file mode 100644 (file)
index 0000000..f9bf5a4
Binary files /dev/null and b/tests/testfile41.bz2 differ