summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2007-09-27 07:31:33 +0000
committerRoland McGrath <roland@redhat.com>2007-09-27 07:31:33 +0000
commitc76f0b05676f6207affbfd85e75063db3b6eeccf (patch)
tree8ccc124a5908a03d34113a7dcdeb2abad7d71522
parentcb6d865011ad98a8ac2018f072f396a2268739ca (diff)
downloadelfutils-c76f0b05676f6207affbfd85e75063db3b6eeccf.tar.gz
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.
-rw-r--r--NEWS5
-rw-r--r--backends/ChangeLog11
-rw-r--r--backends/alpha_retval.c20
-rw-r--r--backends/i386_retval.c20
-rw-r--r--backends/ia64_retval.c39
-rw-r--r--backends/ppc64_retval.c32
-rw-r--r--backends/ppc_retval.c25
-rw-r--r--backends/s390_retval.c14
-rw-r--r--backends/sparc_retval.c24
-rw-r--r--backends/x86_64_retval.c24
-rw-r--r--libdwfl/ChangeLog5
-rw-r--r--libdwfl/dwfl_module_addrsym.c42
-rw-r--r--libelf/ChangeLog15
-rw-r--r--libelf/Makefile.am3
-rw-r--r--libelf/elf_getdata.c4
-rw-r--r--libelf/gelf.h8
-rw-r--r--libelf/gelf_getnote.c119
-rw-r--r--libelf/gelf_xlate.c3
-rw-r--r--libelf/libelf.map1
-rw-r--r--libelf/libelfP.h3
-rw-r--r--libelf/note_xlate.h80
-rw-r--r--src/ChangeLog17
-rw-r--r--src/readelf.c167
-rw-r--r--tests/ChangeLog6
-rw-r--r--tests/Makefile.am3
-rwxr-xr-xtests/run-addrname-test.sh9
-rw-r--r--tests/testfile41.bz2bin0 -> 295 bytes
27 files changed, 527 insertions, 172 deletions
diff --git a/NEWS b/NEWS
index 4eb1ead8..d257c1fd 100644
--- 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)
diff --git a/backends/ChangeLog b/backends/ChangeLog
index 159e6dc1..9c51f986 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -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.
diff --git a/backends/alpha_retval.c b/backends/alpha_retval.c
index 09f8bb4c..57ba867b 100644
--- a/backends/alpha_retval.c
+++ b/backends/alpha_retval.c
@@ -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;
diff --git a/backends/i386_retval.c b/backends/i386_retval.c
index cfd50579..c3bab108 100644
--- a/backends/i386_retval.c
+++ b/backends/i386_retval.c
@@ -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)
{
diff --git a/backends/ia64_retval.c b/backends/ia64_retval.c
index 4100328c..238cd9ef 100644
--- a/backends/ia64_retval.c
+++ b/backends/ia64_retval.c
@@ -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
diff --git a/backends/ppc64_retval.c b/backends/ppc64_retval.c
index 7f5e6f83..454897cc 100644
--- a/backends/ppc64_retval.c
+++ b/backends/ppc64_retval.c
@@ -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;
diff --git a/backends/ppc_retval.c b/backends/ppc_retval.c
index b8d86aca..fa0e303c 100644
--- a/backends/ppc_retval.c
+++ b/backends/ppc_retval.c
@@ -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;
diff --git a/backends/s390_retval.c b/backends/s390_retval.c
index 6c430828..15bd97bf 100644
--- a/backends/s390_retval.c
+++ b/backends/s390_retval.c
@@ -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)
{
diff --git a/backends/sparc_retval.c b/backends/sparc_retval.c
index cfde0d2f..7cd38273 100644
--- a/backends/sparc_retval.c
+++ b/backends/sparc_retval.c
@@ -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;
diff --git a/backends/x86_64_retval.c b/backends/x86_64_retval.c
index 1920abf9..3109431e 100644
--- a/backends/x86_64_retval.c
+++ b/backends/x86_64_retval.c
@@ -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;
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index a5177aca..3a99753b 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -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.
diff --git a/libdwfl/dwfl_module_addrsym.c b/libdwfl/dwfl_module_addrsym.c
index 52dbb3d8..f16de116 100644
--- a/libdwfl/dwfl_module_addrsym.c
+++ b/libdwfl/dwfl_module_addrsym.c
@@ -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;
- }
}
}
}
diff --git a/libelf/ChangeLog b/libelf/ChangeLog
index 4962c30a..c879aede 100644
--- a/libelf/ChangeLog
+++ b/libelf/ChangeLog
@@ -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.
diff --git a/libelf/Makefile.am b/libelf/Makefile.am
index 3e8322e9..3e52bcec 100644
--- a/libelf/Makefile.am
+++ b/libelf/Makefile.am
@@ -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)
diff --git a/libelf/elf_getdata.c b/libelf/elf_getdata.c
index 9d4b83e4..ae5b41df 100644
--- a/libelf/elf_getdata.c
+++ b/libelf/elf_getdata.c
@@ -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
diff --git a/libelf/gelf.h b/libelf/gelf.h
index b985c1c0..9f81b7e9 100644
--- a/libelf/gelf.h
+++ b/libelf/gelf.h
@@ -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
index 00000000..e4900185
--- /dev/null
+++ b/libelf/gelf_getnote.c
@@ -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;
+}
diff --git a/libelf/gelf_xlate.c b/libelf/gelf_xlate.c
index 080474fd..a4134c30 100644
--- a/libelf/gelf_xlate.c
+++ b/libelf/gelf_xlate.c
@@ -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), \
diff --git a/libelf/libelf.map b/libelf/libelf.map
index bc597c6f..9453c438 100644
--- a/libelf/libelf.map
+++ b/libelf/libelf.map
@@ -122,4 +122,5 @@ ELFUTILS_1.3 {
global:
gelf_getauxv;
gelf_update_auxv;
+ gelf_getnote;
};
diff --git a/libelf/libelfP.h b/libelf/libelfP.h
index f06252d7..291206ca 100644
--- a/libelf/libelfP.h
+++ b/libelf/libelfP.h
@@ -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
index 00000000..6e8b78c6
--- /dev/null
+++ b/libelf/note_xlate.h
@@ -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;
+ }
+}
diff --git a/src/ChangeLog b/src/ChangeLog
index 2c51f472..0d92d721 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -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.
diff --git a/src/readelf.c b/src/readelf.c
index 74730959..bb79e28b 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -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,28 +5821,23 @@ 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)
{
/* Get the section header string table index. */
@@ -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);
}
}
diff --git a/tests/ChangeLog b/tests/ChangeLog
index adfcb2c7..e854a6be 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -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.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index decefe77..eb34e438 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -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) \
diff --git a/tests/run-addrname-test.sh b/tests/run-addrname-test.sh
index 59290b39..ce47fe10 100755
--- a/tests/run-addrname-test.sh
+++ b/tests/run-addrname-test.sh
@@ -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
index 00000000..f9bf5a48
--- /dev/null
+++ b/tests/testfile41.bz2
Binary files differ