PSARC/2007/509 elfedit

Ali Bahrami Ali.Bahrami at Sun.COM
Wed Sep 5 08:57:46 PDT 2007


I am sponsoring the following fast track for myself - timeout 9/12/2007

-----------------------------------------------------------------------
Release Binding:				Patch/Micro

elfedit command line (shell) interface		Committed
elfedit internal command interface		Committed
output from simple and num output styles	Committed

Command line editing features (libtecla)	Uncommitted
Output from default (elfdump) output style	Uncommitted

Internal Module interface			Private
-----------------------------------------------------------------------

This case proposes to integrate a new command line level utility
named elfedit into the Solaris ON consolidation. A hand formatted
version of the manpage for the proposed utility can be found
in the case materials. Much of the information in that document
is not repeated here.

elfedit is a tool for examining and modifying the ELF metadata that
resides within ELF objects. It can be used as a batch mode tool
from shell scripts, makefiles, etc, or as an interactive tool, for
examining and exploring objects.

Prior to elfedit, the sorts of modifications elfedit is designed to
do required the user to write a program, usually in C using libelf.
elfedit raises the programming level required to do this significantly.
Many operations can be done using already written elfedit commands.
For those that cannot, it is far easier to write an elfedit module
to add the ability than it is to write a standalone program.

elfedit is working software. It is installed and usable on my
desktop machines. I invite anyone who is interested to log
in (ssh) and try it:

	rtld.central	(Ultra 20 --- amd64)
	ldd.central	(Sunblade 2500 - sparcv9)

The code may be examined in its current development gate:

	/net/linkers.central/export/ws/elfedit


We envision elfedit being used to solve the following sorts of problems:

     [Small Fixups]
         To correct minor issues in a built file that cannot be easily
         rebuilt, or for which sources are not available.

         Probably the most notable such item is the ability to alter
         the runpath of objects built following the integration of

	   PSARC 2007/127 Reserved space for editing ELF dynamic sections
	   6516118 Reserved space needed in ELF dynamic section and string table

         The ability to do this is a "Frequently Asked Question" for which
         there has previously been no good answer. This feature is expected
	to be used nearly as soon as it is available, to fix the runpaths
         of FOSS (free open source software) built for Solaris, which often
         has the wrong runpaths set.

     [Better Way To Support Specialized Rarely Used Features]
         As an avenue for delivering small features to change some object
         attributes without the need to add additional complex and specialized
         features to ld and ld.so.1.

         For example, we have had requests to allow a mechanism to ld that
         would allow the user to override the hardware capability bits
         that are set by the linker. Such a feature would be complex to
         document and burdens already complex commands with features that
         are rarely used. Such features are a natural fit to elfedit.
	(See the elfedit manpage for an example of modifying the hardware
	capabilities).

     [Linker Development]
         We sometimes work on linker features that require objects
         with new values or flag bits that the compilers do not
         yet generate. An elfedit utility will allow us to set
         arbitrary values for such items.

     [Linker Testing]
         Many bugs involve an object that is broken in some way.
         Once the bug is fixed, we need an object broken in that
         particular way for our test suite. There are several problems
         that arise:

	    - Cataloging and archiving broken objects is
               time consuming and error prone.

             - Producing similarly broken objects for different
               platforms is not always possible.

	    - As new platforms appear, we end up with coverage
               gaps where some platforms can do a given test and
               others cannot.

         elfedit gives us the ability to build a simple object, and
         then break it intentionally in a specific and controlled
	manner. Tests can then be self contained, requiring no external
	data, and applicable to all relevant platforms.

	elfedit's ability to extract specific bits of data from
	an object will also prove valuable in improving the test
         suite used by the linker group to test our work.


Every elfedit module contains documentation for the commands it
provides. This information is displayed using the built in help
command, in a format that is based on that of Solaris manpages.
The help strings in the standard elfedit modules supplied
with Solaris are internationalized using the same i18n mechanisms
employed by the rest of the linker software found under sgs.
Hence, all elfedit modules supplied by Sun will have complete
documentation, and will support the necessary language locales.

As with any program that changes the contents of an ELF file, changes
to an object by elfedit will invalidate any pre-existing elfsign
signature. Assuming the changes are understood and acceptable to
the signing authority, such objects will need to be signed after
the edits are done.



