PATCH: Support VER_FLG_INFO in readelf
Rainer Orth
ro@CeBiTec.Uni-Bielefeld.DE
Mon Mar 1 22:11:00 GMT 2010
While looking at Sun ld-generated executables with readelf, I noticed
that it doesn't support the VER_FLG_INFO flag. While it is missing from
the Object File Format chapter of the Solaris Linker and Libraries Guide
http://docs.sun.com/app/docs/doc/819-0690?l=en
it is described, though indirectly, in the chapter on Application Binary
Interfaces and Versioning:
http://docs.sun.com/app/docs/doc/819-0690/chapter5-84101?l=en&a=view
in the `Binding to a Version Definition' section: normally, only the
last version in a dependency chain is recorded without flags in an
executable, and if ld.so.1 has verified that, it is guaranteed that
earlier versions are also present. Nonetheless, ld records those
version whose symbols were used with the VER_FLG_INFO flag set
(displayed by pvs -rv as INFO, but only if -v is given, otherwise those
informational dependencies are omitted).
In order to avoid readelf displaying the flag in Sun ld-generated
objects as unknown, I've added support for displaying it. While I was
at it, I've added support to gold, too, though I've not yet tried to
compile, let alone run that (I've not tried if gold works on Solaris 2
at all).
I didn't bother to implement setting the flag when creating executables
or shared objects, though:
* While glibc ld.so.1 doesn't support it, it seems that at least it
doesn't choke if it encounters it (just from code inspection), but
I've no way of trying.
* It is just an optimization.
Ok for mainline?
Rainer
--
-----------------------------------------------------------------------------
Rainer Orth, Center for Biotechnology, Bielefeld University
2010-02-27 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
include:
* elf/common.h (VER_FLG_INFO): Define.
gold:
* dynobj.h (Verdef::Verdef): Add is_info arg, is_info member
function, is_info_ member.
* dynobj.cc (Verdef::write): Set VER_FLG_INFO if this->is_info_.
(Versions::Versions): Update caller.
(Versions::define_base_version): Likewise.
(Versions::add_def): Likewise.
elfcpp:
* elfcpp.h (VER_FLG_INFO): Define.
binutils:
* readelf.c (get_ver_flags): Handle VER_FLG_INFO.
Index: binutils/readelf.c
===================================================================
RCS file: /vol/gnu/src/binutils/src-cvs/src/binutils/readelf.c,v
retrieving revision 1.484
diff -u -p -r1.484 readelf.c
--- binutils/readelf.c 9 Feb 2010 12:14:43 -0000 1.484
+++ binutils/readelf.c 27 Feb 2010 06:25:23 -0000
@@ -6652,7 +6652,15 @@ get_ver_flags (unsigned int flags)
strcat (buff, "WEAK ");
}
- if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK))
+ if (flags & VER_FLG_INFO)
+ {
+ if (flags & (VER_FLG_BASE|VER_FLG_WEAK))
+ strcat (buff, "| ");
+
+ strcat (buff, "INFO ");
+ }
+
+ if (flags & ~(VER_FLG_BASE | VER_FLG_WEAK | VER_FLG_INFO))
strcat (buff, "| <unknown>");
return buff;
Index: elfcpp/elfcpp.h
===================================================================
RCS file: /vol/gnu/src/binutils/src-cvs/src/elfcpp/elfcpp.h,v
retrieving revision 1.29
diff -u -p -r1.29 elfcpp.h
--- elfcpp/elfcpp.h 19 Jan 2010 17:55:49 -0000 1.29
+++ elfcpp/elfcpp.h 27 Feb 2010 06:26:49 -0000
@@ -1,6 +1,6 @@
// elfcpp.h -- main header file for elfcpp -*- C++ -*-
-// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
// Written by Ian Lance Taylor <iant@google.com>.
// This file is part of elfcpp.
@@ -784,6 +784,7 @@ const int VER_NEED_CURRENT = 1;
const int VER_FLG_BASE = 0x1;
const int VER_FLG_WEAK = 0x2;
+const int VER_FLG_INFO = 0x4;
// Special constants found in the SHT_GNU_versym entries.
Index: gold/dynobj.cc
===================================================================
RCS file: /vol/gnu/src/binutils/src-cvs/src/gold/dynobj.cc,v
retrieving revision 1.56
diff -u -p -r1.56 dynobj.cc
--- gold/dynobj.cc 12 Jan 2010 06:41:36 -0000 1.56
+++ gold/dynobj.cc 27 Feb 2010 06:39:47 -0000
@@ -1221,7 +1221,8 @@ Verdef::write(const Stringpool* dynpool,
elfcpp::Verdef_write<size, big_endian> vd(pb);
vd.set_vd_version(elfcpp::VER_DEF_CURRENT);
vd.set_vd_flags((this->is_base_ ? elfcpp::VER_FLG_BASE : 0)
- | (this->is_weak_ ? elfcpp::VER_FLG_WEAK : 0));
+ | (this->is_weak_ ? elfcpp::VER_FLG_WEAK : 0)
+ | (this->is_info_ ? elfcpp::VER_FLG_INFO : 0));
vd.set_vd_ndx(this->index());
vd.set_vd_cnt(1 + this->deps_.size());
vd.set_vd_hash(Dynobj::elf_hash(this->name()));
@@ -1353,7 +1354,7 @@ Versions::Versions(const Version_script_
Verdef* const vd = new Verdef(
version,
this->version_script_.get_dependencies(version),
- false, false, false);
+ false, false, false, false);
this->defs_.push_back(vd);
Key key(version_key, 0);
this->version_table_.insert(std::make_pair(key, vd));
@@ -1391,7 +1392,7 @@ Versions::define_base_version(Stringpool
name = parameters->options().output_file_name();
name = dynpool->add(name, false, NULL);
Verdef* vdbase = new Verdef(name, std::vector<std::string>(),
- true, false, true);
+ true, false, false, true);
this->defs_.push_back(vdbase);
this->needs_base_version_ = false;
}
@@ -1474,7 +1475,7 @@ Versions::add_def(const Symbol* sym, con
// When creating a regular executable, automatically define
// a new version.
Verdef* vd = new Verdef(version, std::vector<std::string>(),
- false, false, false);
+ false, false, false, false);
this->defs_.push_back(vd);
ins.first->second = vd;
}
Index: gold/dynobj.h
===================================================================
RCS file: /vol/gnu/src/binutils/src-cvs/src/gold/dynobj.h,v
retrieving revision 1.37
diff -u -p -r1.37 dynobj.h
--- gold/dynobj.h 5 Jan 2010 21:52:51 -0000 1.37
+++ gold/dynobj.h 27 Feb 2010 06:35:56 -0000
@@ -360,9 +360,9 @@ class Verdef : public Version_base
{
public:
Verdef(const char* name, const std::vector<std::string>& deps,
- bool is_base, bool is_weak, bool is_symbol_created)
+ bool is_base, bool is_weak, bool is_info, bool is_symbol_created)
: name_(name), deps_(deps), is_base_(is_base), is_weak_(is_weak),
- is_symbol_created_(is_symbol_created)
+ is_info_(is_info), is_symbol_created_(is_symbol_created)
{ }
// Return the version name.
@@ -391,6 +391,11 @@ class Verdef : public Version_base
clear_weak()
{ this->is_weak_ = false; }
+ // Return whether this definition is informational.
+ bool
+ is_info() const
+ { return this->is_info_; }
+
// Return whether a version symbol has been created for this
// definition.
bool
@@ -419,6 +424,8 @@ class Verdef : public Version_base
bool is_base_;
// Whether this version is weak.
bool is_weak_;
+ // Whether this version is informational.
+ bool is_info_;
// Whether a version symbol has been created.
bool is_symbol_created_;
};
Index: include/elf/common.h
===================================================================
RCS file: /vol/gnu/src/binutils/src-cvs/src/include/elf/common.h,v
retrieving revision 1.121
diff -u -p -r1.121 common.h
--- include/elf/common.h 9 Feb 2010 12:14:43 -0000 1.121
+++ include/elf/common.h 27 Feb 2010 06:40:43 -0000
@@ -816,6 +816,7 @@
#define VER_FLG_BASE 0x1
#define VER_FLG_WEAK 0x2
+#define VER_FLG_INFO 0x4
/* These special constants can be found in an Elf32_Versym field. */
More information about the Binutils
mailing list