Modular Design And Extensibility
--------------------------------

     elfedit has a modular design, reflecting our own experience
with dynamic linking, and influenced heavily by the design of
mdb, the modular debugger.

The elfedit program contains the code that handles the details
of reading objects, executing commands to modify them, and saving
the results. Very little of the code that performs the actual
edits is found in elfedit itself. Rather, the commands exist in
modules, which are sharable objects with a well defined
elfedit-specific interface. elfedit loads needed modules on
demand when a command from the module is executed. These modules are
self contained, and include their own documentation in a standard
format that elfedit can display using its help command.

The module forms a namespace for the commands that it supplies.
Each module delivers a set of commands, focused on related
functionality. A command is specified by combining the
module and command names with a colon (:) delimiter, with
no intervening whitespace. For example, dyn:runpath refers
to the runpath command provided by the dyn module.

Module names must be unique. The command names within a given
module are unique within that module, but the same command
names can be used in more than one module. For example, most
modules contain a command named 'dump', which is used to provide
an elfedump-style view of the data.

We have adopted the following general rules of thumb for
naming modules and commands:

	- The module name reflects the part of the ELF format
	  the module addresses (ehdr, phdr, shdr, ...)

	- Commands that directly access a field in an ELF structure
	  are given the name of the field (e.g. ehdr:e_flags).

	- Commands that are higher level have a simple descriptive
	  name that reflects their purpose (e.g. dyn:runpath).

elfedit was designed from the very beginning with the idea that others
outside of the Sun OS group should be able to write their own modules
to extend its abilities. This is still the long term plan. However, we
are planning to initially make the module interface private. This is
a transitional move. We are satisfied with the user level functionality,
and wish to integrate elfedit in order to make use of it and gain wider
experience. Holding back the internal details for a period of time will
allow necessary internal changes that result from this experience to
be made more easily. We intend to file a case to open the internal
module interface at a later time.


Future Directions
-----------------

    The items discussed in this section are forward looking, and are
not part of this case. However, it may be helpful to know what we
consider to be the next steps:

     [Make Module Interface Public]
	As discussed in the previous section, our ultimate goal
	is to open the internal module interface and allow others
	to write their own modules.

     [Provide Missing Modules]
         The initial set of modules provided with elfedit cover the
         most commonly needed features, and represent a widely useful
         set of functionality. However, there are ELF data structures
         that we do not yet cover. Ultimately, a stock elfedit should
         have the ability to understand any part of a standard ELF
	object. My intent is to write and integrate additional modules
         to complete our coverage of the ELF standard as required
	to support other work, and/or as time allows.

I would summarize these goals as

     (1) Let people write their own modules.
     (2) Make sure it is rarely necessary to do so.

The overall goal is for elfedit as delivered to completely cover
the ELF standard, leaving the need for custom modules to those
working on new ELF extensions or other related activities.


Files Delivered
---------------

Once integrated, the source files for elfedit will be located with
the rest of the linker software in:

	usr/src/cmd/sgs/elfedit

On an installed system, this proposal adds elfedit executables
under /usr/bin, and creates the new directory /usr/lib/elfedit
for elfedit modules.

On x86, the new files this case plans to integrate can be viewed
with the command:

	# ls -alFR /usr/bin/elfedit /usr/bin/amd64/elfedit /usr/lib/elfedit
	-r-xr-xr-x   1 root  bin   159448 Sep  3 14:32 /usr/bin/amd64/elfedit*
	-r-xr-xr-x   1 root  bin   124916 Sep  3 14:32 /usr/bin/elfedit*

	/usr/lib/elfedit/:
	total 1016
	drwxr-xr-x   3 root  bin      512 Sep  4 14:00 ./
	drwxr-xr-x 146 root  bin    39424 Sep  4 14:00 ../
	lrwxrwxrwx   1 root  root       1 Sep  4 14:00 32 -> ./
	lrwxrwxrwx   1 root  root       5 Sep  4 14:00 64 -> amd64/
	drwxr-xr-x   2 root  bin      512 Sep  4 14:00 amd64/
	-rwxr-xr-x   1 root  bin    52484 Sep  3 14:32 cap.so*
	-rwxr-xr-x   1 root  bin    80408 Sep  3 14:32 dyn.so*
	-rwxr-xr-x   1 root  bin    97312 Sep  3 14:32 ehdr.so*
	-rwxr-xr-x   1 root  bin    61416 Sep  3 14:32 phdr.so*
	-rwxr-xr-x   1 root  bin    66152 Sep  3 14:32 shdr.so*
	-rwxr-xr-x   1 root  bin    66364 Sep  3 14:32 sym.so*
	-rwxr-xr-x   1 root  bin    49152 Sep  3 14:32 syminfo.so*

	/usr/lib/elfedit/amd64:
	total 1244
	drwxr-xr-x   2 root  bin      512 Sep  4 14:00 ./
	drwxr-xr-x   3 root  bin      512 Sep  4 14:00 ../
	-rwxr-xr-x   1 root  bin    70848 Sep  3 14:32 cap.so*
	-rwxr-xr-x   1 root  bin    99624 Sep  3 14:32 dyn.so*
	-rwxr-xr-x   1 root  bin   121192 Sep  3 14:32 ehdr.so*
	-rwxr-xr-x   1 root  bin    79608 Sep  3 14:32 phdr.so*
	-rwxr-xr-x   1 root  bin    80384 Sep  3 14:32 shdr.so*
	-rwxr-xr-x   1 root  bin    88920 Sep  3 14:32 sym.so*
	-rwxr-xr-x   1 root  bin    67424 Sep  3 14:32 syminfo.so*


On sparc, the same files are installed, with "sparcv9" taking the
place of "amd64":



	% ls -alFR /usr/bin/elfedit /usr/bin/sparcv9/elfedit /usr/lib/elfedit
	-r-xr-xr-x   1 root  bin   139048 Sep  3 14:50 /usr/bin/elfedit*
	-r-xr-xr-x   1 root  bin   147176 Sep  3 14:50 /usr/bin/sparcv9/elfedit*

	/usr/lib/elfedit/:
	total 1162
	drwxr-xr-x   3 root  bin      512 Sep  4 14:04 ./
	drwxr-xr-x 146 root  bin    39936 Sep  4 14:04 ../
	lrwxrwxrwx   1 root  root       1 Sep  4 14:04 32 -> ./
	lrwxrwxrwx   1 root  root       7 Sep  4 14:04 64 -> sparcv9/
	-rwxr-xr-x   1 root  bin    58660 Sep  3 14:51 cap.so*
	-rwxr-xr-x   1 root  bin    91040 Sep  3 14:51 dyn.so*
	-rwxr-xr-x   1 root  bin   107856 Sep  3 14:51 ehdr.so*
	-rwxr-xr-x   1 root  bin    71632 Sep  3 14:51 phdr.so*
	-rwxr-xr-x   1 root  bin    72184 Sep  3 14:51 shdr.so*
	drwxr-xr-x   2 root  bin      512 Sep  4 14:04 sparcv9/
	-rwxr-xr-x   1 root  bin    75872 Sep  3 14:51 sym.so*
	-rwxr-xr-x   1 root  bin    55464 Sep  3 14:51 syminfo.so*

	/usr/lib/elfedit/sparcv9:
	total 1200
	drwxr-xr-x   2 root  bin      512 Sep  4 14:04 ./
	drwxr-xr-x   3 root  bin      512 Sep  4 14:04 ../
	-rwxr-xr-x   1 root  bin    72840 Sep  3 14:52 cap.so*
	-rwxr-xr-x   1 root  bin    98016 Sep  3 14:52 dyn.so*
	-rwxr-xr-x   1 root  bin   115208 Sep  3 14:52 ehdr.so*
	-rwxr-xr-x   1 root  bin    77568 Sep  3 14:52 phdr.so*
	-rwxr-xr-x   1 root  bin    78080 Sep  3 14:52 shdr.so*
	-rwxr-xr-x   1 root  bin    82160 Sep  3 14:52 sym.so*
	-rwxr-xr-x   1 root  bin    69456 Sep  3 14:52 syminfo.so*



More information about the opensolaris-arc mailing list