catch up phonesim-integ to tip phonesim-integ
authorcdavies@GUAR
Tue, 26 Jan 2010 13:28:08 +0000
branchphonesim-integ
changeset 37 2925e6e5efd7
parent 36 a587897e3bb2 (current diff)
parent 35 bfd7df5b9067 (diff)
child 38 33dfab4ab0fc
catch up phonesim-integ to tip
--- a/.hgtags	Tue Jan 26 13:03:40 2010 +0000
+++ b/.hgtags	Tue Jan 26 13:28:08 2010 +0000
@@ -1,1 +1,6 @@
 5c4b0c1fa5f84f299d50ad82f561454aa109a2a4 PDK_3.0.b
+c506b18dc03fca6edca100e3b2cd2ae4c175215c PDK_3.0.c
+c506b18dc03fca6edca100e3b2cd2ae4c175215c PDK_2.0.1
+1a93ed2e38bd484d72fdaa19792e0f9568455b8a PDK_3.0.d
+1a93ed2e38bd484d72fdaa19792e0f9568455b8a PDK_2.0.2
+7048876724acc5d17377ab5ff1747863859d4efc PDK_3.0.e
--- a/README.txt	Tue Jan 26 13:03:40 2010 +0000
+++ b/README.txt	Tue Jan 26 13:28:08 2010 +0000
@@ -1,5 +1,8 @@
 This is repo contains the following; 
 
+applications/
+	Sample application 
+
 baseport/
 	The baseport (BSP) needed to run Symbian OS in QEMU
 
@@ -12,6 +15,13 @@
 	A corresponding set of Windows/Linux binaries is available from the Symbian Foundation wiki
         http://developer.symbian.org/wiki/index.php/SYBORG/QEMU
 
+tools/e32test-driver/
+	A simple python script to run the E32test-suite and collect/summarize the results.
+
+tools/elf4rom/
+	The ELF4ROM command line tool and libraries. This tool is used to convert Symbian ROM images
+	into debuggable elf files. See docs/wiki/ELF4ROM.doc for more information.
+
 Some notes;
 
 * The source layout for baseport now matches the Symbian Foundation layout, and 
--- a/baseport/syborg/bld.inf	Tue Jan 26 13:03:40 2010 +0000
+++ b/baseport/syborg/bld.inf	Tue Jan 26 13:28:08 2010 +0000
@@ -32,6 +32,11 @@
 
 PRJ_EXTENSIONS
 start		extension		base/genexec
+#ifdef SYMBIAN_OLD_EXPORT_LOCATION
+option INC_PATH   /epoc32/include
+#else
+option INC_PATH  /epoc32/include/platform
+#endif
 option		EXTRA_SRC_PATH  $(EXTENSION_ROOT)/../../../../os/kernelhwsrv/kernel/eka/kernel
 end
 
@@ -95,6 +100,11 @@
 
 PRJ_EXTENSIONS
 start		extension		base/bootstrap
+#ifdef SYMBIAN_OLD_EXPORT_LOCATION
+option INC_PATH   /epoc32/include
+#else
+option INC_PATH  /epoc32/include/platform
+#endif
 option		NAME			_syborg_bootloader_bootrom
 option		MEMMODEL		multiple
 //option		MEMMODEL		flexible
@@ -105,3 +115,10 @@
 option		EXTRA_INC_PATH	$(EXTENSION_ROOT)/bootstrap
 option		EXTRA_SRC_PATH	$(EXTENSION_ROOT)/bootstrap 
 end
+
+// Build image armv5 for urel and udeb
+PRJ_EXTENSIONS
+start	extension	base/rom
+option	REE_TARGET	syborg
+option	TYPE	tshell
+end
--- a/baseport/syborg/soundsc/shared_sound.h	Tue Jan 26 13:03:40 2010 +0000
+++ b/baseport/syborg/soundsc/shared_sound.h	Tue Jan 26 13:28:08 2010 +0000
@@ -51,6 +51,11 @@
 	void Callback(TUint aTransferID, TInt aTransferResult, TInt aBytesTransferred);
 
 	void SetCaps();
+        // There was a change in the signature for DfcQ() which
+        // is a pure virtual method in the parent.
+        //  for Symbian^2
+        TDfcQue* DfcQ();
+        //  for Symbian^3
 	TDfcQue* DfcQ(TInt aUnit);
 	
 	TInt CalculateBufferTime(TInt aNumBytes);
--- a/baseport/syborg/soundsc/shared_txsound.cpp	Tue Jan 26 13:03:40 2010 +0000
+++ b/baseport/syborg/soundsc/shared_txsound.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -249,10 +249,14 @@
 	}
 
 TDfcQue*DDriverSyborgSoundScPdd::DfcQ(TInt /* aUnit*/ )
-	{
-	return iPhysicalDevice->iDfcQ;
-	}
+        {
+        return this->DfcQ();
+        }
 
+TDfcQue*DDriverSyborgSoundScPdd::DfcQ()
+        {
+        return iPhysicalDevice->iDfcQ;
+        }
 
 TInt DDriverSyborgSoundScPdd::MaxTransferLen() const
 	{
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/e32test-driver/COPYING	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program 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, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/e32test-driver/COPYING.LESSER	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,165 @@
+		   GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions.
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version.
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+  Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/e32test-driver/qemuruntest.py	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,199 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 Lesser General Public License for more details.
+# 
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Launch QEMU for SVP with a specified ROM image and core using a COM port for IO
+# Uses Python's Popen class for process control.
+# Test output is captured by invoking QEMU in -nographic mode. This redirects serial output to stdout which can then be PIPE'd
+# using Popen.
+# Tests which hang(or crash into the the crash debugger) are detected using a trivial 'watchdog'. IWBN to use e.g. 'select'
+# with a timeout, but this won't work on Windoze, which only supports timeout's on sockets. If the watchdog timeouts out QEMU is killed.
+# When the test suite runs to (recognizable) completion QEMU is killed. Unfortunately this appears to require an OS specific
+# solution. NB unrecognized completion will result in the watchdog killing QEMU.
+# QemuTestRunner collects  output into LineTimeInfo objects. These record the time at which each line was received. The time can be used as a crude
+# measure of how long a test took to execute.
+# The raw data gathered from running the tests can be retrieved using GetResults. This returns a list of LineTimeInfo objects.
+
+import sys
+mswindows = (sys.platform == "win32")
+
+# import the following so we can kill QEMU
+
+if mswindows:
+#    import win32api
+    import signal
+else:
+    import signal
+
+import os
+
+import time
+
+import re
+
+import subprocess
+from subprocess import *
+
+from stat import *
+
+import watchdog
+
+__all__ = ["QemuTestRunner"]
+
+class LineTimeInfo(object):
+    def __init__(self, line, atime):
+        self.line = line
+        self.time = atime
+
+    def GetLine(self):
+        return self.line
+
+    def GetTime(self):
+        return self.time
+
+class QemuTestRunner(object):
+    def __init__(self, qemupath, cpu, rompath, board = 'syborg', endOfTestFn=None, displayp=False, dataFile = None):
+        """Create new QemuTestRunner instance."""
+        self.qemupath = qemupath
+        self.board = board
+        self.cpu = cpu
+        self.rompath = rompath
+        self.endOfTestFn = endOfTestFn
+        self.displayp = displayp
+        #self.cmd = qemupath + " -M syborg -cpu " + cpu + " -kernel " + rompath + " -nographic"
+        self.cmd = "%s -M %s -cpu %s -kernel %s -nographic" % (qemupath, board, cpu, rompath)
+        self.endOfTestPattern = re.compile('RUNTESTS: Completed test script')
+        self.lineTimeInfo = []
+        self.id = None
+        self.dataFile = dataFile
+        self.watchdog = watchdog.WatchDog(900, lambda : self.KillSim())
+        
+    def Run(self):
+        self.lineTimeInfo = []
+        output = False
+        self.timeStarted = time.gmtime()
+        self.id = time.strftime("%d-%m%--%Y-%H-%M-%S", self.timeStarted)
+        if self.dataFile != None:
+            filename = self.dataFile + "-" + self.GetRunId() + "-data.txt"
+            self.dataFileName = filename
+            output = open(filename, 'wb')
+        p = Popen( self.cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE )
+        self.popen = p
+        stdin = p.stdin
+        stdout = p.stdout
+        stop = False
+
+        if self.displayp:
+            print >> sys.stdout, self.cmd
+            
+        self.watchdog.Start()
+        try:
+            while p.poll() == None and not stop:
+                line = stdout.readline()
+                atime = time.clock()
+                self.watchdog.Reset()
+                if self.displayp and p.returncode == None:
+                    print >> sys.stdout , line
+                if output and p.returncode == None:
+                    print >> output , line
+                if p.returncode == None:
+                    self.lineTimeInfo.append(LineTimeInfo(line, atime))
+                    if self.endOfTestFn != None:
+                        stop = self.endOfTestFn(line)
+                    else:
+                        stop = self.EndOfTestp(line)
+        finally:
+            self.timeEnded = time.gmtime()
+            self.watchdog.Stop()
+            if output:
+                output.close()
+            self.testSuiteFinished = stop;
+                
+        if p.returncode == None:
+            self.KillSim()
+            return True
+        else:
+            return False
+
+    def GetDataFileName(self):
+        return self.dataFileName
+
+    def TestSuiteFinishedp(self):
+        return self.testSuiteFinished
+    
+    def EndOfTestp(self, l):
+        return re.match(self.endOfTestPattern,l) != None
+
+    def KillSim(self):
+#        if mswindows:
+#            win32api.TerminateProcess(int(self.popen._handle), -1)
+#        else:
+            os.kill(slef.popen.pid, signal.SIGKILL)
+
+    def GetResults(self):
+        return self.lineTimeInfo
+
+    def GetRomName(self):
+        return self.rompath
+
+    def GetRunId(self):
+        return self.id
+
+    def GetSummary(self):
+        simStat = os.stat(self.qemupath)
+        simSummary = "QEMU Executable: %s size: %d creation time: %d\n" % (self.qemupath, simStat[ST_SIZE], simStat[ST_CTIME])
+        boardSummary ="Board: %s\n" %  self.board
+        cpuSummary = "CPU: %s\n" % self.cpu
+        romStat = os.stat(self.rompath)
+        romSummary = "ROM image: %s size: %d creation date: %d\n" % (self.rompath, romStat[ST_SIZE], romStat[ST_CTIME])
+        timeFormat = "%d-%m%--%Y %H:%M:%S"
+        startTime = "Start time: " + time.strftime(timeFormat, self.timeStarted) + "\n"
+        endTime = "End time: " + time.strftime(timeFormat, self.timeEnded) + "\n"
+        status = "Testsuite did not complete\n"
+        if self.TestSuiteFinishedp():
+            status = "Testsuite completed\n"
+        return simSummary + boardSummary + cpuSummary + romSummary + startTime + endTime + status
+
+    def GetReportFileName(self):
+        return self.GetRomName() + "-" + self.GetRunId() + "-results-summary.txt"
+
+class PseudoRunner(QemuTestRunner):
+    def __init__(self, input):
+        #self.qemupath = qemupath
+        #self.board = board
+        #self.cpu = cpu
+        #self.rompath = rompath
+        #self.endOfTestFn = endOfTestFn
+        #self.displayp = displayp
+        #self.cmd = qemupath + " -M syborg -cpu " + cpu + " -kernel " + rompath + " -nographic"
+        #self.endOfTestPattern = re.compile('RUNTESTS: Completed test script')
+        self.lineTimeInfo = []
+        #self.id = None
+        self.dataFile = input
+        for line in open(input):
+            self.lineTimeInfo.append(LineTimeInfo(line, 0))
+        
+    def GetRomName(self):
+        return "Unknown"
+
+    def GetRunId(self):
+        return None
+
+    def GetSummary(self):
+        return ""
+
+    def GetReportFileName(self):
+        return "Runtest-Summary.txt"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/e32test-driver/rtest.py	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,246 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 Lesser General Public License for more details.
+# 
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# RTestParser represents the results of running an RTest testsuite on the target in terms of RTest
+# objects. Each RTest object captures the LineTimeInfo associated with the test and can determine
+# whether the test errored, failed or passed. It also provides further information such as the name of
+# the test and how long it took to gather the output from the test (which is a crude estimate of how long
+# it took to run the test. It can provide various useful bits of information like the line number in the
+# raw test data of a given line and the 'context' of a failure (in terms of the lines in the raw data).
+
+import sys
+
+import re
+
+import qemuruntest
+
+startRTestPattern = re.compile('RTEST TITLE:')
+bmSuiteFailurePattern = re.compile('Error:')
+endRTestPattern = re.compile('RUNTESTS: Test')
+failedRTestPattern = re.compile('RUNTESTS: Test .* FAIL')
+erroredRTestPattern = re.compile('RUNTESTS: Test .* ERROR')
+nameRTestPattern = re.compile('RUNTESTS: Test (\w+)')
+testSuiteEndingPattern = re.compile('RUNTESTS: Elapsed')
+
+class NoRTestsFound(Exception):
+    def __init__(self, parser):
+        self.parser = parser
+
+    def __str__(self):
+        return "No test results found in output from running '%s' rom image" % (self.parser.GetRomName())
+    
+    def GetParser(self):
+        return self.parser
+
+class RTestEndMissing(Exception):
+    def __init__(self, rtest):
+        self.rtest = rtest
+
+    def __str__(self):
+        return "Could not find end of test started on line %d: '%s'" % (self.rtest.GetLineNumber(0), self.rtest.GetLine(0))
+    
+    def GetParser(self):
+        return self.parser
+
+    def GetIndex(self):
+        return self.index
+
+class RTestNameMissing(Exception):
+    def __init__(self, rtest, line):
+        self.rtest = rtest
+        self.line = line
+
+    def GetRTest(self):
+        return self.rtest
+    
+    def __str__(self):
+        return "Could not find RTest name in line '%s'" % (self.line)
+    
+    def GetParser(self):
+        return self.parser
+
+    def GetLine(self):
+        return self.line
+
+class RTest(object):
+    def __init__(self, parser, lineTimeInfo, startLine = 0):
+        """return new RTest instance"""
+        self.parser = parser
+        self.lineTimeInfoList = []
+        self.lineTimeInfoList.append(lineTimeInfo)
+        self.timeTaken = None
+        self.result = None
+        self.name = None
+        self.startLine = startLine
+        #line = lineTimeInfo.GetLine()
+        #print >> sys.stdout, line
+
+    def __str__(self):
+            return self.GetName() + " " + self.GetResult()
+        
+    def Consume(self,lineTimeInfoList, start):
+        newStart = start;
+        for i in range(start, len(lineTimeInfoList) - 1):
+            lineTimeInfo = lineTimeInfoList[i]
+            self.lineTimeInfoList.append(lineTimeInfo)
+            line = lineTimeInfo.GetLine()
+            newStart = newStart + 1
+            if self.EndOfTestp(line):
+                break
+        else:
+            raise RTestEndMissing(self)
+        
+        return newStart
+            
+    def EndOfTestp(self,line):
+        return re.match(endRTestPattern, line) != None
+
+    def FailedTestp(self,line):
+        return re.match(failedRTestPattern, line) != None
+
+    def ErroredTestp(self,line):
+        return re.match(erroredRTestPattern, line) != None
+
+    def GetTimeTaken(self):
+        if self.timeTaken == None:
+            self.timeTaken = self.lineTimeInfoList[-1].GetTime() - self.lineTimeInfoList[0].GetTime()
+        return self.timeTaken
+
+    def GetResult(self):
+        if self.result == None:
+            line = self.lineTimeInfoList[-1].GetLine()
+            if self.FailedTestp(line):
+                self.result = 'Failed'
+            elif self.ErroredTestp(line):
+                self.result = 'Errored'
+            else:
+                self.result = 'Passed'
+        return self.result
+
+    def Failedp(self):
+        return self.GetResult() == 'Failed'
+
+    def Erroredp(self):
+        return self.GetResult() == 'Errored'
+    
+    def Passedp(self):
+        return self.GetResult() == 'Passed'
+    
+    def GetName(self):
+        if self.name == None:
+            try:
+                self.name = self.ParseName()
+            except RTestNameMissing, x:
+                print >> sys.stderr, "WARNING: ", x
+                self.name = "RTEST @ line %d" % (x.GetRTest().GetLineNumber(0))
+        return self.name
+
+    def ParseName(self):
+        line = self.lineTimeInfoList[-1].GetLine()
+        m = re.match(nameRTestPattern, line)
+        if m != None:
+            return m.group(1)
+        else:
+            raise RTestNameMissing(self, line)
+
+    def GetLineNumber(self, i):
+        return self.startLine + i
+
+    def GetLine(self, index):
+        return self.lineTimeInfoList[index].GetLine()
+
+    def ErrorContext(self):
+        if self.Failedp():
+            return map(qemuruntest.LineTimeInfo.GetLine, self.lineTimeInfoList[-5:-1])
+        else:
+            return []
+        
+    
+class RTestParser(object):
+    def __init__(self, testRunner, lineTimeInfoList = None):
+        self.testRunner = testRunner
+        if lineTimeInfoList == None:
+            self.lineTimeInfoList = testRunner.GetResults()
+        else:
+            self.lineTimeInfoList = lineTimeInfoList
+        self.rtestList = []
+        self.result = None
+        
+    def Parse(self):
+        index = 0
+        end = len(self.lineTimeInfoList)
+        self.rtestList = []
+        testSuiteComplete = False
+        testErroredp = False
+
+        # find first test
+        while index < end:
+            lineTimeInfo = self.lineTimeInfoList[index]
+            index += 1;
+            line = lineTimeInfo.GetLine()
+            if self.StartOfTestp(line):
+                break
+            if self.ErroredTestp(line):
+                self.rtestList.append(RTest(self, lineTimeInfo, index-1))
+        else:
+            raise NoRTestsFound(self)
+
+        try:
+            while index < end:
+                # NB making startLine index means that line number are based at 1 rather than 0
+                rtest = RTest(self, lineTimeInfo, startLine = index)
+                self.rtestList.append(rtest)
+                index = rtest.Consume(self.lineTimeInfoList, index)
+
+                if self.TestSuiteEnding(self.lineTimeInfoList[index].GetLine()):
+                    testSuiteComplete = True
+                    break
+
+                while index < end:
+                    lineTimeInfo = self.lineTimeInfoList[index]
+                    index += 1;
+                    line = lineTimeInfo.GetLine()
+                    if self.StartOfTestp(line):
+                        break
+                    if self.ErroredTestp(line):
+                        self.rtestList.append(RTest(self, lineTimeInfo, startLine = index))
+        except RTestEndMissing, x:
+            print >> sys.stderr, "WARNING: ", x
+        return testSuiteComplete
+    
+    def StartOfTestp(self,line):
+        if re.match(startRTestPattern, line) != None:
+            return True
+        if re.match(bmSuiteFailurePattern, line) != None:
+            return True
+        return False
+
+    def ErroredTestp(self,line):
+        if re.match(erroredRTestPattern, line) != None:
+            return True
+        
+    def TestSuiteEnding(self,line):
+        return re.match(testSuiteEndingPattern, line) != None
+
+    def GetRTests(self):
+        return self.rtestList
+
+    def GetLine(self,index):
+        return self.lineTimeInfoList[index]
+    
+    def GetRomName(self):
+        return self.testRunner.GetRomName()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/e32test-driver/rtestreport.py	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,78 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 Lesser General Public License for more details.
+# 
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# A simple report generator for the results of running an RTest testsuite.
+#
+
+import sys
+import qemuruntest
+import rtest
+
+class RTestReport(object):
+    def __init__(self, testRunner, reportFileRoot = None):
+        self.testRunner = testRunner
+        self.reportFileRoot = reportFileRoot
+
+    def SummariseErrors(self, file = sys.stdout ):
+        print >> file, "%d errors were detected while running rom %s :" % (len(self.erroredTests), self.parser.GetRomName())
+        for e in self.erroredTests:
+            print >> file, e.GetName()
+        print >> file, "\n"
+
+    def SummariseFailures(self, file = sys.stdout ):
+        print >> file, "%d failures were detected while running rom %s :" % (len(self.failedTests), self.parser.GetRomName())
+        for e in self.failedTests:
+            print >> file, e.GetName()
+            for l in e.ErrorContext():
+                print >> file, "\t%s" %(l)
+        print >> file, "\n"
+
+    def SummarisePassed(self, file = sys.stdout ):
+        print >> file, "The following %d tests passed while running rom %s (times are approximate):" % (len(self.passedTests), self.parser.GetRomName())
+        for e in self.passedTests:
+            print >> file, e.GetName(), " : ", e.GetTimeTaken(), "seconds"
+        print >> file, "\n"
+        
+    def OpenReportFile(self):
+        name = self.reportFileRoot
+        if not name:
+            name = self.testRunner.GetReportFileName()
+        return open(name, 'w')
+
+    def GetReportFileName(self):
+        return self.reportFileName
+    
+    def PrepareReport(self):
+        self.parser = rtest.RTestParser(self.testRunner)
+        try:
+            self.parser.Parse()
+        except rtest.NoRTestsFound, x:
+            print x
+            sys.exit(1)
+        self.failedTests = filter(rtest.RTest.Failedp, self.parser.GetRTests())
+        self.erroredTests = filter(rtest.RTest.Erroredp, self.parser.GetRTests())
+        self.passedTests = filter(rtest.RTest.Passedp, self.parser.GetRTests())
+
+    def WriteReport(self, file = sys.stdout):
+        self.PrepareReport()
+        print >> file, self.testRunner.GetSummary()
+        self.SummariseErrors(file)
+        self.SummariseFailures(file)
+        self.SummarisePassed(file)
+        return 0
+        
+        
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/e32test-driver/runtests.py	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,99 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 Lesser General Public License for more details.
+# 
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Provides 'ui' for running RTests on target and generating a report of the results.
+# Uses qemuruntest to run the tests and rtestreport to generate the results.
+
+import glob
+import sys
+import os.path
+
+from optparse import OptionParser
+
+import qemuruntest
+import rtestreport
+
+def ParseOptions():
+    optParser = OptionParser()
+    optParser.add_option("-b", "--board", action="store", type="string", default="syborg")
+    optParser.add_option("-c", "--cpu", action="store", type="string", default="cortex-a8")
+    optParser.add_option("-d", "--display", action="store_true", dest="displayp")
+    optParser.add_option("-i", "--input", action="store", type="string")
+    optParser.add_option("-o", "--output", action="store", type="string")
+    optParser.add_option("-q", "--qemu", action="store", type="string", dest="qemupath", default="qemu-system-arm.exe")
+    optParser.add_option("-r", "--rom", action="store", type="string", default="syborg.e32test.a8.urel.elf")
+    optParser.add_option("-s", "--summary", action="store", type="string")
+
+    return optParser.parse_args()
+
+def main():
+    errors = False
+    (options, args) = ParseOptions()
+
+    if  not options.input:
+        gl = glob.glob(options.qemupath)
+        if len(gl) == 0:
+            gl = glob.glob(options.qemupath + ".exe")
+
+        if len(gl) == 0:
+            print >> sys.stderr, "ERROR: can't find qemu executable %s" % (options.qemupath)
+            errors = True
+        else:
+            qemupath = gl[0]
+
+        gl = glob.glob(options.rom)
+        if len(gl) == 0:
+            print >> sys.stderr, "ERROR: can't find ROM image %s" % (options.rom)
+            errors = True
+        else:
+            rompath = gl[0]
+
+        if errors:
+            sys.exit(1)
+
+        output = options.output
+        if output == None:
+            output = rompath
+
+        runner = qemuruntest.QemuTestRunner(qemupath, options.cpu, rompath, board = options.board, displayp = options.displayp, dataFile = output)
+        runner.Run()
+    else:
+        gl = glob.glob(options.input)
+        if len(gl) == 0:
+            print >> sys.stderr, "ERROR: can't find input file %s" % (options.input)
+            sys.exit(1)
+
+        input = gl[0]
+        runner = qemuruntest.PseudoRunner(input)
+        
+    testReporter = rtestreport.RTestReport(runner, reportFileRoot = options.summary)
+    reportFile = False
+    status = 1
+    try:
+        reportFile = testReporter.OpenReportFile()
+        status = testReporter.WriteReport(reportFile)
+    except Exception, x:
+        print >> sys.stderr, x
+        status = 1
+        if reportFile:
+            reportFile.close()
+
+    return status
+        
+    
+if __name__ == "__main__":
+    main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/e32test-driver/setup.py	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,23 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 Lesser General Public License for more details.
+# 
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Script for 'compiling' runtests app into a distributable collection of files for windoze using py2exe
+
+from distutils.core import setup
+import py2exe
+
+setup(console=['runtests.py'])
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/e32test-driver/watchdog.py	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 Lesser General Public License for more details.
+# 
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# Implements a 'simple' watchdog built on top of the Timer class from
+# the Threading module.
+# After a specified interval a WatchDog will invoke a specified function.
+# At any point the WatchDog can be Reset, which means the countdown will start from scratch.
+# WatchDogs can also be Started and Stopped.
+# NB the WatchDog has no idea what the function it invokes will do.
+
+import threading
+
+class WatchDog(object):
+    def __init__(self, interval, function):
+        self.interval = interval
+        self.function = function
+        self.Watcher()
+
+    def Watcher(self):
+        self.timerThread = threading.Timer(self.interval, self.function)
+
+    def Start(self):
+        self.timerThread.start()
+
+    def Stop(self):
+        self.timerThread.cancel()
+        
+    def Reset(self):
+        self.Stop()
+        self.Watcher()
+        self.Start()
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/README.txt	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,15 @@
+The ELF4ROM command line tool and libraries. This tool is used to convert Symbian ROM images
+into debuggable elf files. See docs/wiki/ELF4ROM.doc for more information.
+
+ELF4ROM depends on the following libraries;
+
+* boost/program_options
+* boost/regex
+* boost/filesystem
+* libelf
+* libdwarf
+
+Supported libelf and libdwarf can be found in the libs/ folder
+Boost can be downloaded and built from http://www.boost.org/
+
+On windows please use mingw or cygwin to build.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/COPYING	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,31 @@
+
+David Anderson: December 2006
+The code in the dwarfdump directory is (if you look
+in each file) covered by the GPL (not the LGPL).  The
+DWARFDUMPCOPYRIGHT file, though, said (before December 24,
+2006) the copyright is LGPL.  There is no doubt in my (David
+Anderson) mind that the intent was always that dwarfdump be
+GPL and the copyright markings in each file are correct.
+
+There are three files marked with the LGPL: tag_tree.list
+tag_attr.list acconfig.h.  These markings are left as is and
+these are are therefore LGPL files.
+
+The DWARFDUMPCOPYRIGHT file now (Dec 24 2006) has both
+copyrights and an explanation of where each applies.
+
+
+
+-------------------------------------------
+The text present for years, thru Dec 23, 2006:
+The files:
+	dwarfdump.c
+	and all the .h and .c files in this implementation of
+	dwarfdump are copyrighted according to the file
+	DWARFDUMPCOPYRIGHT.   
+
+
+
+$Source: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/COPYING,v $
+$Revision: 1.1 $
+$Date: 2001/01/16 17:47:55 $
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/ChangeLog	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,108 @@
+2007-12-09 DavidAnderson <davea42@earthlink.net>
+     * print_sections.c print_frames.c: Forgot to commit yesterday. 
+       yesterday's commit includes renaming _dwarf_fde_section_offset
+       _dwarf_cie_section_offset, _dwarf_print_lines, _dwarf_ld_sort_lines
+       to dwarf_* form while retaining support for the now obsolete
+       _dwarf_* form.
+2007-12-08 DavidAnderson <davea42@earthlink.net>
+     * config.h.in, configure.in: Latest linux libelf.h requires
+       _GNU_SOURCE to get off64_t defined so dwarfdump compiles.
+       Only define _GNU_SOURCE  if libelf.h defines off64_t.
+       Regenerated configure.
+     * config.guess, config.sub: Updated to 2.61
+     * acconfig.h: Deleted, removing autoconf complaint.
+2007-10-15 DavidAnderson <davea42@earthlink.net>
+     * print_die.c (clean_up_die_esb): New function
+       cleans up malloc space.
+     * print_reloc.c (clean_up_syms_malloc_data): New function
+       cleans up malloc space.
+     * dwarfdump.c (main): Call new cleanup functions at end.
+     * globals.h: Declare new cleanup functions.
+
+2007-09-04 DavidAnderson <davea42@earthlink.net>
+     * print_die.c (print_attribute): For DWARF4: DW_AT_high_pc:
+       add qualifier to value when the value is an offset from
+       DW_AT_low_pc (thus not itself a address).
+       Update the address of the FSF.
+     * print_frames.h DWARFDUMPCOPYRIGHT print_sections.c
+       print_reloc.c dwarfdump.c tag_tree.c tag_attr.c
+       esb.c esb.h makename.c acconfig.h dwconf.c makename.h
+       dwconf.h globals.h print_frames.c:
+       Update the address of the FSF.
+
+2007-07-03 DavidAnderson <davea42@earthlink.net>
+     * print_sections.c (dump_block): Removed superfluous return byte from
+       printed characters. Removed unused variables.
+     * print_die.c: A little refactoring for clarity.
+     * globals.h: dwarfdump_print_one_locdesc() is now a 
+       global-to-dwarfdump function.
+     * print_frames.c: Now (with -v) prints dwarf expression bytes
+       in frame expressions readably.
+2007-07-02 DavidAnderson <davea42@earthlink.net>
+     * dwarfdump.c: Add new -R option for 'generic' register sets.
+     * dwarfdump.1: document -R, add new -x documentation.
+     * dwconf.c: Set up -R configuration. Slight revision of
+       register printing code.
+     * dwconf.h: Interface to register name printing simplified.
+     * print_frames.c: Use the simpler register name interface.
+     * dwarfdump.conf: Add new 'generic' abi for up to 1000 registers.
+
+2007-07-01 DavidAnderson <davea42@earthlink.net>
+     * print_frames.c: For DW_CFA_def_cfa_sf & DW_CFA_def_cfa_offset_sf 
+       print a computed data alignment factor.
+2007-06-29 DavidAnderson <davea42@earthlink.net>
+     * dwarfdump.1: Corrected spelling error.
+2007-05-25 DavidAnderson <davea42@earthlink.net>
+     * dwconf.h dwconf.c: Changed field name to 
+       cf_named_regs_table_size as old name was less than clear.
+     * dwarfdump.c: Call frame table setup with
+       cf_table_entry_count not cf_named_regs_table_size. The newly
+       renamed field makes it clearer the call was wrong.
+2007-05-04 DavidAnderson <davea42@earthlink.net>
+     * print_die.c: printing of global offset of DIEs 
+       with -G is now more in the style of previous output.
+2007-04-18 Chris Quenelle <chris.quenelle@sun.com>
+     * Makefile.in:
+          - use $(srcdir) for files in source directory
+          - support running rules in parallel by
+          - use different tmp file names in different rules.
+          - use more accurate target for dwarf_names.{c,h}
+     * dwarf_names.awk: Enhance script to be able to generate either
+       #define-style headers or enum-style headers
+     * dwarfdump.c: dump most everything by default if no arguments
+       are given to dwarfdump.  This seems to be a more useful default
+       than showing nothing at all.  Also add a -G option to show
+       the (G)lobal section offset for each die within an a.out. If you
+       think you're seeing data corruption inside a .debug_info
+       section, this is a useful option to have.
+     * print_die.c: Support compressed integer blocks.  This is an
+       array (DW_FORM_block) of LEB numbers used as part of a Sun
+       extension, DW_AT_SUN_func_offsets.  Also add support for
+       a new dwarf enum DW_ATCF_xxxx. This is used in DW_AT_SUN_cf_kind.
+       Also, fix DW_AT_upper_bound so it can be a constant or a location
+       list.  DW_AT_count and DW_AT_data_member_location should also be
+       fixed eventually.
+     * print_sections.c: Changes to support zero-padding in the middle of
+       section data.  Change offset labels to be a little more clear.
+       Not sure about the get_str failure.
+     * tag_tree.list: DW_TAG_compile_unit can contain a DW_TAG_namespace
+2007-04-10 David Anderson <davea42@earthlink.net>
+     * print_reloc.c dwarfdump.c print_frames.c: Unified
+       copyright to the SGI form.  No copyright change.
+
+2007-04-06 David Anderson <davea42@earthlink.net>
+     * print_die.c (print_die_and_children): Increase static
+       depth of die stack.  Notice if it overflows and
+       print error.
+2007-02-23 David Anderson <davea42@earthlink.net>
+     * print_reloc.c: 2 lines added (long) cast in printf
+       and made %3ld instead of %3d to fix compiler warning.
+     * print_frames.c:  newline was missing from the output.
+       Thanks to Chris Quenelle for noticing.
+2007-02-20 David Anderson <davea42@earthlink.net>
+     * print_frame.c (print_frame_inst_bytes): Fixed
+       an off by one error  (several places)
+       when printing dwarf expressions and added commentary about it.
+       Thanks to Julian Seward for pointing out it was off by one.
+     * dwarfdump.c (print_error): added fflush of stdout, stderr
+       where we are going to exit right away anyway.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/ChangeLog2006	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,332 @@
+2006-12-24 David Anderson <davea@sgi.com>
+     * DWARFDUMPCOPYRIGHT: Added GPL copyright text with
+       explanation of the intended content.
+     * COPYING: added text explaining confusion of GPL vs LGPL.
+       Thanks to Chris Quenelle for pointing out the disconnect
+       between DWARFDUMPCOPYRIGHT and the source files in dwarfdump.
+2006-12-21 David Anderson <davea@sgi.com>
+     * tag_tree.list: add tags to make allowed list more complete.
+       Omission noticed by Marcel Mettes.
+2006-06-14 David Anderson <davea@sgi.com>
+     * print_frames.c: Clean up printing of augmentation data  by
+       eliminating dangling 0x (for eh_frame).
+2006-04-28 David Anderson <davea@sgi.com>
+     * dwarfdump.conf: Now has x86_64 register names.
+       x86_64 with help from Tom Hughes (verified
+       from independent sources). 
+       Added m68k register names and refined  x86 list
+       by looking at various information-sources.
+2006-04-18 David Anderson <davea@sgi.com>
+     * *.c: Ran indent so all now follow a standard look.
+     * dwconf.c: Added fclose(conf_stream).
+2006-04-18 David Anderson <davea@sgi.com>
+     * dwarfdump.c: Forgot to call key new functions for
+       handling variable-size frame data and different 
+       frame rule initialization value.
+     * dwconf.c: Add a default print for CFA in case of
+       an omission in dwarfdump.conf. 
+     * dwarfdump.conf: Move setup and rename the ABIs slightly.
+2006-04-17 David Anderson <davea@sgi.com>
+     * dwarfdump.conf: Correct typos. Remove some register names.
+     * dwarfdump.c: Fix compiler warnings, fix -x option usage message.
+     * dwconf.h: Fix compiler warnings by changing types.
+     * dwconf.c: Change error checking so we check all errors, do
+       not stop at first error. Ran indent.  Added code to check
+       for extra junk after operand(s).
+     * print_frames.c: Fix compiler warnings.
+     * Makefile.in: get <prefix> used in install rule and creating
+       places to search for dwarfdump.conf
+2006-04-16 David Anderson <davea@sgi.com>
+     * dwarfdump.conf: New dwarfdump configuration file. Makes using frame
+           information easy to read and correct for any ABI/ISA
+           without rebuilding dwarfdump.
+     * Makefile.in: Added new files dwconf.h dwconf.c
+     * dwconf.h dwconf.c: New files implement reading dwarfdump.conf
+       and help print_frames.c print frame information correctly
+       for ABIs specified at runtime.
+     * dwarfdump.1: document -x commands.
+     * globals.h: Minor changes to support dwarfdump.conf
+     * print_frames.c: Major changes to support a run-time description of 
+       the frames info and dwarfdump.conf.
+     * print_frames.h: Changes  to support a run-time description of 
+       the frames info and dwarfdump.conf.
+     * print_sections.c: Minor tweaks to support a run-time 
+       description of the frames info and dwarfdump.conf.
+
+2006-03-31 David Anderson <davea@sgi.com>
+     * Makefile.in globals.h print_sections.c: Refer to new
+       print_frames.h print_frames.c.
+     * print_frames.h print_frames.c: Extract cie, fde printing
+       to separate file, separating loop logic from the printing
+       of an entry from the loop.
+2006-03-31 David Anderson <davea@sgi.com>
+     * dwarfdump.c global.h print_sections.c: Preparing for 
+       dwarf3 frame interface.
+     * print_die.c: Corrects handling of DW_AT_encoding (etc) value.
+2006-03-29 David Anderson <davea@sgi.com>
+     * print_sections.c: define DWARFDUMP_TURN_OFF_MIPS_REG_NAMES 
+       at compile time
+       to turn off the MIPS register names printing.  Instead
+       (aside from cfa) use a name like  r4 (where the DWARF 
+       register number follows the letter 'r').
+       Indent. Initialize some local variables at declarations.
+2006-03-13 David Anderson <davea@sgi.com>
+     * print_sections.c: Now gets gnu eh_augmentation data by calling
+       dwarf_get_cie_augmentation_data() or dwarf_get_fde_augmentation_data()
+       and prints it (use -v to see cie data).
+       Now prints DWARF3 frame information.
+2006-03-08 David Anderson <davea@sgi.com>
+     * print_sections.c: Add 'break;' at line 710.
+       Thanks to Richard Stuckey for noticing.
+2005-12-01 David Anderson <davea@sgi.com>
+     * dwarf_names.awk: use snprintf instead of sprintf for safety.
+2005-12-01 David Anderson <davea@sgi.com>
+     * Makefile.in: Build attr/tag trees with
+       individual commands to catch build errors.
+     * tag_attr.c,tag_tree.c: Verify that
+       tables fit in the generated C code and check for 
+       format errors in the *.list files.
+     * tag_attr.list, tag_tree.list: Added some valid entries. 
+     * globals.h: add DWARF_ERROR3 macro for better diagnostics.
+     * print_die.c: Show both sides of questionable tag relation
+       in CHECK  -k diagnostic output.
+
+2005-11-25 David Anderson <davea@sgi.com>
+     * print_die.c: DW_AT_stride_size changed to DW_AT_bit_stride,
+                    added DW_AT_byte_stride.
+     * tag_attr.c,tag_tree.c: fixed array size now a #define for
+	readability.
+     * tag_attr.list: Added DWARF3  attributes, also new TAGs.
+     * tag_tree.list: Added DWARF3 TAGs.
+
+2005-11-08 David Anderson <davea@sgi.com>
+      * makename.c: remove non-standard malloc.h include,
+        stdlib.h suffices and is already included.
+
+2005-10-24 David Anderson <davea@sgi.com>
+      * tag_attr.c tag_tree.c: added DWARF3 TAGs to string array.
+
+2005-08-01 David Anderson <davea@sgi.com>
+      * Makefile.in: Add esb.o and test rule (test code for esb.c).
+      * dwarfdump.c:  Remove old static buffer initialization.
+      * print_die.c: Use esb now, avoid crash due to long loclist
+        overrunning static buffer. Uses snprintf now, not sprintf.
+        snprintf is for safety.
+      * esb.h esb.c: Adding extensible string buffer (esb) code.
+      * testesb.c: Test code for esb.c.
+      * print_reloc.c: size field is now Elf64_Xword for 
+        Elf64  as Elf64_Word is only 32 bits.
+
+2005-07-15 David Anderson <davea@sgi.com>
+      * dwarfdump.c: Add print of .debug_pubtypes, remove
+        erroneous dealloc after dwarf_formstring() call.
+      * globals.h: Add declarations for .debug_pubtypes print.  Add
+        declaration for full dealloc.
+      * print_die.c: Remove erroneous dealloc after dwarf_formstring() call.
+      * print_exception_tables.c: Call dwarf_fde_cie_list_dealloc()
+        for complete dealloc.
+      * print_sections.c: Remove incorrect dealloc() call.
+        Add calls to new dealloc routines. Add support of .debug_pubtypes
+        print.
+2005-07-14 David Anderson <davea@sgi.com>
+      * print_sections.c (print_line_numbers_this_cu): Use new
+        dwarf_srclines_dealloc() for deallocation after
+        dwarf_srclines() called.
+
+2005-04-13 David Anderson <davea@sgi.com>
+      * print_sections.c: Factors out common print code into
+        a new routine. Avoid indexing past end of register names
+        array.  Adds checks and prints so that certain errors
+        in pubnames-like sections are printed usefully (and dwarfdump
+        then stops if libdwarf gave an error).
+        
+2005-03-21 David Anderson <davea@sgi.com>
+      * dwarfdump.c: Add -F flag to
+        request .eh_frame section print. Changed -f flag meaning
+        to print .debug_frame only. -a flag no longer
+	prints .debug_frame by default.
+      * print_sections.c: avoid printing an eh_frame we don't understand.
+	Add new information per CU when printing line info: specifically
+        the line section offset.  
+      * globals.h: Added arguments to print_frames() for -F flag.
+
+2005-03-18 David Anderson <davea@sgi.com>
+      * print_sections.c: Correct macro section printing.
+
+2004-10-28 David Anderson <davea@sgi.com>
+      * DWARFDUMPCOPYRIGHT config.h defs.h dwarfdump.c globals.h
+	makename.c makename.h print_die.c print_exception_tables.c 
+	print_reloc.c print_sections.c tag_attr.c tag_attr.list
+	tag_tree.c tag_tree.list: Copyright update, SGI
+        corporate address change.
+
+2004-10-26 David Anderson <davea@sgi.com>
+      * acconfig.h: removed. Was old style autoconf usage.
+      * configure.in: Updated AC_DEFINE usage, adding args 2 & 3.
+      * config.guess: Updated. timestamp='2004-06-11'.
+      * config.sub: Updated.  timestamp='2004-03-12'.
+      * configure config.h.in: regenerated with autoconf 2.58.
+
+2004-05-14 David Anderson <davea@sgi.com>
+
+      * print_die.c (print_die_and_children): Change to iteration
+        on siblings (still recursing on children).
+
+	
+2004-03-30 David Anderson <davea@sgi.com>
+      * dwarfdump.c (main): getopt() string should contain k:g
+        not kg:    Thanks to Peter Seiderer for pointing this out.
+
+2003-12-31 David Anderson <davea@sgi.com>
+      * README: Added configure example.
+      * Makefile.in: Removed bogus LIBS line, updated copyright date.
+      * acconfig.h: Added LGPL copyright to match libdwarf
+	Silly, but it matches libdwarf version boilerplate.
+      * config.guess config.sub: new versions from automake-1.6.
+      * config.h.in configure: Regenerated.
+
+
+2003-10-06   David Anderson <davea@sgi.com>
+     * dwarfdump.c print_sections.c: applied indent(1).
+     * print_die.c: applied indent and added ; after
+       invocations of macros PUSH_DIE_STACK POP_DIE_STACK SPACE
+       as these were confusing indent a bit.
+       The indent control file .indent.pro contained:
+  	-bad -bap -nbbo -br -ce -brs
+  	-l72  -lc72  -hnl  -nprs
+  	-fca -i4  -lp -psl -npcs 
+        
+
+
+2003-10-02   David Anderson <davea@sgi.com>
+     * dwarfdump.c: Add -g to indicate use of older 
+       location entry code in libdwarf.  So dwarf_loclist 
+       and dwarf_loclist_n are testable.
+     * globals.h: Added use_old_dwarf_loclist flag so one
+       can choose the old dwarf_loclist() interface.
+       For testing.
+     * print_die.c: Rearranged to avoid code duplication.
+       Now supports .debug_loc fully.
+     * print_sections.c: Prints .debug_loc now.
+
+2003-09-29   David Anderson <davea@sgi.com>
+
+      * print_die.c: with -v, print 'loclist' start and
+	end addr and also a hint that DW_FORM_indirect is used.
+        No change for normal output (for now).
+
+2003-05-19   David Anderson <davea@sgi.com>
+      * dwarfdump.c call dwarf_srcfiles() to get file names
+        per cu and pass down to die print routines.
+	Removed incorrect tests for when to print ".debug_info",
+	leaving simpler test.
+      * print_die.c globals.h: print file name (from line info)
+	with DW_AT_decl_file, adding data from dwarf_srcfiles
+	to argument list of a few routines to make that possible. 
+      * print_sections.c: moved "line number info" string print so
+	it prints for -v as well as normal  line ouput.
+
+2002-10-23   Amaury Le Leyzour amaury@sgi.com
+      * print_sections.c (print_weaknames): Changed
+        DW_DLA_TYPENAME to DW_DLA_WEAK at dwarf_dealloc().
+
+2002-10-22  Tom Hughes <thh@cyberscience.com>
+      * print_sections.c: macro printing now supported.
+      * dwarfdump.c: removed erroneous dwarf_dealloc()
+        of string returned by dwarf_errmsg().
+ 
+2002-11-22  David Anderson <davea@sgi.com>
+      * dwarf_names.awk at_list.awk: Allow an name to have two 
+        spellings so the historical name preserved yet the dwarf3 
+        version is supported. First name seen is used/reported
+        by dwarfdump.
+      * dwarf.h:   DW_TAG_template_type_param(eter)
+        DW_TAG_template_value_param(eter) DW_AT_namelist_itm(s)   
+        are the ones with alternate spellings now.
+        Added Universal Parallel C TAGs/Attributes in
+	user namespace.
+      * tag_attr.c tag_attr.list tag_tree.c tag_tree.list:
+        Use the DW_TAG_template_* dwarf3 spellings.
+
+
+2002-05-08  David Anderson <davea@sgi.com>
+      * tag_attr.list dwarf.h: DW_AT_namelist_items is
+	wrong, changed to DW_AT_namelist_item
+
+2002-04-29  Stephen Clarke <stephen.clarke@superh.com>
+      * dwarfdump.c (main): #ifdef for __CYGWIN__ on open().
+
+2001-06-14  David Anderson <davea@sgi.com>
+
+      * print_sections.c: Calling the new libdwarf function
+	dwarf_get_arange_cu_header_offset() so we can print
+	the cu header offset for aranges.
+
+
+2000-07-14  Fred Fish  <fnf@ninemoons.com>
+ 
+      * configure.in (LOCATION_OF_LIBELFHEADER): Fix typo for configure
+      variable to be tested and enclose libelf/libelf.h in <>.
+      * configure: Regenerated.
+       
+2000-07-10  Fred Fish  <fnf@ninemoons.com>
+ 
+      * Makefile.in (install): Install dwarfdump.1 from $(srcdir).
+
+2000 June 12   davea@sgi.com
+  print_sections.c the DW_CFA_offset_extended print 
+	did not multiply by data-alignment factor in the
+	-v -v detailed output.
+	And the offsets used %2d when the values were
+	unsigned int, so now %2u.
+
+	And not all cfa prints of values had
+	necessarily a type to match
+	%llu or %lld where required. Depended on the size of Dwarf_Signed
+	and Dwarf_Unsigned.
+	So now explicitly use cast to the
+	right type to match the % format.
+2000 April 13 davea@sgi.com
+  print_sections.c - 1.56
+        - A single byte of zero is a perfectly legitmate null 
+          abbreviation entry          (in .debug_abbrev) 
+	 now we print those directly and avoid a warning
+          from dwarfdump
+
+  print_die.c - 1.42
+        - Explain what combo checker is doing and make it 
+	  more maintainable (and fix bug which would 
+	  not be hit, but was real enough (in combo checker),
+	  using too large a number as highest tag number).
+
+  tag_tree.list - 1.2
+        - Add valid parent/child relationships so checker 
+	  does not report valid entries as bogus.
+
+
+
+
+2000 Feb 24
+  Jason Merrill <jason@cygnus.com> noticed that gcc did
+  not like   gcc -E foo.list, so  incorporated his fix so
+  now the Makefile.in makes a link and does gcc -E _tmp.c
+
+2000 Jan 26
+  elena.demikhovsky@intel.com noticed that 3 statements in
+  print_sections.c got warnings from the compiler
+  she was using. Simple casts  (provided by her) fixed these.
+
+1999 July 21
+  davea@sgi.com 
+  print_sections changed to allow printing
+  of dwarf-ish egcs c++ .eh_frame data
+
+
+1999 June 14
+  Fred Fish fnf@ninemoons.com contributed
+  autoconf'ing of the libdwarf and dwarfdump source.  
+
+
+
+1999 June 10
+ ChangeLog started. davea@sgi.com  David Anderson
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/DWARFDUMPCOPYRIGHT	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,85 @@
+
+========The dwarfdump copyright=======
+
+The full text of the GPL version 2 is provided in the file GPL.txt.
+
+Nearly all the files in this directory have contained a GPL
+copyright, not an LGPL copyright, for years.  The following
+is an example of that copyright as used in the dwarfdump
+source, and is what SGI always intended (in David
+Anderson's opinion) to have present in
+the DWARFDUMPCOPYRIGHT file.  (tag_tree.list tag_attr.list
+acconfig.h have long been marked LGPL and therefore the LGPL
+copyright, not GPL, applies to those three files.)  This GPL
+copyright text added  here to DWARFDUMPCOPYRIGHT Dec 4, 2006
+
+  Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write the Free Software Foundation, Inc., 51
+  Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+The following was the entire content of this file before
+December 24 2006, Being the LGPL text this is in conflict
+with the individual source files and I (David Anderson)
+believe the source file copyright was intended for dwarfdump
+not the LGPL source directly following this note.  However the
+3 files tag_tree.list tag_attr.list acconfig.h have long been
+marked LGPL and the following copyright applies to those three.
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/GPL.txt	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,339 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program 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; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/Makefile.in	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,131 @@
+#
+#  Makefile for dwarfdump
+#  This is made very simple so it should work with
+#  any 'make'.
+
+#
+
+srcdir =	@srcdir@
+VPATH =		@srcdir@
+
+prefix =	@prefix@
+exec_prefix =	@exec_prefix@
+bindir =	$(exec_prefix)/bin
+libdir =	$(exec_prefix)/lib
+mandir = 	@mandir@
+man1dir =       $(mandir)/man1
+
+INSTALL =	@INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA =	@INSTALL_DATA@
+SHELL =		/bin/sh
+CC =		@CC@
+AR =		@AR@
+ARFLAGS =	@ARFLAGS@
+RM =		rm
+RANLIB =	@RANLIB@
+DEFS =		@DEFS@
+LIBS =		@LIBS@ -L../libdwarf -ldwarf -lelf
+INCLUDES =	-I. -I$(srcdir) -I$(srcdir)/../libdwarf
+CFLAGS =	@CFLAGS@ $(INCLUDES) -DCONFPREFIX=${libdir}
+LDFLAGS =	@LDFLAGS@  $(LIBS)
+
+# ../libdwarf gets us to local headers
+
+DIRINC =  $(srcdir)/../libdwarf
+INSTALL = cp
+
+binprefix =
+
+GEN_CFILES = \
+	dwarf_names.c
+
+OBJECTS =  tag_tree_table.o \
+	tag_attr_table.o \
+	dwarfdump.o \
+	dwconf.o \
+	esb.o \
+	print_sections.o \
+	print_die.o \
+	print_reloc.o \
+	print_frames.o \
+	dwarf_names.o \
+	makename.o 
+GEN_HFILES = \
+	dwarf_names.h    \
+	_tag_tree_table.c \
+	_tag_attr_table.c
+
+all: dwarfdump
+
+$(OBJECTS): $(GEN_HFILES) $(srcdir)/globals.h $(srcdir)/print_frames.h
+
+default: $(TARGETS)
+
+
+dwarfdump: $(OBJECTS)
+	$(CC) $(CFLAGS) -o $@ $(OBJECTS) $(LDFLAGS) 
+
+
+#at_list.i: at_list.awk $(DIRINC)/dwarf.h
+#	awk -f $(srcdir)/at_list.awk $(DIRINC)/dwarf.h > $@
+#at_list.o: at_list.i
+#	 $(CC) $(CFLAGS) -c at_list.i -o $@
+
+_tag_tree_table.c: $(srcdir)/tag_tree.list $(srcdir)/tag_tree.c $(DIRINC)/dwarf.h
+	$(CC) $(CFLAGS)  $(LDFLAGS) -o tag_tree_build $(srcdir)/tag_tree.c
+	# gcc -E tag_tree.list does not work, so use a .c name
+	rm -f _tmp1.c && ln -s $(srcdir)/tag_tree.list _tmp1.c
+	$(CC) $(CFLAGS) -E _tmp1.c \
+		| awk '!/^#/ && !/^[ \t]*$$/' > ./tag_tree_build.tmp
+	./tag_tree_build <tag_tree_build.tmp > $@
+	rm -f tag_tree_build .tmp
+	rm -f tag_tree_build
+tag_tree_table.o: _tag_tree_table.c
+	$(CC) $(CFLAGS) -c _tag_tree_table.c -o $@ 
+
+_tag_attr_table.c: $(srcdir)/tag_attr.list $(srcdir)/tag_attr.c $(DIRINC)/dwarf.h
+	$(CC) $(CFLAGS)  $(LDFLAGS) -o tag_attr_build $(srcdir)/tag_attr.c
+	# gcc -E tag_attr.list does not work, so use a .c name
+	rm -f _tmp2.c && ln -s $(srcdir)/tag_attr.list _tmp2.c
+	$(CC) $(CFLAGS)  -E _tmp2.c \
+		| awk '!/^#/ && !/^[ \t]*$$/' > ./tag_attr_build.tmp
+	./tag_attr_build <tag_attr_build.tmp > $@
+	rm -f tag_attr_build.tmp
+	rm -f tag_attr_build
+tag_attr_table.o: _tag_attr_table.c
+	$(CC) $(CFLAGS) -c _tag_attr_table.c -o $@ 
+
+# The file dwarf_names.awk generates BOTH dwarf_names.h and dwarf_names.c
+#   be careful of the make dependencies here
+dwarf_names.h: dwarf_names.awk $(DIRINC)/dwarf.h
+	rm -f dwarf_names.h dwarf_names.c
+	awk -f $(srcdir)/dwarf_names.awk $(DIRINC)/dwarf.h > dwarf_names.c
+dwarf_names.c: dwarf_names.h
+
+test: esb.o $(srcdir)/testesb.c
+	$(CC) -o test $(srcdir)/testesb.c esb.o
+	./test
+	-rm -f ./test
+
+
+install: all
+	$(INSTALL) dwarfdump $(bindir)/dwarfdump
+	$(INSTALL) $(srcdir)/dwarfdump.1 $(man1dir)/dwarfdump.1
+	$(INSTALL) $(srcdir)/dwarfdump.conf $(libdir)/dwarfdump.conf
+
+uninstall:
+	-rm -f $(bindir)/dwarfdump
+	-rm -f $(man1dir)/dwarfdump.1
+	-rm -f $(libdir)/dwarfdump.conf
+
+clean:
+	rm -f *.o dwarfdump dwarf_names.h *~ _tag_attr_table.c _tag_tree_table.c dwarf_names.c
+
+distclean: clean
+	rm -f config.log config.h config.cache config.status dwarf_names.c
+
+shar:
+	@echo "shar not set up yet"
+dist:
+	@echo "dist not set up yet"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/NEWS	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,111 @@
+December 8, 2007
+  Had to add an ugly configure conditional as libelf has
+  unconditional use of off64_t in recent libelf.h
+July 3, 2007
+  Now with -v dwarf expression blocks in frame operations
+  are printed expanded out.
+July 2, 2007
+  Added a new abi -x abi=general usable for any cpu with
+  up to 1000 registers.
+May 7, 2007
+  Sun Microsystems contributes new dwarf.h extensions and a new -G option
+  to dwarfdump -i (so one can see the 'global' offset to DIEs).
+  Thanks to Chris Quenelle of Sun.
+April 17, 2006
+  New -x name=<conf file> -x abi=<abiname> and configuration file
+  enable sensible printing of a wide range of .debug_frame eh_frame
+  correctly without recompiling dwarfdump or touching libdwarf.h or
+  dwarf.h.
+March 29, 2005
+  Now handles DWARF3. For non-MIPS objects, the list of register
+  names in print_sections.c is not appropriate, #define
+  DWARFDUMP_TURN_OFF_MIPS_REG_NAMES to turn off the MIPS names.
+December 1, 2005
+  Added new DWARF3 TAGs and ATtributes to the -k lists,
+  clarified the -k reporting, and made the build more robust
+  in the face of errors in the *.list relationship-spec-files.
+
+August 1, 2005
+  Now print_die.c deals with long loclists without a coredump.
+  Added esb.h esb.c (and testesb.c for testing) to encapsulate 
+  getting space for possibly-long strings.
+  Now print_die.c uses snprintf() not sprintf (hopefully this
+  will not inconvenience anyone, snprintf() has been available
+  on most systems for years now).
+  Altered print of location lists a little bit - for better appearance.
+
+July 15, 2005
+  Now completely frees all allocated memory. Various
+  routines were not calling dealloc() code and
+  new libdwarf dealloc routines are now used where those
+  are needed.
+
+  Now prints DWARF3 .debug_pubtypes section (with -a or -y).
+  The .debug_pubtypes section and  SGI-specific .debug_typenames
+  are equvalent so they are treated alike.
+
+Mar 21, 2005
+  The -f flag now prints only .debug_frame data. The .eh_frame section
+  (GNU exceptions data) now prints with -F (not -a). 
+  Printing gcc 3.3 or 3.4 .eh_frame with zR augmentation
+  does not work at this time, so do not use -F
+  to print such an object.
+  The line section print now prints a CU-DIE offset for each such DIEs
+  line information.   This makes it much easier to correctly associate
+  -l (or -v -l) output with -v -v -l when debugging a faulty
+  linetable in an executable.
+  With -v -v -l (two -v) the output of line info continues to be a 
+  completely different format than zero or one -v, the two-v
+  form showing the detailed line table opcodes.
+  With g++ 3.3.3 one sees bad line addresses at times as the 
+  DW_LNE_set_address address for header files do not always 
+  get their relocations applied.  I am told this is fixed in 3.4.x.
+
+
+Mar 18, 2005
+  In correcting printing of macro information the format
+  of the macro (-m) output has changed substantially.
+  Much more complete now.  Still could use enhancement.
+
+Oct 28, 2004
+  Updated contact address in copyright: SGI moved 1/4 mile
+  to a new address: 1500 Crittenden Lane.
+
+Oct 02, 2003
+  Now fully supports .debug_loc section.
+
+June 14, 2001
+  Now calling a new function dwarf_get_arange_cu_header_offset()
+  in libdwarf and printing the returned cu header offset for 
+  aranges entries.   Making it easier to track down internal 
+  errors in the dwarf2 data.  Also added small other
+  consistency checks, printing a message and exit()ing on 
+  error.
+
+April 14, 2000
+  The libdwarf copyright has changed to
+     version 2.1 of the GNU Lesser General Public License.
+  Anyone holding a version of libdwarf that was published
+              before this new copyright
+  is allowed to use
+    the copyright published in that earlier libdwarf source
+    on the earlier source
+  or to use 
+    this new copyright on the earlier source,
+  at their option.
+
+July 21, 1999
+  Added gnu extensions to the frame information printer
+  and handling for egcs eh_frame printing.
+  libdwarf changes mean this now can print little-endian
+  object dwarf on a big-endian system and vice-versa.
+
+December, 1998
+  added dwarfdump to the dwarf public source distribution.
+
+June, 1994
+  libdwarf consumer interface changed completely so updated to match.
+
+May,  1993
+  Initial version of dwarfdump  for dwarf version 2
+  written at sgi.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/README	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,43 @@
+
+To build dwarfdump, first build libdwarf in the neighboring
+directory then type
+	./configure
+	make
+
+To use dwarf or libdwarf, you may want to install dwarf.h and
+libdwarf.h somewhere convenient, and you may need the libdwarf
+in the accompanying libdwarf directory
+
+If your headers or libelf/libdwarf are not in the expected places,
+use the configure script to access them (and to add other ld
+or C flags).
+For example, using csh syntax:
+	setenv PRIVATE_LIBDIR /home/davea/lib
+	./configure LDFLAGS="-L$PRIVATE_LIBDIR" \
+		CPPFLAGS="-I/home/davea/inc" CFLAGS="-I/home/davea/inc"
+Set both CFLAGS and CPPFLAGS so that configure works properly.
+
+If your primary target cpu architecture ( of objects that you are using
+dwarfdump on) is not MIPS, you will probably want to
+add   -DDWARFDUMP_TURN_OFF_MIPS_REG_NAMES=1
+to CPPFLAGS and CFLAGS  to avoid using misleading 
+register names.  See print_sections.c.
+
+
+If $PRIVATE_LIBDIR  has both libelf.so and libelf.a, the libelf.so
+will be picked up and 
+  "./tag_tree_build: error while loading shared libraries: 
+	libelf.so.0: cannot open shared object file: 
+	No such file or directory"
+will probably result.
+Either: remove libelf.so.* from your $PRIVATE_LIBDIR
+or set LD_LIBRARY_PATH to $PRIVATE_LIBDIR, or use LDFLAGS to
+set rpath.   Much simpler all around to ensure that $PRIVATE_LIBDIR
+only has archive libelf, not shared-library libelf.
+
+
+David Anderson.  davea@sgi.com
+
+$Source: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/README,v $
+$Revision: 1.3 $
+$Date: 2006/03/29 23:26:01 $
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/at_list.awk	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,22 @@
+# print code to return attribute name from list of attrs in dwarf.h (the input)
+# In case of a duplicate value, accept the first as definitive.
+# dwarf2 had a couple ambiguities/mistakes in attribute spelling.
+BEGIN {
+	printf "static int list_of_attrs[] = {\n"
+	used_pref["0"] = "";
+}
+{
+	prefix = "DW_AT_"
+	prefix_len = length(prefix)
+	if ($1 == "#define" && substr($2,1,prefix_len) == prefix) {
+		if ( used_pref[ $3] != $3 )  {
+		   printf "\t%s,\n", $2
+		   used_pref [$3] = $3 ;
+	        }
+	}
+}
+END {
+	printf "\t0\n"		# last value
+	printf "};\n"
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/config.guess	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1504 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
+#   Inc.
+
+timestamp='2006-11-15'
+
+# This file 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	case ${UNAME_MACHINE} in
+	    pc98)
+		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:windows32*:*)
+    	# uname -m includes "-pc" on this system.
+    	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    x86:Interix*:[3456]*)
+	echo i586-pc-interix${UNAME_RELEASE}
+	exit ;;
+    EM64T:Interix*:[3456]* | authenticamd:Interix*:[3456]*)
+	echo x86_64-unknown-interix${UNAME_RELEASE}
+	exit ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-gnu
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^CPU/{
+		s: ::g
+		p
+	    }'`"
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^CPU/{
+		s: ::g
+		p
+	    }'`"
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    or32:Linux:*:*)
+	echo or32-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-gnu
+	exit ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^LIBC/{
+		s: ::g
+		p
+	    }'`"
+	test x"${LIBC}" != x && {
+		echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+		exit
+	}
+	test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && { echo i486-ncr-sysv4; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+and
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/config.h.in	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,85 @@
+/* config.h.in.  Generated from configure.in by autoheader.  */
+
+/* Define to 1 if the elf64_getehdr function is in libelf.a. */
+#undef HAVE_ELF64_GETEHDR
+
+/* Define to 1 if the Elf64_Rel structure has r_info field. */
+#undef HAVE_ELF64_R_INFO
+
+/* Define to 1 if you have the <elf.h> header file. */
+#undef HAVE_ELF_H
+
+/* Define to 1 if you have the <getopt.h> header file. */
+#undef HAVE_GETOPT_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <libelf.h> header file. */
+#undef HAVE_LIBELF_H
+
+/* Define to 1 if you have the <libelf/libelf.h> header file. */
+#undef HAVE_LIBELF_LIBELF_H
+
+/* Define 1 if off64 is defined via libelf with GNU_SOURCE. */
+#undef HAVE_LIBELF_OFF64_OK
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define 1 if plain libelf builds. */
+#undef HAVE_RAW_LIBELF_OK
+
+/* Define to 1 if you have the <sgidefs.h> header file. */
+#undef HAVE_SGIDEFS_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* See if __uint32_t is predefined in the compiler. */
+#undef HAVE___UINT32_T
+
+/* Define 1 if sys/types.h defines __uint32_t. */
+#undef HAVE___UINT32_T_IN_SYS_TYPES_H
+
+/* See if __uint64_t is predefined in the compiler. */
+#undef HAVE___UINT64_T
+
+/* Define to header that first defines elf. */
+#undef LOCATION_OF_LIBELFHEADER
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/config.sub	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1619 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
+#   Inc.
+
+timestamp='2006-11-07'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | mcore \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| mt \
+	| msp430 \
+	| nios | nios2 \
+	| ns16k | ns32k \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu | strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nios-* | nios2-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16c)
+		basic_machine=cr16c-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+        score-*)
+		os=-elf
+		;;
+        spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+        c4x-* | tic4x-*)
+        	os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/configure	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,4694 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="dwarfdump.c"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA RANLIB ac_ct_RANLIB AR ac_ct_AR LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+	      localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$0" : 'X\(//\)[^/]' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+			  [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+			  [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+	   test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+	"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=$`echo $ac_var`
+	echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+	       sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+	ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+          ac_config_headers="$ac_config_headers config.h"
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+	;;
+    conftest.$ac_ext )
+	# This is the source file.
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	# FIXME: I believe we export ac_cv_exeext for Libtool,
+	# but it would be cool to find out if it's true.  Does anybody
+	# maintain Libtool? --akim.
+	export ac_cv_exeext
+	break;;
+    * )
+	break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  export ac_cv_exeext
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX 10.20 and later	-Ae
+# HP-UX older versions	-Aa -D_HPUX_SOURCE
+# SVR4			-Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+if test $ac_cv_c_compiler_gnu = yes; then
+    echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5
+echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6
+if test "${ac_cv_prog_gcc_traditional+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+    ac_pattern="Autoconf.*'x'"
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sgtty.h>
+Autoconf TIOCGETP
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "$ac_pattern" >/dev/null 2>&1; then
+  ac_cv_prog_gcc_traditional=yes
+else
+  ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+  if test $ac_cv_prog_gcc_traditional = no; then
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <termio.h>
+Autoconf TCGETA
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "$ac_pattern" >/dev/null 2>&1; then
+  ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+  fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5
+echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6
+  if test $ac_cv_prog_gcc_traditional = yes; then
+    CC="$CC -traditional"
+  fi
+fi
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	    break 3
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="${ac_tool_prefix}ar"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+  ac_ct_AR=$AR
+  # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="ar"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
+echo "${ECHO_T}$ac_ct_AR" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  AR=$ac_ct_AR
+else
+  AR="$ac_cv_prog_AR"
+fi
+
+
+
+/* Define to 1 if the elf64_getehdr function is in libelf.a */
+#undef HAVE_ELF64_GETEHDR
+
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+
+
+
+for ac_header in elf.h getopt.h libelf.h libelf/libelf.h sgidefs.h sys/types.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+echo "$as_me:$LINENO: checking for elf64_getehdr in -lelf" >&5
+echo $ECHO_N "checking for elf64_getehdr in -lelf... $ECHO_C" >&6
+if test "${ac_cv_lib_elf_elf64_getehdr+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lelf  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char elf64_getehdr ();
+int
+main ()
+{
+elf64_getehdr ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_elf_elf64_getehdr=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_elf_elf64_getehdr=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_elf_elf64_getehdr" >&5
+echo "${ECHO_T}$ac_cv_lib_elf_elf64_getehdr" >&6
+if test $ac_cv_lib_elf_elf64_getehdr = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ELF64_GETEHDR 1
+_ACEOF
+
+fi
+
+
+if test "$ac_cv_header_elf_h" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define LOCATION_OF_LIBELFHEADER <elf.h>
+_ACEOF
+
+elif test "$ac_cv_header_libelf_h" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define LOCATION_OF_LIBELFHEADER <libelf.h>
+_ACEOF
+
+elif test "$ac_cv_header_libelf_libelf_h" = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define LOCATION_OF_LIBELFHEADER <libelf/libelf.h>
+_ACEOF
+
+fi
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include LOCATION_OF_LIBELFHEADER
+int
+main ()
+{
+Elf64_Rel *p; int i; i = p->r_info;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ELF64_R_INFO 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+__uint32_t p; p = 3;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE___UINT32_T 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+__uint64_t p; p = 3;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE___UINT64_T 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+int
+main ()
+{
+  __uint32_t p; p = 3;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE___UINT32_T_IN_SYS_TYPES_H 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <libelf.h>
+
+int
+main ()
+{
+  int p; p = 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_RAW_LIBELF_OK 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#define _GNU_SOURCE
+#include <libelf.h>
+
+int
+main ()
+{
+  off64_t  p; p = 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBELF_OFF64_OK 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+
+          ac_config_files="$ac_config_files Makefile"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[	 ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[	 ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+	 sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+		   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+		   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@AR@,$AR,;t t
+s,@ac_ct_AR@,$ac_ct_AR,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+				     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([	 ]*\)#\([	 ]*define[	 ][	 ]*\)'
+ac_dB='[	 ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([	 ]*\)#\([	 ]*\)undef\([	 ][	 ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 # Do quote $f, to prevent DOS paths from being IFS'd.
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[	 ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*\)\(([^)]*)\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[	 ]*#[	 ]*undef[	 ][	 ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[	 ]*#[	 ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[	 ]*#[	 ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[	 ]*#[	 ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/configure.in	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,58 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(dwarfdump.c)
+AC_CONFIG_HEADER(config.h)
+
+AC_PROG_CC
+AC_GCC_TRADITIONAL
+AC_PROG_INSTALL
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(AR, ar)
+dnl AC_ARFLAGS
+
+
+/* Define to 1 if the elf64_getehdr function is in libelf.a */
+#undef HAVE_ELF64_GETEHDR
+
+
+
+AC_CHECK_HEADERS(elf.h getopt.h libelf.h libelf/libelf.h sgidefs.h sys/types.h)
+AC_CHECK_LIB(elf,elf64_getehdr,
+  AC_DEFINE(HAVE_ELF64_GETEHDR,1, 
+	[Define to 1 if the elf64_getehdr function is in libelf.a.]))
+
+dnl Find out where the elf header is.
+if test "$ac_cv_header_elf_h" = yes; then
+ AC_DEFINE(LOCATION_OF_LIBELFHEADER,[<elf.h>], [Define to header that first defines elf])
+elif test "$ac_cv_header_libelf_h" = yes; then
+ AC_DEFINE(LOCATION_OF_LIBELFHEADER, [<libelf.h>],
+	[Define to header that first defines elf.])
+elif test "$ac_cv_header_libelf_libelf_h" = yes; then
+ AC_DEFINE(LOCATION_OF_LIBELFHEADER,[<libelf/libelf.h>],
+	[Define to header that first defines elf.])
+fi
+
+AC_TRY_COMPILE([#include LOCATION_OF_LIBELFHEADER],  Elf64_Rel *p; int i; i = p->r_info; ,AC_DEFINE(HAVE_ELF64_R_INFO,1,
+	[Define to 1 if the Elf64_Rel structure has r_info field.]))
+AC_TRY_COMPILE([],  __uint32_t p; p = 3; ,AC_DEFINE(HAVE___UINT32_T,
+	1,[See if __uint32_t is predefined in the compiler.  ]))
+AC_TRY_COMPILE([],  __uint64_t p; p = 3; ,AC_DEFINE(HAVE___UINT64_T,
+	1,[See if __uint64_t is predefined in the compiler. ]))
+AC_TRY_COMPILE([#include <sys/types.h>],[  __uint32_t p; p = 3]; ,
+	AC_DEFINE(HAVE___UINT32_T_IN_SYS_TYPES_H,1,
+		[Define 1 if sys/types.h defines __uint32_t.]))
+
+AC_TRY_COMPILE([
+#include <libelf.h>
+],[  int p; p = 0; ] ,
+  AC_DEFINE(HAVE_RAW_LIBELF_OK,1,
+        [Define 1 if plain libelf builds.]))
+AC_TRY_COMPILE([
+#define _GNU_SOURCE
+#include <libelf.h>
+],[  off64_t  p; p = 0;] ,
+  AC_DEFINE(HAVE_LIBELF_OFF64_OK,1,
+        [Define 1 if  off64 is defined via libelf with GNU_SOURCE.]))
+
+
+
+AC_OUTPUT(Makefile)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwarfdump.1	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,144 @@
+.TH DWARFDUMP
+.SH NAME
+dwarfdump \- dumps DWARF debug information of an ELF object
+.SH SYNOPSIS
+.B dwarfdump
+[-abcdefilmoprsvy] [-t{afv}] [-u\f2objectfile\fP] \f2filename\fP
+.SH DESCRIPTION
+The 
+.B dwarfdump
+command prints DWARF sections as requested by specific options.
+With no options nothing prints!
+.PP
+The format is intended to be human readable.
+If a script is to parse the output, the
+.B \-d
+option is useful.
+.P
+Not all sections actually exist in any given object file.
+.P
+The format may change from release to release, so it is
+unwise to depend too heavily on the format.
+.P
+.PP
+Frame information (.debug_frame and .eh_frame) is heavily
+dependent on the ABI/ISA of the object file.  
+The '-R' option uses a built-in 'generic' register name set
+handling up to 1000 registers named r0-r999.
+The '-x abi=<abi>'
+flavors below describe how to name an abi and use that to guide
+the -f or -F processing.
+Without '-R' or '-x abi=<abi>'/ dwarfdump ignores
+the dwarfdump.conf file and uses compiled-in MIPS/IRIX 
+conventions).  
+If no '-x name=<path>' is given, dwarfdump
+looks for "./dwarfdump.conf", "$HOME/.dwarfdump.conf", "<install-prefix>/lib/dwarfdump.conf" and takes the first it finds.
+If one or more '-x name=<path>' is given the last of these is
+used and all other such files ignored.
+.PP
+The 
+.B dwarfdump
+command accepts one or more of the following options:
+.RS
+.TP
+.B \-a
+Dumps all sections.
+Same as 
+.B \-bcfilmoprsy
+.BR \-tfv .
+.TP
+.B \-b
+Dumps the .debug_abbrev section.  
+.TP
+.B \-c
+Dumps the .debug_loc section.
+.TP
+.B \-d
+Dense mode.  Each die information of the .debug_info section is 
+printed in one-line format.  This option does not imply \fB\-i\fP.  
+.TP
+.B \-e
+Ellipsis mode.  Short names for DW_TAG_* and DW_ATTR_* are used 
+in the output for the .debug_info section.  
+.TP
+.B \-f
+Dumps the .debug_frame section.
+.TP
+.B \-i
+Dumps the .debug_info section.
+.TP
+.B \-l
+Dumps the .debug_line information.  
+.TP
+.B \-m
+Dumps the .debug_macinfo section.
+.TP
+.B \-o
+Dumps the .reloc_debug_* sections.
+.TP
+.B \-p
+Dumps the .debug_pubnames section.
+.TP
+.B \-r
+Dumps the .debug_aranges section.
+.TP
+.B \-s
+Dumps .debug_string section.
+.TP
+.B \-ta
+Same as 
+.B \-tfv.
+.TP
+.B \-tf
+Dumps the .debug_static_funcs section.
+.TP
+.B \-tv
+Dumps the .debug_static_vars section.
+.TP
+.BI \-u ofile
+Restricts the dumping of sections to the named
+compilation unit.
+.TP
+.B \-v
+Verbose mode.  Shows more detailed information.  
+More detailed information about the .debug_frame section prints if
+2 or 3 
+.B \-v
+options are given.
+.TP
+.B \-w
+Dumps the .debug_weaknames section.
+.TP
+.B \-x abi=<conf>
+where abi=names an abi in dwarfdump.conf (see the
+abiname: command in dwarfdump.conf).
+.TP
+.B \-x name=<conf>
+where name=names the full pathname of a dwarfdump configuration
+file.  Default install location is /usr/local/lib/dwarfdump.conf.
+dwarfdump looks first for local ./dwarfdump.conf, then
+for $HOME/.dwarfdump.conf then  for  /usr/local/lib/dwarfdump.conf.
+The predefined abi names in dwarfdump.conf are
+generic, ia64,  m68k, x86, and x86_64.
+.TP
+.B \-y
+Dumps the .debug_types section.
+.SH FILES
+dwarfdump
+./dwarfdump.conf
+$(HOME)/.dwarfdump.conf
+<install-prefix>/lib/dwarfdump.conf
+.SH NOTES
+In some cases compilers use DW_FORM_data1 (for example)
+and in such cases the signedness of the value must be taken
+from context. Rather than attempt to determine the
+context, dwarfdump prints the value with both signednesses
+whenever there is ambiguity about the correct interpretation.
+For example, 
+"DW_AT_const_value           176(as signed = -80)".
+For normal DWARF consumers that correctly and fully
+evaluate all attributes there is no ambiguity of signedness:
+the ambiguity for dwarfdump is due to dwarfdump evaluating
+DIEs in a simple order and not keeping track of much context.
+.SH BUGS
+Support for DWARF3 is being completed but may not be complete.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwarfdump.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,763 @@
+/* 
+  Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
+  Portions Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+  
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write the Free Software Foundation, Inc., 51
+  Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/dwarfdump.c,v 1.48 2006/04/18 18:05:57 davea Exp $ */
+
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+#include "globals.h"
+
+/* for 'open' */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+
+#include "makename.h"
+#include "dwconf.h"
+extern char *optarg;
+
+#define OKAY 0
+#define FAILED 1
+#define BYTES_PER_INSTRUCTION 4
+
+static string process_args(int argc, char *argv[]);
+static void print_infos(Dwarf_Debug dbg);
+static void print_usage_message(void);
+
+static string program_name;
+int check_error = 0;
+
+/* defined in print_sections.c, die for the current compile unit, 
+   used in get_fde_proc_name() */
+extern Dwarf_Die current_cu_die_for_print_frames;
+
+
+boolean info_flag = FALSE;
+boolean use_old_dwarf_loclist = FALSE;	/* This so both dwarf_loclist() 
+					   and dwarf_loclist_n() can be
+					   tested. Defaults to new
+					   dwarf_loclist_n() */
+
+static boolean line_flag = FALSE;
+static boolean abbrev_flag = FALSE;
+static boolean frame_flag = FALSE;	/* .debug_frame section. */
+static boolean eh_frame_flag = FALSE;	/* GNU .eh_frame section. */
+static boolean pubnames_flag = FALSE;
+static boolean macinfo_flag = FALSE;
+static boolean loc_flag = FALSE;
+static boolean aranges_flag = FALSE;
+static boolean string_flag = FALSE;
+static boolean reloc_flag = FALSE;
+static boolean static_func_flag = FALSE;
+static boolean static_var_flag = FALSE;
+static boolean type_flag = FALSE;
+static boolean weakname_flag = FALSE;
+
+int verbose = 0;
+boolean dense = FALSE;
+boolean ellipsis = FALSE;
+boolean dst_format = FALSE;
+boolean show_global_offsets = FALSE;
+
+boolean check_abbrev_code = FALSE;
+boolean check_pubname_attr = FALSE;
+boolean check_reloc_offset = FALSE;
+boolean check_attr_tag = FALSE;
+boolean check_tag_tree = FALSE;
+boolean check_type_offset = FALSE;
+boolean generic_1000_regs = FALSE;
+
+static boolean dwarf_check = FALSE;
+
+/* These configure items are for the 
+   frame data.
+*/
+static char *config_file_path = 0;
+static char *config_file_abi = 0;
+static char *config_file_defaults[] = {
+    "./dwarfdump.conf",
+    /* Note: HOME location uses .dwarfdump.  */
+    "HOME/.dwarfdump.conf",
+#ifdef CONFPREFIX
+/* See Makefile.in  "libdir"  and CFLAGS  */
+/* We need 2 levels of macro to get the name turned into
+   the string we want. */
+#define STR2(s) # s
+#define STR(s)  STR2(s)
+    STR(CONFPREFIX)
+	"/dwarfdump.conf",
+#else
+    "/usr/lib/dwarfdump.conf",
+#endif
+    0
+};
+static struct dwconf_s config_file_data;
+
+char cu_name[BUFSIZ];
+boolean cu_name_flag = FALSE;
+Dwarf_Unsigned cu_offset = 0;
+
+Dwarf_Check_Result abbrev_code_result;
+Dwarf_Check_Result pubname_attr_result;
+Dwarf_Check_Result reloc_offset_result;
+Dwarf_Check_Result attr_tag_result;
+Dwarf_Check_Result tag_tree_result;
+Dwarf_Check_Result type_offset_result;
+
+Dwarf_Error err;
+
+#define PRINT_CHECK_RESULT(str,result)  {\
+    fprintf(stderr, "%-24s%8d%8d\n", str, result.checks, result.errors); \
+}
+
+static int process_one_file(Elf * elf, string file_name, int archive,
+			    struct dwconf_s *conf);
+static int
+open_a_file(string name)
+{
+    int f = 0;
+
+#ifdef __CYGWIN__
+    f = open(name, O_RDONLY | O_BINARY);
+#else
+    f = open(name, O_RDONLY);
+#endif
+    return f;
+
+}
+
+/*
+ * Iterate through dwarf and print all info.
+ */
+int
+main(int argc, char *argv[])
+{
+    string file_name;
+    int f;
+    Elf_Cmd cmd;
+    Elf *arf, *elf;
+    int archive = 0;
+
+    (void) elf_version(EV_NONE);
+    if (elf_version(EV_CURRENT) == EV_NONE) {
+	(void) fprintf(stderr, "dwarfdump: libelf.a out of date.\n");
+	exit(1);
+    }
+
+    file_name = process_args(argc, argv);
+    f = open_a_file(file_name);
+    if (f == -1) {
+	fprintf(stderr, "%s ERROR:  can't open %s\n", program_name,
+		file_name);
+	return (FAILED);
+    }
+
+    cmd = ELF_C_READ;
+    arf = elf_begin(f, cmd, (Elf *) 0);
+    if (elf_kind(arf) == ELF_K_AR) {
+	archive = 1;
+    }
+    while ((elf = elf_begin(f, cmd, arf)) != 0) {
+	Elf32_Ehdr *eh32;
+
+#ifdef HAVE_ELF64_GETEHDR
+	Elf64_Ehdr *eh64;
+#endif /* HAVE_ELF64_GETEHDR */
+	eh32 = elf32_getehdr(elf);
+	if (!eh32) {
+#ifdef HAVE_ELF64_GETEHDR
+	    /* not a 32-bit obj */
+	    eh64 = elf64_getehdr(elf);
+	    if (!eh64) {
+		/* not a 64-bit obj either! */
+		/* dwarfdump is quiet when not an object */
+	    } else {
+		process_one_file(elf, file_name, archive,
+				 &config_file_data);
+	    }
+#endif /* HAVE_ELF64_GETEHDR */
+	} else {
+	    process_one_file(elf, file_name, archive,
+			     &config_file_data);
+	}
+	cmd = elf_next(elf);
+	elf_end(elf);
+    }
+    elf_end(arf);
+    /* Trivial malloc space cleanup. */
+    clean_up_die_esb();
+    clean_up_syms_malloc_data();
+
+    if (check_error)
+	return FAILED;
+    else
+	return OKAY;
+}
+
+/*
+  Given a file which we know is an elf file, process
+  the dwarf data.
+
+*/
+static int
+process_one_file(Elf * elf, string file_name, int archive,
+		 struct dwconf_s *config_file_data)
+{
+    Dwarf_Debug dbg;
+    int dres;
+
+    dres = dwarf_elf_init(elf, DW_DLC_READ, NULL, NULL, &dbg, &err);
+    if (dres == DW_DLV_NO_ENTRY) {
+	printf("No DWARF information present in %s\n", file_name);
+	return 0;
+    }
+    if (dres != DW_DLV_OK) {
+	print_error(dbg, "dwarf_elf_init", dres, err);
+    }
+
+    if (archive) {
+	Elf_Arhdr *mem_header = elf_getarhdr(elf);
+
+	printf("\narchive member \t%s\n",
+	       mem_header ? mem_header->ar_name : "");
+    }
+    dwarf_set_frame_rule_inital_value(dbg,
+				      config_file_data->
+				      cf_initial_rule_value);
+    dwarf_set_frame_rule_table_size(dbg,
+				    config_file_data->
+				    cf_table_entry_count);
+
+    if (info_flag || line_flag || cu_name_flag)
+	print_infos(dbg);
+    if (pubnames_flag)
+	print_pubnames(dbg);
+    if (macinfo_flag)
+	print_macinfo(dbg);
+    if (loc_flag)
+	print_locs(dbg);
+    if (abbrev_flag)
+	print_abbrevs(dbg);
+    if (string_flag)
+	print_strings(dbg);
+    if (aranges_flag)
+	print_aranges(dbg);
+    if (frame_flag || eh_frame_flag) {
+	current_cu_die_for_print_frames = 0;
+	print_frames(dbg, frame_flag, eh_frame_flag, config_file_data);
+    }
+    if (static_func_flag)
+	print_static_funcs(dbg);
+    if (static_var_flag)
+	print_static_vars(dbg);
+    /* DWARF_PUBTYPES is the standard typenames dwarf section.
+       SGI_TYPENAME is the same concept but is SGI specific ( it was
+       defined 10 years before dwarf pubtypes). */
+
+    if (type_flag) {
+	print_types(dbg, DWARF_PUBTYPES);
+	print_types(dbg, SGI_TYPENAME);
+    }
+    if (weakname_flag)
+	print_weaknames(dbg);
+    if (reloc_flag)
+	print_relocinfo(dbg);
+    if (dwarf_check) {
+	fprintf(stderr, "DWARF CHECK RESULT\n");
+	fprintf(stderr, "<item>                  <checks><errors>\n");
+    }
+    if (check_pubname_attr)
+	PRINT_CHECK_RESULT("pubname_attr", pubname_attr_result)
+	    if (check_attr_tag)
+	    PRINT_CHECK_RESULT("attr_tag", attr_tag_result)
+		if (check_tag_tree)
+		PRINT_CHECK_RESULT("tag_tree", tag_tree_result)
+		    if (check_type_offset)
+		    PRINT_CHECK_RESULT("type_offset",
+				       type_offset_result)
+
+			dres = dwarf_finish(dbg, &err);
+    if (dres != DW_DLV_OK) {
+	print_error(dbg, "dwarf_finish", dres, err);
+    }
+    return 0;
+
+}
+
+static void do_all()
+{
+	info_flag = line_flag = frame_flag = abbrev_flag = TRUE;
+	pubnames_flag = aranges_flag = macinfo_flag = TRUE;
+	loc_flag = string_flag = TRUE;
+	reloc_flag = TRUE;
+	static_func_flag = static_var_flag = TRUE;
+	type_flag = weakname_flag = TRUE;
+}
+
+/* process arguments and return object filename */
+static string
+process_args(int argc, char *argv[])
+{
+    extern int optind;
+    int c = 0;
+    boolean usage_error = FALSE;
+    int oarg = 0;
+
+    program_name = argv[0];
+
+    /* j q unused */
+    if (argv[1] != NULL && argv[1][0] != '-') {
+		do_all();
+    }
+
+    while ((c =
+	    getopt(argc, argv,
+		   "abcdefFgGhik:lmoprRst:u:vVwx:yz")) != EOF) {
+	switch (c) {
+	case 'x':		/* Select abi/path to use */
+	    {
+		char *path = 0;
+		char *abi = 0;
+
+		/* -x name=<path> meaning name dwarfdump.conf file -x
+		   abi=<abi> meaning select abi from dwarfdump.conf
+		   file. Must always select abi to use dwarfdump.conf */
+		if (strncmp(optarg, "name=", 5) == 0) {
+		    path = makename(&optarg[5]);
+		    if (strlen(path) < 1)
+			goto badopt;
+		    config_file_path = path;
+		} else if (strncmp(optarg, "abi=", 4) == 0) {
+		    abi = makename(&optarg[4]);
+		    if (strlen(abi) < 1)
+			goto badopt;
+		    config_file_abi = abi;
+		    break;
+		} else {
+		  badopt:
+		    fprintf(stderr, "-x name=<path-to-conf> \n");
+		    fprintf(stderr, " and  \n");
+		    fprintf(stderr, "-x abi=<abi-in-conf> \n");
+		    fprintf(stderr, "are legal, not -x %s\n", optarg);
+		    usage_error = TRUE;
+		    break;
+		}
+	    }
+	    break;
+	case 'g':
+	    use_old_dwarf_loclist = TRUE;
+	    /* FALL THROUGH. */
+	case 'i':
+	    info_flag = TRUE;
+	    break;
+	case 'l':
+	    line_flag = TRUE;
+	    break;
+	case 'f':
+	    frame_flag = TRUE;
+	    break;
+	case 'F':
+	    eh_frame_flag = TRUE;
+	    break;
+	case 'b':
+	    abbrev_flag = TRUE;
+	    break;
+	case 'p':
+	    pubnames_flag = TRUE;
+	    break;
+	case 'r':
+	    aranges_flag = TRUE;
+	    break;
+	case 'R':
+	    generic_1000_regs = TRUE;
+	    info_flag = TRUE;
+	    break;
+	case 'm':
+	    macinfo_flag = TRUE;
+	    break;
+	case 'c':
+	    loc_flag = TRUE;
+	    break;
+	case 's':
+	    string_flag = TRUE;
+	    break;
+	case 'a':
+	    do_all();
+	    break;
+	case 'v':
+	    verbose++;
+	    break;
+	case 'V':
+	    {
+	    printf("%s\n","Version 4May2007");
+	    }
+	    break;
+	case 'd':
+	    dense = TRUE;
+	    break;
+	case 'e':
+	    ellipsis = TRUE;
+	    break;
+	case 'o':
+	    reloc_flag = TRUE;
+	    break;
+	case 'k':
+	    dwarf_check = TRUE;
+	    oarg = optarg[0];
+	    switch (oarg) {
+	    case 'a':
+		check_pubname_attr = TRUE;
+		check_attr_tag = TRUE;
+		check_tag_tree = check_type_offset = TRUE;
+		pubnames_flag = info_flag = TRUE;
+		break;
+	    case 'e':
+		check_pubname_attr = TRUE;
+		pubnames_flag = TRUE;
+		break;
+	    case 'r':
+		check_attr_tag = TRUE;
+		info_flag = TRUE;
+		break;
+	    case 't':
+		check_tag_tree = TRUE;
+		info_flag = TRUE;
+		break;
+	    case 'y':
+		check_type_offset = TRUE;
+		info_flag = TRUE;
+		break;
+	    default:
+		usage_error = TRUE;
+		break;
+	    }
+	    break;
+	case 'u':		/* compile unit */
+	    cu_name_flag = TRUE;
+	    strcpy(cu_name, optarg);
+	    break;
+	case 't':
+	    oarg = optarg[0];
+	    switch (oarg) {
+	    case 'a':
+		/* all */
+		static_func_flag = static_var_flag = TRUE;
+		break;
+	    case 'f':
+		/* .debug_static_func */
+		static_func_flag = TRUE;
+		break;
+	    case 'v':
+		/* .debug_static_var */
+		static_var_flag = TRUE;
+		break;
+	    default:
+		usage_error = TRUE;
+		break;
+	    }
+	    break;
+	case 'y':		/* .debug_types */
+	    type_flag = TRUE;
+	    break;
+	case 'w':		/* .debug_weaknames */
+	    weakname_flag = TRUE;
+	    break;
+	case 'z':
+	    fprintf(stderr, "-z is no longer supported:ignored\n");
+	    break;
+	case 'G':
+	    show_global_offsets = TRUE;
+	    break;
+	default:
+	    usage_error = TRUE;
+	    break;
+	}
+    }
+
+    init_conf_file_data(&config_file_data);
+    if (config_file_abi && generic_1000_regs) {
+        printf("Specifying both -R and -x abi= is not allowed. Use one "
+              "or the other.  -x abi= ignored.\n");
+        config_file_abi = FALSE;
+    }
+    if(generic_1000_regs) {
+        init_generic_config_1000_regs(&config_file_data);
+    }
+    if (config_file_abi && (frame_flag || eh_frame_flag)) {
+	int res = find_conf_file_and_read_config(config_file_path,
+						 config_file_abi,
+						 config_file_defaults,
+						 &config_file_data);
+
+	if (res > 0) {
+	    printf
+		("Frame not configured due to error(s). Giving up.\n");
+	    eh_frame_flag = FALSE;
+	    frame_flag = FALSE;
+	}
+    }
+    if (usage_error || (optind != (argc - 1))) {
+	print_usage_message();
+	exit(FAILED);
+    }
+    return argv[optind];
+}
+
+static void
+print_usage_message(void)
+{
+    fprintf(stderr, "Usage:  %s <options> <object file>\n",
+	    program_name);
+    fprintf(stderr, "options:\t-a\tprint all .debug_* sections\n");
+    fprintf(stderr, "\t\t-b\tprint abbrev section\n");
+    fprintf(stderr, "\t\t-c\tprint loc section\n");
+    fprintf(stderr,
+	    "\t\t-d\tdense: one line per entry (info section only)\n");
+    fprintf(stderr,
+	    "\t\t-e\tellipsis: short names for tags, attrs etc.\n");
+    fprintf(stderr, "\t\t-f\tprint dwarf frame section\n");
+    fprintf(stderr, "\t\t-F\tprint gnu .eh_frame section\n");
+    fprintf(stderr, "\t\t-g\t(use incomplete loclist support)\n");
+    fprintf(stderr, "\t\t-G\tshow global die offsets\n");
+    fprintf(stderr, "\t\t-h\tprint exception tables\n");
+    fprintf(stderr, "\t\t-i\tprint info section\n");
+    fprintf(stderr, "\t\t-k[aerty] check dwarf information\n");
+    fprintf(stderr, "\t\t   a\tdo all checks\n");
+    fprintf(stderr, "\t\t   e\texamine attributes of pubnames\n");
+    fprintf(stderr, "\t\t   r\texamine attr-tag relation\n");
+    fprintf(stderr, "\t\t   t\texamine tag trees\n");
+    fprintf(stderr, "\t\t   y\texamine type info\n");
+    fprintf(stderr, "\t\t-l\tprint line section\n");
+    fprintf(stderr, "\t\t-m\tprint macinfo section\n");
+    fprintf(stderr, "\t\t-o\tprint relocation info\n");
+    fprintf(stderr, "\t\t-p\tprint pubnames section\n");
+    fprintf(stderr, "\t\t-r\tprint aranges section\n");
+    fprintf(stderr, "\t\t-R\tPrint frame register names as r33 etc\n");
+    fprintf(stderr, "\t\t  \t    and allow up to 1000 registers.\n");
+    fprintf(stderr, "\t\t  \t    Print using a 'generic' register set.\n");
+    fprintf(stderr, "\t\t-s\tprint string section\n");
+    fprintf(stderr, "\t\t-t[afv] static: \n");
+    fprintf(stderr, "\t\t   a\tprint both sections\n");
+    fprintf(stderr, "\t\t   f\tprint static func section\n");
+    fprintf(stderr, "\t\t   v\tprint static var section\n");
+    fprintf(stderr,
+	    "\t\t-u<file> print sections only for specified file\n");
+    fprintf(stderr, "\t\t-v\tverbose: show more information\n");
+    fprintf(stderr, "\t\t-vv verbose: show even more information\n");
+    fprintf(stderr, "\t\t-V print version information\n");	
+    fprintf(stderr, "\t\t-x name=<path>\tname dwarfdump.conf\n");
+    fprintf(stderr, "\t\t-x abi=<abi>\tname abi in dwarfdump.conf\n");
+    fprintf(stderr, "\t\t-w\tprint weakname section\n");
+    fprintf(stderr, "\t\t-y\tprint type section\n");
+
+}
+
+/* process each compilation unit in .debug_info */
+static void
+print_infos(Dwarf_Debug dbg)
+{
+    Dwarf_Unsigned cu_header_length = 0;
+    Dwarf_Unsigned abbrev_offset = 0;
+    Dwarf_Half version_stamp = 0;
+    Dwarf_Half address_size = 0;
+    Dwarf_Die cu_die = 0;
+    Dwarf_Unsigned next_cu_offset = 0;
+    int nres = DW_DLV_OK;
+
+    if (info_flag)
+	printf("\n.debug_info\n");
+
+    /* Loop until it fails.  */
+    while ((nres =
+	    dwarf_next_cu_header(dbg, &cu_header_length, &version_stamp,
+				 &abbrev_offset, &address_size,
+				 &next_cu_offset, &err))
+	   == DW_DLV_OK) {
+	int sres;
+
+	if (cu_name_flag) {
+	    int tres;
+	    Dwarf_Half tag;
+	    Dwarf_Attribute attrib;
+	    Dwarf_Half theform;
+	    int fres;
+	    int ares;
+
+	    sres = dwarf_siblingof(dbg, NULL, &cu_die, &err);
+	    if (sres != DW_DLV_OK) {
+		print_error(dbg, "siblingof cu header", sres, err);
+	    }
+	    tres = dwarf_tag(cu_die, &tag, &err);
+	    if (tres != DW_DLV_OK) {
+		print_error(dbg, "tag of cu die", tres, err);
+	    }
+	    ares = dwarf_attr(cu_die, DW_AT_name, &attrib, &err);
+	    if (ares != DW_DLV_OK) {
+		print_error(dbg, "dwarf DW_AT_name ", ares, err);
+	    }
+	    fres = dwarf_whatform(attrib, &theform, &err);
+	    if (fres != DW_DLV_OK) {
+		print_error(dbg, "dwarf_whatform problem ", fres, err);
+	    } else if (theform == DW_FORM_string
+		       || theform == DW_FORM_strp) {
+		string temps;
+		int strres;
+		string p;
+
+		strres = dwarf_formstring(attrib, &temps, &err);
+		p = temps;
+		if (strres != DW_DLV_OK) {
+		    print_error(dbg,
+				"formstring failed unexpectedly",
+				strres, err);
+		}
+		if (cu_name[0] != '/') {
+		    p = strrchr(temps, '/');
+		    if (p == NULL) {
+			p = temps;
+		    } else {
+			p++;
+		    }
+		}
+		if (strcmp(cu_name, p)) {
+		    continue;
+		}
+	    } else {
+		print_error(dbg,
+			    "dwarf_whatform unexpected value",
+			    fres, err);
+	    }
+	    dwarf_dealloc(dbg, attrib, DW_DLA_ATTR);
+	    dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
+	}
+	if (verbose) {
+	    if (dense) {
+		printf("<%s>", "cu_header");
+		printf(" %s<%llu>", "cu_header_length",
+		       cu_header_length);
+		printf(" %s<%d>", "version_stamp", version_stamp);
+		printf(" %s<%llu>", "abbrev_offset", abbrev_offset);
+		printf(" %s<%d>\n", "address_size", address_size);
+
+	    } else {
+		printf("\nCU_HEADER:\n");
+		printf("\t\t%-28s%llu\n", "cu_header_length",
+		       cu_header_length);
+		printf("\t\t%-28s%d\n", "version_stamp", version_stamp);
+		printf("\t\t%-28s%llu\n", "abbrev_offset",
+		       abbrev_offset);
+		printf("\t\t%-28s%d", "address_size", address_size);
+	    }
+	}
+
+	/* process a single compilation unit in .debug_info. */
+	sres = dwarf_siblingof(dbg, NULL, &cu_die, &err);
+	if (sres == DW_DLV_OK) {
+	    if (info_flag || cu_name_flag) {
+		Dwarf_Signed cnt = 0;
+		char **srcfiles = 0;
+		int srcf = dwarf_srcfiles(cu_die,
+					  &srcfiles, &cnt, &err);
+
+		if (srcf != DW_DLV_OK) {
+		    srcfiles = 0;
+		    cnt = 0;
+		}
+
+		print_die_and_children(dbg, cu_die, srcfiles, cnt);
+		if (srcf == DW_DLV_OK) {
+		    int si;
+
+		    for (si = 0; si < cnt; ++si) {
+			dwarf_dealloc(dbg, srcfiles[si], DW_DLA_STRING);
+		    }
+		    dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST);
+		}
+	    }
+	    if (line_flag)
+		print_line_numbers_this_cu(dbg, cu_die);
+	    dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
+	} else if (sres == DW_DLV_NO_ENTRY) {
+	    /* do nothing I guess. */
+	} else {
+	    print_error(dbg, "Regetting cu_die", sres, err);
+	}
+	cu_offset = next_cu_offset;
+    }
+    if (nres == DW_DLV_ERROR) {
+	string errmsg = dwarf_errmsg(err);
+	Dwarf_Unsigned myerr = dwarf_errno(err);
+
+	fprintf(stderr, "%s ERROR:  %s:  %s (%lu)\n",
+		program_name, "attempting to print .debug_info",
+		errmsg, (unsigned long) myerr);
+	fprintf(stderr, "attempting to continue.\n");
+    }
+}
+
+/* ARGSUSED */
+void
+print_error(Dwarf_Debug dbg, string msg, int dwarf_code,
+	    Dwarf_Error err)
+{
+    fflush(stdout);
+    fflush(stderr);
+    if (dwarf_code == DW_DLV_ERROR) {
+	string errmsg = dwarf_errmsg(err);
+	Dwarf_Unsigned myerr = dwarf_errno(err);
+
+	fprintf(stderr, "%s ERROR:  %s:  %s (%lu)\n",
+		program_name, msg, errmsg, (unsigned long) myerr);
+    } else if (dwarf_code == DW_DLV_NO_ENTRY) {
+	fprintf(stderr, "%s NO ENTRY:  %s: \n", program_name, msg);
+    } else if (dwarf_code == DW_DLV_OK) {
+	fprintf(stderr, "%s:  %s \n", program_name, msg);
+    } else {
+	fprintf(stderr, "%s InternalError:  %s:  code %d\n",
+		program_name, msg, dwarf_code);
+    }
+    fflush(stderr);
+    exit(FAILED);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwarfdump.conf	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,415 @@
+# MIPS/IRIX  ISA/ABI
+# Used to configure dwarfdump printing of .debug_frame and
+# .eh_frame.
+
+# Any number of abi's can be described. Only one can be selected
+# in a given darfdump run (see dwarfdump options)
+#  Available commands are
+# beginabi:  <abiname>
+# reg: <regname> <dwarf regnumber>
+# frame_interface: <integer value 2 or 3>
+# cfa_reg:  <number>
+# initial_reg_value:  <number: normally 1034 or 1035 >
+# reg_table_size: <size of table>
+# endabi:  <abiname>
+#
+# Symbolic names do not work here, use literal numbers
+# where applicable (in C standard decimal, octal (leading 0) or
+# hexadecimal <leading 0x>).
+#
+# Whitespace is required to separate command: from operands and
+# operands from each other on a line.
+#
+# There is no ordering required within a beginabi/endabi pair.
+# As many ABIs as required may be listed.
+# dwarfdump will choose exactly one abi to dump frame information.
+#
+
+
+# Here using MIPS abi as an example to describe
+# the format. The MIPS/IRIX ABI is built-in to dwarfdump, so this one
+# is not really required.
+# Begin with abi name (use here and on dwarfdump command line).
+beginabi: mips
+
+# Instructs dwarfdump to default to the older frame interface.
+# Use value 3 to use the newer interface.
+# The '2' interface is supported but deprecated (deprecated
+# because it cannot work with all popular ABIs: mixing
+# the cfa-rule into the table column set was not a good idea
+# but it is part of the MIPS/IRIX standard usage).
+frame_interface: 2
+
+# If (and only if) using  frame_interface: 2 tell dwarfdump
+# what table colum that DW_FRAME_CFA_COL is.
+# If using frame_interface: 3 cfa_reg: should be 
+#  DW_FRAME_CFA_COL3 (1036)
+cfa_reg: 0
+
+# For MIPS, the same as DW_FRAME_SAME_VAL (1035).
+# For other ISA/ABIs 1034 (DW_FRAME_UNDEFINED_VAL) might be better.
+# Depends on the ABI convention, if set wrong way too many
+# regs will be listed in the frame output.
+# This instructs  dwarfdump  to set libdwarf to this value,
+# overriding the libdwarf default.
+# If initial_reg_value not set the libdwarf default is used
+# (see libdwarf.h DW_FRAME_REG_INITIAL_VALUE).
+initial_reg_value:  1035  # DW_FRAME_SAME_VAL
+
+# Built in to frame_interface: 2 as 66.
+reg_table_size: 66
+
+
+# Only name registers for wich a r4 (for example) is not what you
+# want to  see
+# No particular order  of the reg: lines required.
+reg: cfa 0   # Used with MIPS/IRIX original DWARF2 interface
+reg: r1/at 1
+reg: r2/v0 2 
+reg: r3/v1 3
+reg: r4/a0  4
+reg: r5/a1  5
+reg: r6/a2  6
+reg: r7/a3  7
+reg: r8/t0  8
+reg: r9/t1  9
+reg: r10/t2 10
+reg: r11/t3 11
+reg: r12/t4 12
+reg: r13/t5 13
+reg: r14/t6 14
+reg: r15/t7 15
+reg: r16/s0 16
+reg: r17/s1 17
+reg: r18/s2 18
+reg: r19/s3 19
+reg: r20/s4 20
+reg: r21/s5 21
+reg: r22/s6 22
+reg: r23/s7 23
+reg: r24/t8 24
+reg: r25/t9 25
+reg: r26/k0 26
+reg: r27/k1 27
+reg: r28/gp 28
+reg: r29/sp 29
+reg: r30/s8 30
+reg: r31  31
+
+reg: $f0 32
+reg: $f1 33
+reg: $f2  34
+reg: $f3 35
+reg: $f4 36
+reg: $f5 37
+reg: $f6 38
+reg: $f7 39
+reg: $f8 40
+reg: $f9 41
+reg: $f10 42
+reg: $f11 43
+reg: $f12 44
+reg: $f13 45
+reg: $f14  46
+reg: $f15 47
+reg: $f16 48
+reg: $f17 49
+reg: $f18 50
+reg: $f19 51
+reg: $f20 52
+reg: $f21 53
+reg: $f22 54
+reg: $f23 55
+reg: $f24 56
+reg: $f25 57
+reg: $f26 58
+reg: $f27 59
+reg: $f28 60
+reg: $f29 61
+reg: $f30 62
+reg: $f31 63
+reg: ra  64
+reg: slk 65
+
+
+# End of abi definition.
+endabi: mips
+
+
+
+
+
+
+# MIPS/IRIX  ISA/ABI for testing libdwarf.
+beginabi: mips-simple
+frame_interface: 2
+reg_table_size: 66
+cfa_reg: 0
+initial_reg_value:  1035
+
+reg: cfa 0   # Used with MIPS/IRIX original DWARF2 interface
+reg: ra  64
+reg: slk 65
+
+# End of abi definition.
+endabi: mips-simple
+
+# MIPS/IRIX  ISA/ABI for testing  the new frame interface
+# with libdwarf.
+beginabi: mips-simple3
+frame_interface: 3
+
+# When using frame_interface: 3 the size of the register table
+# is not fixed. It can be as large as needed. 
+reg_table_size: 66
+cfa_reg: 1036  # DW_FRAME_CFA_COL3
+initial_reg_value:  1035
+
+# No cfa as a 'normal' register. 
+# Rule 0 is just register 0, which is not used
+# in frame descriptions.
+# (so cfa does not have a number here, and dwarfdump gives
+# it the name 'cfa' automatically).
+reg: ra  64
+reg: slk 65
+# End of abi definition.
+endabi: mips-simple3
+
+
+beginabi: ia64
+frame_interface: 3
+initial_reg_value: 1034  # DW_FRAME_UNDEFINED_VAL
+cfa_reg: 1036  # DW_FRAME_CFA_COL3
+reg_table_size: 695
+
+# The following register names are not necessarily correct...
+# Register indexes r32-r127 not used.
+reg: f0 128
+# ...
+reg: f127 255
+reg: b0 321
+reg: b1 322
+reg: b2 323
+reg: b3 324
+reg: b4 325
+reg: b5 326
+reg: b6 327
+reg: b7 328
+reg: vfp 329
+reg: vrap 330
+reg: pr 331
+reg: ip 332
+reg: psr 333
+reg: cfm 334
+reg: k0 335
+reg: k1 336
+reg: k2 337
+reg: k3 338
+reg: k4 339
+reg: k5 340
+reg: k6 341
+reg: k7 342
+reg: rsc  350 
+reg: bsp 351 
+reg: bspstore 352 
+reg: rnat 353
+reg: fcr 355
+reg: eflag 358
+reg: csd 359
+reg: ssd 360 
+reg: cflg 361
+reg:  fsr 362
+reg: fir 363
+reg:  fdr 364
+reg: pfs 398 
+reg: lc 399
+reg: ec 400
+
+endabi: ia64
+
+
+beginabi: x86
+frame_interface: 3
+initial_reg_value: 1035  # DW_FRAME_SAME_VAL
+reg_table_size: 66  # more than large enough, hopefully.
+cfa_reg: 1036  # DW_FRAME_CFA_COL3
+
+# The following register names are not necessarily correct...
+reg: eax 0
+reg: ecx 1    
+reg: edx 2
+reg: ebx 3
+reg: esp 4
+reg: ebp 5
+reg: esi 6
+reg: edi 7
+reg: eip 8
+reg: eflags 9
+
+reg: trapno 10
+reg: st0 11
+reg: st1 12
+reg: st2 13
+reg: st3 14
+reg: st4 15
+reg: st5 16
+reg: st6 17
+reg: st7 18
+# 19 is ? 20 is ?
+reg: xmm0  21
+reg: xmm1  22 
+reg: xmm2  23
+reg: xmm3  24
+reg: xmm4  25
+reg: xmm5  26
+reg: xmm6  27
+reg: xmm7  28
+
+reg: mm0  29
+reg: mm1  30
+reg: mm2  31
+reg: mm3  32
+reg: mm4  33
+reg: mm5  34
+reg: mm6  35
+reg: mm7  36
+
+reg: fcw  37
+reg: fsw  38
+reg: mxcsr 39
+
+reg: es 40
+reg: cs 41
+reg: ss 42
+reg: ds 43
+reg: fs 44
+reg: gs 45
+# 46 47 are ?
+reg: tr 48
+reg: ldtr 49
+
+
+endabi: x86
+
+
+beginabi: x86_64
+frame_interface: 3
+initial_reg_value: 1035  # DW_FRAME_SAME_VAL
+reg_table_size: 66  # more than large enough, hopefully.
+cfa_reg: 1036  # DW_FRAME_CFA_COL3
+
+# The following register names are not necessarily correct...
+reg: rax 0
+reg: rdx 1    
+reg: rcx 2
+reg: rbx 3
+reg: rsi 4
+reg: rdi 5
+reg: rbp 6
+reg: rsp 7
+reg: r8 8
+reg: r9 9
+reg: r10 10
+reg: r11 11
+reg: r12 12
+reg: r13 13
+reg: r14 14
+reg: r15 15
+reg: rip 16
+reg: xmm0 17
+reg: xmm1 18
+reg: xmm2 19
+reg: xmm3 20
+reg: xmm4 21
+reg: xmm5 22
+reg: xmm6 23
+reg: xmm7 24
+reg: xmm8 25
+reg: xmm9 26
+reg: xmm10 27
+reg: xmm11 28
+reg: xmm12 29
+reg: xmm13 30
+reg: xmm14 31
+reg: xmm15 32
+
+reg: st0 33
+reg: st1 34
+reg: st2 35
+reg: st3 36
+reg: st4 37
+reg: st5 38
+reg: st6 39
+reg: st7 40
+
+reg: mm0 41
+reg: mm1 42
+reg: mm2 43
+reg: mm3 44
+reg: mm4 45
+reg: mm5 46
+reg: mm6 47
+reg: mm7 48
+
+reg: rflags 49
+reg: es 50
+reg: cs 51
+reg: ss 52
+reg: ds 53
+reg: fs 54
+reg: gs 55
+# 56, 57 are ?
+reg: fs.base 58
+reg: gs.base 59
+# 60 61 are ?
+reg: tr 62
+reg: ldtr 63
+
+endabi: x86_64
+
+beginabi: m68k
+frame_interface: 3
+initial_reg_value: 1035  # DW_FRAME_SAME_VAL
+reg_table_size: 66  # more than large enough, hopefully.
+cfa_reg: 1036  # DW_FRAME_CFA_COL3
+
+reg: d0 0
+reg: d1 1
+reg: d2 2
+reg: d3 3
+reg: d4 4
+reg: d5 5
+reg: d6 6
+reg: d7 7
+
+reg: a0 8
+reg: a1 9
+reg: a2 10
+reg: a3 11
+reg: a4 12
+reg: a5 13
+reg: a6 14
+reg: sp 15
+
+reg: fp0 16
+reg: fp1 17
+reg: fp2 18
+reg: fp3 19
+reg: fp4 20
+reg: fp5 21
+reg: fp6 22
+reg: pc 23
+
+endabi: m68k
+
+# 'Generic 1000 register abi'.
+# This is useful as a 'general' ABI settings for
+# cpus using up to 1000 registers. The register names
+# show as a number, like  'r991'.
+beginabi: generic
+frame_interface: 3
+initial_reg_value: 1035  # DW_FRAME_SAME_VAL
+cfa_reg: 1036  # DW_FRAME_CFA_COL3
+reg_table_size: 1000
+reg: r0 0
+endabi: generic
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwconf.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1142 @@
+/*
+  Copyright (C) 2006 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write the Free Software Foundation, Inc., 51
+  Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/dwconf.c,v 1.4 2006/04/18 18:05:57 davea Exp $ */
+
+
+#include "globals.h"
+#include <ctype.h>
+#include "dwconf.h"
+#include "makename.h"
+
+
+struct token_s {
+    unsigned tk_len;
+    char *tk_data;
+};
+enum linetype_e {
+    LT_ERROR,
+    LT_COMMENT,
+    LT_BLANK,
+    LT_BEGINABI,
+    LT_REG,
+    LT_FRAME_INTERFACE,
+    LT_CFA_REG,
+    LT_INITIAL_REG_VALUE,
+    LT_REG_TABLE_SIZE,
+    LT_ENDABI
+};
+
+struct comtable_s {
+    enum linetype_e type;
+    char *name;
+    size_t namelen;
+};
+
+static int errcount = 0;	/* Count errors found in this scan of
+				   the configuration file. */
+
+static char name_begin_abi[] = "beginabi:";
+static char name_reg[] = "reg:";
+static char name_frame_interface[] = "frame_interface:";
+static char name_cfa_reg[] = "cfa_reg:";
+static char name_initial_reg_value[] = "initial_reg_value:";
+static char name_reg_table_size[] = "reg_table_size:";
+static char name_endabi[] = "endabi:";
+
+static struct comtable_s comtable[] = {
+    {LT_BEGINABI, name_begin_abi},
+    {LT_REG, name_reg},
+    {LT_FRAME_INTERFACE, name_frame_interface},
+    {LT_CFA_REG, name_cfa_reg},
+    {LT_INITIAL_REG_VALUE, name_initial_reg_value},
+    {LT_REG_TABLE_SIZE, name_reg_table_size},
+    {LT_ENDABI, name_endabi},
+};
+static int size_of_comtable = sizeof(comtable) / sizeof(comtable[0]);
+
+
+static FILE *find_a_file(char *named_file, char **defaults,
+			 string * name_used);
+static int find_abi_start(FILE * stream, char *abi_name, long *offset,
+			  unsigned long *lineno_out);
+static int parse_abi(FILE * stream, char *fname, char *abiname,
+		     struct dwconf_s *out, unsigned long lineno);
+static char *get_token(char *cp, struct token_s *outtok);
+
+
+
+
+
+/*  This finds a dwarfdump.conf file and
+    then parses it.  It updates
+    conf_out as appropriate.
+
+    This finds the first file (looking in a set of places)
+    with that name.  It then looks for the right  ABI entry.
+    If the first file it finds does not have that ABI entry it
+    gives up.
+  
+    It would also be reasonable to search every 'dwarfdump.conf'
+    it finds for the abi. But we stop at the first dwarfdump.conf
+    we find.
+*/
+int
+find_conf_file_and_read_config(char *named_file,
+			       char *named_abi, char **defaults,
+			       struct dwconf_s *conf_out)
+{
+
+    FILE *conf_stream = 0;
+    char *name_used = 0;
+    long offset = 0;
+    int res = FALSE;
+    unsigned long lineno = 0;
+
+    errcount = 0;
+
+    conf_stream = find_a_file(named_file, defaults, &name_used);
+    if (!conf_stream) {
+	++errcount;
+	printf("dwarfdump found no file %s!\n",
+	       named_file ? named_file : "readable for configuration. "
+	       "(add options -v -v to see what file names tried)\n");
+	return errcount;
+    }
+    if (verbose > 1) {
+	printf("dwarfdump using configuration file %s\n", name_used);
+    }
+
+    res = find_abi_start(conf_stream, named_abi, &offset, &lineno);
+    if (errcount > 0) {
+	++errcount;
+	printf("dwarfdump found no ABI %s in file %s.\n",
+	       named_abi, name_used);
+	return errcount;
+    }
+    res = fseek(conf_stream, offset, SEEK_SET);
+    if (res != 0) {
+	++errcount;
+	printf("dwarfdump seek to %ld offset in %s failed!\n",
+	       offset, name_used);
+	return errcount;
+    }
+    parse_abi(conf_stream, name_used, named_abi, conf_out, lineno);
+    fclose(conf_stream);
+    return errcount;
+}
+
+/* Given path strings, attempt to make a canonical file name:
+   that is, avoid superfluous '/' so that no
+    '//' (or worse) is created in the output. The path components
+    are to be separated so at least one '/'
+    is to appear between the two 'input strings' when
+    creating the output.
+*/
+static char *
+canonical_append(char *target, unsigned int target_size,
+		 char *first_string, char *second_string)
+{
+    size_t firstlen = strlen(first_string);
+
+    /* +1 +1: Leave room for added "/" and final NUL, though that is
+       overkill, as we drop a NUL byte too. */
+    if ((firstlen + strlen(second_string) + 1 + 1) >= target_size) {
+	/* Not enough space. */
+	return NULL;
+    }
+    for (; *second_string == '/'; ++second_string) {
+    }
+    for (; firstlen > 0 && first_string[firstlen - 1] == '/';
+	 --firstlen) {
+    }
+    target[0] = 0;
+    if (firstlen > 0) {
+	strncpy(target, first_string, firstlen);
+	target[firstlen + 1] = 0;
+    }
+    target[firstlen] = '/';
+    firstlen++;
+    target[firstlen] = 0;
+    strcat(target, second_string);
+    return target;
+}
+
+#ifdef BUILD_FOR_TEST
+#define CANBUF 25
+struct canap_s {
+    char *res_exp;
+    char *first;
+    char *second;
+} canap[] = {
+    {
+    "ab/c", "ab", "c"}, {
+    "ab/c", "ab/", "c"}, {
+    "ab/c", "ab", "/c"}, {
+    "ab/c", "ab////", "/////c"}, {
+    "ab/", "ab", ""}, {
+    "ab/", "ab////", ""}, {
+    "ab/", "ab////", ""}, {
+    "/a", "", "a"}, {
+    0, "/abcdefgbijkl", "pqrstuvwxyzabcd"}, {
+    0, 0, 0}
+};
+static void
+test_canonical_append(void)
+{
+    /* Make buf big, this is test code, so be safe. */
+    char lbuf[1000];
+    unsigned i;
+    unsigned failcount = 0;
+
+    printf("Entry test_canonical_append\n");
+    for (i = 0;; ++i) {
+	char *res = 0;
+
+	if (canap[i].first == 0 && canap[i].second == 0)
+	    break;
+
+	res = canonical_append(lbuf, CANBUF, canap[i].first,
+			       canap[i].second);
+	if (res == 0) {
+	    if (canap[i].res_exp == 0) {
+		/* GOOD */
+		printf("PASS %u\n", i);
+	    } else {
+		++failcount;
+		printf("FAIL: entry %u wrong, expected %s, got NULL\n",
+		       i, canap[i].res_exp);
+	    }
+	} else {
+	    if (canap[i].res_exp == 0) {
+		++failcount;
+		printf("FAIL: entry %u wrong, got %s expected NULL\n",
+		       i, res);
+	    } else {
+		if (strcmp(res, canap[i].res_exp) == 0) {
+		    printf("PASS %u\n", i);
+		    /* GOOD */
+		} else {
+		    ++failcount;
+		    printf("FAIL: entry %u wrong, expected %s got %s\n",
+			   i, canap[i].res_exp, res);
+		}
+	    }
+	}
+    }
+    printf("FAIL count %u\n", failcount);
+
+}
+#endif /* BUILD_FOR_TEST */
+/* Try to find a file as named and open for read.
+   We treat each name as a full name, we are not
+   combining separate name and path components.
+   This is  an arbitrary choice...
+
+    The defaults are listed in dwarfdump.c in the array 
+    config_file_defaults[].
+*/
+static FILE *
+find_a_file(char *named_file, char **defaults, string * name_used)
+{
+    FILE *fin = 0;
+    char *lname = named_file;
+    const char *type = "rw";
+    int i = 0;
+
+#ifdef BUILD_FOR_TEST
+    test_canonical_append();
+#endif /* BUILD_FOR_TEST */
+
+    if (lname) {
+	/* Name given, just assume it is fully correct, try no other. */
+	if (verbose > 1) {
+	    printf("dwarfdump looking for configuration as %s\n",
+		   lname);
+	}
+	fin = fopen(lname, type);
+	if (fin) {
+	    *name_used = lname;
+	    return fin;
+	}
+	return 0;
+    }
+    /* No name given, find a default, if we can. */
+    for (i = 0; defaults[i]; ++i) {
+	lname = defaults[i];
+	if (strncmp(lname, "HOME/", 5) == 0) {
+	    /* arbitrary size */
+	    char buf[2000];
+	    char *homedir = getenv("HOME");
+
+	    if (homedir) {
+		char *cp = canonical_append(buf, sizeof(buf),
+					    homedir, lname + 5);
+
+		if (!cp) {
+		    /* OOps, ignore this one. */
+		    continue;
+		}
+		lname = makename(buf);
+	    }
+	}
+	if (verbose > 1) {
+	    printf("dwarfdump looking for configuration as %s\n",
+		   lname);
+	}
+	fin = fopen(lname, type);
+	if (fin) {
+	    *name_used = lname;
+	    return fin;
+	}
+    }
+    return 0;
+}
+
+/* Start at a token begin, see how long it is,
+   return length. */
+unsigned
+find_token_len(char *cp)
+{
+    unsigned len = 0;
+
+    for (; *cp; ++cp) {
+	if (isspace(*cp)) {
+	    return len;
+	}
+	if (*cp == '#') {
+	    return len;		/* begins comment */
+	}
+	++len;
+    }
+    return len;
+}
+
+/*
+   Skip past all whitespace: the only code that even knows
+   what whitespace is.
+*/
+static char *
+skipwhite(char *cp)
+{
+    for (; *cp; ++cp) {
+	if (!isspace(*cp)) {
+	    return cp;
+	}
+    }
+    return cp;
+}
+
+/* Return TRUE if ok. FALSE if find more tokens.
+   Emit error message if error.
+*/
+static int
+ensure_has_no_more_tokens(char *cp, char *fname, unsigned long lineno)
+{
+    struct token_s tok;
+
+    cp = get_token(cp, &tok);
+    if (tok.tk_len > 0) {
+	printf("dwarfdump.conf error: "
+	       "extra characters after command operands, found "
+	       "\"%s\" in %s line %lu\n", tok.tk_data, fname, lineno);
+	++errcount;
+	return FALSE;
+    }
+    return TRUE;
+}
+
+
+/*
+	There may be many  beginabi: lines in a dwarfdump.conf file,
+	find the one we want and return it's file offset.
+*/
+static int
+find_abi_start(FILE * stream,
+	       char *abi_name, long *offset, unsigned long *lineno_out)
+{
+    char buf[100];
+    unsigned long lineno = 0;
+
+    for (; !feof(stream);) {
+
+	struct token_s tok;
+	char *line = 0;
+	long loffset = ftell(stream);
+
+	line = fgets(buf, sizeof(buf), stream);
+	++lineno;
+	if (!line) {
+	    ++errcount;
+	    return FALSE;
+	}
+
+	line = get_token(buf, &tok);
+
+	if (strcmp(tok.tk_data, name_begin_abi) != 0) {
+	    continue;
+	}
+	get_token(line, &tok);
+	if (strcmp(tok.tk_data, abi_name) != 0) {
+	    continue;
+	}
+
+	*offset = loffset;
+	*lineno_out = lineno;
+	return TRUE;
+    }
+
+    ++errcount;
+    return FALSE;
+}
+
+static char *tempstr = 0;
+static unsigned tempstr_len = 0;
+
+/*
+	Use a global buffer (tempstr) to turn a non-delimited
+	input char array into a NUL-terminated C string
+        (with the help of makename() to get a permanent
+        address for the result ing string).
+*/
+static char *
+build_string(unsigned tlen, char *cp)
+{
+    if (tlen >= tempstr_len) {
+	free(tempstr);
+	tempstr = malloc(tlen + 100);
+    }
+    strncpy(tempstr, cp, tlen);
+    tempstr[tlen] = 0;
+    return makename(tempstr);
+}
+
+/*
+	The tokenizer for our simple parser.
+*/
+static char *
+get_token(char *cp, struct token_s *outtok)
+{
+    char *lcp = skipwhite(cp);
+    unsigned tlen = find_token_len(lcp);
+
+    outtok->tk_len = tlen;
+    if (tlen > 0) {
+	outtok->tk_data = build_string(tlen, lcp);
+    } else {
+	outtok->tk_data = "";
+    }
+    return lcp + tlen;
+
+}
+
+/*
+	We can't get all the field set up statically very easily,
+        so we get the command string length set here.
+*/
+static void
+finish_comtable_setup(void)
+{
+    unsigned i;
+
+    for (i = 0; i < size_of_comtable; ++i) {
+	comtable[i].namelen = strlen(comtable[i].name);
+    }
+}
+
+/*
+    Given  a line of the table, determine if it is a command
+    or not, and if a command, which one is it.
+    Return LT_ERROR if it's not recognized.
+*/
+static enum linetype_e
+which_command(char *cp, struct comtable_s **tableentry)
+{
+    int i;
+    struct token_s tok;
+
+    if (*cp == '#')
+	return LT_COMMENT;
+    if (!*cp)
+	return LT_BLANK;
+
+    get_token(cp, &tok);
+
+    for (i = 0; i < size_of_comtable; ++i) {
+	if (tok.tk_len == comtable[i].namelen &&
+	    strcmp(comtable[i].name, tok.tk_data) == 0) {
+
+	    *tableentry = &comtable[i];
+	    return comtable[i].type;
+	}
+    }
+
+    return LT_ERROR;
+}
+
+/* We are promised it's an abiname: command
+   find the name on the line.
+*/
+static int
+parsebeginabi(char *cp, char *fname, char *abiname,
+	      unsigned long lineno, struct comtable_s *comtab)
+{
+    size_t clen = comtab->namelen;
+    size_t abinamelen = strlen(abiname);
+    struct token_s tok;
+
+
+    cp = cp + clen + 1;
+    cp = skipwhite(cp);
+    get_token(cp, &tok);
+    if (tok.tk_len != abinamelen ||
+	strncmp(cp, abiname, abinamelen) != 0) {
+	printf("dwarfdump internal error: "
+	       "mismatch %s with %s   %s line %lu\n",
+	       cp, tok.tk_data, fname, lineno);
+	++errcount;
+	return FALSE;
+    }
+    {
+	int res =
+	    ensure_has_no_more_tokens(cp + tok.tk_len, fname, lineno);
+	return res;
+    }
+}
+
+/* This expands register names as required, but does not
+   ensure no names duplicated.
+*/
+#define CONF_TABLE_OVERSIZE  100
+static void
+add_to_reg_table(struct dwconf_s *conf,
+		 char *rname, unsigned long rval, char *fname,
+		 unsigned long lineno)
+{
+    if (conf->cf_regs_malloced == 0) {
+	conf->cf_regs = 0;
+	conf->cf_named_regs_table_size = 0;
+    }
+    if (rval >= conf->cf_named_regs_table_size) {
+	char **newregs = 0;
+	unsigned long newtablen = rval + CONF_TABLE_OVERSIZE;
+	unsigned long newtabsize = newtablen * sizeof(char *);
+	unsigned long oldtabsize =
+	    conf->cf_named_regs_table_size * sizeof(char *);
+	newregs = realloc(conf->cf_regs, newtabsize);
+	if (!newregs) {
+	    printf("dwarfdump: unable to malloc table %lu bytes. "
+		   " %s line %lu\n", newtabsize, fname, lineno);
+	    exit(1);
+	}
+	/* Zero out the new entries. */
+	memset((char *) newregs + (oldtabsize), 0,
+	       (newtabsize - oldtabsize));
+	conf->cf_named_regs_table_size = (unsigned long) newtablen;
+	conf->cf_regs = newregs;
+	conf->cf_regs_malloced = 1;
+    }
+    conf->cf_regs[rval] = rname;
+    return;
+}
+
+/* Our input is supposed to be a number.
+   Determine the value (and return it) or generate an error message.
+*/
+static int
+make_a_number(char *cmd, char *filename, unsigned long
+	      lineno, struct token_s *tok, unsigned long *val_out)
+{
+    char *endnum = 0;
+    unsigned long val = 0;
+
+    val = strtoul(tok->tk_data, &endnum, 0);
+    if (val == 0 && endnum == (tok->tk_data)) {
+	printf("dwarfdump.conf error: "
+	       "%s missing register number (\"%s\" not valid)  %s line %lu",
+	       cmd, tok->tk_data, filename, lineno);
+	++errcount;
+	return FALSE;
+    }
+    if (endnum != (tok->tk_data + tok->tk_len)) {
+	printf("dwarfdump.conf error: "
+	       "%s Missing register number (\"%s\" not valid)  %s line %lu",
+	       cmd, tok->tk_data, filename, lineno);
+	++errcount;
+	return FALSE;
+    }
+    *val_out = val;
+    return TRUE;
+
+
+
+}
+
+/* We are guaranteed it's a reg: command, so parse that command
+    and record the interesting data.
+*/
+static int
+parsereg(char *cp, char *fname, unsigned long lineno,
+	 struct dwconf_s *conf, struct comtable_s *comtab)
+{
+    size_t clen = comtab->namelen;
+    struct token_s regnum;
+    struct token_s tokreg;
+    unsigned long val = 0;
+    int ok = FALSE;
+
+    cp = cp + clen + 1;
+    cp = get_token(cp, &tokreg);
+    cp = get_token(cp, &regnum);
+    if (tokreg.tk_len == 0) {
+	printf("dwarfdump.conf error: "
+	       "reg: missing register name  %s line %lu",
+	       fname, lineno);
+	++errcount;
+	return FALSE;
+
+    }
+    if (regnum.tk_len == 0) {
+	printf("dwarfdump.conf error: "
+	       "reg: missing register number  %s line %lu",
+	       fname, lineno);
+	++errcount;
+	return FALSE;
+    }
+
+    ok = make_a_number(comtab->name, fname, lineno, &regnum, &val);
+
+    if (!ok) {
+	++errcount;
+	return FALSE;
+    }
+
+    add_to_reg_table(conf, tokreg.tk_data, val, fname, lineno);
+
+    {
+	int res = ensure_has_no_more_tokens(cp, fname, lineno);
+
+	return res;
+    }
+}
+
+/*
+   We are guaranteed it's an frame_interface: command.
+   Parse it and record the value data.
+*/
+static int
+parseframe_interface(char *cp, char *fname, unsigned long lineno,
+		     struct dwconf_s *conf, struct comtable_s *comtab)
+{
+    size_t clen = comtab->namelen;
+    struct token_s tok;
+    unsigned long val = 0;
+    int ok = FALSE;
+
+    cp = cp + clen + 1;
+    cp = get_token(cp, &tok);
+    if (tok.tk_len == 0) {
+	printf("dwarfdump.conf error: "
+	       "%s missing interface number %s line %lu",
+	       comtab->name, fname, lineno);
+	++errcount;
+	return FALSE;
+    }
+
+    ok = make_a_number(comtab->name, fname, lineno, &tok, &val);
+
+    if (!ok) {
+	++errcount;
+	return FALSE;
+    }
+    if (val != 2 && val != 3) {
+	printf("dwarfdump.conf error: "
+	       "%s only interface numbers 2 or 3 are allowed, "
+	       " not %lu. %s line %lu",
+	       comtab->name, val, fname, lineno);
+	++errcount;
+	return FALSE;
+    }
+
+    conf->cf_interface_number = (int) val;
+    {
+	int res = ensure_has_no_more_tokens(cp, fname, lineno);
+
+	return res;
+    }
+}
+
+/*
+   We are guaranteed it's a cfa_reg: command. Parse it
+   and record the important data.
+*/
+static int
+parsecfa_reg(char *cp, char *fname, unsigned long lineno,
+	     struct dwconf_s *conf, struct comtable_s *comtab)
+{
+    size_t clen = comtab->namelen;
+    struct token_s tok;
+    unsigned long val = 0;
+    int ok = FALSE;
+
+    cp = cp + clen + 1;
+    cp = get_token(cp, &tok);
+    if (tok.tk_len == 0) {
+	printf("dwarfdump.conf error: "
+	       "%s missing cfa_reg number %s line %lu",
+	       comtab->name, fname, lineno);
+	++errcount;
+	return FALSE;
+    }
+
+    ok = make_a_number(comtab->name, fname, lineno, &tok, &val);
+
+    if (!ok) {
+	++errcount;
+	return FALSE;
+    }
+    conf->cf_cfa_reg = (int) val;
+    {
+	int res = ensure_has_no_more_tokens(cp, fname, lineno);
+
+	return res;
+    }
+}
+
+
+/* We are guaranteed it's an initial_reg_value: command,
+   parse it and put the reg value where it will be remembered. 
+*/
+static int
+parseinitial_reg_value(char *cp, char *fname,
+		       unsigned long lineno,
+		       struct dwconf_s *conf, struct comtable_s *comtab)
+{
+    size_t clen = comtab->namelen;
+    struct token_s tok;
+    unsigned long val = 0;
+    int ok = FALSE;
+
+    cp = cp + clen + 1;
+    cp = get_token(cp, &tok);
+    if (tok.tk_len == 0) {
+	printf("dwarfdump.conf error: "
+	       "%s missing initial reg value %s line %lu",
+	       comtab->name, fname, lineno);
+	++errcount;
+	return FALSE;
+    }
+
+    ok = make_a_number(comtab->name, fname, lineno, &tok, &val);
+
+    if (!ok) {
+
+	++errcount;
+	return FALSE;
+    }
+    conf->cf_initial_rule_value = (int) val;
+    {
+	int res = ensure_has_no_more_tokens(cp, fname, lineno);
+
+	return res;
+    }
+}
+
+
+/* We are guaranteed it's a table size command, parse it
+    and record the table size.
+*/
+static int
+parsereg_table_size(char *cp, char *fname, unsigned long lineno,
+		    struct dwconf_s *conf, struct comtable_s *comtab)
+{
+    size_t clen = comtab->namelen;
+    struct token_s tok;
+    unsigned long val = 0;
+    int ok = FALSE;
+
+    cp = cp + clen + 1;
+    cp = get_token(cp, &tok);
+    if (tok.tk_len == 0) {
+	printf("dwarfdump.conf error: "
+	       "%s missing reg table size value %s line %lu",
+	       comtab->name, fname, lineno);
+	++errcount;
+	return FALSE;
+    }
+
+    ok = make_a_number(comtab->name, fname, lineno, &tok, &val);
+
+    if (!ok) {
+	++errcount;
+	return FALSE;
+    }
+    conf->cf_table_entry_count = (unsigned long) val;
+    {
+	int res = ensure_has_no_more_tokens(cp, fname, lineno);
+
+	return res;
+    }
+
+}
+
+
+/*  We are guaranteed it's an endabi: command, parse it and
+    check we have the right abi.
+*/
+static int
+parseendabi(char *cp, char *fname, char *abiname, unsigned long lineno,
+	    struct comtable_s *comtab)
+{
+    size_t clen = comtab->namelen;
+    struct token_s tok;
+
+
+    cp = cp + clen + 1;
+    cp = get_token(cp, &tok);
+    if (strcmp(abiname, tok.tk_data) != 0) {
+	printf("%s error: "
+	       "mismatch abi name %s (here) vs. %s (beginabi:)  %s line %lu\n",
+	       comtab->name, tok.tk_data, abiname, fname, lineno);
+	++errcount;
+	return FALSE;
+    }
+    {
+	int res = ensure_has_no_more_tokens(cp, fname, lineno);
+
+	return res;
+    }
+
+}
+
+
+
+/* Return TRUE if we succeeded and filed in *out.
+   Return FALSE if we failed (and fill in nothing).
+  beginabi:  <abiname>
+  reg: <regname> <dwarf regnumber>
+  frame_interface: <integer value 2 or 3>
+  cfa_reg:  <number>
+  initial_reg_value:  <number: normally 1034 or 1035 >
+  reg_table_size: <size of table>
+  endabi:  <abiname>
+ 
+  We are positioned at the start of a beginabi: line when
+  called.
+
+*/
+static int
+parse_abi(FILE * stream, char *fname, char *abiname,
+	  struct dwconf_s *out, unsigned long lineno)
+{
+    struct dwconf_s localconf;
+    char buf[1000];
+    int comtype = 0;
+    long regcount = 0;
+
+    unsigned long beginabi_lineno = 0;
+    unsigned long frame_interface_lineno = 0;
+    unsigned long initial_reg_value_lineno = 0;
+    unsigned long reg_table_size_lineno = 0;
+    unsigned long cfa_reg_lineno = 0;
+    static int first_time_done = 0;
+    struct comtable_s *comtabp = 0;
+
+
+    if (first_time_done == 0) {
+	finish_comtable_setup();
+	first_time_done = 1;
+    }
+
+
+
+
+    init_conf_file_data(&localconf);
+
+    for (; !feof(stream);) {
+
+	char *line = 0;
+
+	/* long loffset = ftell(stream); */
+	line = fgets(buf, sizeof(buf), stream);
+	if (!line) {
+	    ++errcount;
+	    printf
+		("dwarfdump: end of file or error before endabi: in %s, line %lu\n",
+		 fname, lineno);
+	    return FALSE;
+	}
+	++lineno;
+	line = skipwhite(line);
+	comtype = which_command(line, &comtabp);
+	switch (comtype) {
+	case LT_ERROR:
+	    ++errcount;
+	    printf
+		("dwarfdump: Unknown text in %s is \"%s\" at line %lu\n",
+		 fname, line, lineno);
+	    break;
+	case LT_COMMENT:
+	    break;
+	case LT_BLANK:
+	    break;
+	case LT_BEGINABI:
+	    if (beginabi_lineno > 0) {
+		++errcount;
+		printf
+		    ("dwarfdump: Encountered beginabi: when not expected. "
+		     "%s line %lu previous beginabi line %lu\n", fname,
+		     lineno, beginabi_lineno);
+	    }
+	    beginabi_lineno = lineno;
+	    parsebeginabi(line, fname, abiname, lineno, comtabp);
+	    break;
+
+	case LT_REG:
+	    parsereg(line, fname, lineno, &localconf, comtabp);
+	    ++regcount;
+	    break;
+	case LT_FRAME_INTERFACE:
+	    if (frame_interface_lineno > 0) {
+		++errcount;
+		printf
+		    ("dwarfdump: Encountered duplicate frame_interface: "
+		     "%s line %lu previous frame_interface: line %lu\n",
+		     fname, lineno, frame_interface_lineno);
+	    }
+	    frame_interface_lineno = lineno;
+	    parseframe_interface(line, fname,
+				 lineno, &localconf, comtabp);
+	    break;
+	case LT_CFA_REG:
+	    if (cfa_reg_lineno > 0) {
+		printf("dwarfdump: Encountered duplicate cfa_reg: "
+		       "%s line %lu previous cfa_reg line %lu\n",
+		       fname, lineno, cfa_reg_lineno);
+		++errcount;
+	    }
+	    cfa_reg_lineno = lineno;
+	    parsecfa_reg(line, fname, lineno, &localconf, comtabp);
+	    break;
+	case LT_INITIAL_REG_VALUE:
+	    if (initial_reg_value_lineno > 0) {
+		printf
+		    ("dwarfdump: Encountered duplicate initial_reg_value_lineno: "
+		     "%s line %lu previous initial_reg_value: line %lu\n",
+		     fname, lineno, initial_reg_value_lineno);
+		++errcount;
+	    }
+	    initial_reg_value_lineno = lineno;
+
+	    parseinitial_reg_value(line, fname,
+				   lineno, &localconf, comtabp);
+	    break;
+	case LT_REG_TABLE_SIZE:
+	    if (reg_table_size_lineno > 0) {
+		printf("dwarfdump: duplicate reg_table_size: "
+		       "%s line %lu previous reg_table_size: line %lu\n",
+		       fname, lineno, reg_table_size_lineno);
+		++errcount;
+	    }
+	    reg_table_size_lineno = lineno;
+	    parsereg_table_size(line, fname,
+				lineno, &localconf, comtabp);
+	    break;
+	case LT_ENDABI:
+	    parseendabi(line, fname, abiname, lineno, comtabp);
+
+	    if (regcount > localconf.cf_table_entry_count) {
+		printf("dwarfdump: more registers named than "
+		       " in  %s  ( %lu named vs  %s %lu)  %s line %lu\n",
+		       abiname, (unsigned long) regcount,
+		       name_reg_table_size,
+		       (unsigned long) localconf.cf_table_entry_count,
+		       fname, (unsigned long) lineno);
+		++errcount;
+	    }
+
+	    *out = localconf;
+	    return TRUE;
+	default:
+	    printf
+		("dwarfdump internal error, impossible line type %d  %s %lu \n",
+		 (int) comtype, fname, lineno);
+	    exit(1);
+
+	}
+    }
+    ++errcount;
+    printf("End of file, no endabi: found. %s, line %lu\n",
+	   fname, lineno);
+    return FALSE;
+}
+
+/* MIPS/IRIX frame register names.
+   For alternate name sets, use dwarfdump.conf or
+   revise dwarf.h and libdwarf.h and this table.
+*/
+static char *regnames[] = {
+    "cfa",
+    "r1/at", "r2/v0", "r3/v1",
+    "r4/a0", "r5/a1", "r6/a2", "r7/a3",
+    "r8/t0", "r9/t1", "r10/t2", "r11/t3",
+    "r12/t4", "r13/t5", "r14/t6", "r15/t7",
+    "r16/s0", "r17/s1", "r18/s2", "r19/s3",
+    "r20/s4", "r21/s5", "r22/s6", "r23/s7",
+    "r24/t8", "r25/t9", "r26/k0", "r27/k1",
+    "r28/gp", "r29/sp", "r30/s8", "r31",
+
+    "$f0", "$f1",
+    "$f2", "$f3",
+    "$f4", "$f5",
+    "$f6", "$f7",
+    "$f8", "$f9",
+    "$f10", "$f11",
+    "$f12", "$f13",
+    "$f14", "$f15",
+    "$f16", "$f17",
+    "$f18", "$f19",
+    "$f20", "$f21",
+    "$f22", "$f23",
+    "$f24", "$f25",
+    "$f26", "$f27",
+    "$f28", "$f29",
+    "$f30", "$f31",
+    "ra", "slk",
+};
+
+
+/* These defaults match MIPS/IRIX ABI defaults.
+   For a 'generic' ABI, see -R.
+   For other ABIs, see -x abi=<whatever>
+   to configure dwarfdump (and libdwarf) frame 
+   data reporting at runtime.
+*/
+void
+init_conf_file_data(struct dwconf_s *config_file_data)
+{
+    unsigned long base_table_count =
+	sizeof(regnames) / sizeof(regnames[0]);
+
+    memset(config_file_data, 0, sizeof(*config_file_data));
+    config_file_data->cf_interface_number = 2;
+    config_file_data->cf_table_entry_count = DW_REG_TABLE_SIZE;
+    config_file_data->cf_initial_rule_value =
+	DW_FRAME_REG_INITIAL_VALUE;
+    config_file_data->cf_cfa_reg = DW_FRAME_CFA_COL;
+    config_file_data->cf_regs = regnames;
+    config_file_data->cf_named_regs_table_size = base_table_count;
+    config_file_data->cf_regs_malloced = 0;
+    if (config_file_data->cf_table_entry_count != base_table_count) {
+	printf("dwarfdump: improper base table initization, "
+	       "header files wrong: "
+	       "DW_REG_TABLE_SIZE %u != string table size %lu\n",
+	       (unsigned) DW_REG_TABLE_SIZE,
+	       (unsigned long) base_table_count);
+	exit(1);
+    }
+
+    return;
+}
+
+/* Naming a few registers makes printing these just
+   a little bit faster.
+*/
+static char *genericregnames[] = {
+  "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9",
+  "r10", "r11", "r12", "r13", "r14", "r15", "r16", "r17", "r18", "r19",
+  "r20",
+};
+
+/* A 'generic' ABI. For up to 1000 registers. 
+   Perhaps cf_initial_rule_value should be d
+   UNDEFINED VALUE (1034) instead, but for the purposes of
+   getting the dwarfdump output correct
+   either will work.
+*/
+void
+init_generic_config_1000_regs(struct dwconf_s *config_file_data)
+{
+    unsigned long generic_table_count =
+	sizeof(genericregnames) / sizeof(genericregnames[0]);
+    config_file_data->cf_interface_number = 3;
+    config_file_data->cf_table_entry_count = 1000;
+    config_file_data->cf_initial_rule_value = 1035; /* SAME VALUE */
+    config_file_data->cf_cfa_reg = 1036;
+    config_file_data->cf_regs = genericregnames;
+    config_file_data->cf_named_regs_table_size = generic_table_count;
+    config_file_data->cf_regs_malloced = 0;
+}
+
+/*  Print the 'right' string for the register we are given.
+    Deal sensibly with the special regs as well as numbers
+    we know and those we have not been told about.
+
+*/
+void
+print_reg_from_config_data(Dwarf_Signed reg,
+			   struct dwconf_s *config_data)
+{
+    char *name = 0;
+
+    if (reg == config_data->cf_cfa_reg) {
+	fputs("cfa",stdout);
+	return;
+    }
+    if (reg == DW_FRAME_CFA_COL3) {
+	/* This should not be necessary, but sometimes one forgets to
+	   do the cfa_reg: command in dwarfdump.conf */
+	fputs("cfa",stdout);
+	return;
+    }
+    if (reg == DW_FRAME_UNDEFINED_VAL) {
+	fputs("u",stdout);
+	return;
+    }
+    if (reg == DW_FRAME_SAME_VAL) {
+	fputs("s",stdout);
+	return;
+    }
+    if (config_data->cf_regs == 0 ||
+	reg < 0 || reg > config_data->cf_named_regs_table_size) {
+	printf("r%lld", (signed long long) reg);
+	return;
+    }
+    name = config_data->cf_regs[reg];
+    if (!name) {
+        /* Can happen, the reg names table can be sparse. */
+	printf("r%lld", (signed long long) reg);
+	return;
+    }
+    fputs(name,stdout);
+    return;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwconf.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,91 @@
+/*
+  Copyright (C) 2006 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write the Free Software Foundation, Inc., 51
+  Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/dwconf.h,v 1.2 2006/04/18 04:29:39 davea Exp $ */
+
+
+/*
+    declarations helping configure the frame reader.
+*/
+struct dwconf_s {
+    char *cf_config_file_path;
+    char *cf_abi_name;
+
+    /* 2 for old, 3 for frame interface 3. 2 means use the old
+       mips-abi-oriented frame interface. 3 means use the new
+       DWARF3-capable and configureable-abi interface.
+
+       Now, anyone who revises dwarf.h and libdwarf.h to match their
+       abi-of-interest will still be able to use cf_interface_number 2
+       as before.  But most folks don't update those header files and
+       instead of making *them* configurable we make dwarfdump (and
+       libdwarf) configurable sufficiently to print frame information
+       sensibly. */
+    int cf_interface_number;
+
+    /* The number of table rules , aka columns. For MIPS/IRIX is 66. */
+    unsigned long cf_table_entry_count;
+
+    /* Array of cf_table_entry_count reg names. Names not filled in
+       from dwarfdump.conf have NULL (0) pointer value. 
+	cf_named_regs_table_size must match size of cf_regs array.
+	Set cf_regs_malloced  1  if table was malloced. Set 0
+        if static.
+	*/
+    char **cf_regs;
+    unsigned long cf_named_regs_table_size;
+    int    cf_regs_malloced; 
+
+    /* The 'default initial value' when intializing a table. for MIPS
+       is DW_FRAME_SAME_VAL(1035). For other ISA/ABIs may be
+       DW_FRAME_UNDEFINED_VAL(1034). */
+    int cf_initial_rule_value;
+
+    /* The number of the cfa 'register'. For cf_interface_number 2 of 
+       MIPS this is 0. For other architectures (and anytime using
+       cf_interface_number 3) this should be outside the table, a
+       special value such as 1036, not a table column at all).  */
+    int cf_cfa_reg;
+};
+
+
+/* Returns DW_DLV_OK if works. DW_DLV_ERROR if cannot do what is asked. */
+int find_conf_file_and_read_config(char *named_file,
+				   char *named_abi, char **defaults,
+				   struct dwconf_s *conf_out);
+void init_conf_file_data(struct dwconf_s *config_file_data);
+
+void print_reg_from_config_data(Dwarf_Signed reg,
+		struct dwconf_s *config_data);
+
+
+void init_generic_config_1000_regs(struct dwconf_s *conf);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/esb.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,210 @@
+/*
+  Copyright (C) 2005 Silicon Graphics, Inc.  All Rights Reserved.
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write the Free Software Foundation, Inc., 51
+  Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/esb.c,v 1.1 2005/08/04 05:09:37 davea Exp $ */
+
+/* esb.c 
+   extensible string buffer.
+
+   A simple means (vaguely like a C++ class) that
+   enables safely saving strings of arbitrary length built up
+   in small pieces.
+
+*/
+
+#include "globals.h"
+#include "esb.h"
+
+#define INITIAL_ALLOC 1024
+static size_t alloc_size = INITIAL_ALLOC;
+
+
+static void
+init_esb_string(struct esb_s *data, size_t min_len)
+{
+    string d;
+
+    if (data->esb_allocated_size > 0) {
+	return;
+    }
+    if (min_len < alloc_size) {
+	min_len = alloc_size;
+    }
+    d = malloc(min_len);
+    if (!d) {
+	fprintf(stderr,
+		"dwarfdump is out of memory allocating %lu bytes\n",
+		(unsigned long) min_len);
+	exit(5);
+    }
+    data->esb_string = d;
+    data->esb_allocated_size = min_len;
+    data->esb_string[0] = 0;
+    data->esb_used_bytes = 0;
+}
+
+/* Make more room. Leaving  contents unchanged, effectively.
+*/
+static void
+allocate_more(struct esb_s *data, size_t len)
+{
+    size_t new_size = data->esb_allocated_size + len;
+    string newd = 0;
+
+    if (new_size < alloc_size)
+	new_size = alloc_size;
+    newd = realloc(data->esb_string, new_size);
+    if (!newd) {
+	fprintf(stderr, "dwarfdump is out of memory re-allocating "
+		"%lu bytes\n", (unsigned long) new_size);
+	exit(5);
+    }
+    data->esb_string = newd;
+    data->esb_allocated_size = new_size;
+}
+
+static void
+  esb_appendn_internal(struct esb_s *data, string in_string, size_t len);
+
+void
+esb_appendn(struct esb_s *data, string in_string, size_t len)
+{
+    size_t full_len = strlen(in_string);
+
+    if (full_len < len) {
+	fprintf(stderr, "dwarfdump internal error, bad string length "
+		" %lu  < %lu \n",
+		(unsigned long) full_len, (unsigned long) len);
+	len = full_len;
+    }
+
+    esb_appendn_internal(data, in_string, len);
+}
+
+/* The length is gotten from the in_string itself. */
+void
+esb_append(struct esb_s *data, string in_string)
+{
+    size_t len = strlen(in_string);
+
+    esb_appendn_internal(data, in_string, len);
+}
+
+/* The 'len' is believed. Do not pass in strings < len bytes long. */
+static void
+esb_appendn_internal(struct esb_s *data, string in_string, size_t len)
+{
+    size_t remaining = 0;
+    size_t needed = len + 1;
+
+    if (data->esb_allocated_size == 0) {
+	size_t maxlen = (len > alloc_size) ? len : alloc_size;
+
+	init_esb_string(data, maxlen);
+    }
+    remaining = data->esb_allocated_size - data->esb_used_bytes;
+    if (remaining < needed) {
+	allocate_more(data, needed);
+    }
+    strncpy(&data->esb_string[data->esb_used_bytes], in_string, len);
+    data->esb_used_bytes += len;
+    /* Insist on explicit NUL terminator */
+    data->esb_string[data->esb_used_bytes] = 0;
+}
+
+/* Always returns an empty string or a non-empty string. Never 0. */
+string
+esb_get_string(struct esb_s *data)
+{
+    if (data->esb_allocated_size == 0) {
+	init_esb_string(data, alloc_size);
+    }
+    return data->esb_string;
+}
+
+
+/* Sets esb_used_bytes to zero. The string is not freed and
+   esb_allocated_size is unchanged.  */
+void
+esb_empty_string(struct esb_s *data)
+{
+    if (data->esb_allocated_size == 0) {
+	init_esb_string(data, alloc_size);
+    }
+    data->esb_used_bytes = 0;
+    data->esb_string[0] = 0;
+
+}
+
+
+/* Return esb_used_bytes. */
+size_t
+esb_string_len(struct esb_s *data)
+{
+    return data->esb_used_bytes;
+}
+
+
+/* The following are for testing esb, not use by dwarfdump. */
+
+/* *data is presumed to contain garbage, not values, and
+   is properly initialized. */
+void
+esb_constructor(struct esb_s *data)
+{
+    memset(data, 0, sizeof(*data));
+}
+
+/*  The string is freed, contents of *data set to zeroes. */
+void
+esb_destructor(struct esb_s *data)
+{
+    if (data->esb_string) {
+	free(data->esb_string);
+    }
+    esb_constructor(data);
+}
+
+
+/* To get all paths in the code tested, this sets the
+   allocation/reallocation to the given value, which can be quite small
+   but must not be zero. */
+void
+esb_alloc_size(size_t size)
+{
+    alloc_size = size;
+}
+
+size_t
+esb_get_allocated_size(struct esb_s *data)
+{
+    return data->esb_allocated_size;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/esb.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,83 @@
+/*
+  Copyright (C) 2005 Silicon Graphics, Inc.  All Rights Reserved.
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write the Free Software Foundation, Inc., 51
+  Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/esb.h,v 1.1 2005/08/04 05:09:37 davea Exp $ */
+
+
+/*  esb.h
+	Extensible string buffer.
+    A simple vaguely  object oriented extensible string buffer.
+
+    The struct could be opaque here, but it seems ok to expose
+    the contents: simplifies debugging.
+*/
+
+
+struct esb_s {
+    string  esb_string; /* pointer to the data itself, or  NULL. */
+    size_t  esb_allocated_size; /* Size of allocated data or 0 */
+    size_t  esb_used_bytes; /* Amount of space used  or 0 */
+};
+
+/* string length taken from string itself. */
+void esb_append(struct esb_s *data, string in_string);
+
+/* The 'len' is believed. Do not pass in strings < len bytes long. */
+void esb_appendn(struct esb_s *data, string in_string, size_t len);
+
+/* Always returns an empty string or a non-empty string. Never 0. */
+string esb_get_string(struct esb_s *data);
+
+
+/* Sets esb_used_bytes to zero. The string is not freed and
+   esb_allocated_size is unchanged.  */
+void esb_empty_string(struct esb_s *data);
+
+
+/* Return esb_used_bytes. */
+size_t esb_string_len(struct esb_s *data);
+
+/* The following are for testing esb, not use by dwarfdump. */
+
+/* *data is presumed to contain garbage, not values, and
+   is properly initialized. */
+void esb_constructor(struct esb_s *data);
+
+/*  The string is freed, contents of *data set to zeroes. */
+void esb_destructor(struct esb_s *data);
+
+
+/* To get all paths in the code tested, this sets the
+   allocation/reallocation to the given value, which can be quite small
+   but must not be zero. */
+void esb_alloc_size(size_t size);
+size_t esb_get_allocated_size(struct esb_s *data);
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/globals.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,231 @@
+/* 
+  Copyright (C) 2000,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write the Free Software Foundation, Inc., 51
+  Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/globals.h,v 1.25 2006/04/17 00:09:56 davea Exp $ */
+
+#ifndef globals_INCLUDED
+#define globals_INCLUDED
+
+#include "config.h"
+#if (!defined(HAVE_RAW_LIBELF_OK) && defined(HAVE_LIBELF_OFF64_OK) )
+/* At a certain point libelf.h requires _GNU_SOURCE.
+   here we assume the criteria in configure determine that
+   usefully.
+*/
+#define _GNU_SOURCE 1
+#endif
+
+
+/* We want __uint32_t and __uint64_t and __int32_t __int64_t
+   properly defined but not duplicated, since duplicate typedefs
+   are not legal C.
+*/
+/*
+ HAVE___UINT32_T
+ HAVE___UINT64_T will be set by configure if
+ our 4 types are predefined in compiler
+*/
+
+
+#if (!defined(HAVE___UINT32_T)) && defined(HAVE_SGIDEFS_H)
+#include <sgidefs.h> /* sgidefs.h defines them */
+#define HAVE___UINT32_T 1
+#define HAVE___UINT64_T 1
+#endif
+
+
+
+#if (!defined(HAVE___UINT32_T)) && defined(HAVE_SYS_TYPES_H) && defined(HAVE___UINT32_T_IN_SYS_TYPES_H)
+#  include <sys/types.h>
+/* we assume __[u]int32_t and __[u]int64_t defined 
+   since __uint32_t defined in the sys/types.h in use */
+#define HAVE___UINT32_T 1
+#define HAVE___UINT64_T 1
+#endif
+
+#ifndef HAVE___UINT32_T
+typedef int __int32_t;
+typedef unsigned  __uint32_t;
+#define HAVE___UINT32_T 1
+#endif
+#ifndef HAVE___UINT64_T
+typedef long long __int64_t;
+typedef unsigned long long  __uint64_t;
+#define HAVE___UINT64_T 1
+#endif
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#ifdef HAVE_ELF_H
+#include <elf.h>
+#endif
+#ifdef HAVE_LIBELF_H
+#include <libelf.h>
+#else
+#ifdef HAVE_LIBELF_LIBELF_H
+#include <libelf/libelf.h>
+#endif
+#endif
+#include <dwarf.h>
+#include <libdwarf.h>
+
+typedef char * string;
+typedef int boolean;
+#ifndef FALSE
+#define FALSE 0
+#endif 
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+/* size of attrib_buffer, defined in print_die.c */
+#define ATTRIB_BUFSIZ 999
+
+typedef struct {
+    int checks;
+    int errors;
+} Dwarf_Check_Result;
+
+extern int verbose;
+extern boolean dense;
+extern boolean ellipsis;
+extern boolean dst_format;
+extern boolean use_mips_regnames;
+extern boolean show_global_offsets;
+
+extern boolean check_pubname_attr;
+extern boolean check_attr_tag;
+extern boolean check_tag_tree;
+extern boolean check_type_offset;
+
+extern Dwarf_Check_Result abbrev_code_result;
+extern Dwarf_Check_Result pubname_attr_result;
+extern Dwarf_Check_Result reloc_offset_result;
+extern Dwarf_Check_Result attr_tag_result;
+extern Dwarf_Check_Result tag_tree_result;
+extern Dwarf_Check_Result type_offset_result;
+
+extern boolean info_flag;
+extern boolean use_old_dwarf_loclist;
+
+extern char cu_name[ ];
+extern boolean cu_name_flag;
+extern Dwarf_Unsigned cu_offset;
+extern Dwarf_Off fde_offset_for_cu_low;
+extern Dwarf_Off fde_offset_for_cu_high;
+
+
+extern int check_error;
+extern Dwarf_Error err;
+extern void print_error (Dwarf_Debug dbg, string msg,int res, Dwarf_Error err);
+
+extern void print_line_numbers_this_cu (Dwarf_Debug dbg, Dwarf_Die in_die);
+struct dwconf_s;
+extern void print_frames (Dwarf_Debug dbg, int print_debug_frame,
+		int print_eh_frame,struct dwconf_s *);
+extern void print_pubnames (Dwarf_Debug dbg);
+extern void print_macinfo (Dwarf_Debug dbg);
+extern void print_locs (Dwarf_Debug dbg);
+extern void print_abbrevs (Dwarf_Debug dbg);
+extern void print_strings (Dwarf_Debug dbg);
+extern void print_aranges (Dwarf_Debug dbg);
+extern void print_relocinfo (Dwarf_Debug dbg);
+extern void print_static_funcs(Dwarf_Debug dbg);
+extern void print_static_vars(Dwarf_Debug dbg);
+enum type_type_e {SGI_TYPENAME, DWARF_PUBTYPES} ;
+extern void print_types(Dwarf_Debug dbg,enum type_type_e type_type);
+extern void print_weaknames(Dwarf_Debug dbg);
+extern void print_exception_tables(Dwarf_Debug dbg);
+extern string get_fde_proc_name(Dwarf_Debug dbg, Dwarf_Addr low_pc);
+extern void print_die_and_children(
+	Dwarf_Debug dbg, 
+	Dwarf_Die in_die,
+	char **srcfiles,
+	Dwarf_Signed cnt);
+extern void print_one_die(
+	Dwarf_Debug dbg, 
+	Dwarf_Die die, 
+	boolean print_information,
+	char **srcfiles,
+	Dwarf_Signed cnt);
+
+#define DWARF_CHECK_ERROR(str) {\
+	printf("*** DWARF CHECK: %s ***\n", str);\
+	check_error ++; \
+}
+
+#define DWARF_CHECK_ERROR2(str1, str2) {\
+	printf("*** DWARF CHECK: %s: %s ***\n", str1, str2);\
+	check_error ++; \
+}
+
+#define DWARF_CHECK_ERROR3(str1, str2,strexpl) {\
+	printf("*** DWARF CHECK: %s -> %s: %s ***\n", str1, str2,strexpl);\
+	check_error ++; \
+}
+
+struct esb_s;
+extern Dwarf_Die current_cu_die_for_print_frames; /* This is
+        an awful hack, making this public. But it enables
+        cleaning up (doing all dealloc needed). */
+extern void printreg(Dwarf_Signed reg,struct dwconf_s *config_data);
+extern void print_frame_inst_bytes(Dwarf_Debug dbg,
+                       Dwarf_Ptr cie_init_inst, Dwarf_Signed len,
+                       Dwarf_Signed data_alignment_factor,
+                       int code_alignment_factor, Dwarf_Half addr_size,
+			struct dwconf_s *config_data);
+
+
+extern Dwarf_Unsigned local_dwarf_decode_u_leb128(unsigned char *leb128,
+                            unsigned int *leb128_length);
+
+extern Dwarf_Signed local_dwarf_decode_s_leb128(unsigned char *leb128,
+                            unsigned int *leb128_length);
+
+extern void dump_block(char *prefix, char *data, Dwarf_Signed len);
+
+int
+dwarfdump_print_one_locdesc(Dwarf_Debug dbg,
+                         Dwarf_Locdesc * llbuf,
+			 int skip_locdesc_header,
+                         struct esb_s *string_out);
+void clean_up_die_esb();
+void clean_up_syms_malloc_data();
+
+
+
+
+#endif /* globals_INCLUDED */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/install.sh	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5; it is not part of GNU.
+#
+# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+
+instcmd="$mvprog"
+chmodcmd=""
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:  no input file specified"
+	exit 1
+fi
+
+if [ x"$dst" = x ]
+then
+	echo "install:  no destination specified"
+	exit 1
+fi
+
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+if [ -d $dst ]
+then
+	dst="$dst"/`basename $src`
+fi
+
+# Make a temp file name in the proper directory.
+
+dstdir=`dirname $dst`
+dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+$doit $instcmd $src $dsttmp
+
+# and set any options; do chmod last to preserve setuid bits
+
+if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
+if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
+if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
+if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
+
+# Now rename the file to the real destination.
+
+$doit $rmcmd $dst
+$doit $mvcmd $dsttmp $dst
+
+
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/makename.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,68 @@
+
+/* 
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write the Free Software Foundation, Inc., 51
+  Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+   makename.c
+   $Revision: 1.4 $ 
+   $Date: 2005/11/08 21:48:42 $
+
+   This used to be elaborate stuff.
+   Now it is trivial, as duplicating names is
+   unimportant in dwarfdump (in general).
+
+   And in fact, this is only called for attributes and
+   tags etc whose true name is unknown. Not for
+   any normal case.
+
+*/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "makename.h"
+
+char *
+makename(char *s)
+{
+    char *newstr;
+
+    if (!s) {
+	return "";
+    }
+
+    newstr = strdup(s);
+    if (newstr == 0) {
+	fprintf(stderr, "Out of memory mallocing %d bytes\n",
+		(int) strlen(s));
+	exit(1);
+    }
+    return newstr;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/makename.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,53 @@
+#ifndef names_h
+#define names_h
+/* 
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write the Free Software Foundation, Inc., 51
+  Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+	makename.h   
+	$Revision: 1.3 $
+	$Date: 2004/10/28 22:26:58 $
+
+	This is for putting strings into stable storage.
+
+        Effectively an strdup() wrapper.
+
+	Rarely called.
+
+	It leaks memory, (the memory
+        is never freed) but that seems unimportant since
+	use of this is very rare.
+
+*/
+
+char * makename(char *); /* makes a copy of the string in
+	a malloc area.  Can never return 0. */
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_die.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1313 @@
+/* 
+  Copyright (C) 2000,2004,2005,2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+  Portions Copyright 2007 David Anderson. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write the Free Software Foundation, Inc., 51
+  Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+$ Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_die.c,v 1.51 2006/04/01 16:20:21 davea Exp $ */
+
+#include "globals.h"
+#include "dwarf_names.h"
+#include "esb.h"		/* For flexible string buffer. */
+#include "makename.h"		/* Non-duplicating string table. */
+
+static void get_attr_value(Dwarf_Debug dbg, Dwarf_Half tag,
+			   Dwarf_Attribute attrib, 
+                           char **srcfiles,
+			   Dwarf_Signed cnt, struct esb_s *esbp);
+static void print_attribute(Dwarf_Debug dbg, Dwarf_Die die,
+			    Dwarf_Half attr,
+			    Dwarf_Attribute actual_addr,
+			    boolean print_information, char **srcfiles,
+			    Dwarf_Signed cnt);
+static void get_location_list(Dwarf_Debug dbg, Dwarf_Die die,
+			      Dwarf_Attribute attr, struct esb_s *esbp);
+static int tag_attr_combination(Dwarf_Half tag, Dwarf_Half attr);
+static int _dwarf_print_one_expr_op(Dwarf_Debug dbg,Dwarf_Loc* expr,int index, struct esb_s *string_out);
+
+/* esb_base is static so gets initialized to zeros.  
+   It is not thread-safe or
+   safe for multiple open producer instances for
+   but that does not matter here in dwarfdump.
+
+   The memory used by esb_base is never freed.
+*/
+static struct esb_s esb_base;	
+
+static int indent_level = 0;
+static boolean local_symbols_already_began = FALSE;
+
+typedef string(*encoding_type_func) (Dwarf_Debug dbg, Dwarf_Half val);
+
+Dwarf_Off fde_offset_for_cu_low = DW_DLV_BADOFFSET;
+Dwarf_Off fde_offset_for_cu_high = DW_DLV_BADOFFSET;
+
+/* Dwarf_Half list_of_attrs[] */
+/*#include "at_list.i" unreferenced */
+
+#define DIE_STACK_SIZE 300
+static Dwarf_Die die_stack[DIE_STACK_SIZE];
+
+#define PUSH_DIE_STACK(x) { die_stack[indent_level] = x; }
+#define POP_DIE_STACK { die_stack[indent_level] = 0; }
+
+#include "_tag_tree_table.c"
+
+/*
+   Look only at valid table entries
+   The check here must match the building-logic in
+   tag_tree.c
+   And must match the tags defined in dwarf.h
+*/
+#define MAX_CHECKED_TAG_ID 0x35
+static int
+tag_tree_combination(Dwarf_Half tag_parent, Dwarf_Half tag_child)
+{
+    if (tag_parent > 0 && tag_parent <= MAX_CHECKED_TAG_ID
+	&& tag_child > 0 && tag_child <= MAX_CHECKED_TAG_ID) {
+	return ((tag_tree_combination_table[tag_parent]
+		 [tag_child / 0x20]
+		 & (1 << (tag_child % 0x20))) > 0 ? TRUE : FALSE);
+    } else
+	return (FALSE);
+}
+
+/* recursively follow the die tree */
+extern void
+print_die_and_children(Dwarf_Debug dbg, Dwarf_Die in_die_in,
+		       char **srcfiles, Dwarf_Signed cnt)
+{
+    Dwarf_Die child;
+    Dwarf_Die sibling;
+    Dwarf_Error err;
+    int tres;
+    int cdres;
+    Dwarf_Die in_die = in_die_in;
+
+    for (;;) {
+	PUSH_DIE_STACK(in_die);
+
+	if (check_tag_tree) {
+	    tag_tree_result.checks++;
+	    if (indent_level == 0) {
+		Dwarf_Half tag;
+
+		tres = dwarf_tag(in_die, &tag, &err);
+		if (tres != DW_DLV_OK) {
+		    tag_tree_result.errors++;
+		    DWARF_CHECK_ERROR
+			("Tag-tree root is not DW_TAG_compile_unit")
+		} else if (tag == DW_TAG_compile_unit) {
+		    /* OK */
+		} else {
+		    tag_tree_result.errors++;
+		    DWARF_CHECK_ERROR
+			("tag-tree root is not DW_TAG_compile_unit")
+		}
+	    } else {
+		Dwarf_Half tag_parent, tag_child;
+		int pres;
+		int cres;
+		char *ctagname = "<child tag invalid>";
+		char *ptagname = "<parent tag invalid>";
+
+		pres =
+		    dwarf_tag(die_stack[indent_level - 1], &tag_parent,
+			      &err);
+		cres = dwarf_tag(in_die, &tag_child, &err);
+		if (pres != DW_DLV_OK)
+		    tag_parent = 0;
+		if (cres != DW_DLV_OK)
+		    tag_child = 0;
+		if (cres != DW_DLV_OK || pres != DW_DLV_OK) {
+		    if (cres == DW_DLV_OK) {
+			ctagname = get_TAG_name(dbg, tag_child);
+		    }
+		    if (pres == DW_DLV_OK) {
+			ptagname = get_TAG_name(dbg, tag_parent);
+		    }
+		    DWARF_CHECK_ERROR3(ptagname,
+				       ctagname,
+				       "Tag-tree relation is not standard..");
+		} else if (tag_tree_combination(tag_parent, tag_child)) {
+		    /* OK */
+		} else {
+		    DWARF_CHECK_ERROR3(get_TAG_name(dbg, tag_parent),
+				       get_TAG_name(dbg, tag_child),
+				       "tag-tree relation is not standard.");
+		}
+	    }
+	}
+
+	/* here to pre-descent processing of the die */
+	print_one_die(dbg, in_die, info_flag, srcfiles, cnt);
+
+	cdres = dwarf_child(in_die, &child, &err);
+	/* child first: we are doing depth-first walk */
+	if (cdres == DW_DLV_OK) {
+	    indent_level++;
+	    if(indent_level >= DIE_STACK_SIZE ) {
+	        print_error(dbg,
+                  "compiled in DIE_STACK_SIZE limit exceeded",
+                  DW_DLV_OK,err);
+	    }
+	    print_die_and_children(dbg, child, srcfiles, cnt);
+	    indent_level--;
+	    if (indent_level == 0)
+		local_symbols_already_began = FALSE;
+	    dwarf_dealloc(dbg, child, DW_DLA_DIE);
+	} else if (cdres == DW_DLV_ERROR) {
+	    print_error(dbg, "dwarf_child", cdres, err);
+	}
+
+	cdres = dwarf_siblingof(dbg, in_die, &sibling, &err);
+	if (cdres == DW_DLV_OK) {
+	    /* print_die_and_children(dbg, sibling, srcfiles, cnt); We
+	       loop around to actually print this, rather than
+	       recursing. Recursing is horribly wasteful of stack
+	       space. */
+	} else if (cdres == DW_DLV_ERROR) {
+	    print_error(dbg, "dwarf_siblingof", cdres, err);
+	}
+
+	/* Here do any post-descent (ie post-dwarf_child) processing of 
+	   the in_die. */
+
+	POP_DIE_STACK;
+	if (in_die != in_die_in) {
+	    /* Dealloc our in_die, but not the argument die, it belongs 
+	       to our caller. Whether the siblingof call worked or not. 
+	     */
+	    dwarf_dealloc(dbg, in_die, DW_DLA_DIE);
+	}
+	if (cdres == DW_DLV_OK) {
+	    /* Set to process the sibling, loop again. */
+	    in_die = sibling;
+	} else {
+	    /* We are done, no more siblings at this level. */
+
+	    break;
+	}
+    }				/* end for loop on siblings */
+    return;
+}
+
+#define SPACE(x) { register int i; for (i=0;i<x;i++) putchar(' '); }
+
+
+/* print info about die */
+void
+print_one_die(Dwarf_Debug dbg, Dwarf_Die die, boolean print_information,
+	      char **srcfiles, Dwarf_Signed cnt)
+{
+    Dwarf_Signed i;
+    Dwarf_Off offset, overall_offset;
+    string tagname;
+    Dwarf_Half tag;
+    Dwarf_Signed atcnt;
+    Dwarf_Attribute *atlist;
+    int tres;
+    int ores;
+    int atres;
+
+    tres = dwarf_tag(die, &tag, &err);
+    if (tres != DW_DLV_OK) {
+	print_error(dbg, "accessing tag of die!", tres, err);
+    }
+    tagname = get_TAG_name(dbg, tag);
+    ores = dwarf_dieoffset(die, &overall_offset, &err);
+    if (ores != DW_DLV_OK) {
+	print_error(dbg, "dwarf_dieoffset", ores, err);
+    }
+    ores = dwarf_die_CU_offset(die, &offset, &err);
+    if (ores != DW_DLV_OK) {
+	print_error(dbg, "dwarf_die_CU_offset", ores, err);
+    }
+
+    if (!dst_format && print_information) {
+	if (indent_level == 0) {
+	    if (dense)
+		printf("\n");
+	    else {
+		printf
+		    ("\nCOMPILE_UNIT<header overall offset = %llu>:\n",
+		     overall_offset - offset);
+	    }
+	} else if (local_symbols_already_began == FALSE &&
+		   indent_level == 1 && !dense) {
+	    printf("\nLOCAL_SYMBOLS:\n");
+	    local_symbols_already_began = TRUE;
+	}
+	if (dense) {
+            if (show_global_offsets) {
+	        if (indent_level == 0) {
+		    printf("<%d><%llu+%llu GOFF=%llu><%s>", indent_level,
+		       overall_offset - offset, offset,
+                       overall_offset, tagname);
+	        } else {
+		    printf("<%d><%llu GOFF=%llu><%s>", indent_level, 
+                       offset, overall_offset, tagname);
+	        }
+            } else {
+	        if (indent_level == 0) {
+		    printf("<%d><%llu+%llu><%s>", indent_level,
+		       overall_offset - offset, offset, tagname);
+	        } else {
+		    printf("<%d><%llu><%s>", indent_level, offset, tagname);
+	        }
+	    }
+	} else {
+            if (show_global_offsets) {
+	        printf("<%d><%5llu GOFF=%llu>\t%s\n", indent_level, offset,
+                    overall_offset, tagname);
+            } else {
+	        printf("<%d><%5llu>\t%s\n", indent_level, offset, tagname);
+	    }
+	}
+    }
+
+    atres = dwarf_attrlist(die, &atlist, &atcnt, &err);
+    if (atres == DW_DLV_ERROR) {
+	print_error(dbg, "dwarf_attrlist", atres, err);
+    } else if (atres == DW_DLV_NO_ENTRY) {
+	/* indicates there are no attrs.  It is not an error. */
+	atcnt = 0;
+    }
+
+
+    for (i = 0; i < atcnt; i++) {
+	Dwarf_Half attr;
+	int ares;
+
+	ares = dwarf_whatattr(atlist[i], &attr, &err);
+	if (ares == DW_DLV_OK) {
+	    print_attribute(dbg, die, attr,
+			    atlist[i],
+			    print_information, srcfiles, cnt);
+	} else {
+	    print_error(dbg, "dwarf_whatattr entry missing", ares, err);
+	}
+    }
+
+    for (i = 0; i < atcnt; i++) {
+	dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);
+    }
+    if (atres == DW_DLV_OK) {
+	dwarf_dealloc(dbg, atlist, DW_DLA_LIST);
+    }
+
+    if (dense && print_information) {
+	printf("\n\n");
+    }
+    return;
+}
+
+/* Encodings have undefined signedness. Accept either
+   signedness.  The values are small (they are defined
+   in the DWARF specification), so the
+   form the compiler uses (as long as it is
+   a constant value) is a non-issue.
+
+   If string_out is non-NULL, construct a string output, either
+   an error message or the name of the encoding.
+   The function pointer passed in is to code generated
+   by a script at dwarfdump build time. The code for
+   the val_as_string function is generated
+   from dwarf.h.  See <build dir>/dwarf_names.c
+
+   If string_out is non-NULL then attr_name and val_as_string
+   must also be non-NULL.
+
+*/
+int
+get_small_encoding_integer_and_name(Dwarf_Debug dbg,
+				    Dwarf_Attribute attrib,
+				    Dwarf_Unsigned * uval_out,
+				    char *attr_name,
+				    string * string_out,
+				    encoding_type_func val_as_string,
+				    Dwarf_Error * err)
+{
+    Dwarf_Unsigned uval = 0;
+    char buf[100];		/* The strings are small. */
+    int vres = dwarf_formudata(attrib, &uval, err);
+
+    if (vres != DW_DLV_OK) {
+	Dwarf_Signed sval = 0;
+
+	vres = dwarf_formsdata(attrib, &sval, err);
+	if (vres != DW_DLV_OK) {
+	    if (string_out != 0) {
+		snprintf(buf, sizeof(buf),
+			 "%s has a bad form.", attr_name);
+		*string_out = makename(buf);
+	    }
+	    return vres;
+	}
+	*uval_out = (Dwarf_Unsigned) sval;
+    } else {
+	*uval_out = uval;
+    }
+    if (string_out)
+	*string_out = val_as_string(dbg, (Dwarf_Half) uval);
+
+    return DW_DLV_OK;
+
+}
+
+
+
+
+/*
+ * We need a 32-bit signed number here, but there's no portable
+ * way of getting that.  So use __uint32_t instead.  It's supplied
+ * in a reliable way by the autoconf infrastructure.
+ */
+
+static void
+get_FLAG_BLOCK_string(Dwarf_Debug dbg, Dwarf_Attribute attrib)
+{
+    int fres = 0;
+    Dwarf_Block *tempb = 0;
+    __uint32_t * array = 0;
+    Dwarf_Unsigned array_len = 0;
+    __uint32_t * array_ptr;
+    Dwarf_Unsigned array_remain = 0;
+    char linebuf[100];
+
+    esb_empty_string(&esb_base);
+    esb_append(&esb_base, "\n");
+
+    /* first get compressed block data */
+    fres = dwarf_formblock (attrib,&tempb, &err);
+    if (fres != DW_DLV_OK) {
+	print_error(dbg,"DW_FORM_blockn cannot get block\n",fres,err);
+	return;
+    }
+
+    /* uncompress block into int array */
+    array = dwarf_uncompress_integer_block(dbg,
+			   1, /* 'true' (meaning signed ints)*/
+			   32, /* bits per unit */
+			   tempb->bl_data,
+			   tempb->bl_len,
+			   &array_len, /* len of out array */
+			   &err);
+    if (array == (void*) DW_DLV_BADOFFSET) {
+	print_error(dbg,"DW_AT_SUN_func_offsets cannot uncompress data\n",0,err);
+	return;
+    }
+    if (array_len == 0) {
+	print_error(dbg,"DW_AT_SUN_func_offsets has no data\n",0,err);
+	return;
+    }
+    
+    /* fill in string buffer */
+    array_remain = array_len;
+    array_ptr = array;
+    while (array_remain > 8) {
+	/* print a full line */
+	/* if you touch this string, update the magic number 78 below! */
+	snprintf(linebuf, sizeof(linebuf), 
+		"\n  %8x %8x %8x %8x %8x %8x %8x %8x",
+		array_ptr[0],		array_ptr[1],
+		array_ptr[2],		array_ptr[3],
+		array_ptr[4],		array_ptr[5],
+		array_ptr[6],		array_ptr[7]);
+	array_ptr += 8;
+	array_remain -= 8;
+	esb_append(&esb_base, linebuf);
+    }
+
+    /* now do the last line */
+    if (array_remain > 0) {
+	esb_append(&esb_base, "\n ");
+	while (array_remain > 0) {
+	    snprintf(linebuf, sizeof(linebuf), " %8x", *array_ptr);
+	    array_remain--;
+	    array_ptr++;
+	    esb_append(&esb_base, linebuf);
+	}
+    }
+    
+    /* free array buffer */
+    dwarf_dealloc_uncompressed_block(dbg, array);
+
+}
+
+static void
+print_attribute(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attr,
+		Dwarf_Attribute attr_in,
+		boolean print_information,
+		char **srcfiles, Dwarf_Signed cnt)
+{
+    Dwarf_Attribute attrib = 0;
+    Dwarf_Unsigned uval = 0;
+    string atname = 0;
+    string valname = 0;
+    int tres = 0;
+    Dwarf_Half tag = 0;
+
+    atname = get_AT_name(dbg, attr);
+
+    /* the following gets the real attribute, even in the face of an 
+       incorrect doubling, or worse, of attributes */
+    attrib = attr_in;
+    /* do not get attr via dwarf_attr: if there are (erroneously) 
+       multiple of an attr in a DIE, dwarf_attr will not get the
+       second, erroneous one and dwarfdump will print the first one
+       multiple times. Oops. */
+
+    tres = dwarf_tag(die, &tag, &err);
+    if (tres == DW_DLV_ERROR) {
+	tag = 0;
+    } else if (tres == DW_DLV_NO_ENTRY) {
+	tag = 0;
+    } else {
+	/* ok */
+    }
+    if (check_attr_tag) {
+	char *tagname = "<tag invalid>";
+
+	attr_tag_result.checks++;
+	if (tres == DW_DLV_ERROR) {
+	    attr_tag_result.errors++;
+	    DWARF_CHECK_ERROR3(tagname,
+			       get_AT_name(dbg, attr),
+			       "check the tag-attr combination.");
+	} else if (tres == DW_DLV_NO_ENTRY) {
+	    attr_tag_result.errors++;
+	    DWARF_CHECK_ERROR3(tagname,
+			       get_AT_name(dbg, attr),
+			       "check the tag-attr combination..")
+	} else if (tag_attr_combination(tag, attr)) {
+	    /* OK */
+	} else {
+	    attr_tag_result.errors++;
+	    tagname = get_TAG_name(dbg, tag);
+	    DWARF_CHECK_ERROR3(tagname,
+			       get_AT_name(dbg, attr),
+			       "check the tag-attr combination")
+	}
+    }
+
+    switch (attr) {
+    case DW_AT_language:
+	get_small_encoding_integer_and_name(dbg, attrib, &uval,
+					    "DW_AT_language", &valname,
+					    get_LANG_name, &err);
+	break;
+    case DW_AT_accessibility:
+	get_small_encoding_integer_and_name(dbg, attrib, &uval,
+					    "DW_AT_accessibility",
+					    &valname, get_ACCESS_name,
+					    &err);
+	break;
+    case DW_AT_visibility:
+	get_small_encoding_integer_and_name(dbg, attrib, &uval,
+					    "DW_AT_visibility",
+					    &valname, get_VIS_name,
+					    &err);
+	break;
+    case DW_AT_virtuality:
+	get_small_encoding_integer_and_name(dbg, attrib, &uval,
+					    "DW_AT_virtuality",
+					    &valname,
+					    get_VIRTUALITY_name, &err);
+	break;
+    case DW_AT_identifier_case:
+	get_small_encoding_integer_and_name(dbg, attrib, &uval,
+					    "DW_AT_identifier",
+					    &valname, get_ID_name,
+					    &err);
+	break;
+    case DW_AT_inline:
+	get_small_encoding_integer_and_name(dbg, attrib, &uval,
+					    "DW_AT_inline", &valname,
+					    get_INL_name, &err);
+	break;
+    case DW_AT_encoding:
+	get_small_encoding_integer_and_name(dbg, attrib, &uval,
+					    "DW_AT_encoding", &valname,
+					    get_ATE_name, &err);
+	break;
+    case DW_AT_ordering:
+	get_small_encoding_integer_and_name(dbg, attrib, &uval,
+					    "DW_AT_ordering", &valname,
+					    get_ORD_name, &err);
+	break;
+    case DW_AT_calling_convention:
+	get_small_encoding_integer_and_name(dbg, attrib, &uval,
+					    "DW_AT_calling_convention",
+					    &valname, get_CC_name,
+					    &err);
+	break;
+    case DW_AT_discr_list:	/* DWARF3 */
+	get_small_encoding_integer_and_name(dbg, attrib, &uval,
+					    "DW_AT_discr_list",
+					    &valname, get_DSC_name,
+					    &err);
+	break;
+    case DW_AT_location:
+    case DW_AT_data_member_location:
+    case DW_AT_vtable_elem_location:
+    case DW_AT_string_length:
+    case DW_AT_return_addr:
+    case DW_AT_use_location:
+    case DW_AT_static_link:
+    case DW_AT_frame_base:
+	/* value is a location description or location list */
+	esb_empty_string(&esb_base);
+	get_location_list(dbg, die, attrib, &esb_base);
+	valname = esb_get_string(&esb_base);
+	break;
+    case DW_AT_SUN_func_offsets:
+	get_FLAG_BLOCK_string(dbg, attrib);
+	valname = esb_get_string(&esb_base);
+	break;
+    case DW_AT_SUN_cf_kind:
+	{
+	    Dwarf_Half kind;
+	    Dwarf_Unsigned tempud;
+	    Dwarf_Error err;
+	    int wres;
+	    wres = dwarf_formudata (attrib,&tempud, &err);
+	    if(wres == DW_DLV_OK) {
+		kind = tempud;
+		valname = get_ATCF_name(dbg, kind);
+	    } else if (wres == DW_DLV_NO_ENTRY) {
+		valname = "?";
+	    } else {
+		print_error(dbg,"Cannot get formudata....",wres,err);
+		valname = "??";
+	    }
+	}
+	break;
+    case DW_AT_upper_bound:
+	{
+	    Dwarf_Half theform;
+	    int rv;
+	    rv = dwarf_whatform(attrib,&theform,&err);
+	    /* depending on the form and the attribute, process the form */
+	    if(rv == DW_DLV_ERROR) {
+		print_error(dbg, "dwarf_whatform cannot find attr form",
+			    rv, err);
+	    } else if (rv == DW_DLV_NO_ENTRY) {
+		break;
+	    }
+
+	    switch (theform) {
+	    case DW_FORM_block1:
+		get_location_list(dbg, die, attrib, &esb_base);
+		valname = esb_get_string(&esb_base);
+		break;
+	    default:
+		esb_empty_string(&esb_base);
+		get_attr_value(dbg, tag, attrib, srcfiles, cnt, &esb_base);
+		valname = esb_get_string(&esb_base);
+		break;
+	    }
+	    break;
+	}
+    case DW_AT_high_pc:
+        {
+	    Dwarf_Half theform;
+	    int rv;
+	    rv = dwarf_whatform(attrib,&theform,&err);
+	    /* depending on the form and the attribute, process the form */
+	    if(rv == DW_DLV_ERROR) {
+		print_error(dbg, "dwarf_whatform cannot find attr form",
+			    rv, err);
+	    } else if (rv == DW_DLV_NO_ENTRY) {
+		break;
+	    }
+	    esb_empty_string(&esb_base);
+	    get_attr_value(dbg, tag, attrib, srcfiles, cnt, &esb_base);
+            if( theform != DW_FORM_addr) {
+              /* New in DWARF4: other forms are not an address
+                 but are instead offset from pc.
+                 One could test for DWARF4 here before adding
+                 this string, but that seems unnecessary as this
+                 could not happen with DWARF3 or earlier. 
+                 A normal consumer would have to add this value to
+                 DW_AT_low_pc to get a grue pc. */
+              esb_append(&esb_base,"<offset-from-lowpc>");
+            }
+	    valname = esb_get_string(&esb_base);
+        }
+    default:
+	esb_empty_string(&esb_base);
+	get_attr_value(dbg, tag, attrib, srcfiles, cnt, &esb_base);
+	valname = esb_get_string(&esb_base);
+	break;
+    }
+    if (print_information) {
+	if (dense)
+	    printf(" %s<%s>", atname, valname);
+	else
+	    printf("\t\t%-28s%s\n", atname, valname);
+    }
+}
+
+
+int
+dwarfdump_print_one_locdesc(Dwarf_Debug dbg,
+			 Dwarf_Locdesc * llbuf,
+                         int skip_locdesc_header,
+			 struct esb_s *string_out)
+{
+
+    Dwarf_Locdesc *locd = 0;
+    Dwarf_Half no_of_ops = 0;
+    int i = 0;
+    char small_buf[100];
+
+
+    if (!skip_locdesc_header && (verbose || llbuf->ld_from_loclist)) {
+	snprintf(small_buf, sizeof(small_buf), "<lowpc=0x%llx>",
+		 (unsigned long long) llbuf->ld_lopc);
+	esb_append(string_out, small_buf);
+
+
+	snprintf(small_buf, sizeof(small_buf), "<highpc=0x%llx>",
+		 (unsigned long long) llbuf->ld_hipc);
+	esb_append(string_out, small_buf);
+	if (verbose) {
+	    snprintf(small_buf, sizeof(small_buf),
+		     "<from %s offset 0x%llx>",
+		     llbuf->
+		     ld_from_loclist ? ".debug_loc" : ".debug_info",
+		     (unsigned long long) llbuf->ld_section_offset);
+	    esb_append(string_out, small_buf);
+
+	}
+    }
+
+
+    locd = llbuf;
+    no_of_ops = llbuf->ld_cents;
+    for (i = 0; i < no_of_ops; i++) {
+        Dwarf_Loc * op = &locd->ld_s[i];
+
+        int res = _dwarf_print_one_expr_op(dbg,op,i,string_out);
+        if(res == DW_DLV_ERROR) {
+          return res;
+        }
+    }
+    return DW_DLV_OK;
+}
+
+int
+_dwarf_print_one_expr_op(Dwarf_Debug dbg,Dwarf_Loc* expr,int index,
+	struct esb_s *string_out)
+{
+     /* local_space_needed is intended to be 'more than big enough'
+       for a short group of loclist entries.  */
+    char small_buf[100];
+    Dwarf_Small op;
+    Dwarf_Unsigned opd1;  
+    Dwarf_Unsigned opd2;
+    string op_name;
+
+
+    if (index > 0)
+        esb_append(string_out, " ");
+
+    op = expr->lr_atom;
+    if (op > DW_OP_nop) {
+        print_error(dbg, "dwarf_op unexpected value", DW_DLV_OK,
+			err);
+	return DW_DLV_ERROR;
+    }
+    op_name = get_OP_name(dbg, op);
+    esb_append(string_out, op_name);
+
+    opd1 = expr->lr_number;
+    if (op >= DW_OP_breg0 && op <= DW_OP_breg31) {
+	    snprintf(small_buf, sizeof(small_buf),
+		     "%+lld", (Dwarf_Signed) opd1);
+	    esb_append(string_out, small_buf);
+    } else {
+        switch (op) {
+        case DW_OP_addr:
+		snprintf(small_buf, sizeof(small_buf), " %#llx", opd1);
+		esb_append(string_out, small_buf);
+		break;
+        case DW_OP_const1s:
+        case DW_OP_const2s:
+        case DW_OP_const4s:
+        case DW_OP_const8s:
+        case DW_OP_consts:
+        case DW_OP_skip:
+        case DW_OP_bra:
+        case DW_OP_fbreg:
+		snprintf(small_buf, sizeof(small_buf),
+			 " %lld", (Dwarf_Signed) opd1);
+		esb_append(string_out, small_buf);
+		break;
+        case DW_OP_const1u:
+        case DW_OP_const2u:
+        case DW_OP_const4u:
+        case DW_OP_const8u:
+        case DW_OP_constu:
+        case DW_OP_pick:
+        case DW_OP_plus_uconst:
+        case DW_OP_regx:
+        case DW_OP_piece:
+        case DW_OP_deref_size:
+        case DW_OP_xderef_size:
+            snprintf(small_buf, sizeof(small_buf), " %llu", opd1);
+            esb_append(string_out, small_buf);
+		break;
+        case DW_OP_bregx:
+            snprintf(small_buf, sizeof(small_buf), "%llu", opd1);
+            esb_append(string_out, small_buf);
+
+
+
+            opd2 = expr->lr_number2;
+            snprintf(small_buf, sizeof(small_buf),
+                "%+lld", (Dwarf_Signed) opd2);
+            esb_append(string_out, small_buf);
+            break;
+        default:
+            break;
+	}
+    }
+    return DW_DLV_OK;
+}
+
+/* Fill buffer with location lists 
+   Buffer esbp expands as needed.
+*/
+ /*ARGSUSED*/ static void
+get_location_list(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Attribute attr,
+		  struct esb_s *esbp)
+{
+    Dwarf_Locdesc *llbuf = 0;
+    Dwarf_Locdesc **llbufarray = 0;
+    Dwarf_Signed no_of_elements;
+    Dwarf_Error err;
+    int i;
+    int lres = 0;
+    int llent = 0;
+    int skip_locdesc_header = 0;
+
+
+    if (use_old_dwarf_loclist) {
+
+	lres = dwarf_loclist(attr, &llbuf, &no_of_elements, &err);
+	if (lres == DW_DLV_ERROR)
+	    print_error(dbg, "dwarf_loclist", lres, err);
+	if (lres == DW_DLV_NO_ENTRY)
+	    return;
+
+	dwarfdump_print_one_locdesc(dbg, llbuf,skip_locdesc_header,esbp);
+	dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK);
+	dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC);
+	return;
+    }
+
+    lres = dwarf_loclist_n(attr, &llbufarray, &no_of_elements, &err);
+    if (lres == DW_DLV_ERROR)
+	print_error(dbg, "dwarf_loclist", lres, err);
+    if (lres == DW_DLV_NO_ENTRY)
+	return;
+
+    for (llent = 0; llent < no_of_elements; ++llent) {
+	char small_buf[100];
+
+	llbuf = llbufarray[llent];
+
+	if (!dense && llbuf->ld_from_loclist) {
+	    if (llent == 0) {
+		snprintf(small_buf, sizeof(small_buf),
+			 "<loclist with %ld entries follows>",
+			 (long) no_of_elements);
+		esb_append(esbp, small_buf);
+	    }
+	    esb_append(esbp, "\n\t\t\t");
+	    snprintf(small_buf, sizeof(small_buf), "[%2d]", llent);
+	    esb_append(esbp, small_buf);
+	}
+	lres = dwarfdump_print_one_locdesc(dbg,
+              llbuf, 
+              skip_locdesc_header,
+              esbp);
+	if (lres == DW_DLV_ERROR) {
+	    return;
+	} else {
+	    /* DW_DLV_OK so we add follow-on at end, else is
+	       DW_DLV_NO_ENTRY (which is impossible, treat like
+	       DW_DLV_OK). */
+	}
+    }
+    for (i = 0; i < no_of_elements; ++i) {
+	dwarf_dealloc(dbg, llbufarray[i]->ld_s, DW_DLA_LOC_BLOCK);
+	dwarf_dealloc(dbg, llbufarray[i], DW_DLA_LOCDESC);
+    }
+    dwarf_dealloc(dbg, llbufarray, DW_DLA_LIST);
+}
+
+static void
+formx_unsigned(Dwarf_Unsigned u, struct esb_s *esbp)
+{
+     char small_buf[40];
+     snprintf(small_buf, sizeof(small_buf),
+      "%llu", (unsigned long long)u);
+     esb_append(esbp, small_buf);
+
+}
+static void
+formx_signed(Dwarf_Signed u, struct esb_s *esbp)
+{
+     char small_buf[40];
+     snprintf(small_buf, sizeof(small_buf),
+      "%lld", (long long)u);
+     esb_append(esbp, small_buf);
+}
+/* We think this is an integer. Figure out how to print it.
+   In case the signedness is ambiguous (such as on 
+   DW_FORM_data1 (ie, unknown signedness) print two ways.
+*/
+static int
+formxdata_print_value(Dwarf_Attribute attrib, struct esb_s *esbp,
+	Dwarf_Error * err)
+{
+    Dwarf_Signed tempsd = 0;
+    Dwarf_Unsigned tempud = 0;
+    int sres = 0;
+    int ures = 0;
+    Dwarf_Error serr = 0;
+    ures = dwarf_formudata(attrib, &tempud, err);
+    sres = dwarf_formsdata(attrib, &tempsd, &serr);
+    if(ures == DW_DLV_OK) {
+      if(sres == DW_DLV_OK) {
+	if(tempud == tempsd) {
+	   /* Data is the same value, so makes no difference which
+		we print. */
+	   formx_unsigned(tempud,esbp);
+	} else {
+	   formx_unsigned(tempud,esbp);
+	   esb_append(esbp,"(as signed = ");
+	   formx_signed(tempsd,esbp);
+	   esb_append(esbp,")");
+        }
+      } else if (sres == DW_DLV_NO_ENTRY) {
+	formx_unsigned(tempud,esbp);
+      } else /* DW_DLV_ERROR */{
+	formx_unsigned(tempud,esbp);
+      }
+      return DW_DLV_OK;
+    } else  if (ures == DW_DLV_NO_ENTRY) {
+      if(sres == DW_DLV_OK) {
+	formx_signed(tempsd,esbp);
+	return sres;
+      } else if (sres == DW_DLV_NO_ENTRY) {
+	return sres;
+      } else /* DW_DLV_ERROR */{
+	*err = serr;
+        return sres;
+      }
+    } 
+    /* else ures ==  DW_DLV_ERROR */ 
+    if(sres == DW_DLV_OK) {
+	formx_signed(tempsd,esbp);
+    } else if (sres == DW_DLV_NO_ENTRY) {
+	return ures;
+    } 
+    /* DW_DLV_ERROR */
+    return ures;
+}
+
+
+/* Fill buffer with attribute value.
+   We pass in tag so we can try to do the right thing with
+   broken compiler DW_TAG_enumerator 
+
+   We append to esbp's buffer.
+
+*/
+static void
+get_attr_value(Dwarf_Debug dbg, Dwarf_Half tag, Dwarf_Attribute attrib,
+	       char **srcfiles, Dwarf_Signed cnt, struct esb_s *esbp)
+{
+    Dwarf_Half theform;
+    string temps;
+    Dwarf_Block *tempb;
+    Dwarf_Signed tempsd = 0;
+    Dwarf_Unsigned tempud = 0;
+    int i;
+    Dwarf_Half attr;
+    Dwarf_Off off;
+    Dwarf_Die die_for_check;
+    Dwarf_Half tag_for_check;
+    Dwarf_Bool tempbool;
+    Dwarf_Addr addr = 0;
+    int fres;
+    int bres;
+    int wres;
+    int dres;
+    Dwarf_Half direct_form = 0;
+    char small_buf[100];
+
+
+    fres = dwarf_whatform(attrib, &theform, &err);
+    /* depending on the form and the attribute, process the form */
+    if (fres == DW_DLV_ERROR) {
+	print_error(dbg, "dwarf_whatform cannot find attr form", fres,
+		    err);
+    } else if (fres == DW_DLV_NO_ENTRY) {
+	return;
+    }
+
+    dwarf_whatform_direct(attrib, &direct_form, &err);
+    /* ignore errors in dwarf_whatform_direct() */
+
+
+    switch (theform) {
+    case DW_FORM_addr:
+	bres = dwarf_formaddr(attrib, &addr, &err);
+	if (bres == DW_DLV_OK) {
+	    snprintf(small_buf, sizeof(small_buf), "%#llx",
+		     (unsigned long long) addr);
+	    esb_append(esbp, small_buf);
+	} else {
+	    print_error(dbg, "addr formwith no addr?!", bres, err);
+	}
+	break;
+    case DW_FORM_ref_addr:
+	/* DW_FORM_ref_addr is not accessed thru formref: ** it is an
+	   address (global section offset) in ** the .debug_info
+	   section. */
+	bres = dwarf_global_formref(attrib, &off, &err);
+	if (bres == DW_DLV_OK) {
+	    snprintf(small_buf, sizeof(small_buf),
+		     "<global die offset %llu>",
+		     (unsigned long long) off);
+	    esb_append(esbp, small_buf);
+	} else {
+	    print_error(dbg,
+			"DW_FORM_ref_addr form with no reference?!",
+			bres, err);
+	}
+	break;
+    case DW_FORM_ref1:
+    case DW_FORM_ref2:
+    case DW_FORM_ref4:
+    case DW_FORM_ref8:
+    case DW_FORM_ref_udata:
+	bres = dwarf_formref(attrib, &off, &err);
+	if (bres != DW_DLV_OK) {
+	    print_error(dbg, "ref formwith no ref?!", bres, err);
+	}
+	/* do references inside <> to distinguish them ** from
+	   constants. In dense form this results in <<>>. Ugly for
+	   dense form, but better than ambiguous. davea 9/94 */
+	snprintf(small_buf, sizeof(small_buf), "<%llu>", off);
+	esb_append(esbp, small_buf);
+	if (check_type_offset) {
+	    wres = dwarf_whatattr(attrib, &attr, &err);
+	    if (wres == DW_DLV_ERROR) {
+
+	    } else if (wres == DW_DLV_NO_ENTRY) {
+	    }
+	    if (attr == DW_AT_type) {
+		dres = dwarf_offdie(dbg, cu_offset + off,
+				    &die_for_check, &err);
+		type_offset_result.checks++;
+		if (dres != DW_DLV_OK) {
+		    type_offset_result.errors++;
+		    DWARF_CHECK_ERROR
+			("DW_AT_type offset does not point to type info")
+		} else {
+		    int tres2;
+
+		    tres2 =
+			dwarf_tag(die_for_check, &tag_for_check, &err);
+		    if (tres2 == DW_DLV_OK) {
+			switch (tag_for_check) {
+			case DW_TAG_array_type:
+			case DW_TAG_class_type:
+			case DW_TAG_enumeration_type:
+			case DW_TAG_pointer_type:
+			case DW_TAG_reference_type:
+			case DW_TAG_string_type:
+			case DW_TAG_structure_type:
+			case DW_TAG_subroutine_type:
+			case DW_TAG_typedef:
+			case DW_TAG_union_type:
+			case DW_TAG_ptr_to_member_type:
+			case DW_TAG_set_type:
+			case DW_TAG_subrange_type:
+			case DW_TAG_base_type:
+			case DW_TAG_const_type:
+			case DW_TAG_file_type:
+			case DW_TAG_packed_type:
+			case DW_TAG_thrown_type:
+			case DW_TAG_volatile_type:
+			    /* OK */
+			    break;
+			default:
+			    type_offset_result.errors++;
+			    DWARF_CHECK_ERROR
+				("DW_AT_type offset does not point to type info")
+				break;
+			}
+			dwarf_dealloc(dbg, die_for_check, DW_DLA_DIE);
+		    } else {
+			type_offset_result.errors++;
+			DWARF_CHECK_ERROR
+			    ("DW_AT_type offset does not exist")
+		    }
+		}
+	    }
+	}
+	break;
+    case DW_FORM_block:
+    case DW_FORM_block1:
+    case DW_FORM_block2:
+    case DW_FORM_block4:
+	fres = dwarf_formblock(attrib, &tempb, &err);
+	if (fres == DW_DLV_OK) {
+	    for (i = 0; i < tempb->bl_len; i++) {
+		snprintf(small_buf, sizeof(small_buf), "%02x",
+			 *(i + (unsigned char *) tempb->bl_data));
+		esb_append(esbp, small_buf);
+	    }
+	    dwarf_dealloc(dbg, tempb, DW_DLA_BLOCK);
+	} else {
+	    print_error(dbg, "DW_FORM_blockn cannot get block\n", fres,
+			err);
+	}
+	break;
+    case DW_FORM_data1:
+    case DW_FORM_data2:
+    case DW_FORM_data4:
+    case DW_FORM_data8:
+	fres = dwarf_whatattr(attrib, &attr, &err);
+	if (fres == DW_DLV_ERROR) {
+	    print_error(dbg, "FORM_datan cannot get attr", fres, err);
+	} else if (fres == DW_DLV_NO_ENTRY) {
+	    print_error(dbg, "FORM_datan cannot get attr", fres, err);
+	} else {
+	    switch (attr) {
+	    case DW_AT_ordering:
+	    case DW_AT_byte_size:
+	    case DW_AT_bit_offset:
+	    case DW_AT_bit_size:
+	    case DW_AT_inline:
+	    case DW_AT_language:
+	    case DW_AT_visibility:
+	    case DW_AT_virtuality:
+	    case DW_AT_accessibility:
+	    case DW_AT_address_class:
+	    case DW_AT_calling_convention:
+	    case DW_AT_discr_list:	/* DWARF3 */
+	    case DW_AT_encoding:
+	    case DW_AT_identifier_case:
+	    case DW_AT_MIPS_loop_unroll_factor:
+	    case DW_AT_MIPS_software_pipeline_depth:
+	    case DW_AT_decl_column:
+	    case DW_AT_decl_file:
+	    case DW_AT_decl_line:
+	    case DW_AT_start_scope:
+	    case DW_AT_byte_stride:
+	    case DW_AT_bit_stride:
+	    case DW_AT_count:
+	    case DW_AT_stmt_list:
+	    case DW_AT_MIPS_fde:
+		wres = get_small_encoding_integer_and_name(dbg,
+							   attrib,
+							   &tempud,
+							   /* attrname */
+		    (char *) NULL,
+							   /* err_string 
+							    */ 
+							   (char **)
+							   NULL,
+							   (encoding_type_func) 0,
+							   &err);
+
+		if (wres == DW_DLV_OK) {
+		    snprintf(small_buf, sizeof(small_buf), "%llu",
+			     tempud);
+		    esb_append(esbp, small_buf);
+		    if (attr == DW_AT_decl_file) {
+			if (srcfiles && tempud > 0 && tempud <= cnt) {
+			    /* added by user request */
+			    /* srcfiles is indexed starting at 0, but
+			       DW_AT_decl_file defines that 0 means no
+			       file, so tempud 1 means the 0th entry in
+			       srcfiles, thus tempud-1 is the correct
+			       index into srcfiles.  */
+			    char *fname = srcfiles[tempud - 1];
+
+			    esb_append(esbp, " ");
+			    esb_append(esbp, fname);
+			}
+		    }
+		} else {
+		    print_error(dbg, "Cannot get encoding attribute ..",
+				wres, err);
+		}
+		break;
+	    case DW_AT_const_value:
+		wres = formxdata_print_value(attrib,esbp, &err);
+		if(wres == DW_DLV_OK){
+		    /* String appended already. */
+		} else if (wres == DW_DLV_NO_ENTRY) {
+		    /* nothing? */
+		} else {
+		   print_error(dbg,"Cannot get DW_AT_const_value ",wres,err);
+		}
+  
+		
+		break;
+	    case DW_AT_upper_bound:
+	    case DW_AT_lower_bound:
+	    default:
+		wres = formxdata_print_value(attrib,esbp, &err);
+		if (wres == DW_DLV_OK) {
+		    /* String appended already. */
+		} else if (wres == DW_DLV_NO_ENTRY) {
+		    /* nothing? */
+		} else {
+		    print_error(dbg, "Cannot get formsdata..", wres,
+				err);
+		}
+		break;
+	    }
+	}
+	if (cu_name_flag) {
+	    if (attr == DW_AT_MIPS_fde) {
+		if (fde_offset_for_cu_low == DW_DLV_BADOFFSET) {
+		    fde_offset_for_cu_low
+			= fde_offset_for_cu_high = tempud;
+		} else if (tempud < fde_offset_for_cu_low) {
+		    fde_offset_for_cu_low = tempud;
+		} else if (tempud > fde_offset_for_cu_high) {
+		    fde_offset_for_cu_high = tempud;
+		}
+	    }
+	}
+	break;
+    case DW_FORM_sdata:
+	wres = dwarf_formsdata(attrib, &tempsd, &err);
+	if (wres == DW_DLV_OK) {
+	    snprintf(small_buf, sizeof(small_buf), "%lld", tempsd);
+	    esb_append(esbp, small_buf);
+	} else if (wres == DW_DLV_NO_ENTRY) {
+	    /* nothing? */
+	} else {
+	    print_error(dbg, "Cannot get formsdata..", wres, err);
+	}
+	break;
+    case DW_FORM_udata:
+	wres = dwarf_formudata(attrib, &tempud, &err);
+	if (wres == DW_DLV_OK) {
+	    snprintf(small_buf, sizeof(small_buf), "%llu", tempud);
+	    esb_append(esbp, small_buf);
+	} else if (wres == DW_DLV_NO_ENTRY) {
+	    /* nothing? */
+	} else {
+	    print_error(dbg, "Cannot get formudata....", wres, err);
+	}
+	break;
+    case DW_FORM_string:
+    case DW_FORM_strp:
+	wres = dwarf_formstring(attrib, &temps, &err);
+	if (wres == DW_DLV_OK) {
+	    esb_append(esbp, temps);
+	} else if (wres == DW_DLV_NO_ENTRY) {
+	    /* nothing? */
+	} else {
+	    print_error(dbg, "Cannot get formstr/p....", wres, err);
+	}
+
+	break;
+    case DW_FORM_flag:
+	wres = dwarf_formflag(attrib, &tempbool, &err);
+	if (wres == DW_DLV_OK) {
+	    if (tempbool) {
+		snprintf(small_buf, sizeof(small_buf), "yes(%d)",
+			 tempbool);
+		esb_append(esbp, small_buf);
+	    } else {
+		snprintf(small_buf, sizeof(small_buf), "no");
+		esb_append(esbp, small_buf);
+	    }
+	} else if (wres == DW_DLV_NO_ENTRY) {
+	    /* nothing? */
+	} else {
+	    print_error(dbg, "Cannot get formflag/p....", wres, err);
+	}
+	break;
+    case DW_FORM_indirect:
+	/* We should not ever get here, since the true form was
+	   determined and direct_form has the DW_FORM_indirect if it is
+	   used here in this attr. */
+	esb_append(esbp, get_FORM_name(dbg, theform));
+	break;
+    default:
+	print_error(dbg, "dwarf_whatform unexpected value", DW_DLV_OK,
+		    err);
+    }
+    if (verbose && direct_form && direct_form == DW_FORM_indirect) {
+	char *form_indir = " (used DW_FORM_indirect) ";
+
+	esb_append(esbp, form_indir);
+    }
+}
+
+/* A cleanup so that when using a memory checker
+   we don't show irrelevant leftovers.
+*/
+void
+clean_up_die_esb()
+{
+   esb_destructor(&esb_base);
+}
+
+#include "_tag_attr_table.c"
+
+static int
+tag_attr_combination(Dwarf_Half tag, Dwarf_Half attr)
+{
+    if (attr > 0 && attr < 0x60) {
+	return ((tag_attr_combination_table[tag][attr / 0x20]
+		 & (1 << (attr % 0x20))) > 0 ? TRUE : FALSE);
+    } else if (attr == DW_AT_MIPS_fde) {
+	/* no check now */
+	return (TRUE);
+    } else
+	return (FALSE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_frames.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1104 @@
+/* 
+  Copyright (C) 2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write the Free Software Foundation, Inc., 51
+  Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_frames.c,v 1.5 2006/06/14 20:34:02 davea Exp $ */
+
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+#include "globals.h"
+
+#include "print_frames.h"
+#include "dwconf.h"
+#include "esb.h"
+
+
+static void
+  print_one_frame_reg_col(Dwarf_Debug dbg,
+                          Dwarf_Unsigned rule_id,
+			  Dwarf_Small value_type,
+			  Dwarf_Unsigned reg_used,
+			  struct dwconf_s *config_data,
+			  Dwarf_Signed offset_relevant,
+			  Dwarf_Signed offset, Dwarf_Ptr block_ptr);
+
+/*
+    Gather the fde print logic here so the control logic
+    determining what FDE to print is clearer.
+*/
+int
+print_one_fde(Dwarf_Debug dbg, Dwarf_Fde fde,
+	      Dwarf_Unsigned fde_index,
+	      Dwarf_Cie * cie_data,
+	      Dwarf_Signed cie_element_count,
+	      Dwarf_Half address_size, int is_eh,
+	      struct dwconf_s *config_data)
+{
+    Dwarf_Addr j = 0;
+    Dwarf_Addr low_pc = 0;
+    Dwarf_Unsigned func_length = 0;
+    Dwarf_Ptr fde_bytes = NULL;
+    Dwarf_Unsigned fde_bytes_length = 0;
+    Dwarf_Off cie_offset = 0;
+    Dwarf_Signed cie_index = 0;
+    Dwarf_Off fde_offset = 0;
+    Dwarf_Signed eh_table_offset = 0;
+    int fres = 0;
+    int offres = 0;
+    string temps = 0;
+    Dwarf_Error err = 0;
+    int printed_intro_addr = 0;
+
+    fres = dwarf_get_fde_range(fde,
+			       &low_pc, &func_length,
+			       &fde_bytes,
+			       &fde_bytes_length,
+			       &cie_offset, &cie_index,
+			       &fde_offset, &err);
+    if (fres == DW_DLV_ERROR) {
+	print_error(dbg, "dwarf_get_fde_range", fres, err);
+    }
+    if (fres == DW_DLV_NO_ENTRY) {
+	return DW_DLV_NO_ENTRY;
+    }
+    if (cu_name_flag &&
+	fde_offset_for_cu_low != DW_DLV_BADOFFSET &&
+	(fde_offset < fde_offset_for_cu_low ||
+	 fde_offset > fde_offset_for_cu_high)) {
+	return DW_DLV_NO_ENTRY;
+    }
+    /* eh_table_offset is IRIX ONLY. */
+    fres = dwarf_get_fde_exception_info(fde, &eh_table_offset, &err);
+    if (fres == DW_DLV_ERROR) {
+	print_error(dbg, "dwarf_get_fde_exception_info", fres, err);
+    }
+    temps = get_fde_proc_name(dbg, low_pc);
+    printf
+	("<%3lld><%#llx:%#llx><%s><fde offset 0x%llx length: 0x%llx>",
+	 cie_index, low_pc, (low_pc + func_length),
+	 temps ? temps : "", fde_offset, fde_bytes_length);
+
+
+    if (!is_eh) {
+	/* IRIX uses eh_table_offset. */
+	if (eh_table_offset == DW_DLX_NO_EH_OFFSET) {
+	    printf("<eh offset %s>\n", "none");
+	} else if (eh_table_offset == DW_DLX_EH_OFFSET_UNAVAILABLE) {
+	    printf("<eh offset %s>\n", "unknown");
+	} else {
+	    printf("<eh offset 0x%llx>\n", eh_table_offset);
+	}
+    } else {
+	int ares = 0;
+	Dwarf_Small *data = 0;
+	Dwarf_Unsigned len = 0;
+
+	ares = dwarf_get_fde_augmentation_data(fde, &data, &len, &err);
+	if (ares == DW_DLV_NO_ENTRY) {
+	    /* do nothing. */
+	} else if (ares == DW_DLV_OK) {
+	    int k2;
+
+	    printf("<eh aug data len 0x%llx", (long long) len);
+	    for (k2 = 0; k2 < len; ++k2) {
+		if (k2 == 0) {
+		    printf(" bytes 0x");
+		}
+		printf("%02x ", (unsigned char) data[k2]);
+	    }
+	    printf(">");
+	}			/* else DW_DLV_ERROR, do nothing */
+        printf("\n");
+    }
+    /* call dwarf_get_fde_info_for_reg() to get whole matrix */
+
+    for (j = low_pc; j < low_pc + func_length; j++) {
+	Dwarf_Half k;
+
+	if (config_data->cf_interface_number == 3) {
+	    Dwarf_Signed reg = 0;
+	    Dwarf_Signed offset_relevant = 0;
+	    Dwarf_Small value_type = 0;
+	    Dwarf_Signed offset_or_block_len = 0;
+	    Dwarf_Signed offset = 0;
+	    Dwarf_Ptr block_ptr = 0;
+	    Dwarf_Addr row_pc = 0;
+
+	    int fires = dwarf_get_fde_info_for_cfa_reg3(fde,
+							j,
+							&value_type,
+							&offset_relevant,
+							&reg,
+							&offset_or_block_len,
+							&block_ptr,
+							&row_pc,
+							&err);
+
+	    offset = offset_or_block_len;
+	    if (fires == DW_DLV_ERROR) {
+		print_error(dbg,
+			    "dwarf_get_fde_info_for_reg", fires, err);
+	    }
+	    if (fires == DW_DLV_NO_ENTRY) {
+		continue;
+	    }
+	    if (row_pc != j) {
+		/* duplicate row */
+		continue;
+	    }
+	    if (!printed_intro_addr) {
+		printf("    %08llx:\t", j);
+		printed_intro_addr = 1;
+	    }
+	    print_one_frame_reg_col(dbg, config_data->cf_cfa_reg,
+				    value_type,
+				    reg,
+				    config_data,
+				    offset_relevant, offset, block_ptr);
+	}
+	for (k = 0; k < config_data->cf_table_entry_count; k++) {
+	    Dwarf_Signed reg = 0;
+	    Dwarf_Signed offset_relevant = 0;
+	    int fires = 0;
+	    Dwarf_Small value_type = 0;
+	    Dwarf_Ptr block_ptr = 0;
+	    Dwarf_Signed offset_or_block_len = 0;
+	    Dwarf_Signed offset = 0;
+	    Dwarf_Addr row_pc = 0;
+
+	    if (config_data->cf_interface_number == 3) {
+
+		fires = dwarf_get_fde_info_for_reg3(fde,
+						    k,
+						    j,
+						    &value_type,
+						    &offset_relevant,
+						    &reg,
+						    &offset_or_block_len,
+						    &block_ptr,
+						    &row_pc, &err);
+		offset = offset_or_block_len;
+	    } else {		/* ASSERT:
+				   config_data->cf_interface_number ==
+				   2 */
+
+
+		value_type = DW_EXPR_OFFSET;
+		fires = dwarf_get_fde_info_for_reg(fde,
+						   k,
+						   j,
+						   &offset_relevant,
+						   &reg,
+						   &offset, &row_pc,
+						   &err);
+	    }
+	    if (fires == DW_DLV_ERROR) {
+                printf("\n");
+		print_error(dbg,
+			    "dwarf_get_fde_info_for_reg", fires, err);
+	    }
+	    if (fires == DW_DLV_NO_ENTRY) {
+		continue;
+	    }
+	    if (row_pc != j) {
+		/* duplicate row */
+		break;
+	    }
+	    if (!printed_intro_addr) {
+		printf("    %08llx:\t", j);
+		printed_intro_addr = 1;
+	    }
+	    print_one_frame_reg_col(dbg,k,
+				    value_type,
+				    reg,
+				    config_data,
+				    offset_relevant, offset, block_ptr);
+
+	}
+	if (printed_intro_addr) {
+	    printf("\n");
+	    printed_intro_addr = 0;
+	}
+    }
+    if (verbose > 1) {
+	Dwarf_Off fde_off;
+	Dwarf_Off cie_off;
+
+	/* get the fde instructions and print them in raw form, just
+	   like cie instructions */
+	Dwarf_Ptr instrs;
+	Dwarf_Unsigned ilen;
+	int res;
+
+	res = dwarf_get_fde_instr_bytes(fde, &instrs, &ilen, &err);
+	offres =
+	    dwarf_fde_section_offset(dbg, fde, &fde_off, &cie_off,
+				      &err);
+	if (offres == DW_DLV_OK) {
+	    printf("\tfde sec. offset %llu 0x%llx"
+		   " cie offset for fde: %llu 0x%llx\n",
+		   (unsigned long long) fde_off,
+		   (unsigned long long) fde_off,
+		   (unsigned long long) cie_off,
+		   (unsigned long long) cie_off);
+
+	}
+
+
+	if (res == DW_DLV_OK) {
+	    int cires = 0;
+	    Dwarf_Unsigned cie_length = 0;
+	    Dwarf_Small version = 0;
+	    string augmenter;
+	    Dwarf_Unsigned code_alignment_factor = 0;
+	    Dwarf_Signed data_alignment_factor = 0;
+	    Dwarf_Half return_address_register_rule = 0;
+	    Dwarf_Ptr initial_instructions = 0;
+	    Dwarf_Unsigned initial_instructions_length = 0;
+
+	    if (cie_index >= cie_element_count) {
+		printf("Bad cie index %lld with fde index %lld! "
+		       "(table entry max %lld)\n",
+		       (long long) cie_index, (long long) fde_index,
+		       (long long) cie_element_count);
+		exit(1);
+	    }
+
+	    cires = dwarf_get_cie_info(cie_data[cie_index],
+				       &cie_length,
+				       &version,
+				       &augmenter,
+				       &code_alignment_factor,
+				       &data_alignment_factor,
+				       &return_address_register_rule,
+				       &initial_instructions,
+				       &initial_instructions_length,
+				       &err);
+	    if (cires == DW_DLV_ERROR) {
+		printf
+		    ("Bad cie index %lld with fde index %lld!\n",
+		     (long long) cie_index, (long long) fde_index);
+		print_error(dbg, "dwarf_get_cie_info", cires, err);
+	    }
+	    if (cires == DW_DLV_NO_ENTRY) {
+		;		/* ? */
+	    } else {
+
+		print_frame_inst_bytes(dbg, instrs,
+				       (Dwarf_Signed) ilen,
+				       data_alignment_factor,
+				       (int) code_alignment_factor,
+				       address_size, config_data);
+	    }
+	} else if (res == DW_DLV_NO_ENTRY) {
+	    printf
+		("Impossible: no instr bytes for fde index %d?\n",
+		 (int) fde_index);
+	} else {
+	    /* DW_DLV_ERROR */
+	    printf
+		("Error: on gettinginstr bytes for fde index %d?\n",
+		 (int) fde_index);
+	    print_error(dbg, "dwarf_get_fde_instr_bytes", res, err);
+	}
+
+    }
+    return DW_DLV_OK;
+}
+
+
+/* Print a cie.  Gather the print logic here so the
+   control logic deciding what to print
+   is clearer.
+*/
+int
+print_one_cie(Dwarf_Debug dbg, Dwarf_Cie cie,
+	      Dwarf_Unsigned cie_index, Dwarf_Half address_size,
+	      struct dwconf_s *config_data)
+{
+
+    int cires = 0;
+    Dwarf_Unsigned cie_length = 0;
+    Dwarf_Small version = 0;
+    string augmenter = "";
+    Dwarf_Unsigned code_alignment_factor = 0;
+    Dwarf_Signed data_alignment_factor = 0;
+    Dwarf_Half return_address_register_rule = 0;
+    Dwarf_Ptr initial_instructions = 0;
+    Dwarf_Unsigned initial_instructions_length = 0;
+    Dwarf_Off cie_off = 0;
+    Dwarf_Error err = 0;
+
+    cires = dwarf_get_cie_info(cie,
+			       &cie_length,
+			       &version,
+			       &augmenter,
+			       &code_alignment_factor,
+			       &data_alignment_factor,
+			       &return_address_register_rule,
+			       &initial_instructions,
+			       &initial_instructions_length, &err);
+    if (cires == DW_DLV_ERROR) {
+	print_error(dbg, "dwarf_get_cie_info", cires, err);
+    }
+    if (cires == DW_DLV_NO_ENTRY) {
+	;			/* ? */
+	printf("Impossible DW_DLV_NO_ENTRY on cie %d\n",
+	       (int) cie_index);
+	return DW_DLV_NO_ENTRY;
+    }
+    {
+	printf("<%3lld>\tversion\t\t\t\t%d\n", cie_index, version);
+	cires = dwarf_cie_section_offset(dbg, cie, &cie_off, &err);
+	if (cires == DW_DLV_OK) {
+	    printf("\tcie sec. offset %llu 0x%llx\n",
+		   (unsigned long long) cie_off,
+		   (unsigned long long) cie_off);
+
+	}
+
+	printf("\taugmentation\t\t\t%s\n", augmenter);
+	printf("\tcode_alignment_factor\t\t%llu\n",
+	       (unsigned long long) code_alignment_factor);
+	printf("\tdata_alignment_factor\t\t%lld\n",
+	       (long long) data_alignment_factor);
+	printf("\treturn_address_register\t\t%d\n",
+	       (int) return_address_register_rule);
+	{
+	    int ares = 0;
+	    Dwarf_Small *data = 0;
+	    Dwarf_Unsigned len = 0;
+
+	    ares =
+		dwarf_get_cie_augmentation_data(cie, &data, &len, &err);
+	    if (ares == DW_DLV_NO_ENTRY) {
+		/* do nothing. */
+	    } else if (ares == DW_DLV_OK && len > 0) {
+		int k2;
+
+		printf("\teh aug data len 0x%llx", (long long) len);
+		for (k2 = 0; data && k2 < len; ++k2) {
+		    if (k2 == 0) {
+			printf(" bytes 0x");
+		    }
+		    printf("%02x ", (unsigned char) data[k2]);
+		}
+		printf("\n");
+	    }			/* else DW_DLV_ERROR or no data, do
+				   nothing */
+	}
+
+	printf
+	    ("\tbytes of initial instructions:\t%lld\n",
+	     (long long) initial_instructions_length);
+	printf("\tcie length :\t\t\t%lld\n", (long long) cie_length);
+	print_frame_inst_bytes(dbg, initial_instructions, (Dwarf_Signed)
+			       initial_instructions_length,
+			       data_alignment_factor,
+			       (int) code_alignment_factor,
+			       address_size, config_data);
+    }
+    return DW_DLV_OK;
+}
+
+void
+get_string_from_locs(Dwarf_Debug dbg,
+    Dwarf_Ptr bytes_in, 
+    Dwarf_Unsigned block_len,struct esb_s *out_string)
+{
+
+    Dwarf_Locdesc *locdescarray = 0;
+    Dwarf_Signed listlen = 0;
+    Dwarf_Error err2 =0;
+    int skip_locdesc_header=1;
+    int res2 = dwarf_loclist_from_expr(dbg,
+        bytes_in,block_len,
+        &locdescarray,
+        &listlen,&err2);
+    if (res2 == DW_DLV_ERROR) {
+        print_error(dbg, "dwarf_get_loclist_from_expr",
+            res2, err2);
+    }
+    if(res2==DW_DLV_NO_ENTRY) {
+        return;
+    }
+    /* lcnt is always 1 */
+
+    /* Use locdescarray  here.*/
+    int res = dwarfdump_print_one_locdesc(dbg,
+                         locdescarray,
+                         skip_locdesc_header,
+                         out_string);
+    if(res != DW_DLV_OK) {
+	   printf("Bad status from _dwarf_print_one_locdesc %d\n",res);
+           exit(1);
+    }
+            
+
+    
+    dwarf_dealloc(dbg, locdescarray->ld_s, DW_DLA_LOC_BLOCK);
+    dwarf_dealloc(dbg, locdescarray, DW_DLA_LOCDESC);
+        
+
+    return ;
+}
+
+/* Print the frame instructions in detail for a glob of instructions.
+*/
+
+ /*ARGSUSED*/ void
+print_frame_inst_bytes(Dwarf_Debug dbg,
+		       Dwarf_Ptr cie_init_inst, Dwarf_Signed len,
+		       Dwarf_Signed data_alignment_factor,
+		       int code_alignment_factor, Dwarf_Half addr_size,
+		       struct dwconf_s *config_data)
+{
+    unsigned char *instp = (unsigned char *) cie_init_inst;
+    Dwarf_Unsigned uval;
+    Dwarf_Unsigned uval2;
+    unsigned int uleblen;
+    unsigned int off = 0;
+    unsigned int loff = 0;
+    unsigned short u16;
+    unsigned int u32;
+    unsigned long long u64;
+
+    for (; len > 0;) {
+	unsigned char ibyte = *instp;
+	int top = ibyte & 0xc0;
+	int bottom = ibyte & 0x3f;
+	int delta;
+	int reg;
+
+	switch (top) {
+	case DW_CFA_advance_loc:
+	    delta = ibyte & 0x3f;
+	    printf("\t%2u DW_CFA_advance_loc %d", off,
+		   (int) (delta * code_alignment_factor));
+	    if (verbose) {
+		printf("  (%d * %d)", (int) delta,
+		       (int) code_alignment_factor);
+	    }
+	    printf("\n");
+	    break;
+	case DW_CFA_offset:
+	    loff = off;
+	    reg = ibyte & 0x3f;
+	    uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+	    instp += uleblen;
+	    len -= uleblen;
+	    off += uleblen;
+	    printf("\t%2u DW_CFA_offset ", loff);
+	    printreg((Dwarf_Signed) reg, config_data);
+	    printf(" %lld", (signed long long)
+		   (((Dwarf_Signed) uval) * data_alignment_factor));
+	    if (verbose) {
+		printf("  (%llu * %d)", (unsigned long long) uval,
+		       (int) data_alignment_factor);
+	    }
+	    printf("\n");
+	    break;
+
+	case DW_CFA_restore:
+	    reg = ibyte & 0x3f;
+	    printf("\t%2u DW_CFA_restore \n", off);
+	    printreg((Dwarf_Signed) reg, config_data);
+	    printf("\n");
+	    break;
+
+	default:
+	    loff = off;
+	    switch (bottom) {
+	    case DW_CFA_set_loc:
+		/* operand is address, so need address size */
+		/* which will be 4 or 8. */
+		switch (addr_size) {
+		case 4:
+		    {
+			__uint32_t v32;
+
+			memcpy(&v32, instp + 1, addr_size);
+			uval = v32;
+		    }
+		    break;
+		case 8:
+		    {
+			__uint64_t v64;
+
+			memcpy(&v64, instp + 1, addr_size);
+			uval = v64;
+		    }
+		    break;
+		default:
+		    printf
+			("Error: Unexpected address size %d in DW_CFA_set_loc!\n",
+			 addr_size);
+		    uval = 0;
+		}
+
+		instp += addr_size;
+		len -= (Dwarf_Signed) addr_size;
+		off += addr_size;
+		printf("\t%2u DW_CFA_set_loc %llu\n",
+		       loff, (unsigned long long) uval);
+		break;
+	    case DW_CFA_advance_loc1:
+		delta = (unsigned char) *(instp + 1);
+		uval2 = delta;
+		instp += 1;
+		len -= 1;
+		off += 1;
+		printf("\t%2u DW_CFA_advance_loc1 %llu\n",
+		       loff, (unsigned long long) uval2);
+		break;
+	    case DW_CFA_advance_loc2:
+		memcpy(&u16, instp + 1, 2);
+		uval2 = u16;
+		instp += 2;
+		len -= 2;
+		off += 2;
+		printf("\t%2u DW_CFA_advance_loc2 %llu\n",
+		       loff, (unsigned long long) uval2);
+		break;
+	    case DW_CFA_advance_loc4:
+		memcpy(&u32, instp + 1, 4);
+		uval2 = u32;
+		instp += 4;
+		len -= 4;
+		off += 4;
+		printf("\t%2u DW_CFA_advance_loc4 %llu\n",
+		       loff, (unsigned long long) uval2);
+		break;
+	    case DW_CFA_MIPS_advance_loc8:
+		memcpy(&u64, instp + 1, 8);
+		uval2 = u64;
+		instp += 8;
+		len -= 8;
+		off += 8;
+		printf("\t%2u DW_CFA_MIPS_advance_loc8 %llu\n",
+		       loff, (unsigned long long) uval2);
+		break;
+	    case DW_CFA_offset_extended:
+		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+		instp += uleblen;
+		len -= uleblen;
+		off += uleblen;
+		uval2 =
+		    local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+		instp += uleblen;
+		len -= uleblen;
+		off += uleblen;
+		printf("\t%2u DW_CFA_offset_extended ", loff);
+		printreg((Dwarf_Signed) uval, config_data);
+		printf(" %lld", (signed long long)
+		       (((Dwarf_Signed) uval2) *
+			data_alignment_factor));
+		if (verbose) {
+		    printf("  (%llu * %d)", (unsigned long long) uval2,
+			   (int) data_alignment_factor);
+		}
+		printf("\n");
+		break;
+
+	    case DW_CFA_restore_extended:
+		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+		instp += uleblen;
+		len -= uleblen;
+		off += uleblen;
+		printf("\t%2u DW_CFA_restore_extended ", loff);
+		printreg((Dwarf_Signed) uval, config_data);
+		printf("\n");
+		break;
+	    case DW_CFA_undefined:
+		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+		instp += uleblen;
+		len -= uleblen;
+		off += uleblen;
+		printf("\t%2u DW_CFA_undefined ", loff);
+		printreg((Dwarf_Signed) uval, config_data);
+		printf("\n");
+		break;
+	    case DW_CFA_same_value:
+		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+		instp += uleblen;
+		len -= uleblen;
+		off += uleblen;
+		printf("\t%2u DW_CFA_same_value ", loff);
+		printreg((Dwarf_Signed) uval, config_data);
+		printf("\n");
+		break;
+	    case DW_CFA_register:
+		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+		instp += uleblen;
+		len -= uleblen;
+		off += uleblen;
+		uval2 =
+		    local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+		instp += uleblen;
+		len -= uleblen;
+		off += uleblen;
+		printf("\t%2u DW_CFA_register ", loff);
+		printreg((Dwarf_Signed) uval, config_data);
+		printf(" = ");
+		printreg((Dwarf_Signed) uval2, config_data);
+		printf("\n");
+		break;
+	    case DW_CFA_remember_state:
+		printf("\t%2u DW_CFA_remember_state\n", loff);
+		break;
+	    case DW_CFA_restore_state:
+		printf("\t%2u DW_CFA_restore_state\n", loff);
+		break;
+	    case DW_CFA_def_cfa:
+		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+		instp += uleblen;
+		len -= uleblen;
+		off += uleblen;
+		uval2 =
+		    local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+		instp += uleblen;
+		len -= uleblen;
+		off += uleblen;
+		printf("\t%2u DW_CFA_def_cfa ", loff);
+		printreg((Dwarf_Signed) uval, config_data);
+		printf(" %llu", (unsigned long long) uval2);
+		printf("\n");
+		break;
+	    case DW_CFA_def_cfa_register:
+		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+		instp += uleblen;
+		len -= uleblen;
+		off += uleblen;
+		printf("\t%2u DW_CFA_def_cfa_register ", loff);
+		printreg((Dwarf_Signed) uval, config_data);
+		printf("\n");
+		break;
+	    case DW_CFA_def_cfa_offset:
+		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+		instp += uleblen;
+		len -= uleblen;
+		off += uleblen;
+		printf("\t%2u DW_CFA_def_cfa_offset %llu\n",
+		       loff, (unsigned long long) uval);
+		break;
+
+	    case DW_CFA_nop:
+		printf("\t%2u DW_CFA_nop\n", loff);
+		break;
+
+	    case DW_CFA_def_cfa_expression:	/* DWARF3 */
+		{
+		    Dwarf_Unsigned block_len =
+			local_dwarf_decode_u_leb128(instp + 1,
+						    &uleblen);
+
+		    instp += uleblen;
+		    len -= uleblen;
+		    off += uleblen;
+		    printf
+			("\t%2u DW_CFA_def_cfa_expression expr block len %lld\n",
+			 loff, (unsigned long long)
+			 block_len);
+		    dump_block("\t\t", (char *) instp+1,
+			       (Dwarf_Signed) block_len);
+                    printf("\n");
+                    if(verbose) {
+                      struct esb_s exprstring;
+                      esb_constructor(&exprstring);
+                      get_string_from_locs(dbg,
+			    instp+1,block_len,&exprstring);
+                      printf("\t\t%s\n",esb_get_string(&exprstring));
+                      esb_destructor(&exprstring);
+                    }
+		    instp += block_len;
+		    len -= block_len;
+		    off += block_len;
+		}
+		break;
+	    case DW_CFA_expression:	/* DWARF3 */
+		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+		instp += uleblen;
+		len -= uleblen;
+		off += uleblen;
+		{
+                    /* instp is always 1 byte back, so we need +1
+			when we use it. See the final increment
+                        of this for loop. */
+		    Dwarf_Unsigned block_len =
+			local_dwarf_decode_u_leb128(instp + 1,
+						    &uleblen);
+
+		    instp += uleblen;
+		    len -= uleblen;
+		    off += uleblen;
+		    printf
+			("\t%2u DW_CFA_expression %llu expr block len %lld\n",
+			 loff, (unsigned long long) uval,
+			 (unsigned long long)
+			 block_len);
+		    dump_block("\t\t", (char *) instp+1,
+			       (Dwarf_Signed) block_len);
+                    printf("\n");
+                    if(verbose) {
+                      struct esb_s exprstring;
+                      esb_constructor(&exprstring);
+                      get_string_from_locs(dbg,
+			    instp+1,block_len,&exprstring);
+                      printf("\t\t%s\n",esb_get_string(&exprstring));
+                      esb_destructor(&exprstring);
+                    }
+		    instp += block_len;
+		    len -= block_len;
+		    off += block_len;
+		}
+
+		break;
+	    case DW_CFA_cfa_offset_extended_sf:	/* DWARF3 */
+		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+		instp += uleblen;
+		len -= uleblen;
+		off += uleblen;
+		{
+                    /* instp is always 1 byte back, so we need +1
+			when we use it. See the final increment
+                        of this for loop. */
+		    Dwarf_Signed sval2 =
+			local_dwarf_decode_s_leb128(instp + 1,
+						    &uleblen);
+
+		    instp += uleblen;
+		    len -= uleblen;
+		    off += uleblen;
+		    printf("\t%2u DW_CFA_offset_extended_sf ", loff);
+		    printreg((Dwarf_Signed) uval, config_data);
+		    printf(" %lld", (signed long long)
+			   ((sval2) * data_alignment_factor));
+		    if (verbose) {
+			printf("  (%lld * %d)", (long long) sval2,
+			       (int) data_alignment_factor);
+		    }
+		}
+		printf("\n");
+		break;
+	    case DW_CFA_def_cfa_sf:	/* DWARF3 */
+                    /* instp is always 1 byte back, so we need +1
+			when we use it. See the final increment
+                        of this for loop. */
+		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+		instp += uleblen;
+		len -= uleblen;
+		off += uleblen;
+		{
+		    Dwarf_Signed sval2 =
+			local_dwarf_decode_s_leb128(instp + 1,
+						    &uleblen);
+
+		    instp += uleblen;
+		    len -= uleblen;
+		    off += uleblen;
+		    printf("\t%2u DW_CFA_def_cfa_sf ", loff);
+		    printreg((Dwarf_Signed) uval, config_data);
+		    printf(" %lld", (long long) sval2); 
+                    printf(" (*data alignment factor=>%lld)",
+                     (long long)(sval2*data_alignment_factor));
+		}
+		printf("\n");
+		break;
+	    case DW_CFA_def_cfa_offset_sf:	/* DWARF3 */
+		{
+                    /* instp is always 1 byte back, so we need +1
+			when we use it. See the final increment
+                        of this for loop. */
+		    Dwarf_Signed sval =
+			local_dwarf_decode_s_leb128(instp + 1,
+						    &uleblen);
+
+		    instp += uleblen;
+		    len -= uleblen;
+		    off += uleblen;
+		    printf("\t%2u DW_CFA_def_cfa_offset_sf %lld (*data alignment factor=> %lld)\n",
+			   loff, (long long) sval,
+                           (long long)(data_alignment_factor*sval));
+
+		}
+		break;
+	    case DW_CFA_val_offset:	/* DWARF3 */
+                    /* instp is always 1 byte back, so we need +1
+			when we use it. See the final increment
+                        of this for loop. */
+		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+		instp += uleblen;
+		len -= uleblen;
+		off += uleblen;
+		{
+		    uval2 =
+			local_dwarf_decode_s_leb128(instp + 1,
+						    &uleblen);
+		    instp += uleblen;
+		    len -= uleblen;
+		    off += uleblen;
+		    printf("\t%2u DW_CFA_val_offset ", loff);
+		    printreg((Dwarf_Signed) uval, config_data);
+		    printf(" %lld", (unsigned long long)
+			   (((Dwarf_Signed) uval2) *
+			    data_alignment_factor));
+		    if (verbose) {
+			printf("  (%lld * %d)", (long long) uval2,
+			       (int) data_alignment_factor);
+		    }
+		}
+		printf("\n");
+
+		break;
+	    case DW_CFA_val_offset_sf:	/* DWARF3 */
+                    /* instp is always 1 byte back, so we need +1
+			when we use it. See the final increment
+                        of this for loop. */
+		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+		instp += uleblen;
+		len -= uleblen;
+		off += uleblen;
+		{
+		    Dwarf_Signed sval2 =
+			local_dwarf_decode_s_leb128(instp + 1,
+						    &uleblen);
+
+		    instp += uleblen;
+		    len -= uleblen;
+		    off += uleblen;
+		    printf("\t%2u DW_CFA_val_offset_sf ", loff);
+		    printreg((Dwarf_Signed) uval, config_data);
+		    printf(" %lld", (signed long long)
+			   ((sval2) * data_alignment_factor));
+		    if (verbose) {
+			printf("  (%lld * %d)", (long long) sval2,
+			       (int) data_alignment_factor);
+		    }
+		}
+		printf("\n");
+
+		break;
+	    case DW_CFA_val_expression:	/* DWARF3 */
+                    /* instp is always 1 byte back, so we need +1
+			when we use it. See the final increment
+                        of this for loop. */
+		uval = local_dwarf_decode_u_leb128(instp + 1, &uleblen);
+		instp += uleblen;
+		len -= uleblen;
+		off += uleblen;
+		{
+		    Dwarf_Unsigned block_len =
+			local_dwarf_decode_u_leb128(instp + 1,
+						    &uleblen);
+
+		    instp += uleblen;
+		    len -= uleblen;
+		    off += uleblen;
+		    printf
+			("\t%2u DW_CFA_val_expression %llu expr block len %lld\n",
+			 loff, (unsigned long long) uval,
+			 (unsigned long long)
+			 block_len);
+		    dump_block("\t\t", (char *) instp+1,
+			       (Dwarf_Signed) block_len);
+                    printf("\n");
+                    if(verbose) {
+                      struct esb_s exprstring;
+                      esb_constructor(&exprstring);
+                      get_string_from_locs(dbg,
+			    instp+1,block_len,&exprstring);
+                      printf("\t\t%s\n",esb_get_string(&exprstring));
+                      esb_destructor(&exprstring);
+                    }
+		    instp += block_len;
+		    len -= block_len;
+		    off += block_len;
+		}
+
+
+		break;
+
+
+#ifdef DW_CFA_GNU_window_save
+	    case DW_CFA_GNU_window_save:{
+		    /* no information: this just tells unwinder to
+		       restore the window registers from the previous
+		       frame's window save area */
+		    printf("\t%2u DW_CFA_GNU_window_save \n", loff);
+		    break;
+		}
+#endif
+#ifdef DW_CFA_GNU_negative_offset_extended
+	    case DW_CFA_GNU_negative_offset_extended:{
+		    printf
+			("\t%2u DW_CFA_GNU_negative_offset_extended \n",
+			 loff);
+		}
+#endif
+#ifdef  DW_CFA_GNU_args_size
+		/* single uleb128 is the current arg area size in
+		   bytes. no register exists yet to save this in */
+	    case DW_CFA_GNU_args_size:{
+		    Dwarf_Unsigned lreg;
+
+                    /* instp is always 1 byte back, so we need +1
+			when we use it. See the final increment
+                        of this for loop. */
+		    lreg =
+			local_dwarf_decode_u_leb128(instp + 1,
+						    &uleblen);
+		    printf
+			("\t%2u DW_CFA_GNU_args_size arg size: %llu\n",
+			 loff, (unsigned long long) lreg);
+		    instp += uleblen;
+		    len -= uleblen;
+		    off += uleblen;
+
+		    break;
+		}
+#endif
+
+	    default:
+		printf("\t%u Unexpected op 0x%x: \n",
+		       loff, (unsigned int) bottom);
+		len = 0;
+		break;
+	    }
+	}
+	instp++;
+	len--;
+	off++;
+    }
+}
+
+/* Print our register names for the cases we have a name.
+   Delegate to the configure code to actually do the print.
+*/
+void
+printreg(Dwarf_Signed reg, struct dwconf_s *config_data)
+{
+    print_reg_from_config_data(reg, config_data);
+}
+
+
+/*
+   Actually does the printing of a rule in the table.
+   This may print something or may print nothing!
+*/
+
+static void
+print_one_frame_reg_col(Dwarf_Debug dbg,
+                        Dwarf_Unsigned rule_id,
+                        Dwarf_Small value_type,
+                        Dwarf_Unsigned reg_used,
+                        struct dwconf_s *config_data,
+                        Dwarf_Signed offset_relevant,
+                        Dwarf_Signed offset, 
+                        Dwarf_Ptr block_ptr)
+{
+    char *type_title = "";
+    int print_type_title = 1;
+
+    if (config_data->cf_interface_number == 2)
+	print_type_title = 0;
+
+    switch (value_type) {
+    case DW_EXPR_OFFSET:
+	type_title = "off";
+	goto preg2;
+    case DW_EXPR_VAL_OFFSET:
+	type_title = "valoff";
+      preg2:
+	if (reg_used == config_data->cf_initial_rule_value) {
+	    break;
+	}
+	if (print_type_title)
+	    printf("<%s ", type_title);
+	printreg((Dwarf_Signed) rule_id, config_data);
+	printf("=");
+	if (offset_relevant == 0) {
+	    printreg((Dwarf_Signed) reg_used, config_data);
+	    printf(" ");
+	} else {
+	    printf("%02lld", offset);
+	    printf("(");
+	    printreg((Dwarf_Signed) reg_used, config_data);
+	    printf(") ");
+	}
+	if (print_type_title)
+	    printf("%s", "> ");
+	break;
+    case DW_EXPR_EXPRESSION:
+	type_title = "expr";
+	goto pexp2;
+    case DW_EXPR_VAL_EXPRESSION:
+	type_title = "valexpr";
+      pexp2:
+	if (print_type_title)
+	    printf("<%s ", type_title);
+	printreg((Dwarf_Signed) rule_id, config_data);
+	printf("=");
+	printf("expr-block-len=%lld", (long long) offset);
+	if (print_type_title)
+	    printf("%s", "> ");
+	if (verbose) {
+	    char pref[40];
+
+	    strcpy(pref, "<");
+	    strcat(pref, type_title);
+	    strcat(pref, "bytes:");
+	    dump_block(pref, block_ptr, offset);
+	    printf("%s", "> ");
+            if(verbose) {
+                      struct esb_s exprstring;
+                      esb_constructor(&exprstring);
+                      get_string_from_locs(dbg,
+			    block_ptr,offset,&exprstring);
+                      printf("<expr:%s>",esb_get_string(&exprstring));
+                      esb_destructor(&exprstring);
+            }
+	}
+	break;
+    default:
+	printf("Internal error in libdwarf, value type %d\n",
+	       value_type);
+	exit(1);
+    }
+    return;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_frames.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,49 @@
+/*
+  Copyright (C) 2006 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write the Free Software Foundation, Inc., 51
+  Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_frames.h,v 1.2 2006/04/17 00:09:56 davea Exp $ */
+
+int
+  print_one_fde(Dwarf_Debug dbg, Dwarf_Fde fde,
+		Dwarf_Unsigned fde_index,
+		Dwarf_Cie * cie_data,
+		Dwarf_Signed cie_element_count,
+		Dwarf_Half address_size, 
+		int is_eh,
+		struct dwconf_s * config_data);
+
+int
+  print_one_cie(Dwarf_Debug dbg, Dwarf_Cie cie,
+		Dwarf_Unsigned cie_index, 
+		Dwarf_Half address_size,
+		struct dwconf_s * config_data);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_reloc.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,512 @@
+/* 
+  Copyright (C) 2000,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write the Free Software Foundation, Inc., 51
+  Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_reloc.c,v 1.11 2005/08/04 05:09:37 davea Exp $ */
+
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+
+#include "globals.h"
+
+
+#define DW_SECTION_REL_DEBUG_INFO    0
+#define DW_SECTION_REL_DEBUG_LINE    1
+#define DW_SECTION_REL_DEBUG_PUBNAME 2
+#define DW_SECTION_REL_DEBUG_ABBREV  3
+#define DW_SECTION_REL_DEBUG_ARANGES 4
+#define DW_SECTION_REL_DEBUG_FRAME   5
+#define DW_SECTION_REL_DEBUG_NUM     6
+
+#define DW_SECTNAME_REL_DEBUG_INFO    ".rel.debug_info"
+#define DW_SECTNAME_REL_DEBUG_LINE    ".rel.debug_line"
+#define DW_SECTNAME_REL_DEBUG_PUBNAME ".rel.debug_pubname"
+#define DW_SECTNAME_REL_DEBUG_ABBREV  ".rel.debug_abbrev"
+#define DW_SECTNAME_REL_DEBUG_ARANGES ".rel.debug_aranges"
+#define DW_SECTNAME_REL_DEBUG_FRAME   ".rel.debug_frame"
+
+#define STRING_FOR_DUPLICATE " duplicate"
+#define STRING_FOR_NULL      " null"
+
+static char *sectnames[] = {
+    DW_SECTNAME_REL_DEBUG_INFO,
+    DW_SECTNAME_REL_DEBUG_LINE,
+    DW_SECTNAME_REL_DEBUG_PUBNAME,
+    DW_SECTNAME_REL_DEBUG_ABBREV,
+    DW_SECTNAME_REL_DEBUG_ARANGES,
+    DW_SECTNAME_REL_DEBUG_FRAME,
+};
+
+static char *error_msg_duplicate[] = {
+    DW_SECTNAME_REL_DEBUG_INFO STRING_FOR_DUPLICATE,
+    DW_SECTNAME_REL_DEBUG_LINE STRING_FOR_DUPLICATE,
+    DW_SECTNAME_REL_DEBUG_PUBNAME STRING_FOR_DUPLICATE,
+    DW_SECTNAME_REL_DEBUG_ABBREV STRING_FOR_DUPLICATE,
+    DW_SECTNAME_REL_DEBUG_ARANGES STRING_FOR_DUPLICATE,
+    DW_SECTNAME_REL_DEBUG_FRAME STRING_FOR_DUPLICATE,
+};
+
+static char *error_msg_null[] = {
+    DW_SECTNAME_REL_DEBUG_INFO STRING_FOR_NULL,
+    DW_SECTNAME_REL_DEBUG_LINE STRING_FOR_NULL,
+    DW_SECTNAME_REL_DEBUG_PUBNAME STRING_FOR_NULL,
+    DW_SECTNAME_REL_DEBUG_ABBREV STRING_FOR_NULL,
+    DW_SECTNAME_REL_DEBUG_ARANGES STRING_FOR_NULL,
+    DW_SECTNAME_REL_DEBUG_FRAME STRING_FOR_NULL,
+};
+
+#define SECT_DATA_SET(x) { \
+	    if (sect_data[(x)].buf != NULL) { \
+		print_error(dbg, error_msg_duplicate[(x)],DW_DLV_OK, err); \
+	    } \
+            if ((data = elf_getdata(scn, 0)) == NULL || data->d_size == 0) { \
+		print_error(dbg, error_msg_null[(x)],DW_DLV_OK, err); \
+	    } \
+	    sect_data[(x)].buf = data -> d_buf; \
+	    sect_data[(x)].size = data -> d_size; \
+	    }
+
+static char *reloc_type_names[] = {
+    "R_MIPS_NONE", "R_MIPS_16", "R_MIPS_32", "R_MIPS_REL32",
+    "R_MIPS_26", "R_MIPS_HI16", "R_MIPS_LO16", "R_MIPS_GPREL16",
+    "R_MIPS_LITERAL", "R_MIPS_GOT16", "R_MIPS_PC16", "R_MIPS_CALL16",
+    "R_MIPS_GPREL32",		/* 12 */
+    "reloc type 13?", "reloc type 14?", "reloc type 15?",
+    "R_MIPS_SHIFT5",		/* 16 */
+    "R_MIPS_SHIFT6",		/* 17 */
+    "R_MIPS_64",		/* 18 */
+    "R_MIPS_GOT_DISP",		/* 19 */
+    "R_MIPS_GOT_PAGE",		/* 20 */
+    "R_MIPS_GOT_OFST",		/* 21 */
+    "R_MIPS_GOT_HI16",		/* 22 */
+    "R_MIPS_GOT_LO16",		/* 23 */
+    "R_MIPS_SUB",		/* 24 */
+    "R_MIPS_INSERT_A",		/* 25 */
+    "R_MIPS_INSERT_B",		/* 26 */
+    "R_MIPS_DELETE",		/* 27 */
+    "R_MIPS_HIGHER",		/* 28 */
+    "R_MIPS_HIGHEST",		/* 29 */
+    "R_MIPS_CALL_HI16",		/* 30 */
+    "R_MIPS_CALL_LO16",		/* 31 */
+    "R_MIPS_SCN_DISP",		/* 32 */
+    "R_MIPS_REL16",		/* 33 */
+    "R_MIPS_ADD_IMMEDIATE",	/* 34 */
+};
+
+/*
+	return valid reloc type names. 
+	if buf is used, it is static, so beware it
+	will be overrwritten by the next call.
+*/
+static char *
+get_reloc_type_names(int index)
+{
+    static char buf[100];
+    int arysiz = sizeof(reloc_type_names) / sizeof(char *);
+    char *retval;
+
+    if (index < 0 || index >= arysiz) {
+	sprintf(buf, "reloc type %d unknown", (int) index);
+	retval = buf;
+    } else {
+	retval = reloc_type_names[index];
+    }
+    return retval;
+}
+
+
+static struct {
+    Dwarf_Small *buf;
+    Dwarf_Unsigned size;
+} sect_data[DW_SECTION_REL_DEBUG_NUM];
+
+#ifndef HAVE_ELF64_GETEHDR
+#define Elf64_Addr  long
+#define Elf64_Word  unsigned long
+#define Elf64_Xword unsigned long
+#define Elf64_Sym   long
+#endif
+
+typedef size_t indx_type;
+
+typedef struct {
+    indx_type indx;
+    char *name;
+    Elf32_Addr value;
+    Elf32_Word size;
+    int type;
+    int bind;
+    unsigned char other;
+    Elf32_Half shndx;
+} SYM;
+
+
+typedef struct {
+    indx_type indx;
+    char *name;
+    Elf64_Addr value;
+    Elf64_Xword size;
+    int type;
+    int bind;
+    unsigned char other;
+    unsigned short shndx;
+} SYM64;
+
+static void print_reloc_information_64(int section_no,
+				       Dwarf_Small * buf,
+				       Dwarf_Unsigned size);
+static void print_reloc_information_32(int section_no,
+				       Dwarf_Small * buf,
+				       Dwarf_Unsigned size);
+static SYM *readsyms(Elf32_Sym * data, size_t num, Elf * elf,
+		     Elf32_Word link);
+static SYM64 *read_64_syms(Elf64_Sym * data, size_t num, Elf * elf,
+			   Elf64_Word link);
+static void *get_scndata(Elf_Scn * fd_scn, size_t * scn_size);
+static void print_relocinfo_64(Dwarf_Debug dbg, Elf * elf);
+static void print_relocinfo_32(Dwarf_Debug dbg, Elf * elf);
+
+static SYM *sym_data;
+static SYM64 *sym_data_64;
+
+void
+print_relocinfo(Dwarf_Debug dbg)
+{
+    Elf *elf;
+    char *endr_ident;
+    int is_64bit;
+    int res;
+    int i;
+    Elf32_Sym *sym = 0;
+
+    for (i = 0; i < DW_SECTION_REL_DEBUG_NUM; i++) {
+	sect_data[i].buf = 0;
+	sect_data[i].size = 0;
+    }
+    res = dwarf_get_elf(dbg, &elf, &err);
+    if (res != DW_DLV_OK) {
+	print_error(dbg, "dwarf_get_elf error", res, err);
+    }
+    if ((endr_ident = elf_getident(elf, NULL)) == NULL) {
+	print_error(dbg, "DW_ELF_GETIDENT_ERROR", res, err);
+    }
+    is_64bit = (endr_ident[EI_CLASS] == ELFCLASS64);
+    if (is_64bit) {
+	print_relocinfo_64(dbg, elf);
+    } else {
+	print_relocinfo_32(dbg, elf);
+    }
+}
+
+static void
+print_relocinfo_64(Dwarf_Debug dbg, Elf * elf)
+{
+#ifdef HAVE_ELF64_GETEHDR
+    Elf_Scn *scn = NULL;
+    Elf_Data *data;
+    Elf64_Ehdr *ehdr64;
+    Elf64_Shdr *shdr64;
+    char *scn_name;
+    int i;
+    Elf64_Sym *sym_64 = 0;
+
+    if ((ehdr64 = elf64_getehdr(elf)) == NULL) {
+	print_error(dbg, "DW_ELF_GETEHDR_ERROR", DW_DLV_OK, err);
+    }
+
+    while ((scn = elf_nextscn(elf, scn)) != NULL) {
+
+	if ((shdr64 = elf64_getshdr(scn)) == NULL) {
+	    print_error(dbg, "DW_ELF_GETSHDR_ERROR", DW_DLV_OK, err);
+	}
+	if ((scn_name =
+	     elf_strptr(elf, ehdr64->e_shstrndx, shdr64->sh_name))
+	    == NULL) {
+	    print_error(dbg, "DW_ELF_STRPTR_ERROR", DW_DLV_OK, err);
+	}
+	if (shdr64->sh_type == SHT_SYMTAB) {
+	    size_t sym_size = 0;
+	    size_t count = 0;
+
+	    if ((sym_64 =
+		 (Elf64_Sym *) get_scndata(scn, &sym_size)) == NULL) {
+		print_error(dbg, "no symbol table data", DW_DLV_OK,
+			    err);
+	    }
+	    count = sym_size / sizeof(Elf64_Sym);
+	    sym_64++;
+            free(sym_data_64);
+	    sym_data_64 = read_64_syms(sym_64, count, elf, shdr64->sh_link);
+	    if (sym_data_64  == NULL) {
+		print_error(dbg, "problem reading symbol table data",
+			    DW_DLV_OK, err);
+	    }
+	} else if (strncmp(scn_name, ".rel.debug_", 11))
+	    continue;
+	else if (strcmp(scn_name, ".rel.debug_info") == 0) {
+	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_INFO)
+	} else if (strcmp(scn_name, ".rel.debug_line") == 0) {
+	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_LINE)
+	} else if (strcmp(scn_name, ".rel.debug_pubname") == 0) {
+	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_PUBNAME)
+	} else if (strcmp(scn_name, ".rel.debug_aranges") == 0) {
+	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_ARANGES)
+	} else if (strcmp(scn_name, ".rel.debug_abbrev") == 0) {
+	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_ABBREV)
+	} else if (strcmp(scn_name, ".rel.debug_frame") == 0) {
+	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_FRAME)
+	}
+    }				/* while */
+
+    for (i = 0; i < DW_SECTION_REL_DEBUG_NUM; i++) {
+	if (sect_data[i].buf != NULL && sect_data[i].size > 0) {
+	    print_reloc_information_64(i, sect_data[i].buf,
+				       sect_data[i].size);
+	}
+    }
+#endif
+}
+
+static void
+print_relocinfo_32(Dwarf_Debug dbg, Elf * elf)
+{
+    Elf_Scn *scn = NULL;
+    Elf_Data *data;
+    Elf32_Ehdr *ehdr32;
+    Elf32_Shdr *shdr32;
+    char *scn_name;
+    int i;
+    Elf32_Sym  *sym = 0;
+
+    if ((ehdr32 = elf32_getehdr(elf)) == NULL) {
+	print_error(dbg, "DW_ELF_GETEHDR_ERROR", DW_DLV_OK, err);
+    }
+    while ((scn = elf_nextscn(elf, scn)) != NULL) {
+	if ((shdr32 = elf32_getshdr(scn)) == NULL) {
+	    print_error(dbg, "DW_ELF_GETSHDR_ERROR", DW_DLV_OK, err);
+	}
+	if ((scn_name =
+	     elf_strptr(elf, ehdr32->e_shstrndx, shdr32->sh_name)
+	    ) == NULL) {
+	    print_error(dbg, "DW_ELF_STRPTR_ERROR", DW_DLV_OK, err);
+	}
+	if (shdr32->sh_type == SHT_SYMTAB) {
+	    size_t sym_size = 0;
+	    size_t count = 0;
+
+	    if ((sym =
+		 (Elf32_Sym *) get_scndata(scn, &sym_size)) == NULL) {
+		print_error(dbg, "no symbol table data", DW_DLV_OK,
+			    err);
+	    }
+	    sym = (Elf32_Sym *) get_scndata(scn, &sym_size);
+	    count = sym_size / sizeof(Elf32_Sym);
+	    sym++;
+            free(sym_data);
+	    sym_data = readsyms(sym, count, elf, shdr32->sh_link);
+	    if (sym_data  == NULL) {
+		print_error(dbg, "problem reading symbol table data",
+			    DW_DLV_OK, err);
+	    }
+	} else if (strncmp(scn_name, ".rel.debug_", 11))
+	    continue;
+	else if (strcmp(scn_name, ".rel.debug_info") == 0) {
+	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_INFO)
+	} else if (strcmp(scn_name, ".rel.debug_line") == 0) {
+	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_LINE)
+	} else if (strcmp(scn_name, ".rel.debug_pubname") == 0) {
+	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_PUBNAME)
+	} else if (strcmp(scn_name, ".rel.debug_aranges") == 0) {
+	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_ARANGES)
+	} else if (strcmp(scn_name, ".rel.debug_abbrev") == 0) {
+	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_ABBREV)
+	} else if (strcmp(scn_name, ".rel.debug_frame") == 0) {
+	    SECT_DATA_SET(DW_SECTION_REL_DEBUG_FRAME)
+	}
+    }				/* while */
+
+    for (i = 0; i < DW_SECTION_REL_DEBUG_NUM; i++) {
+	if (sect_data[i].buf != NULL && sect_data[i].size > 0) {
+	    print_reloc_information_32(i, sect_data[i].buf,
+				       sect_data[i].size);
+	}
+    }
+}
+
+#if HAVE_ELF64_R_INFO
+#ifndef ELF64_R_TYPE
+#define ELF64_R_TYPE(x) 0	/* FIXME */
+#endif
+#ifndef ELF64_R_SYM
+#define ELF64_R_SYM(x) 0	/* FIXME */
+#endif
+#ifndef ELF64_ST_TYPE
+#define ELF64_ST_TYPE(x) 0	/* FIXME */
+#endif
+#ifndef ELF64_ST_BIND
+#define ELF64_ST_BIND(x) 0	/* FIXME */
+#endif
+#endif /* HAVE_ELF64_R_INFO */
+
+
+static void
+print_reloc_information_64(int section_no, Dwarf_Small * buf,
+			   Dwarf_Unsigned size)
+{
+    Dwarf_Unsigned off;
+
+    printf("\n%s:\n", sectnames[section_no]);
+#if HAVE_ELF64_GETEHDR
+    for (off = 0; off < size; off += sizeof(Elf64_Rel)) {
+#if HAVE_ELF64_R_INFO
+	/* This works for the Elf64_Rel in linux */
+	Elf64_Rel *p = (Elf64_Rel *) (buf + off);
+
+	printf("%5lu\t<%3ld> %-34s%s\n",
+	       (unsigned long int) (p->r_offset),
+	       (long)ELF64_R_SYM(p->r_info),
+	       sym_data[ELF64_R_SYM(p->r_info) - 1].name,
+	       get_reloc_type_names(ELF64_R_TYPE(p->r_info)));
+#else
+	/* sgi/mips -64 does not have r_info in the 64bit relocations,
+	   but seperate fields, with 3 types, actually. Only one of
+	   which prints here, as only one really used with dwarf */
+	Elf64_Rel *p = (Elf64_Rel *) (buf + off);
+
+	printf("%5llu\t<%3d> %-34s%s\n",
+	       (unsigned long long int) (p->r_offset),
+	       (long)p->r_sym, sym_data_64[p->r_sym - 1].name,
+	       get_reloc_type_names(p->r_type));
+#endif
+    }
+#endif /* HAVE_ELF64_GETEHDR */
+}
+
+static void
+print_reloc_information_32(int section_no, Dwarf_Small * buf,
+			   Dwarf_Unsigned size)
+{
+    Dwarf_Unsigned off;
+
+    printf("\n%s:\n", sectnames[section_no]);
+    for (off = 0; off < size; off += sizeof(Elf32_Rel)) {
+	Elf32_Rel *p = (Elf32_Rel *) (buf + off);
+
+	printf("%5lu\t<%3d> %-34s%s\n",
+	       (unsigned long int) (p->r_offset),
+	       ELF32_R_SYM(p->r_info),
+	       sym_data[ELF32_R_SYM(p->r_info) - 1].name,
+	       get_reloc_type_names(ELF32_R_TYPE(p->r_info)));
+    }
+}
+
+static SYM *
+readsyms(Elf32_Sym * data, size_t num, Elf * elf, Elf32_Word link)
+{
+    SYM *s, *buf;
+    indx_type i;
+
+    if ((buf = (SYM *) calloc(num, sizeof(SYM))) == NULL) {
+	return NULL;
+    }
+    s = buf;			/* save pointer to head of array */
+    for (i = 1; i < num; i++, data++, buf++) {
+	buf->indx = i;
+	buf->name = (char *) elf_strptr(elf, link, data->st_name);
+	buf->value = data->st_value;
+	buf->size = data->st_size;
+	buf->type = ELF32_ST_TYPE(data->st_info);
+	buf->bind = ELF32_ST_BIND(data->st_info);
+	buf->other = data->st_other;
+	buf->shndx = data->st_shndx;
+    }				/* end for loop */
+    return (s);
+}
+
+static SYM64 *
+read_64_syms(Elf64_Sym * data, size_t num, Elf * elf, Elf64_Word link)
+{
+#ifdef HAVE_ELF64_GETEHDR
+
+    SYM64 *s, *buf;
+    indx_type i;
+
+    if ((buf = (SYM64 *) calloc(num, sizeof(SYM64))) == NULL) {
+	return NULL;
+    }
+    s = buf;			/* save pointer to head of array */
+    for (i = 1; i < num; i++, data++, buf++) {
+	buf->indx = i;
+	buf->name = (char *) elf_strptr(elf, link, data->st_name);
+	buf->value = data->st_value;
+	buf->size = data->st_size;
+	buf->type = ELF64_ST_TYPE(data->st_info);
+	buf->bind = ELF64_ST_BIND(data->st_info);
+	buf->other = data->st_other;
+	buf->shndx = data->st_shndx;
+    }				/* end for loop */
+    return (s);
+#else
+    return 0;
+#endif /* HAVE_ELF64_GETEHDR */
+}
+
+static void *
+get_scndata(Elf_Scn * fd_scn, size_t * scn_size)
+{
+    Elf_Data *p_data;
+
+    p_data = 0;
+    if ((p_data = elf_getdata(fd_scn, p_data)) == 0 ||
+	p_data->d_size == 0) {
+	return NULL;
+    }
+    *scn_size = p_data->d_size;
+    return (p_data->d_buf);
+}
+
+/* Cleanup of malloc space (some of the pointers will be 0 here)
+   so dwarfdump looks 'clean' to a malloc checker.
+*/
+void
+clean_up_syms_malloc_data()
+{
+    free(sym_data);
+    free(sym_data_64);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_sections.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1758 @@
+/* 
+  Copyright (C) 2000,2003,2004,2005,2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write the Free Software Foundation, Inc., 51
+  Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/print_sections.c,v 1.69 2006/04/17 00:09:56 davea Exp $ */
+#include "globals.h"
+#include "dwarf_names.h"
+#include "dwconf.h"
+
+#include "print_frames.h"
+/*
+ * Print line number information:
+ * 	filename
+ *	new basic-block
+ *	[line] [address] <new statement>
+ */
+
+
+static void
+  print_pubname_style_entry(Dwarf_Debug dbg,
+			    char *line_title,
+			    char *name,
+			    Dwarf_Unsigned die_off,
+			    Dwarf_Unsigned cu_off,
+			    Dwarf_Unsigned global_cu_off,
+			    Dwarf_Unsigned maxoff);
+
+
+/* referred in dwarfdump.c */
+Dwarf_Die current_cu_die_for_print_frames;
+
+/* If an offset is bad, libdwarf will notice it and
+   return an error.
+   If it does the error checking in
+	print_pubname_style_entry()
+   will be useless as we give up here on an error.
+
+   This intended for checking pubnames-style call return
+   values (for all the pubnames-style interfaces).
+
+   In at least one gigantic executable die_off turned out wrong.
+*/
+
+static void
+deal_with_name_offset_err(Dwarf_Debug dbg,
+			  char *err_loc,
+			  char *name, Dwarf_Unsigned die_off,
+			  int nres, Dwarf_Error err)
+{
+    if (nres == DW_DLV_ERROR) {
+	Dwarf_Unsigned myerr = dwarf_errno(err);
+
+	if (myerr == DW_DLE_OFFSET_BAD) {
+	    printf("Error: bad offset %s, %s %lld (0x%llx)\n",
+		   err_loc,
+		   name,
+		   (long long) die_off, (unsigned long long) die_off);
+	}
+	print_error(dbg, err_loc, nres, err);
+    }
+}
+
+static void
+print_source_intro(Dwarf_Die cu_die)
+{
+    Dwarf_Off off = 0;
+    int ores = dwarf_dieoffset(cu_die, &off, &err);
+
+    if (ores == DW_DLV_OK) {
+	printf
+	    ("Source lines (from CU-DIE at .debug_info offset %llu):\n",
+	     (unsigned long long) off);
+    } else {
+	printf("Source lines (for the CU-DIE at unknown location):\n");
+    }
+}
+
+
+extern void
+print_line_numbers_this_cu(Dwarf_Debug dbg, Dwarf_Die cu_die)
+{
+    Dwarf_Signed linecount = 0;
+    Dwarf_Line *linebuf = NULL;
+    Dwarf_Signed i = 0;
+    Dwarf_Addr pc = 0;
+    Dwarf_Unsigned lineno = 0;
+    Dwarf_Signed column = 0;
+    string filename;
+    Dwarf_Bool newstatement = 0;
+    Dwarf_Bool lineendsequence = 0;
+    Dwarf_Bool new_basic_block = 0;
+    int lres = 0;
+    int sres = 0;
+    int ares = 0;
+    int lires = 0;
+    int cores = 0;
+
+    printf("\n.debug_line: line number info for a single cu\n");
+    if (verbose > 1) {
+	print_source_intro(cu_die);
+	print_one_die(dbg, cu_die, /* print_information= */ 1,
+		      /* srcfiles= */ 0, /* cnt= */ 0);
+
+	lres = dwarf_print_lines(cu_die, &err);
+	if (lres == DW_DLV_ERROR) {
+	    print_error(dbg, "dwarf_srclines details", lres, err);
+	}
+	return;
+    }
+    lres = dwarf_srclines(cu_die, &linebuf, &linecount, &err);
+    if (lres == DW_DLV_ERROR) {
+	print_error(dbg, "dwarf_srclines", lres, err);
+    } else if (lres == DW_DLV_NO_ENTRY) {
+	/* no line information is included */
+    } else {
+	print_source_intro(cu_die);
+	if (verbose) {
+	    print_one_die(dbg, cu_die, /* print_information= */ 1,
+			  /* srcfiles= */ 0, /* cnt= */ 0);
+	}
+	printf
+	    ("<source>\t[row,column]\t<pc>\t//<new statement or basic block\n");
+
+	for (i = 0; i < linecount; i++) {
+	    Dwarf_Line line = linebuf[i];
+	    int nsres;
+
+	    sres = dwarf_linesrc(line, &filename, &err);
+	    ares = dwarf_lineaddr(line, &pc, &err);
+	    if (sres == DW_DLV_ERROR) {
+		print_error(dbg, "dwarf_linesrc", sres, err);
+	    }
+	    if (sres == DW_DLV_NO_ENTRY) {
+		filename = "<unknown>";
+	    }
+	    if (ares == DW_DLV_ERROR) {
+		print_error(dbg, "dwarf_lineaddr", ares, err);
+	    }
+	    if (ares == DW_DLV_NO_ENTRY) {
+		pc = 0;
+	    }
+	    lires = dwarf_lineno(line, &lineno, &err);
+	    if (lires == DW_DLV_ERROR) {
+		print_error(dbg, "dwarf_lineno", lires, err);
+	    }
+	    if (lires == DW_DLV_NO_ENTRY) {
+		lineno = -1LL;
+	    }
+	    cores = dwarf_lineoff(line, &column, &err);
+	    if (cores == DW_DLV_ERROR) {
+		print_error(dbg, "dwarf_lineoff", cores, err);
+	    }
+	    if (cores == DW_DLV_NO_ENTRY) {
+		column = -1LL;
+	    }
+	    printf("%s:\t[%3llu,%2lld]\t%#llx", filename, lineno,
+		   column, pc);
+	    if (sres == DW_DLV_OK)
+		dwarf_dealloc(dbg, filename, DW_DLA_STRING);
+
+	    nsres = dwarf_linebeginstatement(line, &newstatement, &err);
+	    if (nsres == DW_DLV_OK) {
+		if (newstatement) {
+		    printf("\t// new statement");
+		}
+	    } else if (nsres == DW_DLV_ERROR) {
+		print_error(dbg, "linebeginstatment failed", nsres,
+			    err);
+	    }
+	    nsres = dwarf_lineblock(line, &new_basic_block, &err);
+	    if (nsres == DW_DLV_OK) {
+		if (new_basic_block) {
+		    printf("\t// new basic block");
+		}
+	    } else if (nsres == DW_DLV_ERROR) {
+		print_error(dbg, "lineblock failed", nsres, err);
+	    }
+	    nsres = dwarf_lineendsequence(line, &lineendsequence, &err);
+	    if (nsres == DW_DLV_OK) {
+		if (lineendsequence) {
+		    printf("\t// end of text sequence");
+		}
+	    } else if (nsres == DW_DLV_ERROR) {
+		print_error(dbg, "lineblock failed", nsres, err);
+	    }
+	    printf("\n");
+
+	}
+	dwarf_srclines_dealloc(dbg, linebuf, linecount);
+    }
+}
+
+/*
+
+A strcpy which ensures NUL terminated string
+and never overruns the output.
+
+*/
+static void
+safe_strcpy(char *out, long outlen, char *in, long inlen)
+{
+    if (inlen >= (outlen - 1)) {
+	strncpy(out, in, outlen - 1);
+	out[outlen - 1] = 0;
+    } else {
+	strcpy(out, in);
+    }
+}
+
+/*
+	Returns 1 if a proc with this low_pc found.
+	Else returns 0.
+
+
+*/
+static int
+get_proc_name(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr low_pc,
+	      char *proc_name_buf, int proc_name_buf_len)
+{
+    Dwarf_Signed atcnt = 0;
+    Dwarf_Signed i = 0;
+    Dwarf_Attribute *atlist = NULL;
+    Dwarf_Addr low_pc_die = 0;
+    int atres = 0;
+    int funcres = 1;
+    int funcpcfound = 0;
+    int funcnamefound = 1;
+
+    proc_name_buf[0] = 0;	/* always set to something */
+    atres = dwarf_attrlist(die, &atlist, &atcnt, &err);
+    if (atres == DW_DLV_ERROR) {
+	print_error(dbg, "dwarf_attrlist", atres, err);
+	return 0;
+    }
+    if (atres == DW_DLV_NO_ENTRY) {
+	return 0;
+    }
+    for (i = 0; i < atcnt; i++) {
+	Dwarf_Half attr;
+	int ares;
+	string temps;
+	int sres;
+	int dres;
+
+	if (funcnamefound == 1 && funcpcfound == 1) {
+	    /* stop as soon as both found */
+	    break;
+	}
+	ares = dwarf_whatattr(atlist[i], &attr, &err);
+	if (ares == DW_DLV_ERROR) {
+	    print_error(dbg, "get_proc_name whatattr error", ares, err);
+	} else if (ares == DW_DLV_OK) {
+	    switch (attr) {
+	    case DW_AT_name:
+		sres = dwarf_formstring(atlist[i], &temps, &err);
+		if (sres == DW_DLV_ERROR) {
+		    print_error(dbg,
+				"formstring in get_proc_name failed",
+				sres, err);
+		    /* 50 is safe wrong length since is bigger than the 
+		       actual string */
+		    safe_strcpy(proc_name_buf, proc_name_buf_len,
+				"ERROR in dwarf_formstring!", 50);
+		} else if (sres == DW_DLV_NO_ENTRY) {
+		    /* 50 is safe wrong length since is bigger than the 
+		       actual string */
+		    safe_strcpy(proc_name_buf, proc_name_buf_len,
+				"NO ENTRY on dwarf_formstring?!", 50);
+		} else {
+		    long len = (long) strlen(temps);
+
+		    safe_strcpy(proc_name_buf, proc_name_buf_len, temps,
+				len);
+		}
+		funcnamefound = 1;	/* FOUND THE NAME */
+		break;
+	    case DW_AT_low_pc:
+		dres = dwarf_formaddr(atlist[i], &low_pc_die, &err);
+		if (dres == DW_DLV_ERROR) {
+		    print_error(dbg, "formaddr in get_proc_name failed",
+				dres, err);
+		    low_pc_die = ~low_pc;
+		    /* ensure no match */
+		}
+		funcpcfound = 1;
+
+		break;
+	    default:
+		break;
+	    }
+	}
+    }
+    for (i = 0; i < atcnt; i++) {
+	dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);
+    }
+    dwarf_dealloc(dbg, atlist, DW_DLA_LIST);
+    if (funcnamefound == 0 || funcpcfound == 0 || low_pc != low_pc_die) {
+	funcres = 0;
+    }
+    return (funcres);
+}
+
+/*
+	Modified Depth First Search looking for the procedure:
+	a) only looks for children of subprogram.
+	b) With subprogram looks at current die *before* looking
+	   for a child.
+	
+	Needed since some languages, including MP Fortran,
+	have nested functions.
+	Return 0 on failure, 1 on success.
+*/
+static int
+get_nested_proc_name(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Addr low_pc,
+		     char *ret_name_buf, int ret_name_buf_len)
+{
+    char name_buf[BUFSIZ];
+    Dwarf_Die curdie = die;
+    int die_locally_gotten = 0;
+    Dwarf_Die prev_child = 0;
+    Dwarf_Die newchild = 0;
+    Dwarf_Die newsibling = 0;
+    Dwarf_Half tag;
+    Dwarf_Error err = 0;
+    int chres = DW_DLV_OK;
+
+    ret_name_buf[0] = 0;
+    while (chres == DW_DLV_OK) {
+	int tres;
+
+	tres = dwarf_tag(curdie, &tag, &err);
+	newchild = 0;
+	err = 0;
+	if (tres == DW_DLV_OK) {
+	    int lchres;
+
+	    if (tag == DW_TAG_subprogram) {
+		int proc_name_v;
+
+		proc_name_v = get_proc_name(dbg, curdie, low_pc,
+					    name_buf, BUFSIZ);
+		if (proc_name_v) {
+		    /* this is it */
+		    safe_strcpy(ret_name_buf, ret_name_buf_len,
+				name_buf, (long) strlen(name_buf));
+		    if (die_locally_gotten) {
+			/* If we got this die from the parent, we do
+			   not want to dealloc here! */
+			dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
+		    }
+		    return 1;
+		}
+		/* check children of subprograms recursively should
+		   this really be check children of anything? */
+
+		lchres = dwarf_child(curdie, &newchild, &err);
+		if (lchres == DW_DLV_OK) {
+		    /* look for inner subprogram */
+		    int newprog =
+			get_nested_proc_name(dbg, newchild, low_pc,
+					     name_buf, BUFSIZ);
+
+		    dwarf_dealloc(dbg, newchild, DW_DLA_DIE);
+		    if (newprog) {
+			/* Found it.  We could just take this name or
+			   we could concatenate names together For now, 
+			   just take name */
+			if (die_locally_gotten) {
+			    /* If we got this die from the parent, we
+			       do not want to dealloc here! */
+			    dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
+			}
+			safe_strcpy(ret_name_buf, ret_name_buf_len,
+				    name_buf, (long) strlen(name_buf));
+			return 1;
+		    }
+		} else if (lchres == DW_DLV_NO_ENTRY) {
+		    /* nothing to do */
+		} else {
+		    print_error(dbg,
+				"get_nested_proc_name dwarf_child() failed ",
+				chres, err);
+		    if (die_locally_gotten) {
+			/* If we got this die from the parent, we do
+			   not want to dealloc here! */
+			dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
+		    }
+		    return 0;
+		}
+	    }			/* end if TAG_subprogram */
+	} else {
+	    print_error(dbg, "no tag on child read ", tres, err);
+	    if (die_locally_gotten) {
+		/* If we got this die from the parent, we do not want
+		   to dealloc here! */
+		dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
+	    }
+	    return 0;
+	}
+	/* try next sibling */
+	prev_child = curdie;
+	chres = dwarf_siblingof(dbg, curdie, &newsibling, &err);
+	if (chres == DW_DLV_ERROR) {
+	    print_error(dbg, "dwarf_cu_header On Child read ", chres,
+			err);
+	    if (die_locally_gotten) {
+		/* If we got this die from the parent, we do not want
+		   to dealloc here! */
+		dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
+	    }
+	    return 0;
+	} else if (chres == DW_DLV_NO_ENTRY) {
+	    if (die_locally_gotten) {
+		/* If we got this die from the parent, we do not want
+		   to dealloc here! */
+		dwarf_dealloc(dbg, prev_child, DW_DLA_DIE);
+	    }
+	    return 0;		/* proc name not at this level */
+	} else {		/* DW_DLV_OK */
+	    curdie = newsibling;
+	    if (die_locally_gotten) {
+		/* If we got this die from the parent, we do not want
+		   to dealloc here! */
+		dwarf_dealloc(dbg, prev_child, DW_DLA_DIE);
+	    }
+	    prev_child = 0;
+	    die_locally_gotten = 1;
+	}
+
+    }
+    if (die_locally_gotten) {
+	/* If we got this die from the parent, we do not want to
+	   dealloc here! */
+	dwarf_dealloc(dbg, curdie, DW_DLA_DIE);
+    }
+    return 0;
+}
+
+/*
+  For MP Fortran and possibly other languages, functions 
+  nest!  As a result, we must dig thru all functions, 
+  not just the top level.
+
+
+  This remembers the CU die and restarts each search at the start
+  of  the current cu.
+
+  
+*/
+string
+get_fde_proc_name(Dwarf_Debug dbg, Dwarf_Addr low_pc)
+{
+    static char proc_name[BUFSIZ];
+    Dwarf_Unsigned cu_header_length;
+    Dwarf_Unsigned abbrev_offset;
+    Dwarf_Half version_stamp;
+    Dwarf_Half address_size;
+    Dwarf_Unsigned next_cu_offset = 0;
+    int cures = DW_DLV_OK;
+    int dres = DW_DLV_OK;
+    int chres = DW_DLV_OK;
+    int looping = 0;
+
+    if (current_cu_die_for_print_frames == NULL) {
+	cures
+	    = dwarf_next_cu_header(dbg, &cu_header_length,
+				   &version_stamp, &abbrev_offset,
+				   &address_size, &next_cu_offset,
+				   &err);
+	if (cures == DW_DLV_ERROR) {
+	    return NULL;
+	} else if (cures == DW_DLV_NO_ENTRY) {
+	    /* loop thru the list again */
+	    current_cu_die_for_print_frames = 0;
+	    ++looping;
+	} else {		/* DW_DLV_OK */
+	    dres = dwarf_siblingof(dbg, NULL,
+				   &current_cu_die_for_print_frames,
+				   &err);
+	    if (dres == DW_DLV_ERROR) {
+		return NULL;
+	    }
+	}
+    }
+    if (dres == DW_DLV_OK) {
+	Dwarf_Die child = 0;
+
+	if (current_cu_die_for_print_frames == 0) {
+	    /* no information. Possibly a stripped file */
+	    return NULL;
+	}
+	chres =
+	    dwarf_child(current_cu_die_for_print_frames, &child, &err);
+	if (chres == DW_DLV_ERROR) {
+	    print_error(dbg, "dwarf_cu_header on child read ", chres,
+			err);
+	} else if (chres == DW_DLV_NO_ENTRY) {
+	} else {		/* DW_DLV_OK */
+	    int gotname =
+		get_nested_proc_name(dbg, child, low_pc, proc_name,
+				     BUFSIZ);
+
+	    dwarf_dealloc(dbg, child, DW_DLA_DIE);
+	    if (gotname) {
+		return (proc_name);
+	    }
+	    child = 0;
+	}
+    }
+    for (;;) {
+	Dwarf_Die ldie;
+
+	cures = dwarf_next_cu_header(dbg, &cu_header_length,
+				     &version_stamp, &abbrev_offset,
+				     &address_size, &next_cu_offset,
+				     &err);
+
+	if (cures != DW_DLV_OK) {
+	    break;
+	}
+
+
+	dres = dwarf_siblingof(dbg, NULL, &ldie, &err);
+
+	if (current_cu_die_for_print_frames) {
+	    dwarf_dealloc(dbg, current_cu_die_for_print_frames,
+			  DW_DLA_DIE);
+	}
+	current_cu_die_for_print_frames = 0;
+	if (dres == DW_DLV_ERROR) {
+	    print_error(dbg,
+			"dwarf_cu_header Child Read finding proc name for .debug_frame",
+			chres, err);
+	    continue;
+	} else if (dres == DW_DLV_NO_ENTRY) {
+	    ++looping;
+	    if (looping > 1) {
+		print_error(dbg, "looping  on cu headers!", dres, err);
+		return NULL;
+	    }
+	    continue;
+	}
+	/* DW_DLV_OK */
+	current_cu_die_for_print_frames = ldie;
+	{
+	    int chres;
+	    Dwarf_Die child;
+
+	    chres =
+		dwarf_child(current_cu_die_for_print_frames, &child,
+			    &err);
+	    if (chres == DW_DLV_ERROR) {
+		print_error(dbg, "dwarf Child Read ", chres, err);
+	    } else if (chres == DW_DLV_NO_ENTRY) {
+
+		;		/* do nothing, loop on cu */
+	    } else {		/* DW_DLV_OK) */
+
+		int gotname =
+		    get_nested_proc_name(dbg, child, low_pc, proc_name,
+					 BUFSIZ);
+
+		dwarf_dealloc(dbg, child, DW_DLA_DIE);
+		if (gotname) {
+		    return (proc_name);
+		}
+	    }
+	}
+    }
+    return (NULL);
+}
+
+/* get all the data in .debug_frame (or .eh_frame). 
+ The '3' versions mean print using the dwarf3 new interfaces.
+ The non-3 mean use the old interfaces.
+ All combinations of requests are possible.
+*/
+extern void
+print_frames(Dwarf_Debug dbg, int print_debug_frame, int print_eh_frame,
+	     struct dwconf_s *config_data)
+{
+    Dwarf_Cie *cie_data = NULL;
+    Dwarf_Signed cie_element_count = 0;
+    Dwarf_Fde *fde_data = NULL;
+    Dwarf_Signed fde_element_count = 0;
+    Dwarf_Signed i;
+    int fres = 0;
+    Dwarf_Half address_size = 0;
+    int framed = 0;
+
+    fres = dwarf_get_address_size(dbg, &address_size, &err);
+    if (fres != DW_DLV_OK) {
+	print_error(dbg, "dwarf_get_address_size", fres, err);
+    }
+    for (framed = 0; framed < 2; ++framed) {
+	char *framename = 0;
+	int silent_if_missing = 0;
+	int is_eh = 0;
+
+	if (framed == 0) {
+	    if (!print_debug_frame) {
+		continue;
+	    }
+	    framename = ".debug_frame";
+	    /* 
+	     * Big question here is how to print all the info?
+	     * Can print the logical matrix, but that is huge,
+	     * though could skip lines that don't change.
+	     * Either that, or print the instruction statement program
+	     * that describes the changes.
+	     */
+	    fres =
+		dwarf_get_fde_list(dbg, &cie_data, &cie_element_count,
+				   &fde_data, &fde_element_count, &err);
+	} else {
+	    if (!print_eh_frame) {
+		continue;
+	    }
+	    is_eh = 1;
+	    /* This is gnu g++ exceptions in a .eh_frame section. Which 
+	       is just like .debug_frame except that the empty, or
+	       'special' CIE_id is 0, not -1 (to distinguish fde from
+	       cie). And the augmentation is "eh". As of egcs-1.1.2
+	       anyway. A non-zero cie_id is in a fde and is the
+	       difference between the fde address and the beginning of
+	       the cie it belongs to. This makes sense as this is
+	       intended to be referenced at run time, and is part of
+	       the running image. For more on augmentation strings, see 
+	       libdwarf/dwarf_frame.c.  */
+
+	    /* 
+	     * Big question here is how to print all the info?
+	     * Can print the logical matrix, but that is huge,
+	     * though could skip lines that don't change.
+	     * Either that, or print the instruction statement program
+	     * that describes the changes.
+	     */
+	    silent_if_missing = 1;
+	    framename = ".eh_frame";
+	    fres =
+		dwarf_get_fde_list_eh(dbg, &cie_data,
+				      &cie_element_count, &fde_data,
+				      &fde_element_count, &err);
+	}
+	if (fres == DW_DLV_ERROR) {
+	    printf("\n%s\n", framename);
+	    print_error(dbg, "dwarf_get_fde_list", fres, err);
+	} else if (fres == DW_DLV_NO_ENTRY) {
+	    if (!silent_if_missing)
+		printf("\n%s\n", framename);
+	    /* no frame information */
+	} else {		/* DW_DLV_OK */
+
+	    printf("\n%s\n", framename);
+	    printf("\nfde:\n");
+
+	    for (i = 0; i < fde_element_count; i++) {
+		print_one_fde(dbg, fde_data[i],
+			      i, cie_data, cie_element_count,
+			      address_size, is_eh, config_data);
+	    }
+	    /* 
+	       Print the cie set. */
+	    if (verbose) {
+		printf("\ncie:\n");
+		for (i = 0; i < cie_element_count; i++) {
+		    print_one_cie(dbg, cie_data[i], i, address_size,
+				  config_data);
+		}
+	    }
+	    dwarf_fde_cie_list_dealloc(dbg, cie_data, cie_element_count,
+				       fde_data, fde_element_count);
+	}
+    }
+    if (current_cu_die_for_print_frames) {
+	dwarf_dealloc(dbg, current_cu_die_for_print_frames, DW_DLA_DIE);
+	current_cu_die_for_print_frames = 0;
+    }
+}
+
+
+
+
+int
+  dwarf_get_section_max_offsets(Dwarf_Debug /* dbg */ ,
+				Dwarf_Unsigned *	/* debug_info_size 
+							 */ ,
+				Dwarf_Unsigned *	/* debug_abbrev_size 
+							 */
+				, Dwarf_Unsigned *	/* debug_line_size 
+							 */ ,
+				Dwarf_Unsigned *	/* debug_loc_size 
+							 */ ,
+				Dwarf_Unsigned *
+				/* debug_aranges_size */ ,
+				Dwarf_Unsigned *
+				/* debug_macinfo_size */ ,
+				Dwarf_Unsigned *
+				/* debug_pubnames_size */ ,
+				Dwarf_Unsigned *	/* debug_str_size 
+							 */ ,
+				Dwarf_Unsigned *	/* debug_frame_size 
+							 */
+				, Dwarf_Unsigned *	/* debug_ranges_size 
+							 */
+				, Dwarf_Unsigned *
+				/* debug_pubtypes_size */ );
+
+/* The new (April 2005) dwarf_get_section_max_offsets()
+   in libdwarf returns all max-offsets, but we only
+   want one of those offsets. This function returns 
+   the one we want from that set,
+   making functions needing this offset as readable as possible.
+   (avoiding code duplication).
+*/
+static Dwarf_Unsigned
+get_info_max_offset(Dwarf_Debug dbg)
+{
+    Dwarf_Unsigned debug_info_size = 0;
+    Dwarf_Unsigned debug_abbrev_size = 0;
+    Dwarf_Unsigned debug_line_size = 0;
+    Dwarf_Unsigned debug_loc_size = 0;
+    Dwarf_Unsigned debug_aranges_size = 0;
+    Dwarf_Unsigned debug_macinfo_size = 0;
+    Dwarf_Unsigned debug_pubnames_size = 0;
+    Dwarf_Unsigned debug_str_size = 0;
+    Dwarf_Unsigned debug_frame_size = 0;
+    Dwarf_Unsigned debug_ranges_size = 0;
+    Dwarf_Unsigned debug_pubtypes_size = 0;
+
+    dwarf_get_section_max_offsets(dbg,
+				  &debug_info_size,
+				  &debug_abbrev_size,
+				  &debug_line_size,
+				  &debug_loc_size,
+				  &debug_aranges_size,
+				  &debug_macinfo_size,
+				  &debug_pubnames_size,
+				  &debug_str_size,
+				  &debug_frame_size,
+				  &debug_ranges_size,
+				  &debug_pubtypes_size);
+
+    return debug_info_size;
+}
+
+/* This unifies the code for some error checks to
+   avoid code duplication.
+*/
+static void
+check_info_offset_sanity(char *sec,
+			 char *field,
+			 char *global,
+			 Dwarf_Unsigned offset, Dwarf_Unsigned maxoff)
+{
+    if (maxoff == 0) {
+	/* Lets make a heuristic check. */
+	if (offset > 0xffffffff) {
+	    printf("Warning: section %s %s %s offset 0x%llx "
+		   "exceptionally large \n",
+		   sec, field, global, (unsigned long long) offset);
+	}
+    }
+    if (offset >= maxoff) {
+	printf("Warning: section %s %s %s offset 0x%llx "
+	       "larger than max of 0x%llx\n",
+	       sec, field, global, (unsigned long long) offset,
+	       (unsigned long long) maxoff);
+    }
+}
+
+/* Unified pubnames style output.
+   The error checking here against maxoff may be useless
+   (in that libdwarf may return an error if the offset is bad
+   and we will not get called here).
+   But we leave it in nonetheless as it looks sensible.
+   In at least one gigantic executable such offsets turned out wrong.
+*/
+static void
+print_pubname_style_entry(Dwarf_Debug dbg,
+			  char *line_title,
+			  char *name,
+			  Dwarf_Unsigned die_off,
+			  Dwarf_Unsigned cu_off,
+			  Dwarf_Unsigned global_cu_offset,
+			  Dwarf_Unsigned maxoff)
+{
+    Dwarf_Die die = NULL;
+    Dwarf_Die cu_die = NULL;
+    Dwarf_Off die_CU_off = 0;
+    int dres = 0;
+    int ddres = 0;
+    int cudres = 0;
+
+    /* get die at die_off */
+    dres = dwarf_offdie(dbg, die_off, &die, &err);
+    if (dres != DW_DLV_OK)
+	print_error(dbg, "dwarf_offdie", dres, err);
+
+    /* get offset of die from its cu-header */
+    ddres = dwarf_die_CU_offset(die, &die_CU_off, &err);
+    if (ddres != DW_DLV_OK) {
+	print_error(dbg, "dwarf_die_CU_offset", ddres, err);
+    }
+
+    /* get die at offset cu_off */
+    cudres = dwarf_offdie(dbg, cu_off, &cu_die, &err);
+    if (cudres != DW_DLV_OK) {
+	dwarf_dealloc(dbg, die, DW_DLA_DIE);
+	print_error(dbg, "dwarf_offdie", cudres, err);
+    }
+    printf("%s %-15s die-in-sect %lld, cu-in-sect %lld,"
+	   " die-in-cu %lld, cu-header-in-sect %lld",
+	   line_title, name, (long long) die_off, (long long) cu_off,
+	   /* the cu die offset */
+	   (long long) die_CU_off,
+	   /* following is absolute offset of the ** beginning of the
+	      cu */
+	   (long long) (die_off - die_CU_off));
+
+    if ((die_off - die_CU_off) != global_cu_offset) {
+	printf(" error: real cuhdr %llu", global_cu_offset);
+	exit(1);
+    }
+    if (verbose) {
+	printf(" cuhdr %llu", global_cu_offset);
+    }
+
+
+    dwarf_dealloc(dbg, die, DW_DLA_DIE);
+    dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
+
+
+    printf("\n");
+
+    check_info_offset_sanity(line_title,
+			     "die offset", name, die_off, maxoff);
+    check_info_offset_sanity(line_title,
+			     "die cu offset", name, die_CU_off, maxoff);
+    check_info_offset_sanity(line_title,
+			     "cu offset", name,
+			     (die_off - die_CU_off), maxoff);
+
+}
+
+
+/* get all the data in .debug_pubnames */
+extern void
+print_pubnames(Dwarf_Debug dbg)
+{
+    Dwarf_Global *globbuf = NULL;
+    Dwarf_Signed count = 0;
+    Dwarf_Signed i = 0;
+    Dwarf_Off die_off = 0;
+    Dwarf_Off cu_off = 0;
+    char *name = 0;
+    int res = 0;
+
+    printf("\n.debug_pubnames\n");
+    res = dwarf_get_globals(dbg, &globbuf, &count, &err);
+    if (res == DW_DLV_ERROR) {
+	print_error(dbg, "dwarf_get_globals", res, err);
+    } else if (res == DW_DLV_NO_ENTRY) {
+	/* (err == 0 && count == DW_DLV_NOCOUNT) means there are no
+	   pubnames.  */
+    } else {
+	Dwarf_Unsigned maxoff = get_info_max_offset(dbg);
+
+	for (i = 0; i < count; i++) {
+	    int nres;
+	    int cures3;
+	    Dwarf_Off global_cu_off = 0;
+
+	    nres = dwarf_global_name_offsets(globbuf[i],
+					     &name, &die_off, &cu_off,
+					     &err);
+	    deal_with_name_offset_err(dbg, "dwarf_global_name_offsets",
+				      name, die_off, nres, err);
+
+	    cures3 = dwarf_global_cu_offset(globbuf[i],
+					    &global_cu_off, &err);
+	    if (cures3 != DW_DLV_OK) {
+		print_error(dbg, "dwarf_global_cu_offset", cures3, err);
+	    }
+
+	    print_pubname_style_entry(dbg,
+				      "global",
+				      name, die_off, cu_off,
+				      global_cu_off, maxoff);
+
+	    /* print associated die too? */
+
+	    if (check_pubname_attr) {
+		Dwarf_Bool has_attr;
+		int ares;
+		int dres;
+		Dwarf_Die die;
+
+		/* get die at die_off */
+		dres = dwarf_offdie(dbg, die_off, &die, &err);
+		if (dres != DW_DLV_OK) {
+		    print_error(dbg, "dwarf_offdie", dres, err);
+		}
+
+
+		ares =
+		    dwarf_hasattr(die, DW_AT_external, &has_attr, &err);
+		if (ares == DW_DLV_ERROR) {
+		    print_error(dbg, "hassattr on DW_AT_external", ares,
+				err);
+		}
+		pubname_attr_result.checks++;
+		if (ares == DW_DLV_OK && has_attr) {
+		    /* Should the value of flag be examined? */
+		} else {
+		    pubname_attr_result.errors++;
+		    DWARF_CHECK_ERROR2(name,
+				       "pubname does not have DW_AT_external")
+		}
+		dwarf_dealloc(dbg, die, DW_DLA_DIE);
+	    }
+	}
+	dwarf_globals_dealloc(dbg, globbuf, count);
+    }
+}				/* print_pubnames() */
+
+
+struct macro_counts_s {
+    long mc_start_file;
+    long mc_end_file;
+    long mc_define;
+    long mc_undef;
+    long mc_extension;
+    long mc_code_zero;
+    long mc_unknown;
+};
+
+static void
+print_one_macro_entry_detail(long i,
+			     char *type,
+			     struct Dwarf_Macro_Details_s *mdp)
+{
+    /* "DW_MACINFO_*: section-offset file-index [line] string\n" */
+    if (mdp->dmd_macro) {
+	printf("%3ld %s: %6llu %2lld [%4lld] \"%s\" \n",
+	       i,
+	       type,
+	       mdp->dmd_offset,
+	       mdp->dmd_fileindex, mdp->dmd_lineno, mdp->dmd_macro);
+    } else {
+	printf("%3ld %s: %6llu %2lld [%4lld] 0\n",
+	       i,
+	       type,
+	       mdp->dmd_offset, mdp->dmd_fileindex, mdp->dmd_lineno);
+    }
+
+}
+
+static void
+print_one_macro_entry(long i,
+		      struct Dwarf_Macro_Details_s *mdp,
+		      struct macro_counts_s *counts)
+{
+
+    switch (mdp->dmd_type) {
+    case 0:
+	counts->mc_code_zero++;
+	print_one_macro_entry_detail(i, "DW_MACINFO_type-code-0", mdp);
+	break;
+
+    case DW_MACINFO_start_file:
+	counts->mc_start_file++;
+	print_one_macro_entry_detail(i, "DW_MACINFO_start_file", mdp);
+	break;
+
+    case DW_MACINFO_end_file:
+	counts->mc_end_file++;
+	print_one_macro_entry_detail(i, "DW_MACINFO_end_file  ", mdp);
+	break;
+
+    case DW_MACINFO_vendor_ext:
+	counts->mc_extension++;
+	print_one_macro_entry_detail(i, "DW_MACINFO_vendor_ext", mdp);
+	break;
+
+    case DW_MACINFO_define:
+	counts->mc_define++;
+	print_one_macro_entry_detail(i, "DW_MACINFO_define    ", mdp);
+	break;
+
+    case DW_MACINFO_undef:
+	counts->mc_undef++;
+	print_one_macro_entry_detail(i, "DW_MACINFO_undef     ", mdp);
+	break;
+
+    default:
+	{
+	    char create_type[50];	/* More than large enough. */
+
+	    counts->mc_unknown++;
+	    snprintf(create_type, sizeof(create_type),
+		     "DW_MACINFO_0x%x", mdp->dmd_type);
+	    print_one_macro_entry_detail(i, create_type, mdp);
+	}
+	break;
+    }
+}
+
+/* print data in .debug_macinfo */
+/* FIXME: should print name of file whose index is in macro data
+   here  --  somewhere.
+*/
+ /*ARGSUSED*/ extern void
+print_macinfo(Dwarf_Debug dbg)
+{
+    Dwarf_Off offset = 0;
+    Dwarf_Unsigned max = 0;
+    Dwarf_Signed count = 0;
+    long group = 0;
+    Dwarf_Macro_Details *maclist = NULL;
+    int lres = 0;
+
+    printf("\n.debug_macinfo\n");
+
+    while ((lres = dwarf_get_macro_details(dbg, offset,
+					   max, &count, &maclist,
+					   &err)) == DW_DLV_OK) {
+	long i;
+	struct macro_counts_s counts;
+
+
+	memset(&counts, 0, sizeof(counts));
+
+	printf("\n");
+	printf("compilation-unit .debug_macinfo # %ld\n", group);
+	printf
+	    ("num name section-offset file-index [line] \"string\"\n");
+	for (i = 0; i < count; i++) {
+	    struct Dwarf_Macro_Details_s *mdp = &maclist[i];
+
+	    print_one_macro_entry(i, mdp, &counts);
+	}
+
+	if (counts.mc_start_file == 0) {
+	    printf
+		("DW_MACINFO file count of zero is invalid DWARF2/3\n");
+	}
+	if (counts.mc_start_file != counts.mc_end_file) {
+	    printf("Counts of DW_MACINFO file (%ld) end_file (%ld) "
+		   "do not match!.\n",
+		   counts.mc_start_file, counts.mc_end_file);
+	}
+	if (counts.mc_code_zero < 1) {
+	    printf("Count of zeros in macro group should be non-zero "
+		   "(1 preferred), count is %ld\n",
+		   counts.mc_code_zero);
+	}
+	printf("Macro counts: start file %ld, "
+	       "end file %ld, "
+	       "define %ld, "
+	       "undef %ld "
+	       "ext %ld, "
+	       "code-zero %ld, "
+	       "unknown %ld\n",
+	       counts.mc_start_file,
+	       counts.mc_end_file,
+	       counts.mc_define,
+	       counts.mc_undef,
+	       counts.mc_extension,
+	       counts.mc_code_zero, counts.mc_unknown);
+
+
+	/* int type= maclist[count - 1].dmd_type; */
+	/* ASSERT: type is zero */
+
+	offset = maclist[count - 1].dmd_offset + 1;
+	dwarf_dealloc(dbg, maclist, DW_DLA_STRING);
+	++group;
+    }
+    if (lres == DW_DLV_ERROR) {
+	print_error(dbg, "dwarf_get_macro_details", lres, err);
+    }
+}
+
+/* print data in .debug_loc */
+extern void
+print_locs(Dwarf_Debug dbg)
+{
+    Dwarf_Unsigned offset = 0;
+    Dwarf_Addr hipc_offset = 0;
+    Dwarf_Addr lopc_offset = 0;
+    Dwarf_Ptr data = 0;
+    Dwarf_Unsigned entry_len = 0;
+    Dwarf_Unsigned next_entry = 0;
+    int lres = 0;
+
+    printf("\n.debug_loc format <o b e l> means "
+	   "section-offset begin-addr end-addr length-of-block-entry\n");
+    while ((lres = dwarf_get_loclist_entry(dbg, offset,
+					   &hipc_offset, &lopc_offset,
+					   &data, &entry_len,
+					   &next_entry,
+					   &err)) == DW_DLV_OK) {
+	printf("\t <obel> 0x%08llx 0x%09llx " "0x%08llx " "%8lld\n",
+	       (long long) offset, (long long) lopc_offset,
+	       (long long) hipc_offset, (long long) entry_len);
+	offset = next_entry;
+    }
+    if (lres == DW_DLV_ERROR) {
+	print_error(dbg, "dwarf_get_loclist_entry", lres, err);
+    }
+}
+
+/* print data in .debug_abbrev */
+extern void
+print_abbrevs(Dwarf_Debug dbg)
+{
+    Dwarf_Abbrev ab;
+    Dwarf_Unsigned offset = 0;
+    Dwarf_Unsigned length = 0;
+    Dwarf_Unsigned attr_count = 0;
+    Dwarf_Half tag = 0;
+    Dwarf_Half attr = 0;
+    Dwarf_Signed form = 0;
+    Dwarf_Off off = 0;
+    Dwarf_Unsigned i = 0;
+    string child_name;
+    Dwarf_Unsigned abbrev_num = 1;
+    Dwarf_Signed child_flag = 0;
+    int abres = 0;
+    int tres = 0;
+    int acres = 0;
+    Dwarf_Unsigned abbrev_code = 0;
+
+    printf("\n.debug_abbrev\n");
+    while ((abres = dwarf_get_abbrev(dbg, offset, &ab,
+				     &length, &attr_count,
+				     &err)) == DW_DLV_OK) {
+
+	if (attr_count == 0) {
+	    /* Simple innocuous zero : null abbrev entry */
+	    if (dense) {
+		printf("<%lld><%lld><%lld><%s>\n", abbrev_num, offset, (signed long long)	/* abbrev_code 
+												 */ 0,
+		       "null .debug_abbrev entry");
+	    } else {
+		printf("<%4lld><%5lld><code: %2lld> %-20s\n", abbrev_num, offset, (signed long long)	/* abbrev_code 
+													 */ 0,
+		       "null .debug_abbrev entry");
+	    }
+
+	    offset += length;
+	    ++abbrev_num;
+	    dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
+	    continue;
+	}
+	tres = dwarf_get_abbrev_tag(ab, &tag, &err);
+	if (tres != DW_DLV_OK) {
+	    dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
+	    print_error(dbg, "dwarf_get_abbrev_tag", tres, err);
+	}
+	tres = dwarf_get_abbrev_code(ab, &abbrev_code, &err);
+	if (tres != DW_DLV_OK) {
+	    dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
+	    print_error(dbg, "dwarf_get_abbrev_code", tres, err);
+	}
+	if (dense)
+	    printf("<%lld><%lld><%lld><%s>", abbrev_num,
+		   offset, abbrev_code, get_TAG_name(dbg, tag));
+	else
+	    printf("<%4lld><%5lld><code: %2lld> %-20s", abbrev_num,
+		   offset, abbrev_code, get_TAG_name(dbg, tag));
+	++abbrev_num;
+	acres = dwarf_get_abbrev_children_flag(ab, &child_flag, &err);
+	if (acres == DW_DLV_ERROR) {
+	    dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
+	    print_error(dbg, "dwarf_get_abbrev_children_flag", acres,
+			err);
+	}
+	if (acres == DW_DLV_NO_ENTRY) {
+	    child_flag = 0;
+	}
+	child_name = get_children_name(dbg, child_flag);
+	if (dense)
+	    printf(" %s", child_name);
+	else
+	    printf("%s\n", child_name);
+	/* Abbrev just contains the format of a die, which debug_info
+	   then points to with the real data. So here we just print the 
+	   given format. */
+	for (i = 0; i < attr_count; i++) {
+	    int aeres;
+
+	    aeres =
+		dwarf_get_abbrev_entry(ab, i, &attr, &form, &off, &err);
+	    if (aeres == DW_DLV_ERROR) {
+		dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
+		print_error(dbg, "dwarf_get_abbrev_entry", aeres, err);
+	    }
+	    if (aeres == DW_DLV_NO_ENTRY) {
+		attr = -1LL;
+		form = -1LL;
+	    }
+	    if (dense)
+		printf(" <%ld>%s<%s>", (unsigned long) off,
+		       get_AT_name(dbg, attr),
+		       get_FORM_name(dbg, (Dwarf_Half) form));
+	    else
+		printf("      <%5ld>\t%-28s%s\n",
+		       (unsigned long) off, get_AT_name(dbg, attr),
+		       get_FORM_name(dbg, (Dwarf_Half) form));
+	}
+	dwarf_dealloc(dbg, ab, DW_DLA_ABBREV);
+	offset += length;
+	if (dense)
+	    printf("\n");
+    }
+    if (abres == DW_DLV_ERROR) {
+	print_error(dbg, "dwarf_get_abbrev", abres, err);
+    }
+}
+
+/* print data in .debug_string */
+extern void
+print_strings(Dwarf_Debug dbg)
+{
+    Dwarf_Signed length = 0;
+    string name;
+    Dwarf_Off offset = 0;
+    int sres = 0;
+
+    printf("\n.debug_string\n");
+    while ((sres = dwarf_get_str(dbg, offset, &name, &length, &err))
+	   == DW_DLV_OK) {
+	printf("name at offset %lld, length %lld is %s\n",
+	       offset, length, name);
+	offset += length + 1;
+    }
+    /* An inability to find the section is not necessarily
+       a real error, so do not report error unless we've
+       seen a real record. */
+    if(sres == DW_DLV_ERROR && offset != 0) {
+       print_error(dbg, "dwarf_get_str failure", sres, err);
+    }
+}
+
+/* get all the data in .debug_aranges */
+extern void
+print_aranges(Dwarf_Debug dbg)
+{
+    Dwarf_Signed count = 0;
+    Dwarf_Signed i = 0;
+    Dwarf_Arange *arange_buf = NULL;
+    Dwarf_Addr start = 0;
+    Dwarf_Unsigned length = 0;
+    Dwarf_Off cu_die_offset = 0;
+    Dwarf_Die cu_die = NULL;
+    int ares = 0;
+    int aires = 0;
+
+    printf("\n.debug_aranges\n");
+    ares = dwarf_get_aranges(dbg, &arange_buf, &count, &err);
+    if (ares == DW_DLV_ERROR) {
+	print_error(dbg, "dwarf_get_aranges", ares, err);
+    } else if (ares == DW_DLV_NO_ENTRY) {
+	/* no arange is included */
+    } else {
+	for (i = 0; i < count; i++) {
+	    aires = dwarf_get_arange_info(arange_buf[i],
+					  &start, &length,
+					  &cu_die_offset, &err);
+	    if (aires != DW_DLV_OK) {
+		print_error(dbg, "dwarf_get_arange_info", aires, err);
+	    } else {
+		int dres;
+
+		dres = dwarf_offdie(dbg, cu_die_offset, &cu_die, &err);
+		if (dres != DW_DLV_OK) {
+		    print_error(dbg, "dwarf_offdie", dres, err);
+		} else {
+		    if (cu_name_flag) {
+			Dwarf_Half tag;
+			Dwarf_Attribute attrib;
+			Dwarf_Half theform;
+			int tres;
+			int dares;
+			int fres;
+
+			tres = dwarf_tag(cu_die, &tag, &err);
+			if (tres != DW_DLV_OK) {
+			    print_error(dbg, "dwarf_tag in aranges",
+					tres, err);
+			}
+			dares =
+			    dwarf_attr(cu_die, DW_AT_name, &attrib,
+				       &err);
+			if (dares != DW_DLV_OK) {
+			    print_error(dbg, "dwarf_attr arange"
+					" derived die has no name",
+					dres, err);
+			}
+			fres = dwarf_whatform(attrib, &theform, &err);
+			if (fres == DW_DLV_OK) {
+			    if (theform == DW_FORM_string
+				|| theform == DW_FORM_strp) {
+				string temps;
+				int sres;
+
+				sres =
+				    dwarf_formstring(attrib, &temps,
+						     &err);
+				if (sres == DW_DLV_OK) {
+				    string p = temps;
+
+				    if (cu_name[0] != '/') {
+					p = strrchr(temps, '/');
+					if (p == NULL) {
+					    p = temps;
+					} else {
+					    p++;
+					}
+				    }
+				    if (!strcmp(cu_name, p)) {
+				    } else {
+					continue;
+				    }
+				} else {
+				    print_error(dbg,
+						"arange: string missing",
+						sres, err);
+				}
+			    }
+			} else {
+			    print_error(dbg,
+					"dwarf_whatform unexpected value",
+					fres, err);
+			}
+			dwarf_dealloc(dbg, attrib, DW_DLA_ATTR);
+		    }
+		    printf("\narange starts at %llx, "
+			   "length of %lld, cu_die_offset = %lld",
+			   start, length, cu_die_offset);
+		    /* get the offset of the cu header itself in the
+		       section */
+		    {
+			Dwarf_Off off = 0;
+			int cures3 =
+			    dwarf_get_arange_cu_header_offset(arange_buf
+							      [i],
+							      &off,
+							      &err);
+
+			if (cures3 != DW_DLV_OK) {
+			    print_error(dbg, "dwarf_get_cu_hdr_offset",
+					cures3, err);
+			}
+			if (verbose)
+			    printf(" cuhdr %llu", off);
+		    }
+		    printf("\n");
+		    print_one_die(dbg, cu_die, (boolean) TRUE,
+				  /* srcfiles= */ 0,
+				  /* cnt= */ 0);
+
+		    dwarf_dealloc(dbg, cu_die, DW_DLA_DIE);
+		}
+	    }
+	    /* print associated die too? */
+	    dwarf_dealloc(dbg, arange_buf[i], DW_DLA_ARANGE);
+	}
+	dwarf_dealloc(dbg, arange_buf, DW_DLA_LIST);
+    }
+}
+
+/* Get all the data in .debug_static_funcs 
+   On error, this allows some dwarf memory leaks.
+*/
+extern void
+print_static_funcs(Dwarf_Debug dbg)
+{
+    Dwarf_Func *funcbuf = NULL;
+    Dwarf_Signed count = 0;
+    Dwarf_Signed i = 0;
+    Dwarf_Off die_off = 0;
+    Dwarf_Off cu_off = 0;
+    int gfres = 0;
+
+    printf("\n.debug_static_func\n");
+    gfres = dwarf_get_funcs(dbg, &funcbuf, &count, &err);
+    if (gfres == DW_DLV_ERROR) {
+	print_error(dbg, "dwarf_get_funcs", gfres, err);
+    } else if (gfres == DW_DLV_NO_ENTRY) {
+	/* no static funcs */
+    } else {
+	Dwarf_Unsigned maxoff = get_info_max_offset(dbg);
+
+	for (i = 0; i < count; i++) {
+	    int fnres;
+	    int cures3;
+	    Dwarf_Unsigned global_cu_off = 0;
+	    char *name = 0;
+
+	    fnres =
+		dwarf_func_name_offsets(funcbuf[i], &name, &die_off,
+					&cu_off, &err);
+	    deal_with_name_offset_err(dbg, "dwarf_func_name_offsets",
+				      name, die_off, fnres, err);
+
+	    cures3 = dwarf_func_cu_offset(funcbuf[i],
+					  &global_cu_off, &err);
+	    if (cures3 != DW_DLV_OK) {
+		print_error(dbg, "dwarf_global_cu_offset", cures3, err);
+	    }
+
+	    print_pubname_style_entry(dbg,
+				      "static-func", name, die_off,
+				      cu_off, global_cu_off, maxoff);
+
+
+	    /* print associated die too? */
+	    if (check_pubname_attr) {
+		Dwarf_Bool has_attr;
+		int ares;
+		int dres;
+		Dwarf_Die die;
+
+		/* get die at die_off */
+		dres = dwarf_offdie(dbg, die_off, &die, &err);
+		if (dres != DW_DLV_OK) {
+		    print_error(dbg, "dwarf_offdie", dres, err);
+		}
+
+
+		ares =
+		    dwarf_hasattr(die, DW_AT_external, &has_attr, &err);
+		if (ares == DW_DLV_ERROR) {
+		    print_error(dbg, "hassattr on DW_AT_external", ares,
+				err);
+		}
+		pubname_attr_result.checks++;
+		if (ares == DW_DLV_OK && has_attr) {
+		    /* Should the value of flag be examined? */
+		} else {
+		    pubname_attr_result.errors++;
+		    DWARF_CHECK_ERROR2(name,
+				       "pubname does not have DW_AT_external")
+		}
+		dwarf_dealloc(dbg, die, DW_DLA_DIE);
+	    }
+	}
+	dwarf_funcs_dealloc(dbg, funcbuf, count);
+    }
+}				/* print_static_funcs() */
+
+/* get all the data in .debug_static_vars */
+extern void
+print_static_vars(Dwarf_Debug dbg)
+{
+    Dwarf_Var *varbuf = NULL;
+    Dwarf_Signed count = 0;
+    Dwarf_Signed i = 0;
+    Dwarf_Off die_off = 0;
+    Dwarf_Off cu_off = 0;
+    char *name = 0;
+    int gvres = 0;
+
+    printf("\n.debug_static_vars\n");
+    gvres = dwarf_get_vars(dbg, &varbuf, &count, &err);
+    if (gvres == DW_DLV_ERROR) {
+	print_error(dbg, "dwarf_get_vars", gvres, err);
+    } else if (gvres == DW_DLV_NO_ENTRY) {
+	/* no static vars */
+    } else {
+	Dwarf_Unsigned maxoff = get_info_max_offset(dbg);
+
+	for (i = 0; i < count; i++) {
+	    int vnres;
+	    int cures3;
+	    Dwarf_Off global_cu_off = 0;
+
+	    vnres =
+		dwarf_var_name_offsets(varbuf[i], &name, &die_off,
+				       &cu_off, &err);
+	    deal_with_name_offset_err(dbg,
+				      "dwarf_var_name_offsets",
+				      name, die_off, vnres, err);
+
+	    cures3 = dwarf_var_cu_offset(varbuf[i],
+					 &global_cu_off, &err);
+	    if (cures3 != DW_DLV_OK) {
+		print_error(dbg, "dwarf_global_cu_offset", cures3, err);
+	    }
+
+	    print_pubname_style_entry(dbg,
+				      "static-var",
+				      name, die_off, cu_off,
+				      global_cu_off, maxoff);
+
+	    /* print associated die too? */
+	}
+	dwarf_vars_dealloc(dbg, varbuf, count);
+    }
+}				/* print_static_vars */
+
+/* get all the data in .debug_types */
+extern void
+print_types(Dwarf_Debug dbg, enum type_type_e type_type)
+{
+    Dwarf_Type *typebuf = NULL;
+    Dwarf_Signed count = 0;
+    Dwarf_Signed i = 0;
+    Dwarf_Off die_off = 0;
+    Dwarf_Off cu_off = 0;
+    char *name = NULL;
+    int gtres = 0;
+
+    char *section_name = NULL;
+    char *offset_err_name = NULL;
+    char *section_open_name = NULL;
+    char *print_name_prefix = NULL;
+    int (*get_types) (Dwarf_Debug, Dwarf_Type **, Dwarf_Signed *,
+		      Dwarf_Error *)
+	= 0;
+    int (*get_offset) (Dwarf_Type, char **, Dwarf_Off *, Dwarf_Off *,
+		       Dwarf_Error *) = NULL;
+    int (*get_cu_offset) (Dwarf_Type, Dwarf_Off *, Dwarf_Error *) =
+	NULL;
+    void (*dealloctype) (Dwarf_Debug, Dwarf_Type *, Dwarf_Signed) =
+	NULL;
+
+
+    if (type_type == DWARF_PUBTYPES) {
+	section_name = ".debug_pubtypes";
+	offset_err_name = "dwarf_pubtype_name_offsets";
+	section_open_name = "dwarf_get_pubtypes";
+	print_name_prefix = "pubtype";
+	get_types = dwarf_get_pubtypes;
+	get_offset = dwarf_pubtype_name_offsets;
+	get_cu_offset = dwarf_pubtype_cu_offset;
+	dealloctype = dwarf_pubtypes_dealloc;
+    } else {
+	/* SGI_TYPENAME */
+	section_name = ".debug_typenames";
+	offset_err_name = "dwarf_type_name_offsets";
+	section_open_name = "dwarf_get_types";
+	print_name_prefix = "type";
+	get_types = dwarf_get_types;
+	get_offset = dwarf_type_name_offsets;
+	get_cu_offset = dwarf_type_cu_offset;
+	dealloctype = dwarf_types_dealloc;
+    }
+
+
+
+    gtres = get_types(dbg, &typebuf, &count, &err);
+    if (gtres == DW_DLV_ERROR) {
+	print_error(dbg, section_open_name, gtres, err);
+    } else if (gtres == DW_DLV_NO_ENTRY) {
+	/* no types */
+    } else {
+	Dwarf_Unsigned maxoff = get_info_max_offset(dbg);
+
+	/* Before July 2005, the section name was printed
+	   unconditionally, now only prints if non-empty section really 
+	   exists. */
+	printf("\n%s\n", section_name);
+
+	for (i = 0; i < count; i++) {
+	    int tnres;
+	    int cures3;
+	    Dwarf_Off global_cu_off = 0;
+
+	    tnres =
+		get_offset(typebuf[i], &name, &die_off, &cu_off, &err);
+	    deal_with_name_offset_err(dbg, offset_err_name, name,
+				      die_off, tnres, err);
+
+	    cures3 = get_cu_offset(typebuf[i], &global_cu_off, &err);
+
+	    if (cures3 != DW_DLV_OK) {
+		print_error(dbg, "dwarf_var_cu_offset", cures3, err);
+	    }
+	    print_pubname_style_entry(dbg,
+				      print_name_prefix,
+				      name, die_off, cu_off,
+				      global_cu_off, maxoff);
+
+	    /* print associated die too? */
+	}
+	dealloctype(dbg, typebuf, count);
+    }
+}				/* print_types() */
+
+/* get all the data in .debug_weaknames */
+extern void
+print_weaknames(Dwarf_Debug dbg)
+{
+    Dwarf_Weak *weaknamebuf = NULL;
+    Dwarf_Signed count = 0;
+    Dwarf_Signed i = 0;
+    Dwarf_Off die_off = 0;
+    Dwarf_Off cu_off = 0;
+    char *name = NULL;
+    int wkres = 0;
+
+    printf("\n.debug_weaknames\n");
+    wkres = dwarf_get_weaks(dbg, &weaknamebuf, &count, &err);
+    if (wkres == DW_DLV_ERROR) {
+	print_error(dbg, "dwarf_get_weaks", wkres, err);
+    } else if (wkres == DW_DLV_NO_ENTRY) {
+	/* no weaknames */
+    } else {
+	Dwarf_Unsigned maxoff = get_info_max_offset(dbg);
+
+	for (i = 0; i < count; i++) {
+	    int tnres;
+	    int cures3;
+
+	    Dwarf_Unsigned global_cu_off = 0;
+
+	    tnres = dwarf_weak_name_offsets(weaknamebuf[i],
+					    &name, &die_off, &cu_off,
+					    &err);
+	    deal_with_name_offset_err(dbg,
+				      "dwarf_weak_name_offsets",
+				      name, die_off, tnres, err);
+
+	    cures3 = dwarf_weak_cu_offset(weaknamebuf[i],
+					  &global_cu_off, &err);
+
+	    if (cures3 != DW_DLV_OK) {
+		print_error(dbg, "dwarf_weakname_cu_offset",
+			    cures3, err);
+	    }
+	    print_pubname_style_entry(dbg,
+				      "weakname",
+				      name, die_off, cu_off,
+				      global_cu_off, maxoff);
+
+	    /* print associated die too? */
+	}
+	dwarf_weaks_dealloc(dbg, weaknamebuf, count);
+    }
+}				/* print_weaknames() */
+
+
+
+/*
+    decode ULEB
+*/
+Dwarf_Unsigned
+local_dwarf_decode_u_leb128(unsigned char *leb128,
+			    unsigned int *leb128_length)
+{
+    unsigned char byte = 0;
+    Dwarf_Unsigned number = 0;
+    unsigned int shift = 0;
+    unsigned int byte_length = 1;
+
+    byte = *leb128;
+    for (;;) {
+	number |= (byte & 0x7f) << shift;
+	shift += 7;
+
+	if ((byte & 0x80) == 0) {
+	    if (leb128_length != NULL)
+		*leb128_length = byte_length;
+	    return (number);
+	}
+
+	byte_length++;
+	byte = *(++leb128);
+    }
+}
+
+#define BITSINBYTE 8
+Dwarf_Signed
+local_dwarf_decode_s_leb128(unsigned char *leb128,
+			    unsigned int *leb128_length)
+{
+    Dwarf_Signed number = 0;
+    Dwarf_Bool sign = 0;
+    Dwarf_Signed shift = 0;
+    unsigned char byte = *leb128;
+    Dwarf_Signed byte_length = 1;
+
+    /* byte_length being the number of bytes of data absorbed so far in
+       turning the leb into a Dwarf_Signed. */
+
+    for (;;) {
+	sign = byte & 0x40;
+	number |= ((Dwarf_Signed) ((byte & 0x7f))) << shift;
+	shift += 7;
+
+	if ((byte & 0x80) == 0) {
+	    break;
+	}
+	++leb128;
+	byte = *leb128;
+	byte_length++;
+    }
+
+    if ((shift < sizeof(Dwarf_Signed) * BITSINBYTE) && sign) {
+	number |= -((Dwarf_Signed) 1 << shift);
+    }
+
+    if (leb128_length != NULL)
+	*leb128_length = byte_length;
+    return (number);
+}
+
+
+/* Dumping a dwarf-expression as a byte stream. */
+void
+dump_block(char *prefix, char *data, Dwarf_Signed len)
+{
+    char *end_data = data + len;
+    char *cur = data;
+    int i = 0;
+
+    printf("%s", prefix);
+    for (; cur < end_data; ++cur, ++i) {
+	if (i > 0 && i % 4 == 0)
+	    printf(" ");
+	printf("%02x", 0xff & *cur);
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/tag_attr.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,288 @@
+/* 
+  Copyright (C) 2000,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write the Free Software Foundation, Inc., 51
+  Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/tag_attr.c,v 1.8 2005/12/01 17:34:59 davea Exp $ */
+#include <dwarf.h>
+#include <stdio.h>
+#include <stdlib.h>		/* For exit() declaration etc. */
+#include <errno.h>		/* For errno declaration. */
+
+
+/*  The following is the magic token used to 
+    distinguish real tags/attrs from group-delimiters. 
+    Blank lines have been eliminated by an awk script.
+*/
+#define MAGIC_TOKEN_VALUE 0xffffffff
+
+/* Expected input format 
+
+0xffffffff
+value of a tag
+value of a standard attribute that follows that tag
+...
+0xffffffff
+value of a tag
+value of a standard attribute that follows that tag
+...
+0xffffffff
+...
+
+No blank lines or commentary allowed, no symbols, just numbers.
+
+
+*/
+
+
+/* We don't need really long lines: the input file is simple. */
+#define MAX_LINE_SIZE 1000
+
+/* 1 more than the higest number in the DW_TAG defines. */
+#define TABLE_SIZE 0x41
+
+/* Enough entries to have a bit for each standard legal attr. */
+#define COLUMN_COUNT 4
+
+/* Bits per 'int' to mark legal attrs. */
+#define BITS_PER_WORD 32
+
+static unsigned int
+    tag_attr_combination_table[TABLE_SIZE][COLUMN_COUNT];
+static char *tag_name[] = {
+    "0x00",
+    "0x01 DW_TAG_array_type",
+    "0x02 DW_TAG_class_type",
+    "0x03 DW_TAG_entry_point",
+    "0x04 DW_TAG_enumeration_type",
+    "0x05 DW_TAG_formal_parameter",
+    "0x06",
+    "0x07",
+    "0x08 DW_TAG_imported_declaration",
+    "0x09",
+    "0x0a DW_TAG_label",
+    "0x0b DW_TAG_lexical_block",
+    "0x0c",
+    "0x0d DW_TAG_member",
+    "0x0e",
+    "0x0f DW_TAG_pointer_type",
+    "0x10 DW_TAG_reference_type",
+    "0x11 DW_TAG_compile_unit",
+    "0x12 DW_TAG_string_type",
+    "0x13 DW_TAG_structure_type",
+    "0x14",
+    "0x15 DW_TAG_subroutine_type",
+    "0x16 DW_TAG_typedef",
+    "0x17 DW_TAG_union_type",
+    "0x18 DW_TAG_unspecified_parameters",
+    "0x19 DW_TAG_variant",
+    "0x1a DW_TAG_common_block",
+    "0x1b DW_TAG_common_inclusion",
+    "0x1c DW_TAG_inheritance",
+    "0x1d DW_TAG_inlined_subroutine",
+    "0x1e DW_TAG_module",
+    "0x1f DW_TAG_ptr_to_member_type",
+    "0x20 DW_TAG_set_type",
+    "0x21 DW_TAG_subrange_type",
+    "0x22 DW_TAG_with_stmt",
+    "0x23 DW_TAG_access_declaration",
+    "0x24 DW_TAG_base_type",
+    "0x25 DW_TAG_catch_block",
+    "0x26 DW_TAG_const_type",
+    "0x27 DW_TAG_constant",
+    "0x28 DW_TAG_enumerator",
+    "0x29 DW_TAG_file_type",
+    "0x2a DW_TAG_friend",
+    "0x2b DW_TAG_namelist",
+    "0x2c DW_TAG_namelist_item",
+    "0x2d DW_TAG_packed_type",
+    "0x2e DW_TAG_subprogram",
+    "0x2f DW_TAG_template_type_parameter",
+    "0x30 DW_TAG_template_value_parameter",
+    "0x31 DW_TAG_thrown_type",
+    "0x32 DW_TAG_try_block",
+    "0x33 DW_TAG_variant_part",
+    "0x34 DW_TAG_variable",
+    "0x35 DW_TAG_volatile_type",
+    "0x36 DW_TAG_dwarf_procedure",
+    "0x37 DW_TAG_restrict_type",
+    "0x38 DW_TAG_interface_type",
+    "0x39 DW_TAG_namespace",
+    "0x3a DW_TAG_imported_module",
+    "0x3b DW_TAG_unspecified_type",
+    "0x3c DW_TAG_partial_unit",
+    "0x3d DW_TAG_imported_unit",
+    "0x3e",			/* was DW_TAG_mutable_type, removed
+				   from DWARF3f. */
+    "0x3f DW_TAG_condition",
+    "0x40 DW_TAG_shared_type",
+};
+
+static int linecount = 0;
+static char line_in[MAX_LINE_SIZE];
+
+#define IS_EOF 1
+#define NOT_EOF 0
+
+#define MAX_LINE_SIZE 1000
+
+
+static void
+bad_line_input(char *msg)
+{
+    fprintf(stderr,
+	    "tag_attr table build failed %s, line %d: \"%s\"  \n",
+	    msg, linecount, line_in);
+    exit(1);
+
+}
+static void
+trim_newline(char *line, int max)
+{
+    char *end = line + max - 1;
+
+    for (; *line && (line < end); ++line) {
+	if (*line == '\n') {
+	    /* Found newline, drop it */
+	    *line = 0;
+	    return;
+	}
+    }
+
+    return;
+}
+
+
+/* Reads a value from the text table. 
+   Exits  with non-zero status 
+   if the table is erroneous in some way. 
+*/
+static int
+read_value(unsigned int *outval)
+{
+    char *res = 0;
+    FILE *file = stdin;
+    unsigned long lval;
+    char *strout = 0;
+
+    ++linecount;
+    *outval = 0;
+    res = fgets(line_in, sizeof(line_in), file);
+    if (res == 0) {
+	if (ferror(file)) {
+	    fprintf(stderr,
+		    "tag_attr: Error reading table, %d lines read\n",
+		    linecount);
+	    exit(1);
+	}
+	if (feof(file)) {
+	    return IS_EOF;
+	}
+	/* impossible */
+	fprintf(stderr, "tag_attr: Impossible error reading table, "
+		"%d lines read\n", linecount);
+	exit(1);
+    }
+    trim_newline(line_in, sizeof(line_in));
+    errno = 0;
+    lval = strtoul(line_in, &strout, 0);
+    if (strout == line_in) {
+	bad_line_input("bad number input!");
+    }
+    if (errno != 0) {
+	int myerr = errno;
+
+	fprintf(stderr, "tag_attr errno %d\n", myerr);
+	bad_line_input("invalid number on line");
+    }
+    *outval = (int) lval;
+    return NOT_EOF;
+}
+
+int
+main()
+{
+    int i;
+    unsigned int num;
+    int input_eof;
+
+
+    input_eof = read_value(&num);	/* 0xffffffff */
+    if (IS_EOF == input_eof) {
+	bad_line_input("Empty input file");
+    }
+    if (num != MAGIC_TOKEN_VALUE) {
+	bad_line_input("Expected 0xffffffff");
+    }
+    while (!feof(stdin)) {
+	unsigned int tag;
+
+	input_eof = read_value(&tag);
+	if (IS_EOF == input_eof) {
+	    /* Reached normal eof */
+	    break;
+	}
+	if (tag >= TABLE_SIZE) {
+	    bad_line_input("tag value exceeds table size");
+	}
+	input_eof = read_value(&num);
+	if (IS_EOF == input_eof) {
+	    bad_line_input("Not terminated correctly..");
+	}
+	while (num != MAGIC_TOKEN_VALUE) {
+	    unsigned idx = num / BITS_PER_WORD;
+	    unsigned bit = num % BITS_PER_WORD;
+
+	    if (idx >= COLUMN_COUNT) {
+		bad_line_input
+		    ("too many attributes: table incomplete.");
+	    }
+	    tag_attr_combination_table[tag][idx] |= (1 << bit);
+	    input_eof = read_value(&num);
+	    if (IS_EOF == input_eof) {
+		bad_line_input("Not terminated correctly.");
+	    }
+	}
+    }
+    printf("static unsigned int tag_attr_combination_table [ ][%d]"
+	   " = {\n", COLUMN_COUNT);
+    for (i = 0; i < TABLE_SIZE; i++) {
+	printf("/* %-37s*/\n", tag_name[i]);
+	printf("    { %#.8x, %#.8x, %#.8x, %#.8x,},\n",
+	       tag_attr_combination_table[i][0],
+	       tag_attr_combination_table[i][1],
+	       tag_attr_combination_table[i][2],
+	       tag_attr_combination_table[i][3]
+	    );
+    }
+    printf("};\n");
+    return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/tag_attr.list	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,812 @@
+/* 
+  Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/tag_attr.list,v 1.7 2005/12/01 17:34:59 davea Exp $ 
+*/
+#include <dwarf.h>
+
+/*
+   list for semantic check of tag-attr relation.  
+   
+   0xffffffff is a "punctuation."  The final line of this file 
+   must be 0xffffffff.  The next line after each 0xffffffff 
+   (except the final line) is a tag.  The lines after this line 
+   before the next 0xffffffff are the attributes that can be given 
+   to the tag."
+
+   For example, 
+
+	0xffffffff
+	DW_TAG_access_declaration
+	DW_AT_decl_column
+	DW_AT_decl_file
+	DW_AT_decl_line
+	DW_AT_accessibility
+	DW_AT_name
+	DW_AT_sibling
+	0xffffffff
+
+   means "only DW_AT_decl_column, DW_AT_decl_file, DW_AT_decl_line, 
+   DW_AT_accessibility, DW_AT_name and DW_AT_sibling can be given to 
+   DW_TAG_access_declaration."
+
+   This file is applied to the preprocessor, thus any C comment and 
+   preprocessor control line is available.  
+ */
+
+0xffffffff
+DW_TAG_access_declaration
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_name
+DW_AT_sibling
+0xffffffff
+DW_TAG_array_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_allocated
+DW_AT_associated
+DW_AT_bit_stride
+DW_AT_byte_size
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_ordering
+DW_AT_sibling
+DW_AT_specification
+DW_AT_start_scope
+DW_AT_type
+DW_AT_visibility
+0xffffffff
+DW_TAG_base_type
+DW_AT_allocated
+DW_AT_associated
+DW_AT_binary_scale
+DW_AT_bit_offset
+DW_AT_bit_size
+DW_AT_byte_size
+DW_AT_data_location
+DW_AT_decimal_scale 
+DW_AT_decimal_sign
+DW_AT_description
+DW_AT_digit_count
+DW_AT_encoding
+DW_AT_endianity
+DW_AT_name
+DW_AT_name
+DW_AT_picture_string
+DW_AT_sibling
+DW_AT_small
+0xffffffff
+DW_TAG_catch_block
+DW_AT_abstract_origin
+DW_AT_high_pc
+DW_AT_low_pc
+DW_AT_ranges
+DW_AT_segment
+DW_AT_sibling
+0xffffffff
+DW_TAG_class_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_allocated
+DW_AT_associated
+DW_AT_byte_size
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_specification
+DW_AT_start_scope
+DW_AT_visibility
+0xffffffff
+DW_TAG_common_block
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_declaration
+DW_AT_location
+DW_AT_name
+DW_AT_segment
+DW_AT_sibling
+DW_AT_visibility
+0xffffffff
+DW_TAG_common_inclusion
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_common_reference
+DW_AT_declaration
+DW_AT_sibling
+DW_AT_visibility
+0xffffffff
+DW_TAG_compile_unit
+DW_AT_base_types
+DW_AT_comp_dir
+DW_AT_identifier_case
+DW_AT_high_pc
+DW_AT_language
+DW_AT_low_pc
+DW_AT_macro_info
+DW_AT_name
+DW_AT_producer
+DW_AT_ranges
+DW_AT_segment
+DW_AT_sibling
+DW_AT_stmt_list
+DW_AT_use_UTF8
+0xffffffff
+DW_TAG_condition
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_name
+DW_AT_sibling
+0xffffffff
+DW_TAG_const_type
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_constant
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_const_value
+DW_AT_declaration
+DW_AT_description
+DW_AT_endianity
+DW_AT_external
+DW_AT_name
+DW_AT_sibling
+DW_AT_start_scope
+DW_AT_type
+DW_AT_visibility
+0xffffffff
+DW_TAG_dwarf_procedure
+DW_AT_location
+0xffffffff
+DW_TAG_entry_point
+DW_AT_address_class
+DW_AT_description
+DW_AT_low_pc
+DW_AT_name
+DW_AT_return_addr
+DW_AT_segment
+DW_AT_sibling
+DW_AT_static_link
+DW_AT_type
+0xffffffff
+DW_TAG_enumeration_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_allocated
+DW_AT_associated
+DW_AT_bit_stride
+DW_AT_byte_size
+DW_AT_byte_stride
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_specification
+DW_AT_start_scope
+DW_AT_type
+DW_AT_visibility
+0xffffffff
+DW_TAG_enumerator
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_const_value
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+0xffffffff
+DW_TAG_file_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_allocated
+DW_AT_associated
+DW_AT_byte_size
+DW_AT_data_location
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_start_scope
+DW_AT_type
+DW_AT_visibility
+0xffffffff
+DW_TAG_formal_parameter
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_artificial
+DW_AT_const_value
+DW_AT_default_value
+DW_AT_description
+DW_AT_endianity
+DW_AT_is_optional
+DW_AT_location
+DW_AT_name
+DW_AT_segment
+DW_AT_sibling
+DW_AT_type
+DW_AT_variable_parameter
+0xffffffff
+DW_TAG_friend
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_friend
+DW_AT_sibling
+0xffffffff
+DW_TAG_imported_declaration
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_description
+DW_AT_import
+DW_AT_name
+DW_AT_sibling
+DW_AT_start_scope
+0xffffffff
+DW_TAG_imported_module
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_import
+DW_AT_sibling
+DW_AT_start_scope
+0xffffffff
+DW_TAG_imported_unit
+DW_AT_import
+0xffffffff
+DW_TAG_inheritance
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_data_member_location
+DW_AT_sibling
+DW_AT_type
+DW_AT_virtuality
+0xffffffff
+DW_TAG_inlined_subroutine
+DW_AT_abstract_origin
+DW_AT_call_column
+DW_AT_call_file
+DW_AT_call_line
+DW_AT_entry_pc
+DW_AT_high_pc
+DW_AT_low_pc
+DW_AT_ranges
+DW_AT_return_addr
+DW_AT_segment
+DW_AT_sibling
+DW_AT_start_scope
+DW_AT_trampoline
+0xffffffff
+DW_TAG_interface_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_start_scope
+0xffffffff
+DW_TAG_label
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_description
+DW_AT_low_pc
+DW_AT_name
+DW_AT_segment
+DW_AT_start_scope
+DW_AT_sibling
+0xffffffff
+DW_TAG_lexical_block
+DW_AT_abstract_origin
+DW_AT_description
+DW_AT_high_pc
+DW_AT_low_pc
+DW_AT_name
+DW_AT_ranges
+DW_AT_segment
+DW_AT_sibling
+0xffffffff
+DW_TAG_member
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_bit_offset
+DW_AT_bit_size
+DW_AT_byte_size
+DW_AT_data_member_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_mutable
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+DW_AT_visibility
+0xffffffff
+DW_TAG_module
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_declaration
+DW_AT_description
+DW_AT_entry_pc
+DW_AT_high_pc
+DW_AT_low_pc
+DW_AT_name
+DW_AT_priority
+DW_AT_segment
+DW_AT_sibling
+DW_AT_specification
+DW_AT_visibility
+0xffffffff
+DW_TAG_namelist
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_abstract_origin
+DW_AT_declaration
+DW_AT_name
+DW_AT_sibling
+DW_AT_visibility
+0xffffffff
+DW_TAG_namelist_item
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_namelist_item
+DW_AT_sibling
+0xffffffff
+DW_TAG_namespace
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_description
+DW_AT_extension
+DW_AT_name
+DW_AT_sibling
+DW_AT_start_scope
+0xffffffff
+DW_TAG_packed_type
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_partial_unit
+DW_AT_base_types
+DW_AT_comp_dir
+DW_AT_description
+DW_AT_identifier_case
+DW_AT_high_pc
+DW_AT_language
+DW_AT_low_pc
+DW_AT_macro_info
+DW_AT_name
+DW_AT_producer
+DW_AT_ranges
+DW_AT_segment
+DW_AT_sibling
+DW_AT_stmt_list
+DW_AT_use_UTF8
+0xffffffff
+DW_TAG_pointer_type
+DW_AT_address_class
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_name
+DW_AT_sibling
+DW_AT_specification
+DW_AT_type
+/* Comment from 1993:
+   "Though DWARF spec doesn't refer to DW_AT_byte_size, it may well be 
+   given to DW_TAG_pointer_type."  
+   Comment 29 Nov 2005 by David Anderrson
+   DW_AT_byte_size  would be legal, but what would it mean, given
+   not specifically defined by the DWARF spec?
+   Byte size of the pointer or the pointed-to item?
+   Both should already be known for the ABI/instruction-set
+   in use.
+   Cannot recall why, but SGI/IRIX/MIPS uses this.
+ */
+DW_AT_byte_size
+0xffffffff
+DW_TAG_ptr_to_member_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_address_class
+DW_AT_allocated
+DW_AT_associated
+DW_AT_containing_type
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+DW_AT_use_location
+DW_AT_visibility
+0xffffffff
+DW_TAG_reference_type
+DW_AT_address_class
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_restrict_type
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_set_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_allocated
+DW_AT_associated
+DW_AT_byte_size
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_start_scope
+DW_AT_sibling
+DW_AT_type
+DW_AT_visibility
+0xffffffff
+DW_TAG_shared_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_count
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_string_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_allocated
+DW_AT_associated
+DW_AT_byte_size
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_segment
+DW_AT_sibling
+DW_AT_start_scope
+DW_AT_string_length
+DW_AT_visibility
+0xffffffff
+DW_TAG_structure_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_allocated
+DW_AT_associated
+DW_AT_byte_size
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_specification
+DW_AT_start_scope
+DW_AT_visibility
+0xffffffff
+DW_TAG_subprogram
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_address_class
+DW_AT_artificial
+DW_AT_calling_convention
+DW_AT_declaration
+DW_AT_description
+DW_AT_elemental
+DW_AT_entry_pc
+DW_AT_explicit
+DW_AT_external
+DW_AT_frame_base
+DW_AT_high_pc
+DW_AT_inline
+DW_AT_low_pc
+DW_AT_name
+DW_AT_object_pointer
+DW_AT_prototyped
+DW_AT_pure
+DW_AT_ranges
+DW_AT_recursive
+DW_AT_return_addr
+DW_AT_segment
+DW_AT_sibling
+DW_AT_specification
+DW_AT_start_scope
+DW_AT_static_link
+DW_AT_trampoline
+DW_AT_type
+DW_AT_visibility
+DW_AT_virtuality
+DW_AT_vtable_elem_location
+0xffffffff
+DW_TAG_subrange_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_allocated
+DW_AT_associated
+DW_AT_bit_stride
+DW_AT_byte_size
+DW_AT_byte_stride
+DW_AT_count
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_lower_bound
+DW_AT_name
+DW_AT_sibling
+DW_AT_threads_scaled
+DW_AT_type
+DW_AT_upper_bound
+DW_AT_visibility
+0xffffffff
+DW_TAG_subroutine_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_address_class
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_prototyped
+DW_AT_sibling
+DW_AT_start_scope
+DW_AT_type
+DW_AT_visibility
+0xffffffff
+DW_TAG_template_type_parameter
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_template_value_parameter
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_const_value
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_thrown_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_try_block
+DW_AT_abstract_origin
+DW_AT_high_pc
+DW_AT_low_pc
+DW_AT_ranges
+DW_AT_segment
+DW_AT_sibling
+0xffffffff
+DW_TAG_typedef
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_start_scope
+DW_AT_type
+DW_AT_visibility
+0xffffffff
+DW_TAG_union_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_allocated
+DW_AT_associated
+DW_AT_byte_size
+DW_AT_data_location
+DW_AT_declaration
+DW_AT_description
+DW_AT_name
+DW_AT_sibling
+DW_AT_specification
+DW_AT_start_scope
+DW_AT_visibility
+0xffffffff
+DW_TAG_unspecified_parameters
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_artificial
+DW_AT_sibling
+0xffffffff
+DW_TAG_unspecified_type
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_description
+DW_AT_sibling
+0xffffffff
+DW_TAG_variable
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_abstract_origin
+DW_AT_accessibility
+DW_AT_byte_size
+DW_AT_const_value
+DW_AT_declaration
+DW_AT_description
+DW_AT_endianity
+DW_AT_external
+DW_AT_location
+DW_AT_name
+DW_AT_segment
+DW_AT_sibling
+DW_AT_specification
+DW_AT_start_scope
+DW_AT_type
+DW_AT_visibility
+0xffffffff
+DW_TAG_variant
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_abstract_origin
+DW_AT_declaration
+DW_AT_discr_list
+DW_AT_discr_value
+DW_AT_sibling
+0xffffffff
+DW_TAG_variant_part
+DW_AT_decl_column
+DW_AT_decl_file
+DW_AT_decl_line
+DW_AT_accessibility
+DW_AT_abstract_origin
+DW_AT_declaration
+DW_AT_discr
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_volatile_type
+DW_AT_allocated
+DW_AT_associated
+DW_AT_data_location
+DW_AT_name
+DW_AT_sibling
+DW_AT_type
+0xffffffff
+DW_TAG_with_stmt
+DW_AT_accessibility
+DW_AT_address_class
+DW_AT_declaration
+DW_AT_high_pc
+DW_AT_location
+DW_AT_low_pc
+DW_AT_ranges
+DW_AT_segment
+DW_AT_sibling
+DW_AT_type
+DW_AT_visibility
+0xffffffff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/tag_tree.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,293 @@
+/* 
+  Copyright (C) 2000,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2 of the GNU General Public License as
+  published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU General Public License along
+  with this program; if not, write the Free Software Foundation, Inc., 51
+  Franklin Street - Fifth Floor, Boston MA 02110-1301, USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/tag_tree.c,v 1.8 2005/12/01 17:34:59 davea Exp $ */
+#include <dwarf.h>
+#include <stdio.h>
+#include <stdlib.h>		/* For exit() declaration etc. */
+#include <errno.h>		/* For errno declaration. */
+
+
+/*  The following is the magic token used to
+    distinguish real tags/attrs from group-delimiters.
+    Blank lines have been eliminated by an awk script.
+*/
+#define MAGIC_TOKEN_VALUE 0xffffffff
+
+/* Expected input format
+
+0xffffffff
+value of a tag
+value of a standard tag that may be a child ofthat tag
+...
+0xffffffff
+value of a tag
+value of a standard tag that may be a child ofthat tag
+...
+0xffffffff
+...
+
+No blank lines or commentary allowed, no symbols, just numbers.
+
+
+*/
+
+
+/* We don't need really long lines: the input file is simple. */
+#define MAX_LINE_SIZE 1000
+
+/* 1 more than the higest number in the DW_TAG defines. */
+#define TABLE_SIZE 0x41
+
+/* Enough entries to have a bit for each standard legal tag. */
+#define COLUMN_COUNT 2
+
+/* Bits per 'int' to mark legal attrs. */
+#define BITS_PER_WORD 32
+
+
+
+#define TABLE_SIZE 0x41
+
+static unsigned int
+    tag_tree_combination_table[TABLE_SIZE][COLUMN_COUNT];
+static char *tag_name[] = {
+    "0x00",
+    "0x01 DW_TAG_array_type",
+    "0x02 DW_TAG_class_type",
+    "0x03 DW_TAG_entry_point",
+    "0x04 DW_TAG_enumeration_type",
+    "0x05 DW_TAG_formal_parameter",
+    "0x06",
+    "0x07",
+    "0x08 DW_TAG_imported_declaration",
+    "0x09",
+    "0x0a DW_TAG_label",
+    "0x0b DW_TAG_lexical_block",
+    "0x0c",
+    "0x0d DW_TAG_member",
+    "0x0e",
+    "0x0f DW_TAG_pointer_type",
+    "0x10 DW_TAG_reference_type",
+    "0x11 DW_TAG_compile_unit",
+    "0x12 DW_TAG_string_type",
+    "0x13 DW_TAG_structure_type",
+    "0x14",
+    "0x15 DW_TAG_subroutine_type",
+    "0x16 DW_TAG_typedef",
+    "0x17 DW_TAG_union_type",
+    "0x18 DW_TAG_unspecified_parameters",
+    "0x19 DW_TAG_variant",
+    "0x1a DW_TAG_common_block",
+    "0x1b DW_TAG_common_inclusion",
+    "0x1c DW_TAG_inheritance",
+    "0x1d DW_TAG_inlined_subroutine",
+    "0x1e DW_TAG_module",
+    "0x1f DW_TAG_ptr_to_member_type",
+    "0x20 DW_TAG_set_type",
+    "0x21 DW_TAG_subrange_type",
+    "0x22 DW_TAG_with_stmt",
+    "0x23 DW_TAG_access_declaration",
+    "0x24 DW_TAG_base_type",
+    "0x25 DW_TAG_catch_block",
+    "0x26 DW_TAG_const_type",
+    "0x27 DW_TAG_constant",
+    "0x28 DW_TAG_enumerator",
+    "0x29 DW_TAG_file_type",
+    "0x2a DW_TAG_friend",
+    "0x2b DW_TAG_namelist",
+    "0x2c DW_TAG_namelist_item",
+    "0x2d DW_TAG_packed_type",
+    "0x2e DW_TAG_subprogram",
+    "0x2f DW_TAG_template_type_parameter",
+    "0x30 DW_TAG_template_value_parameter",
+    "0x31 DW_TAG_thrown_type",
+    "0x32 DW_TAG_try_block",
+    "0x33 DW_TAG_variant_part",
+    "0x34 DW_TAG_variable",
+    "0x35 DW_TAG_volatile_type",
+    "0x36 DW_TAG_dwarf_procedure",
+    "0x37 DW_TAG_restrict_type",
+    "0x38 DW_TAG_interface_type",
+    "0x39 DW_TAG_namespace",
+    "0x3a DW_TAG_imported_module",
+    "0x3b DW_TAG_unspecified_type",
+    "0x3c DW_TAG_partial_unit",
+    "0x3d DW_TAG_imported_unit",
+    "0x3e",			/* was DW_TAG_mutable_type, removed
+				   from DWARF3f. */
+    "0x3f DW_TAG_condition",
+    "0x40 DW_TAG_shared_type",
+};
+
+static int linecount = 0;
+static char line_in[MAX_LINE_SIZE];
+
+#define IS_EOF 1
+#define NOT_EOF 0
+
+#define MAX_LINE_SIZE 1000
+
+
+static void
+bad_line_input(char *msg)
+{
+    fprintf(stderr,
+	    "tag_tree table build failed %s, line %d: \"%s\"  \n",
+	    msg, linecount, line_in);
+    exit(1);
+
+}
+static void
+trim_newline(char *line, int max)
+{
+    char *end = line + max - 1;
+
+    for (; *line && (line < end); ++line) {
+	if (*line == '\n') {
+	    /* Found newline, drop it */
+	    *line = 0;
+	    return;
+	}
+    }
+
+    return;
+}
+
+
+/* Reads a value from the text table. 
+   Exits  with non-zero status 
+   if the table is erroneous in some way. 
+*/
+static int
+read_value(unsigned int *outval)
+{
+    char *res = 0;
+    FILE *file = stdin;
+    unsigned long lval;
+    char *strout = 0;
+
+    ++linecount;
+    *outval = 0;
+    res = fgets(line_in, sizeof(line_in), file);
+    if (res == 0) {
+	if (ferror(file)) {
+	    fprintf(stderr,
+		    "tag_attr: Error reading table, %d lines read\n",
+		    linecount);
+	    exit(1);
+	}
+	if (feof(file)) {
+	    return IS_EOF;
+	}
+	/* impossible */
+	fprintf(stderr, "tag_attr: Impossible error reading table, "
+		"%d lines read\n", linecount);
+	exit(1);
+    }
+    trim_newline(line_in, sizeof(line_in));
+    errno = 0;
+    lval = strtoul(line_in, &strout, 0);
+    if (strout == line_in) {
+	bad_line_input("bad number input!");
+    }
+    if (errno != 0) {
+	int myerr = errno;
+
+	fprintf(stderr, "tag_attr errno %d\n", myerr);
+	bad_line_input("invalid number on line");
+    }
+    *outval = (int) lval;
+    return NOT_EOF;
+}
+
+
+int
+main()
+{
+    int i;
+    unsigned int num;
+    int input_eof;
+
+
+    input_eof = read_value(&num);	/* 0xffffffff */
+    if (IS_EOF == input_eof) {
+	bad_line_input("Empty input file");
+    }
+    if (num != MAGIC_TOKEN_VALUE) {
+	bad_line_input("Expected 0xffffffff");
+    }
+
+    while (!feof(stdin)) {
+	unsigned int tag;
+
+	input_eof = read_value(&tag);
+	if (IS_EOF == input_eof) {
+	    /* Reached normal eof */
+	    break;
+	}
+	if (tag >= TABLE_SIZE) {
+	    bad_line_input("tag value exceeds table size");
+	}
+	input_eof = read_value(&num);
+	if (IS_EOF == input_eof) {
+	    bad_line_input("Not terminated correctly..");
+	}
+
+	while (num != 0xffffffff) {
+	    int idx = num / BITS_PER_WORD;
+	    int bit = num % BITS_PER_WORD;
+
+	    if (idx >= COLUMN_COUNT) {
+		bad_line_input("too many TAGs: table incomplete.");
+	    }
+
+	    tag_tree_combination_table[tag][idx] |= (1 << bit);
+	    input_eof = read_value(&num);
+	    if (IS_EOF == input_eof) {
+		bad_line_input("Not terminated correctly.");
+	    }
+	}
+    }
+    printf
+	("static unsigned int tag_tree_combination_table [ ][%d] = {\n",
+	 COLUMN_COUNT);
+    for (i = 0; i < TABLE_SIZE; i++) {
+	printf("/* %-37s*/\n", tag_name[i]);
+	printf("    { %#.8x, %#.8x},\n",
+	       tag_tree_combination_table[i][0],
+	       tag_tree_combination_table[i][1]);
+    }
+    printf("};\n");
+    return (0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/tag_tree.list	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,403 @@
+/* 
+  Copyright (C) 2000,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+
+$Header: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/dwarfdump/RCS/tag_tree.list,v 1.6 2005/12/01 17:34:59 davea Exp $ 
+*/
+#include <dwarf.h>
+
+/*
+   list for semantic check of tag-tree.  
+   
+   0xffffffff is a "punctuation."  The final line of this file 
+   must be 0xffffffff.  The next line after each 0xffffffff 
+   (except the final line)  stands for "parent-tag."  The lines 
+   after this line before the next 0xffffffff are the tags that 
+   can be children of the "parent-tag."
+
+   For example, 
+
+	0xffffffff
+	DW_TAG_array_type
+	DW_TAG_subrange_type
+	DW_TAG_enumeration_type
+	0xffffffff
+
+   means "only DW_TAG_subrange_type and DW_TAG_enumeration_type can 
+   be children of DW_TAG_array_type.  
+
+   This file is applied to the preprocessor, thus any C comment and 
+   preprocessor control line is available.  
+ */
+
+0xffffffff
+DW_TAG_access_declaration
+0xffffffff
+DW_TAG_array_type
+DW_TAG_subrange_type
+DW_TAG_enumeration_type
+0xffffffff
+DW_TAG_base_type
+0xffffffff
+DW_TAG_catch_block
+DW_TAG_formal_parameter
+DW_TAG_unspecified_parameters
+DW_TAG_array_type
+DW_TAG_class_type
+DW_TAG_enumeration_type
+DW_TAG_pointer_type
+DW_TAG_reference_type
+DW_TAG_string_type
+DW_TAG_structure_type
+DW_TAG_subroutine_type
+DW_TAG_typedef
+DW_TAG_union_type
+DW_TAG_ptr_to_member_type
+DW_TAG_set_type
+DW_TAG_subrange_type
+DW_TAG_base_type
+DW_TAG_const_type
+DW_TAG_constant
+DW_TAG_file_type
+DW_TAG_packed_type
+DW_TAG_subprogram
+DW_TAG_variable
+DW_TAG_volatile_type
+0xffffffff
+DW_TAG_class_type
+DW_TAG_member
+DW_TAG_inheritance
+DW_TAG_access_declaration
+DW_TAG_friend
+DW_TAG_ptr_to_member_type
+DW_TAG_subprogram
+DW_TAG_template_type_parameter /* template instantiations */
+DW_TAG_template_value_parameter /* template instantiations */
+DW_TAG_typedef
+DW_TAG_base_type
+DW_TAG_pointer_type
+DW_TAG_union_type
+DW_TAG_const_type
+0xffffffff
+DW_TAG_common_block
+DW_TAG_variable
+0xffffffff
+DW_TAG_common_inclusion
+0xffffffff
+DW_TAG_compile_unit
+DW_TAG_array_type
+DW_TAG_class_type
+DW_TAG_enumeration_type
+DW_TAG_imported_declaration
+DW_TAG_pointer_type
+DW_TAG_reference_type
+DW_TAG_string_type
+DW_TAG_structure_type
+DW_TAG_subroutine_type
+DW_TAG_typedef
+DW_TAG_union_type
+DW_TAG_common_block
+DW_TAG_inlined_subroutine
+DW_TAG_module
+DW_TAG_ptr_to_member_type
+DW_TAG_set_type
+DW_TAG_subrange_type
+DW_TAG_base_type
+DW_TAG_const_type
+DW_TAG_constant
+DW_TAG_file_type
+DW_TAG_namelist
+DW_TAG_namespace
+DW_TAG_packed_type
+DW_TAG_subprogram
+DW_TAG_variable
+DW_TAG_volatile_type
+0xffffffff
+DW_TAG_condition /* COBOL */
+DW_TAG_constant
+DW_TAG_subrange_type
+0xffffffff
+DW_TAG_const_type
+0xffffffff
+DW_TAG_constant
+0xffffffff
+DW_TAG_dwarf_procedure
+0xffffffff
+DW_TAG_entry_point
+DW_TAG_formal_parameter
+DW_TAG_unspecified_parameters
+DW_TAG_common_inclusion
+0xffffffff
+DW_TAG_enumeration_type
+DW_TAG_enumerator
+0xffffffff
+DW_TAG_enumerator
+0xffffffff
+DW_TAG_file_type
+0xffffffff
+DW_TAG_formal_parameter
+0xffffffff
+DW_TAG_friend
+0xffffffff
+DW_TAG_imported_declaration
+0xffffffff
+DW_TAG_imported_module
+0xffffffff
+DW_TAG_imported_unit
+0xffffffff
+DW_TAG_inheritance
+0xffffffff
+DW_TAG_inlined_subroutine
+DW_TAG_formal_parameter
+DW_TAG_unspecified_parameters
+DW_TAG_array_type
+DW_TAG_class_type
+DW_TAG_enumeration_type
+DW_TAG_pointer_type
+DW_TAG_reference_type
+DW_TAG_string_type
+DW_TAG_structure_type
+DW_TAG_subroutine_type
+DW_TAG_lexical_block
+DW_TAG_typedef
+DW_TAG_union_type
+DW_TAG_inlined_subroutine
+DW_TAG_ptr_to_member_type
+DW_TAG_set_type
+DW_TAG_subrange_type
+DW_TAG_base_type
+DW_TAG_const_type
+DW_TAG_constant
+DW_TAG_file_type
+DW_TAG_namelist
+DW_TAG_packed_type
+DW_TAG_subprogram
+DW_TAG_variable
+DW_TAG_volatile_type
+0xffffffff
+DW_TAG_interface_type
+DW_TAG_member
+DW_TAG_subprogram
+0xffffffff
+DW_TAG_label
+0xffffffff
+DW_TAG_lexical_block
+DW_TAG_array_type
+DW_TAG_class_type
+DW_TAG_enumeration_type
+DW_TAG_imported_declaration
+DW_TAG_pointer_type
+DW_TAG_reference_type
+DW_TAG_string_type
+DW_TAG_structure_type
+DW_TAG_subroutine_type
+DW_TAG_typedef
+DW_TAG_union_type
+DW_TAG_inlined_subroutine
+DW_TAG_lexical_block
+DW_TAG_module
+DW_TAG_ptr_to_member_type
+DW_TAG_set_type
+DW_TAG_subrange_type
+DW_TAG_base_type
+DW_TAG_const_type
+DW_TAG_constant
+DW_TAG_namelist
+DW_TAG_packed_type
+DW_TAG_subprogram
+DW_TAG_variable
+DW_TAG_volatile_type
+0xffffffff
+DW_TAG_member
+0xffffffff
+DW_TAG_module
+0xffffffff
+DW_TAG_namelist
+DW_TAG_namelist_item
+0xffffffff
+DW_TAG_namelist_item
+0xffffffff
+DW_TAG_namespace
+DW_TAG_array_type
+DW_TAG_class_type
+DW_TAG_enumeration_type
+DW_TAG_imported_declaration
+DW_TAG_pointer_type
+DW_TAG_reference_type
+DW_TAG_string_type
+DW_TAG_structure_type
+DW_TAG_subroutine_type
+DW_TAG_typedef
+DW_TAG_union_type
+DW_TAG_common_block
+DW_TAG_inlined_subroutine
+DW_TAG_module
+DW_TAG_ptr_to_member_type
+DW_TAG_set_type
+DW_TAG_subrange_type
+DW_TAG_base_type
+DW_TAG_const_type
+DW_TAG_constant
+DW_TAG_namelist
+DW_TAG_packed_type
+DW_TAG_subprogram
+DW_TAG_variable
+DW_TAG_volatile_type
+0xffffffff
+DW_TAG_packed_type
+0xffffffff
+DW_TAG_partial_unit
+DW_TAG_array_type
+DW_TAG_class_type
+DW_TAG_enumeration_type
+DW_TAG_imported_declaration
+DW_TAG_pointer_type
+DW_TAG_reference_type
+DW_TAG_string_type
+DW_TAG_structure_type
+DW_TAG_subroutine_type
+DW_TAG_typedef
+DW_TAG_union_type
+DW_TAG_common_block
+DW_TAG_inlined_subroutine
+DW_TAG_module
+DW_TAG_ptr_to_member_type
+DW_TAG_set_type
+DW_TAG_subrange_type
+DW_TAG_base_type
+DW_TAG_const_type
+DW_TAG_constant
+DW_TAG_file_type
+DW_TAG_namelist
+DW_TAG_packed_type
+DW_TAG_subprogram
+DW_TAG_variable
+DW_TAG_volatile_type
+0xffffffff
+DW_TAG_pointer_type
+0xffffffff
+DW_TAG_ptr_to_member_type
+0xffffffff
+DW_TAG_reference_type
+0xffffffff
+DW_TAG_restrict_type
+0xffffffff
+DW_TAG_set_type
+0xffffffff
+DW_TAG_shared_type
+0xffffffff
+DW_TAG_string_type
+0xffffffff
+DW_TAG_structure_type
+DW_TAG_member
+DW_TAG_inheritance
+DW_TAG_access_declaration
+DW_TAG_friend
+DW_TAG_ptr_to_member_type
+DW_TAG_variant_part
+DW_TAG_subprogram
+DW_TAG_template_type_parameter /* template instantiations */
+DW_TAG_template_value_parameter /* template instantiations */
+DW_TAG_typedef
+DW_TAG_base_type
+DW_TAG_pointer_type
+DW_TAG_union_type
+DW_TAG_const_type
+0xffffffff
+DW_TAG_subprogram
+DW_TAG_formal_parameter
+DW_TAG_unspecified_parameters
+DW_TAG_thrown_type
+DW_TAG_template_type_parameter
+DW_TAG_common_inclusion
+DW_TAG_common_block
+DW_TAG_array_type
+DW_TAG_class_type
+DW_TAG_enumeration_type
+DW_TAG_pointer_type
+DW_TAG_reference_type
+DW_TAG_string_type
+DW_TAG_lexical_block
+DW_TAG_structure_type
+DW_TAG_subroutine_type
+DW_TAG_typedef
+DW_TAG_union_type
+DW_TAG_inlined_subroutine
+DW_TAG_ptr_to_member_type
+DW_TAG_set_type
+DW_TAG_subrange_type
+DW_TAG_base_type
+DW_TAG_const_type
+DW_TAG_constant
+DW_TAG_file_type
+DW_TAG_namelist
+DW_TAG_packed_type
+DW_TAG_subprogram
+DW_TAG_variable
+DW_TAG_volatile_type
+DW_TAG_label
+0xffffffff
+DW_TAG_subrange_type
+0xffffffff
+DW_TAG_subroutine_type
+DW_TAG_formal_parameter
+DW_TAG_unspecified_parameters
+0xffffffff
+DW_TAG_template_type_parameter
+0xffffffff
+DW_TAG_template_value_parameter
+0xffffffff
+DW_TAG_thrown_type
+0xffffffff
+DW_TAG_try_block
+0xffffffff
+DW_TAG_typedef
+0xffffffff
+DW_TAG_union_type
+DW_TAG_member
+DW_TAG_friend
+0xffffffff
+DW_TAG_unspecified_parameters
+0xffffffff
+DW_TAG_unspecified_type
+0xffffffff
+DW_TAG_variable
+0xffffffff
+DW_TAG_variant
+DW_TAG_variant_part
+0xffffffff
+DW_TAG_variant_part
+0xffffffff
+DW_TAG_volatile_type
+0xffffffff
+DW_TAG_with_stmt
+0xffffffff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/dwarfdump/testesb.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,78 @@
+/* testesb.c 
+   test code for esb.h esb.c
+
+   Not part of a compiled dwarfdump.
+
+*/
+
+#include <stdio.h>
+#include <string.h>
+typedef char *string;
+
+#include "esb.h"
+
+void
+check(string msg, struct esb_s *data, string v)
+{
+    string b = esb_get_string(data);
+    size_t l = 0;
+    size_t alloc = 0;
+
+    if (strcmp(b, v)) {
+	fprintf(stderr, "ERROR: %s  content error  %s != %s\n", msg, b,
+		v);
+    }
+
+    l = esb_string_len(data);
+
+    if (l != strlen(v)) {
+	fprintf(stderr, "ERROR: %s length error  %lu != %lu\n", msg,
+		(unsigned long) l, (unsigned long) strlen(v));
+    }
+    alloc = esb_get_allocated_size(data);
+    if (l > alloc) {
+	fprintf(stderr, "ERROR: %s allocation error  %lu > %lu\n", msg,
+		(unsigned long) l, (unsigned long) alloc);
+
+    }
+
+    return;
+}
+
+int
+main(void)
+{
+    struct esb_s data;
+
+
+    esb_alloc_size(2);		/* small to get all code paths tested. */
+    esb_constructor(&data);
+
+    esb_append(&data, "a");
+    esb_appendn(&data, "bc", 1);
+    esb_append(&data, "d");
+    esb_append(&data, "e");
+    check("test 1", &data, "abde");
+
+    esb_destructor(&data);
+    esb_constructor(&data);
+
+    esb_append(&data, "abcdefghij" "0123456789");
+    check("test 2", &data, "abcdefghij" "0123456789");
+
+    esb_destructor(&data);
+    esb_constructor(&data);
+    esb_append(&data, "abcdefghij" "0123456789");
+
+    esb_append(&data, "abcdefghij" "0123456789");
+
+    esb_append(&data, "abcdefghij" "0123456789");
+
+    esb_append(&data, "abcdefghij" "0123456789");
+    check("test 3", &data, "abcdefghij"
+	  "0123456789"
+	  "abcdefghij"
+	  "0123456789"
+	  "abcdefghij" "0123456789" "abcdefghij" "0123456789");
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/CHANGES	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,102 @@
+
+
+-------------------------------------------------------------
+April 14, 2000  davea@sgi.com
+Corrected minor bugs in production of 32bit dwarf with
+64 bit pointers.  Fixed omissions in legal
+DIE children of a DIE.  Make small changes in
+description of regster output in frame information
+access.
+
+-------------------------------------------------------------
+Mar 7, 2000 davea@sgi.com
+Corrected line table reading so it will handle
+reading an object with a diffent number of standard
+op codes than at libdwarf compile time.
+This was possible all along, but libdwarf did
+not do it right.
+
+-------------------------------------------------------------
+Dec 8, 1999  davea@sgi.com
+Changed nearly all files.
+Adding the capability to read and produce
+the new, accepted by committee, but not
+released-publically 64bit extension proposal
+dwarf data.
+This allows dwarf compilation units
+with 64bit section offsets and 32bit
+sections offsets to be mixed. 
+So that offsets can grow very large with
+64-bit pointer applications (though 64bit pointers
+and 64bit offsets are not the same notion).
+
+In addition, removed all the contents (or nearly all)
+of the dwarf_funcs.c dwarf_weaks.c dwarf_vars.c,
+and dwarf_types.c, as the data format is identical
+to dwarf globals (pubnames) and there is no need
+to duplicate all that code.
+
+All these sections whose contents were gutted are things that
+are formatted exactly like pubnames, and all are sgi
+extensions.  Now the implementation uses pubnames code
+(dwarf_global.c) to do the work for all the pubnames-like
+sections.
+
+The (minor, IMO) difference is that in case of an incorrect
+dwarf file (leading to libdwarf being unable to process
+something in one of the sgi-specific pubnames-like sections)
+the dwarf error string may reference pubnames when weaks,
+static functions, static variables, or global typenames are
+actually the problem.  This is fixable, however the price would
+appear to be that even globals would need to call a helper
+function (to pass in the correct error return).  Right now the
+dwarf_weaks.c calls the dwarf_global.c function, for example,
+with no extra arguments indicating the true section involved.
+(Other approaches keeping the original error codes exist.
+Producing the code uniquely via macros seems unappealing.
+Inline functions would be ok though.  This version does not
+inline the functions we are talking about, such as
+dwarf_global_name_offsets() when called from
+dwarf_type_name_offsets().)
+
+Since these extra sections are SGI only and only really used by
+SGI's workshop product, and the performance hit is small, the
+extra function calls in reading each seem acceptable.
+
+
+-------------------------------------------------------------
+Sep 29,1999 davea@sgi.com
+Changed many files, so that it is easy to switch
+from 32bit-offset-only (like cygnus
+and dwarf2 v 2.0.0)  to sgi/mips 64 bit dwarf.
+See NEWS for more info on 32bit-offset.
+
+
+-------------------------------------------------------------
+Since Oct 95 and before May, 1996
+
+Added the function dwarf_get_cie_of_fde() which makes it possible
+to remember a single fde/cie set out of a block usefully.
+
+Enhanced doc of dwarf_bitoffset()
+
+Added new function dwarf_global_formref() so all reference
+forms can be retrieved.
+
+Fixed bug in retrieving array bounds: was failing to sign extend
+formsdata.
+
+Added function dwarf_get_fde_info_for_all_regs(), which makes
+retrieval of the complete set of registers (as needed by
+debuggers and exception handlers) effectively N times faster
+than getting them one a time where N is the number of registers.
+
+Added support for exception table handling (really just support
+for a reference to an exception table for c++ exceptions).
+
+Fixed a bug where useless extra space (several megabytes)
+were malloc'ed for the abbreviations table by the libdwarf
+consumer code.
+
+davea@sgi.com
+-------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/COPYING	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,37 @@
+
+
+The files:
+	libdwarf.h
+	dwarf.h
+	and all the .h and .c files in this implementation of
+	libdwarf are copyrighted according to the file
+	LIBDWARFCOPYRIGHT (which mentions the LGPL version 2.1).   
+        The full text of the LGPL 2.1 is provided in LGPL.txt
+
+
+The dwarf documentation:
+	dwarf.v2.mm and its postscript form and its
+	indexes are copyright Unix International (UI is now defunct).  
+        One presumes XOPEN owns the copyright now. In any case copying
+	and revision without fee is permitted (see the
+	copyright in the document).
+
+The libdwarf documentation:
+	libdwarf2.1.mm
+	is based on material submitted to the UI PLSIG as proposed
+	interfaces for dwarf, but completely rewritten.  
+        Copyright ownership is therefore SGI (but see the document for details)  
+        and it seems clear that the intent was there was to be free
+	copying with no fees.
+
+        libdwarf2p.1.mm
+        is documentation of a set of interfaces 
+        (not part of the UI PLSIG proposals)
+        and the document was written from scratch at SGI.
+        Copyright ownership is therefore SGI (but see the document for details)  
+        and it seems clear that the intent was there was to be free
+	copying with no fees.
+
+$Source: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/libdwarf/RCS/COPYING,v $
+$Revision: 1.2 $
+$Date: 2001/01/16 17:08:36 $
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/ChangeLog	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,217 @@
+2007-12-09 DavidAnderson <davea42@earthlink.net>
+     * dwarf_sort_line.c dwarf_print_lines.c darf_frame.c: Forgot 
+       to commit yesterday.
+       Today's commit includes renaming _dwarf_fde_section_offset
+       _dwarf_cie_section_offset, _dwarf_print_lines, _dwarf_ld_sort_lines
+       to dwarf_* name while retaining support for the now obsolete
+       _dwarf_* form.
+2007-12-08 DavidAnderson <davea42@earthlink.net>
+     * config.h.in, configure.in: Latest linux libelf.h requires
+       _GNU_SOURCE to get off64_t defined so dwarfdump compiles.
+       Only define _GNU_SOURCE  if libelf.h defines off64_t.
+       Regenerated configure.
+     * config.guess, config.sub: Updated to 2.61
+     * acconfig.h: Deleted, removing autoconf complaint.
+2007-11-14 David Anderson <davea42@earthlink.net>
+      * dwarf_frame2.c (gnu_aug_encodings): Now allows 'S' augmentation 
+        character in eh_frame.
+2007-10-16 David Anderson <davea42@earthlink.net>
+      * dwarf_alloc.c: Reformat a comment.
+      * dwarf_die_deliv.c (dwarf_siblingof): When there is no trailing
+        null-DIE in the section, ensure we don't test the contents
+        of a byte past section end.
+      * dwarf_frame.c:  Changed spelling of a local variable
+        so it is easier to grep for and to read.
+      * dwarf_macro.c (free_macro_stack): Was free()ing memory that 
+        _dwarf_get_alloc() had supplied, which could lead to core dump.  
+        Fixed potential memory leaks (said leaks only possible with an
+        error in the macro data, not  with valid macro section
+        data).
+2007-10-15 David Anderson <davea42@earthlink.net>
+      * dwarf_alloc.c: The code supporting the special build
+        flag DWARF_SIMPLE_MALLOC
+        was broken and could coredump libdwarf
+        (which did not affect normal use of libdwarf).
+      * dwarf_opaque.h: Remove the field de_simple_malloc_current
+        as it is no longer used.
+
+2007-09-04 David Anderson <davea42@earthlink.net>
+      * pro_forms.c: Add commentary relating to the
+        recent DWARF4 DW_AT_high_pc change.
+        Correct FSF address.
+      * libdwarf2p.1.mm: Document dwarf_add_AT_dataref()
+        and dwarf_add_AT_ref_address().
+      * libdwarf2p.1.pdf: Regenerate.
+      * dwarf.h: Update FSF address.
+      * dwarf_opaque.h: Add DWARF4 entry (version stamp).
+        Update FSF address.
+      * dwarf_die_deliv.c: Add check for .debug_info version 4 
+        (version stamp). Update FSF address.
+      * libdwarf.h pro_macinfo.h pro_line.h dwarf_incl.h
+        pro_alloc.h pro_section.h libdwarfdefs.h pro_util.h
+        dwarf_vars.h dwarf_funcs.h pro_error.h dwarf_alloc.h pro_arange.h
+        dwarf_arange.h pro_die.h dwarf_global.h pro_expr.h
+        pro_reloc_stream.h pro_incl.h pro_encode_nm.h
+        dwarf_line.h pro_frame.h pro_opaque.h dwarf_error.h
+        dwarf_base_types.h dwarf_abbrev.h pro_types.h pro_reloc_symbolic.h
+        dwarf_weaks.h dwarf_util.h dwarf_loc.h malloc_check.h
+        dwarf_die_deliv.h acconfig.h dwarf_frame.h dwarf_macro.h
+        pro_reloc.h dwarf_types.h
+        pro_funcs.c Makefile.in pro_forms.c pro_line.c
+        dwarf_print_lines.c pro_alloc.c pro_init.c dwarf_addr_finder.c
+        pro_section.c dwarf_form.c dwarf_query.c dwarf_vars.c
+        dwarf_pubtypes.c dwarf_frame3.c dwarf_funcs.c pro_error.c
+        pro_arange.c dwarf_alloc.c dwarf_arange.c pro_die.c
+        dwarf_sort_line.c dwarf_global.c dwarf_init_finish.c pro_weaks.c
+        pro_pubnames.c pro_expr.c pro_reloc_stream.c pro_finish.c
+        pro_encode_nm.c dwarf_line.c pro_frame.c dwarf_error.c
+        dwarf_abbrev.c pro_types.c dwarf_leb.c pro_reloc_symbolic.c
+        dwarf_string.c pro_vars.c dwarf_line2.c dwarf_weaks.c
+        dwarf_frame2.c dwarf_util.c dwarf_loc.c LIBDWARFCOPYRIGHT
+        malloc_check.c dwarf_die_deliv.c dwarf_frame.c dwarf_stubs.c
+        dwarf_macro.c pro_reloc.c dwarf_types.c pro_macinfo.c:
+        Update FSF address.
+2007-07-26 David Anderson <davea42@earthlink.net>
+      * pro_frame.c: Added commentary about some missing DWARF3 support.
+      * dwarf_srclines_dealloc.c: File unused, now deleted.
+2007-07-04 David Anderson <davea42@earthlink.net>
+      * libdwarf.h: dwarf_get_loclist_entry() is implemented,
+        removed the erroneous 'unimplemented' comment.
+      * libdwarf2.1.mm: Improved the dwarf_get_loclist_entry()
+        documentation.
+      * libdwarf2.1.pdf: regenerated
+      * dwarf_loclist_entry.c: Removed from distribution, the
+        source has nothing of interest.
+
+2007-07-03 David Anderson <davea42@earthlink.net>
+      * libdwarf.h: Add declaration of dwarf_loclist_from_expr();
+      * dwarf_loc.c: Implement dwarf_loclist_from_expr() and add 
+        sign-extension macro calls to case DW_OP_const4s numbers.
+        Removed unused local variables.
+      * dwarf_form.c: Removed unused local variables.
+      * libdwarf2.1.mm: Document dwarf_loclist_from_expr().
+      * libdwarf2.1.pdf: Regenerated.
+2007-07-01 David Anderson <davea42@earthlink.net>
+      * dwarf_frame2.c: Add commentary.
+      * dwarf_frame.c: Add in block_len for DW_CFA_val_expression
+        so libdwarf does not get confused by this frame expression
+        operator.  Thanks to Cristian Vlasceanu for providing
+        a test case.
+2007-06-29 David Anderson <davea42@earthlink.net>
+      * README: added a note that a few warnings about conversions
+        from pointer to integer are normal at libdwarf compile time.
+2007-05-25 David Anderson <davea42@earthlink.net>
+      * dwarf_frame2.c (_dwarf_get_fde_list_internal): 
+        Correct cie-list-creation so it adds to the tail of the list.  
+        gcc 4.1.2 generates cie-use in an order the code did
+        not properly handle.
+2007-05-08 David Anderson <davea42@earthlink.net>
+      * Makefile.in:  Now generates pdf files.
+      * mips_extensions.mm: The only changes were to eliminate
+        unsupported macro (.PM) and to try to get correct output
+        from groff.  No technical content change intended.
+        The pdf/postscript output remains a little odd though.
+      * libdwarf2.1.mm: Remove troff comment line.
+2007-04-18 Chris Quenelle <chris.quenelle@sun.com>
+      * dwarf_addr_finder.c: repaired comment
+      * dwarf_form.c: add support for DW_AT_SUN_func_offsets
+      * pro_alloc.c: add memory block tracking to find and fix
+	lingering allocations.  This is more important for very large
+	and intensive compiles.
+      * pro_die.c: Implement "markers" which are a generic way to
+	do things like relocations.  You can set a marker on any
+	die, and when dwarf is produced in binary form, you get back
+	a list of your markers with the offset of each one in the binary
+	output.  This is used by the Sun compilers to implement die
+	references that span compile unit blocks.  (I may remove this,
+	it might be unused code related to partial_units and comdat
+	support)
+      * pro_die.c: Also check for loops in the die relationships so
+	that if you add a child twice, or other errors, you won't get
+	an infinite loop or a crash.  Also start passing a DBG structure
+	to all allocation calls to help with memory block tracking.
+      * pro_expr.c: Add a public function to "reset" an expr.  This
+	allows the same expr object to be reused over and over to save
+	memory if you're creating many many expressions for a location list.
+      * pro_finish.c: Free any left over blocks when the user calls
+	dwarf_producer_finish.
+      * pro_forms.c: More support for compressed integer blocks. Modify
+	error diagnostics so that user-defined attributes can be any type.
+	Add support for dwarf_add_AT_ref_address which is just like
+	dwarf_add_AT_address, only it produces a DW_FORM_ref_addr instead
+	of DW_FORM_addr.  This is needed for cross-CU die pointers.
+      * pro_incl.h: add macros to control the spelling of relocation types.
+      * pro_init.c: use new macros to control reloc types
+      * pro_line.h: correct minimum instruction length on x86
+      * pro_opaque.h: add support for markers (see above) and also ability
+	have libdwarf tell the caller where the string constants are so
+	that they can be recorded as strings in case the binary output of libdwarf
+	needs to be converted back into assembly.  That's what
+	Dwarf_P_Per_Sect_String_Attrs is about.
+        Remove de_mem_list as it is never used.
+      * pro_reloc_stream.c: repair prototype and comment for
+	_dwarf_pro_reloc_name_stream64, and use relocation type macros.
+      * pro_section.c: support for markers (see above) and for tracking
+	inline string attributes.  Add code to sort the attributes so that
+	abbreviation table entries will be reduced.  Change treatment of
+	DW_FORM_ref_addr to be more correct.  Some support for packing
+	in the middle of sections, this will probably be removed.
+	Also pass DBg structure to more allocations.
+      * pro_util.h: relocation type values can't be zero.
+2007-04-10 David Anderson <davea42@earthlink.net
+      * dwarf_print_lines.c pro_section.c dwarf_query.c
+        dwarf_alloc.c dwarf_arange.c dwarf_sort_line.c
+        dwarf_global.c dwarf_line.c dwarf_abbrev.c
+        dwarf_frame2.c dwarf_util.c dwarf_loc.c dwarf_util.h 
+        dwarf_die_deliv.c dwarf_frame.c dwarf_macro.c: Additions
+        to source for year 2007 now fit in with pre-existing 
+        copyright wording.  Effectively no change.
+      * dwarf_srclines_dealloc.c: Now has the (always-intended) SGI
+        LGPL copyright wording.
+2007-04-09 David Anderson <davea42@earthlink.net
+      * dwarf_error.h: Add DW_DLE_LINK_LOOP error code (Sun).
+      * libdwarf.h: Add DW_DLE_LINK_LOOP error code (Sun).
+      * dwarf.h: Incorporate Sun extensions. Thanks to
+        Chris Quenelle at Sun Microsystems.
+2007-04-06 David Anderson <davea42@earthlink.net
+      * dwarf_sort_line.c (_dwarf_update_line_sec): initialize
+        Dwarf_Debug_s struct. Thanks to Chris Quenelle of Sun Microsystems.
+        Also initialize other local variables.
+2007-04-02 David Anderson <davea42@earthlink.net
+      * dwarf_form.c (dwarf_formsdata, dwarf_formudata): Use
+        Dwarf_sfixed in dwarf_formsdata, document need for casts,
+        Use Dwarf_Signed as type for READ_UNALIGNED macro use.
+        The only real correction here is for a 64bit long compiled 
+        libdwarf reading 32bit dwarf_formsdata FORM_data4.
+      * dwarf_base_types.h: Now Dwarf_sfixed64 and Dwarf_ufixed64
+        are properly declared (so they are usable).
+2007-03-11 David Anderson <davea42@earthlink.net
+      * Makefile.in: use groff to produce postscript.
+      * libdwarf2.1.mm libdwarf2.1.ps  libdwarf2p.1.mm
+        libdwarf2p.1.ps: Clean up the introduction and history.
+        Add a non-restrictive copyright notice.
+2007-02-23 David Anderson <davea42@earthlink.net
+      * dwarf_util.h: now the macros use do{} while(0)
+      * pro_forms.c dwarf_print_lines.c pro_section.c dwarf_query.c 
+        dwarf_arange.c dwarf_sort_line.c dwarf_global.c dwarf_line.c
+        dwarf_abbrev.c dwarf_frame2.c dwarf_util.c dwarf_loc.c
+        dwarf_die_deliv.c dwarf_frame.c: Now have ;
+        after all dwarf_util.h macros. Also added local variable
+        initializations (compiler noticed).
+      * dwarf_macro.c: was missing include of <stdlib.h> for free() 
+        declaration. 
+      * dwarf_print_lines.c pro_section.c dwarf_query.c dwarf_alloc.c
+        dwarf_arange.c dwarf_sort_line.c dwarf_global.c dwarf_line.c
+        dwarf_abbrev.c dwarf_srclines_dealloc.c dwarf_frame2.c
+        dwarf_util.c dwarf_loc.c dwarf_die_deliv.c dwarf_frame.c
+        dwarf_macro.c: indent run with standard libdwarf options.
+
+2007-02-20 David Anderson <davea42@earthlink.net
+      * dwarf_macro.c  (dwarf_get_macro_details): Now call
+        dwarf_free_macro_stack() at every return so no data
+        is leaked and there is no longer any global data
+        (restoring thread safety).
+2007-02-09 David Anderson <davea42@earthlink.net
+      * dwarf_line.c (dwarf_srclines): Added in calls
+        to dwarf_free_line_table_prefix() which were omitted
+        by accident.  Thanks to  Cristian Vlasceanu for noticing.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/ChangeLog2006	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,835 @@
+2006-12-05 David Anderson <davea@sgi.com>
+      * dwarf_error.c, libdwarf.h: added 
+        DW_DLE_FRAME_REGISTER_COUNT_MISMATCH.
+      * dwarf_frame.c (_dwarf_exec_frame_instr): removed references
+        to compile-time constants for register table size.  Now uses
+        run-time-chosen sizes.  Now uses heap for reg table instead
+        of stack. Now uses SIMPLE_ERROR_RETURN macro to simplify
+        the code.
+2006-11-08 David Anderson <davea@sgi.com>
+      * pro_expr.c (dwarf_add_expr_gen): DW_OP_deref_size,
+        DW_OP_xderef_size, and  DW_OP_pick were incorrect, missing
+        & operator. Would coredump.  Thanks to Alan Chambers for mentioning
+        the coredump.
+2006-09-26 David Anderson <davea@sgi.com>
+      * dwarf_die_deliv.c (dwarf_offdie): Now returns the
+        correct die (worked before, almost always, but worked by accident).
+        Thanks to Mattias Lindblad for supplying a test case.
+2006-09-01 David Anderson <davea@sgi.com>
+      * libdwarf2.1.mm (dwarf_loclist_n): Minor refinement
+        of the description.
+      * libdwarf2.1.ps: regenerated
+2006-08-31 David Anderson <davea@sgi.com>
+      * libdwarf2.1.mm (dwarf_loclist_n): A location expression
+        sets ld_lopc to 0, ld_hipc to all-bits-on, and this
+        is now documented.
+      * libdwarf2.1.ps: regenerated
+2006-06-14 David Anderson <davea@sgi.com>
+      * dwarf_opaque.h dwarf_frame.h dwarf_frame.c
+        dwarf_init_finish.c dwarf_frame2.c: Corrected handling
+        of eh_frame zP encoding.  
+        Thanks to Cristi Vlasceanu for noticing it was broken.
+      * Makefile.in: remove libdwarf.so in 'clean' rule.
+        Thanks to Cristi Vlasceanu for noticing it was missing.
+2006-04-28 David Anderson <davea@sgi.com>
+      * dwarf_frame.c: Changed local variable type to
+        avoid compiler warning. 
+2006-04-21 David Anderson <davea@sgi.com>
+      * dwarf_frame.c: Initialized local to 0, wrong value.
+         Thanks to Cristi Vlasceanu for noticing.
+2006-04-18 David Anderson <davea@sgi.com>
+      * All *.c: Ran indent so all c files follow a standard look.
+2006-04-16 David Anderson <davea@sgi.com>
+      * dwarf.h: Remove #if 0 around some #defines, it is ok to 
+        leave the defines visible (the defines are HP extensions).
+      * libdwarf.h: Add new dwarf3 interface to frames.
+        (which actually is also a better interface to dwarf2 info,
+        not strictly for dwarf3).
+      * dwarf_alloc.c: Add 'constructor/destructor' pointers 
+        to the initialization table so we can handle a more 
+        flexible (dwarf3) frame interface.Call the functions 
+        at the appropriate times.
+      * dwarf_frame.c: Using macro FDE_NULL_CHECKS_AND_SET_DBG 
+        reduce duplicate coding.Internal code now handles dwarf2 
+        and dwarf3 and interfaces to exported interfaces appropriately.
+      * dwarf_frame.h: Alter internal struct to handle frames more flexibly.
+      * dwarf_frame2.c: Remove unused local variable.
+      * dwarf_init_finish.c: Add initialization of new Dwarf_Debug 
+        struct entries allowing handling
+        of run-time-config of frame info.
+      * dwarf_loc.c: Add DWARF3 operators, such as DW_OP_call4.
+      * dwarf_opaque.h: Declaration of new Dwarf_Debug struct 
+        entries allowing handling of run-time-config of frame info.
+      * pro_expr.c: Add entries allowing creation of DWARF3 DW_OP 
+        such as call2. 
+      * pro_section.c: Change crucial code handling section lengths, 
+        using a macro BEGIN_LEN_SIZE to clarify and correct a few places.
+2006-03-31 David Anderson <davea@sgi.com>
+      * libdwarf.h: Added dwarf_get_fde_info_for_cfa_reg3() prototype
+        preparing for dwarf3 frame interface.
+      * dwarf_frame.c: Now uses separate rule, not DW_FRAME_CFA_COL, 
+        to record CFA.
+      * dwarf_frame.h: Add commentary on frame access.
+2006-03-30 David Anderson <davea@sgi.com>
+      * Makefile.in configure.in: Adding --enable-shared --enable-nonshared
+        --disable-shared  and --disable-nonshared.
+      * configure: regenerated with 2.59 autoconf.
+      * README: Added explanation on changing dwarf.h libdwarf.h.
+2006-03-29 David Anderson <davea@sgi.com>
+      * dwarf_print_lines.c dwarf_sort_line.c: Clean up initialization
+        code for line table reading. When returning rules table
+        data to caller ensure fully filled out yet no overrun
+        (handling case where rules table sizes not defined identically
+        by caller and library).
+      * dwarf.h: New commentary on ABI/register-number issues.
+      * libdwarf.h: New commentary on ABI/register-number issues.
+2006-03-26 David Anderson <davea@sgi.com>
+      * dwarf_line.c: file_entry_count local was not initialized.
+        Initialized some locals at declaration.
+        Thanks to Mikael Vidstedt for noticing.
+2006-03-23 David Anderson <davea@sgi.com>
+      * dwarf_error.c: added error strings for codes 200,201
+      * dwarf_line.c dwarf_line.h dwarf_print_lines.c dwarf_sort_line.c: Moved
+        line prefix reading to a common routine, filling in a new internal
+        struct to make it simple.  Removed much duplicate code.
+        Added more support for dwarf3 line table standard opcodes.
+        Now prints details (with -v -v) of standard opcodes it
+        does not understand (if any present).
+2006-03-13 David Anderson <davea@sgi.com>
+      * dwarf.h: add ALTIUM #defines (extensions to dwarf)
+      * libdwarf.h: Alter arguments to new
+        functions dwarf_get_fde_augmentation_data() and
+        dwarf_get_cie_augmentation_data() used by GNU eh_frame.
+      * dwarf_frame.h: Add new fields so we can handle GNU eh_frame.
+      * dwarf_frame.c: Remove erroneous load_sections calls (wrong for eh_frame
+        data) and correct the new dwarf_get_fde_augmentation_data() and
+        dwarf_get_cie_augmentation_data() implementation.
+      * dwarf_frame2.c: Implement support for GNU eh_frame.
+      * dwarf_line.h: Correct handling of DWARF3 opcode base check.
+      * dwarf_line.c: Add new macro use to get DWARF3 opcode base handling correct.
+      * dwarf_print_lines.c: Add new macro use to get DWARF3 opcode base handling correct.
+      * dwarf_sort_lines.c: Add new macro use to get DWARF3 opcode base handling correct.
+2006-03-08 David Anderson <davea@sgi.com>
+      * dwarf_frame2.c: ensure local variables  initialized
+        to avoid coredump.
+2006-03-08 David Anderson <davea@sgi.com>
+      * dwarf_die_deliv.c: Remove Richard Stukey's -1 and
+        replace with a simpler more complete fix.
+2006-03-07 David Anderson <davea@sgi.com>
+      * Makefile.in: Add dwarf_line2.c dwarf_frame3.c to files to build.
+      * dwarf_addr_finder.c: Add comments about file purpose.
+      * dwarf_frame.c: Move IRIX specific function out of this file.
+      * dwarf_frame3.c: Move IRIX specific function to this new file.
+      * dwarf_frame.h: Add interface declaration.
+      * dwarf_line.c: Move IRIX specific function out of this file.
+      * dwarf_line2.c: Move IRIX specific function to this new file.
+      * dwarf_line.h: Add interface declaration.
+      * dwarf_frame2.c: Altered comments so indent handles them better,
+        ran indent.
+
+2006-03-07 David Anderson <davea@sgi.com>
+      * dwarf_die_deliv.c (dwarf_siblingof): -1 to point to end of cu,
+        not one-past-end.  With thanks to Richard Stuckey.
+      * libdwarf2.1.mm: document existing function dwarf_get_fde_exception_info()
+      * dwarf_frame.h: Add new internal interfaces.
+      * dwarf_frame.c: Remove cie/fde reader to dwarf_frame2.c.
+      * dwarf_frame2.c: Contains heavily refactored cie/fde reader,
+        preparing for eh_frame support and avoids some searching
+        in fde creation.  Removes duplicated code into new 
+        internal functions.
+      * Makefile.in: Adding comment about flag for malloc_checking
+        code. Add dwarf_frame2.c to source list.
+      * libdwarf.h: added declarations for eh_frame information, though
+        these are not yet supported.
+      * dwarf.h: Added defines for eh_frame information, though these
+        are not yet used.
+2006-02-23 David Anderson <davea@sgi.com>
+      * dwarf_line.h dwarf_line.c: added dwarf_line_srcfileno()
+        to complement dwarf_lineno.
+      * libdwarf2.1.mm: document dwarf_line_srcfileno().
+
+2005-11-25 David Anderson <davea@sgi.com>
+      * dwarf.h: Now matches 2005 DWARF3 public review document.
+
+2005-11-08 David Anderson <davea@sgi.com>
+      * dwarf_alloc.c, dwarf_init_finish.c, dwarf_sort_line.c, malloc_check.c:
+        remove malloc.h include, it is not needed, stdlib.h suffices.
+
+2005-10-24 David Anderson <davea@sgi.com>
+      * dwarf.h: Updated to match DWARF3 public review document.
+    
+2005-10-03 David Anderson <davea@sgi.com>
+      * dwarf_alloc.c: Change some entries to BASE_ALLOC.
+      * dwarf_global.h: Add argument to interface so we do not
+        universally use DW_DLA_GLOBAL, but cater to compatibility.
+      * dwarf_funcs.c, dwarf_global.c, dwarf_weaks.c,
+        dwarf_funcs.c, dwarf_types.c: Restored use of DW_DLA_*
+        instead of universally using DW_DLA_GLOBAL.
+      * dwarf_pubtypes.c: added comments about DW_DLA_GLOBAL use.
+2005-08-01 David Anderson <davea@sgi.com>
+      * malloc_check.c: Moved the #ifdef WANT_LIBBDWARF_MALLOC_CHECK
+        down after #includes so the test is meaningful.
+2005-07-15 David Anderson <davea@sgi.com>
+      * libdwarf.h: New DW_DLA codes and full .debug_types support added.
+        new dealloc functions declared.
+      * Makefile.in: Add dwarf_pubtypes.o (.debug_pubtypes support).
+      * dwarf_abbrev.c: Add dealloc() calls where needed.
+      * dwarf_alloc.c: Add dwarf_malloc_check calls, rename and
+        update _DW_RESERVE to DW_RESERVE, make hash table declaration
+        in array more readable. Add optional final dealloc loop.
+      * dwarf_alloc.h: Increase the index array to add .debug_pubtypes
+        support.
+      * dwarf_base_types.h: Increase the index array to add .debug_pubtypes
+        support.
+      * dwarf_die_deliv.c: Add dealloc calls to get full dealloc.
+      * dwarf_error.c: Document new error codes for .debug_pubtypes.
+      * dwarf_init_finish.c: Add .debug_pubtypes support, add
+        dwarf_malloc_check_complete() call for alloc checking.
+      * dwarf_form.c: Document dwarf_formstring() use.
+      * dwarf_frame.c: Add dwarf_fde_cie_list_dealloc() for
+        complete dealloc.
+      * dwarf_global.h: Add _dwarf_internal_globals_dealloc
+        declaration for libdwarf-internal use.
+      * dwarf_global.c dwarf_funcs.c dwarf_types.c dwarf_vars.c
+        dwarf_weaks.c:  Add new dealloc public routines for
+        complete dealloc and add .debug_pubtypes support.
+      * dwarf_pubtypes.c: Support for .debug_pubtypes.
+      * dwarf_malloc_check.h dwarf_malloc_check.c : New checking 
+	for complete accurate dealloc (off by default).
+      * dwarf_opaque.h: Add internal .debug_pubtypes support.
+      * libdwarf2.1.mm: Document new dealloc code, correct
+        dwarf_formstring documentation.
+
+2005-07-14 David Anderson <davea@sgi.com>
+      * dwarf_line.c: Added dwarf_srclines_dealloc and call it
+        for dwarf_srclines output.  Does complete deallocation,
+        unlike previous method, which was incomplete deallocation.
+        Thanks to Alan Alexander for pointing out there was
+        incomplete deallocation.
+      * dwarf_print_lines.c: remove references and allocation
+        of line_context. Memory was leaking due to unreferenced
+        variable.
+      * libdwarf2.1.mm: Document new dwarf_srclines_dealloc()
+        deallocation routine for dwarf_srclines().
+
+2005-07-13 David Anderson <davea@sgi.com>
+      * dwarf_init_finish.c (dwarf_init): if _dwarf_setup() fails,
+        free elf resources with elf_end() call.
+        Thanks to Cristi Vlasceanu for pointing out that a memory
+        leak existed here.
+
+2005-06-13 David Anderson <davea@sgi.com>
+      * dwarf_frame.c (_dwarf_exec_frame_instr): Corrected test
+        so that .o files (pre-relocation) are less likely to generate
+	DW_DLE_DF_NEW_LOC_LESS_OLD_LOC error. Renamed local variable
+	for better readability.
+2005-04-13 David Anderson <davea@sgi.com>
+      * dwarf_error.c: Error  codes 194 and 195 were missing
+	strings, added them to table. 
+      * dwarf_frame.c: Check for newer gcc .eh_frame
+          augmentation strings and avoid trying to handle these
+          for now.
+      * dwarf_global.c: Add an error check for
+          pubnames-style sections for bad offset.
+      * dwarf_init_finish.c: Add dwarf_get_section_max_offsets()
+          to allow clients to do additional error checking.
+          This code will have to change again, so leaving it
+          undocumented. As written it's not useful for COMDAT
+          style DWARF sections.
+      * libdwarf.h: Added prototype for dwarf_get_section_max_offsets().
+
+2005-03-31 David Anderson <davea@sgi.com>
+      * mips_extensions.mm: Documented  the libexc/.debug_funcnames
+        dependency and the 64bit-offset DWARF extension.
+      * mips_extensions.ps: Regenerated.
+
+2005-03-21 David Anderson <davea@sgi.com>
+      * dwarf_line.c: Added commentary.
+      * libdwarf2.1.mm: Documented dwarf_lineendsequence() better.
+      * libdwarf2.1.ps: Regenerated.
+      * libdwarf.h: Added DW_DLE_FRAME_AUGMENTATION_UNKNOWN as
+        error code 195.
+      * dwarf_init_finish.c: Corrected comment spelling. 
+      * dwarf_frame.h dwarf_frame.c: Added handling for 
+        much (but not all) of gcc 3.3 gcc 3.4 .eh_frame
+	'z' augmentation.  Gives error on attempting
+        to get z augmentation data since such is not
+        completely handled.
+
+2005-03-18 David Anderson <davea@sgi.com>
+      * dwarf_frame.h dwarf_frame.c: The gcc .eh_frame
+        info did not print correctly so we now access the
+	correct section data so it prints. Still no support
+	for dwarf3 frame operators.
+      * dwarf_macro.c: Detect end-of-macros properly
+        (stopped too soon before).
+	
+2005-02-14 David Anderson <davea@sgi.com>
+      * pro_incl.h: Added #elif defined(HAVE_LIBELF_H)
+        enabling build on a platform missing normal elf.h.
+
+2005-02-11 David Anderson <davea@sgi.com>
+      * dwarf_base_types.h: Added DW_CIE_VERSION3 define.
+      * dwarf_die_deliv.c: Allowed CURRENT_VERSION_STAMP3.
+      * dwarf_frame.c: Allowed DW_CIE_VERSION3.
+      *	dwarf_frame.h: Define DW_DEBUG_FRAME_VERSION3.
+      *	dwarf_line.c: Allow CURRENT_VERSION_STAMP3.
+      *	dwarf_line.h: Add lc_version_number to line structure.
+      *	dwarf_opaque.h: Add CURRENT_VERSION_STAMP3 and comment showing
+		version numbers (DWARF3 vs DWARF2) by DWARF section.
+
+2004-11-21 David Anderson <davea@sgi.com>
+     *  configure.in libdwarfdefs.h: Now tests more precisely for __uint32_t
+	and __uint64_t (previous test was not sufficient for debian/mips). 
+	Regenerated configure config.h.in.
+
+2004-10-28 David Anderson <davea@sgi.com>
+      * LIBDWARFCOPYRIGHT Makefile.in NEWS config.h dwarf_abbrev.c 
+       dwarf_abbrev.h dwarf_addr_finder.c dwarf_alloc.c dwarf_alloc.h
+        dwarf_arange.c dwarf_arange.h dwarf_base_types.h dwarf_die_deliv.c
+        dwarf_die_deliv.h dwarf_error.c dwarf_error.h dwarf_form.c
+        dwarf_frame.c dwarf_frame.h dwarf_funcs.c dwarf_funcs.h
+        dwarf_global.c dwarf_global.h dwarf_incl.h dwarf_init_finish.c
+	dwarf_leb.c dwarf_line.c dwarf_line.h dwarf_loc.c dwarf_loc.h
+	dwarf_macro.c dwarf_macro.h dwarf_opaque.h dwarf_print_lines.c
+	dwarf_query.c dwarf_sort_line.c dwarf_string.c dwarf_stubs.c
+	dwarf_types.c dwarf_types.h dwarf_util.c dwarf_util.h
+	dwarf_vars.c dwarf_vars.h dwarf_weaks.c dwarf_weaks.h
+	libdwarfdefs.h pro_alloc.c pro_alloc.h pro_arange.c pro_arange.h
+	pro_die.c pro_die.h pro_encode_nm.c pro_encode_nm.h pro_error.c
+	pro_error.h pro_expr.c pro_expr.h pro_finish.c pro_forms.c
+	pro_frame.c pro_frame.h pro_funcs.c pro_funcs.h pro_incl.h
+	pro_init.c pro_line.c pro_line.h pro_macinfo.c pro_macinfo.h
+	pro_opaque.h pro_pubnames.c pro_pubnames.h pro_reloc.c
+	pro_reloc.h pro_reloc_stream.c pro_reloc_stream.h pro_reloc_symbolic.c
+	pro_reloc_symbolic.h pro_section.c pro_section.h pro_types.c
+	pro_types.h pro_util.c pro_util.h pro_vars.c pro_vars.h
+	pro_weaks.c pro_weaks.h: Copyright update with
+        2004 and new SGI official address.
+
+2004-10-26 David Anderson <davea@sgi.com>
+      * acconfig.h: removed. Was old style autoconf usage.
+      * configure.in: Updated AC_DEFINE usage, adding args 2 & 3.
+      * config.guess: Updated. timestamp='2004-06-11'.
+      * config.sub: Updated.  timestamp='2004-03-12'.
+      * configure config.h.in: regenerated with autoconf 2.58.
+
+2004-06-09  David Anderson <davea@sgi.com>
+      * dwarf_frame.c (_dwarf_exec_frame_instr):
+        Was not setting ru_offset to 1 in DW_CFA_def_cfa_offset 
+        case, now it does.
+
+2004-02-24  David Anderson <davea@sgi.com>
+      * dwarf_frame.c (_dwarf_exec_frame_instr):
+        DW_CFA_def_cfa_register case, was setting offset, which
+        is incorrect. Thanks to Tom Hughes <thh@cyberscience.com>
+        for pointing this out.
+
+2004-02-03 David Anderson <davea@sgi.com>
+      * dwarf_util.h:  DECODE_LEB128_UWORD DECODE_LEB128_SWORD
+        were simply wrong if  Dwarf_Word or
+        Dwarf_Sword longer than 4 bytes. Upper bits left random. 
+        Large values not extracted correctly.
+
+2004-01-15 David Anderson <davea@sgi.com>
+      * dwarf_alloc.c pro_alloc.c pro_init.c: changing BSD-ish bzero()
+ 	to posix-standard memset() calls.
+      * configure.in: remove bstring.h test, add alloca.h test.
+        No longer useing bzero, some environments have alloca 
+	in malloc.h, no alloca.h.  If neither exist
+        it's up to you to deal with it.
+      * dwarf_line.c dwarf_print_lines.c dwarf_sort_line.c: Test
+	HAVE_ALLOCA_H
+      * configure config.h.in: regenerated
+
+2003-12-31 David Anderson <davea@sgi.com>
+      * dwarf_init_finish.c: added #error to detect and describe
+  	absence of libelf.h.
+      * README: Added mention of libelf.h requirement, minor
+	cleanout of obsolete comments, added configure example.
+      * Makefile.in: Removed bogus LIBS line, updated copyright date.
+      * acconfig.h: Updated copyright date.
+      * config.guess config.sub: new versions from automake-1.6.
+      * config.h.in configure: Regenerated.
+
+2003-12-15 David Anderson <davea@sgi.com>
+      * dwarf_init_finish.c (_dwarf_setup): test for (section_size)
+        was wrong for eh_frame section. Changed this one to
+	(section_size == 0) so it is like all the others testing 
+	section_size.  Thanks to David Mosberger 
+	for pointing out this inconsistency.
+
+2003-12-08 David Anderson <davea@sgi.com>
+      * dwarf_line.h: reference in comment to li_dbg meant to
+        refer to li_offset. Corrected and amplified comment.
+
+2003-10-06 David Anderson <davea@sgi.com>
+      * dwarf_abbrev.c dwarf_die_deliv.c dwarf_form.c dwarf_loc.c 
+	dwarf_util.c: applied indent(1).
+
+2003-10-02 David Anderson <davea@sgi.com>
+      * dwarf_loc.c: Implemented dwarf_get_loclist_entry(),
+        implemented new dwarf_loclist_n() fully implementing
+        loclist support.
+      * dwarf_stubs.c: removed dwarf_get_loclist_entry stub.
+      * libdwarf2.1.mm: Documented dwarf_loclist_n() and
+        updated documentation on dwarf_loclist().
+
+2003-09-29 David Anderson <davea@sgi.com>
+      * dwarf_abbrev.c: Ensure the .debug_abbrev section is loaded.
+      * dwarf_arange.c dwarf_global.c: Recent dwarf committee 
+    	discussions have revealed we were wrong in not allowing 
+	padding in aranges.
+      * dwarf_die_deliv.c dwarf_query.c: handle DW_FORM_indirect.
+      * dwarf_form.c: Add dwarf_whatform_direct() so folks
+	can report on DW_FORM_indirect use.
+	Fill in new Dwarf_Locdesc fields.
+      * dwarf_loc.c: Handle .debug_loc  partially.
+	Fill in new Dwarf_Locdesc fields.
+	Load .debug_loc if not present and if it's needed.
+      * dwarf_opaque.h: Added ar_attribute_form_direct field
+  	so we can report DW_FORM_indirect
+	in libdwarf-using code (where such wants to).
+      * dwarf_util.c: Don't confuse DW_FORM_indirect uleb length 
+	with other lengths.
+      * libdwarf2.1.mm: Document new function dwarf_whatform_direct()
+	Not needed by ordinary clients, just for clients
+	wanting to print certain debug info.
+
+2003-04-15 Brian Ford <ford@vss.fsi.com>
+      * configure.in (AC_C_BIGENDIAN): Move after AC_PROG_CC so a proper
+        working compiler is used for the test.
+
+2003-01-21 David Anderson <davea@sgi.com>
+      * dwarf_die_deliv.c (dwarf_next_cu_header, dwarf_offdie):
+	Add calls to dwarf_load_object() to load .debug_info, 
+        .debug_abbrev
+      * dwarf_init_finish.c (_dwarf_setup): Remove calls to
+        dwarf_load_object for .debug_info, .debug_abbrev sections.
+      * dwarf_opaque.h: Add new fields to Dwarf_Debug so
+        we don't need to pre-load .debug_info, .debug_abbrev
+      * dwarf_util.h: Fix READ_AREA_LENGTH macro so it uses
+        only length itself to determine which format the
+        length is.
+
+2003-01-14 David Anderson <davea@sgi.com>
+      * dwarf_loc.c: Made comment at head of dwarf_loclist()
+      a bit clearer.
+
+2002-11-22 Tom Hughes <thh@cyberscience.com>
+      * dwarf_macro.c: Corrected bugs in macro-info functions.
+
+2002-10-29 David Anderson <davea@sgi.com>
+      * dwarf_init_finish.c: The libelf_sgi mods
+      left a HAVE_ELF64_GETSHDR ifdef in the wrong place 
+      so folks without Elf64 could not build. Fixed.
+
+2002-10-21 David Anderson <davea@sgi.com>
+      * dwarf_form.c: the form_ref functions were failing to
+      add in cc_extension_size when checking for offset
+      legality. Thanks to Kelly O'Hair <kelly.ohair@sun.com>
+      for pointing out the 4 places this was wrong.
+      Used cu_context local pointer to avoid numerous
+      double indirections.
+
+2002-08-14 David Anderson <davea@sgi.com>
+      * dwarf_string.c (dwarf_get_str): Return
+      DW_DLV_NO_ENTRY when offset is just at the end of the
+      sections, making it possible to use dwarf_get_str
+      to print the section independently.
+      * libdwarf2.1.mm, libdwarf2.1.ps: Document the
+      revised dwarf_get_str interface (which was not
+      fully thought thru before).
+      * dwarf_line.c (dwarf_srcfiles): Avoid core dump
+      when DW_AT_comp_dir absent (it's not required).
+
+
+2002-07-31 David Anderson <davea@sgi.com>
+      * pro_types.c (_dwarf_transform_simplename_to_disk): correct
+      generation of .debug_info size field.
+      Thanks to Kelly O'Hair <kelly.ohair@sun.com> for pointing out
+      the bug.
+
+2002-05-23 Daniel Gohman <gohmandj@sgi.com>
+      * dwarf_init_finish.c: Add support for using SGI's
+      ELF library as an alternative to using AT&T-style
+      libelf.
+      Add a new function _dwarf_load_section to handle
+      loading of sections.
+      * dwarf_opaque.h: Add entries to Dwarf_Debug_s to
+      store section indicies.
+      * most consumer files: Load sections on demand so
+      that unneeded sections don't get loaded.
+      * dwarf_init_finish.c: Fixed an incorrect check for
+      duplicate .eh_frame sections.
+
+2002-04-25 Kelly O'Hair <kelly.ohair@sun.com>
+      * pro_section.c (_dwarf_pro_generate_debuginfo): add
+      required dwarf2 sec 7.5.3 trailing null byte 
+      to .debug_abbrev per compilation-unit.
+
+2002-03-31 David Anderson <davea@sgi.com>
+      * dwarf_abbref.c (dwarf_get_abbrev): change 
+      DW_DLE_DEBUG_ABBREV_NULL to DW_DLE_DWARF_ABBREV_NULL. 
+      Former was wrong code.
+      * libdwarf2.1.mm: correct argument reference, returned_abbrev
+      not returned_fde in dwarf_get_abbrev discussion.
+      
+2002-03-07 David Anderson <davea@sgi.com>
+      * libdwarf.h: added struct Elf declaration
+      to reduce dependency on header include ordering. 
+
+2002-02-11 David Anderson <davea@sgi.com>
+      * libdwarf2.1.mm libdwarf2.1.ps:
+      dwarf_offdie can return DW_DLV_NO_ENTRY and that
+      is now documented.
+      * dwarf_loc.c: if the length of a location description
+      is zero that is ok, not an error. dwarf2 sec 2.4.1.
+
+2002-01-10 David Anderson <davea@sgi.com>
+      * dwarf_opaque.h, dwarf_init_finish.c: if libdwarf does
+      the elf_begin() it must also do the elf_end() to
+      avoid a memory leak, and now does this correctly.
+
+2002-01-10  David Anderson <davea@sgi.com>
+      * dwarf_init_finish.c:  Using a variable to
+      hold ELF_C_READ_MMAP.  Really motivated by
+      code not added to this source. 
+      * dwarf_die_deliv.c: Added comments, moved
+      a couple variables to local scope from function scope.
+
+      * dwarf.h: Added some #defines which were specified in the Dwarf
+      2.1 Dwarf draft 5 (now called dwarf 3 draft 5).
+
+2001-09-18  David Anderson davea@sgi.com
+	* all files: applied gnu indent with
+	-bad -bap -nbbo -br -ce -brs 
+	-l72  -lc72  -hnl  -nprs  
+	-fca -i4  -lp -psl -npcs 
+	Code should use this set in libdwarf.
+
+
+2001-08-21  "kelly o'hair" <kelly.ohair@eng.sun.com>
+	* pro_section.c:  If one called dwarf_add_file_decl()
+	  or dwarf_add_directory_decl() but never added a line,
+	  .debug_line was not produced.  This was a mistake,
+	  as if any file or directory was provided .debug_line
+	  should be produced. 
+
+2001-08-06  davea@sgi.com
+	* libdwarf2.1.mm: documented dwarf_dealloc rules
+	  more clearly. (.ps updated too)
+	* mips_extensions.mm: documented the way SGI
+	  gets frame stack pointer out of debug_frame.
+	  (.ps updated too)
+
+2001-06-14  davea@sgi.com
+	* dwarf_leb.c: changed around where bytes counted in
+	  _dwarf_decode_s_leb128 so it's easier to tell it is correct.
+	  And removed one loop completely: it was
+	  an early attempt at performance improvement and
+	  is no longer relevant.
+
+	* dwarf_global.c: added new 
+	  dwarf_get_cu_die_offset_given_cu_header_offset function
+	  to get CU die offset (as the long name says).
+	  A variety of functions return cu-header-offsets, so
+	  this is useful at times.
+	  Used locals to reduce the number of indirections
+	  and make things easier to follow.
+
+	* dwarf_arange.c: added new dwarf_get_arange_cu_header_offset
+	  function so dwarfdump could print the cu header offset
+	  (which appears in the arange headers).
+
+	* libdwarf2.1.mm: documented the above new functions.
+
+2001-06-07  davea@sgi.com
+	* dwarf_leb.c: shift operator was not being applied
+	  to full size of Dwarf_Signed/Unsigned for 64bit
+	  Dwarf_Signed/Unsigned (ILP32 compile) so
+	  large numbers not decoded if signed.
+	* pro_encode_nm.c: added {} in a couple if/else
+          for 'clarity' and to make inserting debug printf easier.
+	* pro_expr.c: Added comments explaining why possible
+	  compiler (gcc) warnings are ok, the result is safe. 
+
+2001-05-30  davea@sgi.com
+	* pro_reloc_stream.c: Wrote Set_REL32_info and 
+	  Set_REL64_info macros
+	  from generic ELF abi documents to make use acceptable
+	  when IRIX elfaccess.h is not available.
+
+2001-05-30  "kelly o'hair" <kelly.ohair@eng.sun.com>
+	* Makefile.in: was missing   pro_macinfo.o
+ 	  pro_encode_nm.o dwarf_macro.o from the OBJS list.
+
+2001-05-22  davea@sgi.com
+	* dwarf_frame.c, pro_expr.c: Added comments on why
+	  casts are safe in spite of gcc warnings (4 places total).
+
+2001-05-18  Dan Gritter <dgritter@us.ibm.com>
+	* dwarf_loc.c DW_OP_bregx operands are unsigned
+	  reg num followed by signed offset.
+
+2001-04-11  David Anderson <davea@sgi.com>
+	* dwarf_die_deliv.c: check for 0 abbreviation code
+	  and return a 'no entry' return value when found.
+	  (normal dwarf2, 0 means no DIE, the end of some set of DIEs.)
+
+2001-01-16  David Anderson <davea@sgi.com>
+
+	* pro_die.c: set ar_reloc_len field
+	in all cases.
+
+2000-12-14  David Anderson <davea@sgi.com>
+
+	* dwarf_frame.h: clarified some comments.
+
+2000-12-14  Ulrich Drepper <drepper@cygnus.com>
+
+        * dwarf_line.c: Now sets DW_LNE_end_sequence to
+        default_is_stmt, the correct value, not is_stmt.
+
+
+2000 Aug 24  davea@sgi.com
+  dwarf_error.c: a dwarf_init() failure resulted in this
+	using a static Dwarf_Error struct. And dwarf_dealloc
+	did not deal properly with that. 
+  dwarf_alloc.c dwarf_alloc.h: these had DYNAMIC_CHUNK protected code
+  	which was never used.  Deleted the unused code. Added a small
+  	comment (hopefully useful) to dwarf_alloc.h.
+
+	And now deals correctly with a null dbg  on
+	DW_DLA_ERROR  due to failed
+	dwarf_init() call (or due to other error in calling
+	libdwarf that results in libdwarf not knowing the dbg,
+	a likely far more common case) and frees the memory.
+	This used to result in chaos (depending on your
+	luck...).
+
+2000 Aug 23  davea@sgi.com
+  libdwarf2.1.mm, ps.  Failed to mention that dwarf_finish()
+  has to be accompanied by elf_end() if dwarf_init() was used
+  to initialize libdwarf to truly release all stuff.
+  Added text to dwarf_finish() describing how to do that.
+2000 April 14  davea@sgi.com
+
+  dwarf_abbrev.c - 1.22
+        - When it is a null abbrev entry, return it correctly so it can be
+          printed (meaning fill out all the return-parameters so the caller can
+          do the right thing).
+
+  dwarf_init_finish.c - 1.48
+        - For most sections, simply having an empty section (present but empty)
+          is just fine. There is no reason to register an error in such a case.
+
+  Copyright has changed. See LIBDWARFCOPYRIGHT and NEWS
+
+  dwarfdump/print_die.c - 1.42
+        - Explain what combo checker is doing and make it more maintainable (and          fix bug which would not be hit, but was real enough).
+
+  dwarfdump/tag_tree.list - 1.2
+        - Add valid parent/child relationships so checker does not report valid
+          entries as bogus.
+
+  dwarf_form.c - 1.26
+        - Correct dwarf reader to use appropriate size, not de_length_size. This          is part of the handling of the new dwarf2 64bit facilities. I
+          overlooked this small aspect before in one place
+  dwarf_query.c - 1.48
+        - Use correct size, not de_length_size. For offset size.
+  libdwarf2.1.mm - 1.41
+        - Tried to make frame register output args meaning clearer
+  libdwarf2.1.ps - 1.19
+        - Tried to make frame register output args meaning clearer
+  pro_forms.c - 1.33
+        - Get ref4, not ref8 when generating 32bit dwarf per original dwarf2
+          spec. even if pointer size is 64 bits.
+  pro_init.c - 1.18
+        - Get ref4, not ref8 when generating 32bit dwarf per original dwarf2
+          spec. even if pointer size is 64 bits.
+
+
+davea@sgi.com
+
+
+2000 March 7
+dwarf_line.c - 1.48
+dwarf_line.h - 1.16
+dwarf_print_lines.c - 1.10
+dwarf_sort_line.c - 1.8
+        - Now handles opcode_base of line section to be other than that at
+          compile time of libdwarf.
+Important as the dwarf2 committee is adding a new standard opcode  
+davea@sgi.com
+
+2000 Feb 24
+pro_forms.c  1.31 ar_next field not always zeroed before.
+Could lead to infinite loop in the producer code.
+Now the field is always zeroed.
+
+Makefile.in - 1.3 Jason Merrill <jason@cygnus.com>  
+ provided fix so gcc will work on libdwarf
+print_sections.c - 1.54 - casts to avoid warnings
+
+davea@sgi.com
+
+
+1999 Dec 14
+acconfig.h - 1.3
+config.h.in - 1.5
+configure - 1.4
+configure.in - 1.5
+        - HAVE_DWARF2_99_EXTENSION HAVE_OLD_DWARF2_32BIT_OFFSET
+          refinements added.
+CHANGES - 1.3
+Makefile.base - 1.98
+NEWS - 1.5
+config.h - 1.4
+config.h.in - 1.4
+configure.in - 1.4
+dwarf_alloc.c - 1.36
+dwarf_arange.c - 1.19
+dwarf_arange.h - 1.6
+dwarf_die_deliv.c - 1.51
+dwarf_frame.c - 1.62
+dwarf_frame.h - 1.23
+dwarf_funcs.c - 1.10
+dwarf_funcs.h - 1.3
+dwarf_global.c - 1.21
+dwarf_global.h - 1.7
+dwarf_init_finish.c - 1.45
+dwarf_line.c - 1.44
+dwarf_opaque.h - 1.52
+dwarf_print_lines.c - 1.8
+dwarf_query.c - 1.45
+dwarf_types.c - 1.10
+dwarf_types.h - 1.3
+dwarf_util.c - 1.40
+dwarf_util.h - 1.22
+dwarf_vars.c - 1.11
+dwarf_vars.h - 1.3
+dwarf_weaks.c - 1.10
+dwarf_weaks.h - 1.3
+libdwarf2.1.mm - 1.40
+libdwarf2.1.ps - 1.18
+pro_arange.c - 1.15
+pro_die.c - 1.23
+pro_frame.c - 1.29
+pro_init.c - 1.15
+pro_macinfo.c - 1.7
+pro_opaque.h - 1.14
+pro_pubnames.c - 1.18
+pro_reloc_stream.c - 1.5
+pro_section.c - 1.70
+pro_section.h - 1.16
+pro_types.c - 1.12
+        - Allowing generation of correct dwarf2 with the 1999 64bit dwarf
+          extension, and reading all forms of dwarf2 compatibly (all 32/64bit
+          dwarf2 section  forms).
+
+This adds the ability to consume and produce both sgi 64bit
+and the new dwarf2 committee-approved 64bit dwarf extension.
+As a result of the new dwarf2 stuff , a producer (compiler)
+can mix 32 and 64bit dwarf (for a 64bit object) and the
+linker will work seamlessly.  (as long as section sizes don't
+get over 2GBytes).
+
+And the producer is easily configured to produce mips/sgi style
+64bit dwarf or the new form of 64bit dwarf.
+
+This also eliminates a fair amount of rather silly duplicated code.
+davea@sgi.com
+
+
+1999 Nov 4
+
+pro_section.c - 1.69
+        - A pointer size entity had an offset-size value used at one place.
+davea@sgi.com
+
+1999 Sep 30
+dwarf_arange.c - 1.18
+        - Changed // comment to /* */.  // failed to compile 
+          with C89 compiler...
+davea@sgi.com
+
+
+1999 Sep 29
+Changed all the producer code
+substantially to allow generating assembler code
+for the dwarf2 (rather similar to what gcc does)
+allowing symbolic relocations.
+MIPS output still generates the binary form.
+davea@sgi.com
+
+
+
+1999 Aug 20
+Stan Shebs (shebs@cygnus.com) pointed out that the pro_util.h
+use of R_MIPS* was a problem compiling on Sun.
+Since the producer code is not really used at present except for
+MIPS/sgi, I've added #ifndefs to pro_util.h which provide zero values
+when <elf.h> does not provide the macros.
+When anyone needs the producer code to actually *work* for non-MIPS
+something better will have to be done.
+
+This has no effect on those simply compiling libdwarf for 
+use by dwarfdump.
+davea@sgi.com
+
+1999 July 21
+Changed the READ_UNALAGNED macro to call a function
+depending on endianness of the host and the object being read.
+So all the dwarf_* source changed in a trivial way.
+Added support for printing egcs eh_frame section.
+Added a local memcpy-like function to do the cross-endian
+thing where applicable (called by READ_UNALIGNED macro). 
+Because the .eh_frame section 
+after linking can have some zeroed out bytes at the
+end of the CIE/FDE data the code looking for CIEs and FDEs
+now assumes a zero CIE/FDE length means it has reached
+the end of the CIE/FDE data.
+davea@sgi.com
+
+
+1999 June 14
+  Fred Fish fnf@ninemoons.com contributed
+  autoconf'ing of the libdwarf and dwarfdump source.  
+  
+
+  mips_extensions.*  Documented additional old errors
+  in the Dwarf Version 2 spec.
+
+  The ChangeLog before this is incomplete. 
+
+-------------------------------------------------------------
+Since Oct 95 and before May, 1996 davea@sgi.com David Anderson
+
+Added the function dwarf_get_cie_of_fde() which makes it possible
+to remember a single fde/cie set out of a block usefully.
+
+Enhanced doc of dwarf_bitoffset()
+
+Added new function dwarf_global_formref() so all reference
+forms can be retrieved.
+
+Fixed bug in retrieving array bounds: was failing to sign extend
+formsdata.
+
+Added function dwarf_get_fde_info_for_all_regs(), which makes
+retrieval of the complete set of registers (as needed by
+debuggers and exception handlers) effectively N times faster
+than getting them one a time where N is the number of registers.
+
+Added support for exception table handling (really just support
+for a reference to an exception table for c++ exceptions).
+
+Fixed a bug where useless extra space (several megabytes)
+were malloc'ed for the abbreviations table by the libdwarf
+consumer code.
+
+-------------------------------------------------------------
+June 10, 1999
+ Changelog started.
+-------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/LGPL.txt	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,504 @@
+		  GNU LESSER GENERAL PUBLIC LICENSE
+		       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+		  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/LIBDWARFCOPYRIGHT	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,30 @@
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/Makefile.in	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,194 @@
+#
+#
+#  Copyright (C) 2000,2003,2004,2006 Silicon Graphics, Inc.  All Rights Reserved.
+#
+#  This program is free software; you can redistribute it and/or modify it
+#  under the terms of version 2.1 of the GNU Lesser General Public License 
+#  as published by the Free Software Foundation.
+#
+#  This program is distributed in the hope that it would be useful, but
+#  WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+#
+#  Further, this software is distributed without any warranty that it is
+#  free of the rightful claim of any third person regarding infringement 
+#  or the like.  Any license provided herein, whether implied or 
+#  otherwise, applies only to this software file.  Patent licenses, if
+#  any, provided herein do not apply to combinations of this program with 
+#  other software, or any other product whatsoever.  
+#
+#  You should have received a copy of the GNU Lesser General Public 
+#  License along with this program; if not, write the Free Software 
+#  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+#  USA.
+
+#
+#  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+#  Mountain View, CA 94043, or:
+#
+#  http://www.sgi.com
+#
+#  For further information regarding this notice, see:
+#
+#  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+#
+#
+
+#
+#  Makefile for libdwarf
+#  This is made very simple so it should work with
+#  any 'make'.
+#
+
+srcdir =	@srcdir@
+VPATH =		@srcdir@
+
+prefix =	@prefix@
+exec_prefix =	@exec_prefix@
+bindir =	$(exec_prefix)/bin
+libdir =	$(exec_prefix)/lib
+
+INSTALL =	@INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_DATA =	@INSTALL_DATA@
+SHELL =		/bin/sh
+CC =		@CC@
+AR =		@AR@
+#ARFLAGS =	@ARFLAGS@
+RM =		rm
+RANLIB =	@RANLIB@
+DEFS =		@DEFS@
+LIBS =		@LIBS@
+INCLUDES =	-I. -I$(srcdir)
+CFLAGS =	@CFLAGS@ $(INCLUDES)
+# For more checking add -DWANT_LIBBDWARF_MALLOC_CHECK=1 to CFLAGS
+LDFLAGS =	@LDFLAGS@
+
+
+BUILD_BASE = .
+
+OBJS= dwarf_abbrev.o \
+        dwarf_alloc.o \
+        dwarf_arange.o \
+        dwarf_die_deliv.o \
+        dwarf_error.o \
+        dwarf_form.o \
+        dwarf_frame.o \
+        dwarf_frame2.o \
+        dwarf_frame3.o \
+        dwarf_funcs.o \
+        dwarf_global.o \
+        dwarf_init_finish.o  \
+        dwarf_line.o \
+        dwarf_line2.o \
+        dwarf_loc.o \
+        dwarf_query.o \
+        dwarf_string.o \
+        dwarf_stubs.o \
+        dwarf_pubtypes.o \
+        dwarf_types.o \
+        dwarf_util.o \
+        dwarf_leb.o \
+        dwarf_vars.o \
+        dwarf_weaks.o    \
+        dwarf_addr_finder.o \
+	dwarf_sort_line.o \
+	dwarf_print_lines.o \
+	dwarf_macro.o \
+	malloc_check.o \
+        pro_alloc.o \
+        pro_arange.o \
+        pro_die.o \
+	pro_encode_nm.o \
+        pro_error.o \
+        pro_expr.o \
+        pro_finish.o \
+        pro_forms.o \
+        pro_funcs.o \
+        pro_frame.o \
+        pro_init.o \
+        pro_line.o \
+        pro_reloc.o \
+        pro_reloc_stream.o \
+        pro_reloc_symbolic.o \
+        pro_pubnames.o \
+        pro_section.o \
+        pro_types.o \
+        pro_vars.o \
+	pro_macinfo.o \
+        pro_weaks.o
+        
+
+all: @build_shared@ @build_nonshared@
+
+libdwarf.a:	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS) 
+
+libdwarf.so:	$(OBJS)
+	$(CC) $(CFLAGS) -shared $(OBJS) -o $@
+
+none:
+	echo "do nothing"
+
+#
+# The following are very SGI-centric
+# psroff is just a troff formatter.
+# the .mm files are in ATT/USL/USG mm form.
+#
+
+docbld:pdfbld 
+pdfbld: libdwarf2.1.pdf libdwarf2p.1.pdf dwarf.v2.pdf index.v2.pdf mips_extensions.pdf
+#Oriented to using gsroff now.
+TROFF=/usr/bin/groff
+TROFFDEV="-T ps"
+TROFFDEV=
+PSTOPDF=/usr/bin/ps2pdf
+# pr expands tabs to spaces: this avoids problems with tab
+# interpretation
+
+# The warning about 'cant break line' is a too-long line used
+# in the table of contents.
+# Ignore the warning (and those like it).
+libdwarf2.1.pdf:  $(BUILD_BASE)/libdwarf2.1.mm
+	-pr -t -e $(BUILD_BASE)/libdwarf2.1.mm \
+		  | tbl | $(TROFF) $(TROFFDEV) -mm >libdwarf2.1.ps
+	$(PSTOPDF) libdwarf2.1.ps libdwarf2.1.pdf
+
+libdwarf2p.1.pdf:  $(BUILD_BASE)/libdwarf2p.1.mm
+	-pr -t -e  $(BUILD_BASE)/libdwarf2p.1.mm \
+		  | tbl | $(TROFF) $(TROFFDEV) -mm >libdwarf2p.1.ps
+	$(PSTOPDF) libdwarf2p.1.ps libdwarf2p.1.pdf
+
+# At present, the newIndex is not usable: we have no tools
+# to build a new index page at the moment.
+
+dwarf.v2.pdf:	$(BUILD_BASE)/dwarf.v2.mm
+	-pic $(BUILD_BASE)/dwarf.v2.mm \
+		  | tbl | $(TROFF) $(TROFFDEV) -mm >dwarf.v2.ps 2> newIndex
+	$(PSTOPDF) dwarf.v2.ps dwarf.v2.pdf
+
+# the index is only useful till the document changes: it is
+# not autmatically correct. It was prepared by tools internal
+# to USL/Novell
+
+index.v2.pdf:  index.v2.mm
+	-pic index.v2.mm | tbl | $(TROFF) $(TROFFDEV) -mm >index.v2.ps
+	$(PSTOPDF) index.v2.ps  index.v2.pdf
+
+
+mips_extensions.pdf: mips_extensions.mm
+	-pr $(TROFFDEV) -e mips_extensions.mm | tbl | \
+                 $(TROFF) $(TROFFDEV) -mm >mips_extensions.ps
+	$(PSTOPDF) mips_extensions.ps  mips_extensions.pdf
+
+clean:
+		rm -f *.o libdwarf.a 
+		rm -f libdwarf.so
+
+distclean:	clean
+		rm -f config.status config.log config.cache config.h
+
+shar:
+		@echo "shar not set up yet"
+dist:
+		@echo "dist not set up yet"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/NEWS	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,239 @@
+December 8, 2007
+  Had to add an ugly configure conditional as libelf has
+  unconditional use of off64_t in recent libelf.h
+July 3, 2007
+  A new interface function, dwarf_loclist_from_expr(),
+  allows easy extraction of dwarf expression bytes from
+  expressions in frame data.
+May 8, 2007
+  Now documents released as .mm and .pdf (no longer as .ps).
+May 7, 2007
+  Incorporates Sun Microsystems  extensions to dwarf.h and
+  to the consumer and producer libraries.   The changes
+  include corrections so the producer library  cleans up it's memory
+  use on a call to dwarf_producer_finish(dbg).
+  Thanks to Chris Quenelle of Sun for these contributions.
+
+March 20, 2007
+  nroff/troff and the AT&T -mm package are not widely available,
+  so now the Makefile refers to groff, which works quite nicely.
+
+February 20, 2007
+  Documented libdwarf thread safety in README.
+  Fixed memory leak in  dwarf macro reading code.
+  Removed use of static data in dwarf macro
+  reading code: now uses stack/heap (for
+  thread safety).
+
+February 9, 2007
+  Maintenance of libdwarf is now outside SGI
+  as David Anderson has left SGI.
+
+March 29, 2006
+  The March  27, 2006 version accomodates DWARF3.
+  Some people have been using the library without
+  altering dwarf.h, libdwarf.h to accomodate
+  large numbers of registers.  This exposed a bug
+  (an off-by-one error) but also makes it clear
+  additional documentation is needed.  So 
+  in libdwarf large new comments near 'TARGET DEPENDENCY'
+  attempt to explain better.
+Oct 03, 2005
+  The July version had an incompatible interface: old
+  dealloc code did not always work right. The incompatibility
+  is now fixed and the new features remain.
+
+July 15, 2005
+  New optional alloc-check code optionally checks all
+  allocated memory is freed (malloc_check.h malloc_check.c)
+  Various new dealloc routines written as the previous approach
+  of letting client code do detailed dealloc turned out not
+  to dealloc all memory.
+  To get the new checking you must manually change a line
+  in malloc_check.h and rebuild libdwarf.
+
+
+Mar 31, 2005
+  Documented  the libexc.so/.debug_funcnames
+  dependency and the 64bit-offset DWARF extension in
+  mips_extentions.{mm,ps}.
+
+Mar 21, 2005
+  gcc 3.3 and 3.4 .eh_frame 'z' augmentations are not handled
+  correctly, so libdwarf gives an error when attempting to
+  print such. gcc 2 'eh' augmentation is simpler and
+  prints correctly.  (.eh_frame is a GNU section,
+  not DWARF2/3, and what is recorded in .eh_frame is not
+  specified by DWARF2/3, though .eh_frame does resemble
+  DWARF2/3 .debug_frame).
+
+
+Oct 28, 2004
+  Updated contact address in copyright: SGI moved 1/4 mile
+  in 2003 to a new address: 1500 Crittenden Lane.
+  
+  Documented additional vendor extensions.
+
+Oct 27, 2004
+  Added known vendor extensions to dwarf2/3 to dwarf.h
+  HP, GNU, PGI and UPC extensions are now recorded.
+  Recorded vendor extensions from Concurrent.
+
+Feb 3, 2004
+  If 'Dwarf_Word' is 64 bits, two macros reading leb numbers
+  fail to initialize upper bits of the values read.
+  First noticed with bogus line numbers printing from dwarfdump.
+  Now we use already-existing functions, avoiding the problem.
+
+Oct 02, 2003
+  Support .debug_loc section fully.
+
+Sept 29, 2003
+  Support DW_FORM_indirect properly.
+  Supports loclists in part (but not multiple loclist entries yet).
+  Support 'padding bytes' at end of .debug_arange and
+  .debug_pubnames and .debug_pubtypes per CU
+  (recent dwarf committee email made it clear this is appropriate).
+
+May 23, 2002
+  Libdwarf now asks for sections only when they are
+  used, so that unneeded sections aren't loaded.
+  Support for using SGI's ELF library as an alternative to
+  using AT&T libelf-style has been added (the SGI ELF
+  library is presently only available internally to SGI).
+
+Jan 10, 2002
+  Fixed memory leak in dwarf_finish().
+
+Aug 21, 2001
+  If one called dwarf_add_file_decl()
+  or dwarf_add_directory_decl() but never added a line,
+  .debug_line was not produced.  This was a mistake,
+  as if any file or directory was provided .debug_line
+  should be produced. Now it is produced.
+
+June 14, 2001
+  Given a cu header offset, it was not easy to derive the
+  CU header DIE offset. Created the new
+  function dwarf_get_cu_die_offset_given_cu_header_offset()
+  do get the CU header DIE offset.
+  Added the function dwarf_get_arange_cu_header_offset()
+  so the cu header offset could be retrieved from .debug_aranges
+  information.
+
+June 07, 2001
+  Major bug in dwarf_leb.c decoding large integers 
+  (Dwarf_Signed 64 bit where library is compiled in ILP32) 
+  found and fixed.
+
+May 21, 2001
+  Some small fixes have been found by various folks,
+  so it seems time to prepare a new source release.
+  See ChangeLog for details.
+
+April 15, 2000
+  The libdwarf copyright has changed to
+     version 2.1 of the GNU Lesser General Public License.
+  Anyone holding a version of libdwarf that was published
+  before this new copyright is allowed to use
+    the copyright published in that earlier libdwarf source
+    on the earlier source
+  or to use 
+    this new copyright on the earlier source,
+  at their option.
+
+
+December 08, 1999
+  The dwarf committee has adopted the offset-extension
+  proposal. This allows compatibly emitting
+  dwarf with 64bit offsets.
+
+  The dwarf reader now automatically figures out which is in use.
+  The dwarf writer configures itself at the time the
+  writer initialization routine is called, though
+  the writer is restricted, at libdwarf 
+  compile time, to one of
+		mips/sgi pure 32/pure 64 offsets/pointers.
+
+		32bit offsets only (per dwarf 2.0.0 and cygnus)
+
+		32bit offsets with extension to 64bit offsets
+		allowed (the offset-extension newly passed).
+  
+  In addition, a great deal of duplicate code
+  for the sgi  .debug_weaknames, .debug_funcnames, 
+  .debug_varnames and .debug_typenames sections has
+  been removed: a single set of functions does the real work now.
+  
+Sept 29, 1999
+  Just found out that cygnus is, on 64bit targets, generating
+  32bit offsets (as elf32 has, for example) with 64 bit
+  pointers (in references to text and data).
+  Whereas sgi has always generated 64bit dwarf with
+  64 bit offsets (as in elf64) and 64bit pointers for
+  64bit pointer objects.
+  I'll call the sgi approach 64-bit and the cygnus approach
+  32bit-offsets.
+
+  Cygnus is following the DWARF2 spec as written, so they are
+  right in doing only 32bit-offsets.
+
+  Folks at sgi (including me) think that, as for elf64,
+  the offsets in dwarf for 64bit pointer-apps should be
+  64 bits.  We think it is only a matter of time
+  before we really *need* 64bit offsets and when that happens
+  it will be on an important app.  Disk space is cheap,
+  so lets just go 64 bit on 64bit apps (such as ia64 apps)
+  to avoid a future problem.
+  I(davea@sgi.com) think the 'pointer-size' references in the dwarf
+  spec were really written for 64-bit pointer apps.
+  I don't recall serious consideration of 64bit pointer
+  apps in the committee deliberations (I did miss
+  a couple of meetings) and think 64bit offsets
+  are consistent with dwarf2, even though the speci
+  was not written for such. We think true full 64 bit
+  dwarf2 is the right way to go (the spec changes
+  are obvious: file and section offsets become 64bit
+  with 64bit pointer objects.
+ 
+  MIPS/SGI is definitely 64-bit offsets for 64 bit objects,
+  cygnus is definitely 32bit-offsets for earlier 64bit pointer
+  environments.
+
+  At any rate, now the dwarf reader allows and accomodates
+  both and the dwarf producer also accomodates both.
+  Some tweaking of the pro_init.c or dwarf_init_finish.c
+  files may be necessary in future: no other changes should
+  be needed to accomodate the two 64bit approaches, as
+  the library (and dwarfdump) now deal with both forms.
+
+
+August 20, 1999
+  Added some #ifndef/#define to pro_util.h to let libdwarf build
+  on more hosts.  (since those hosts don't need the producer
+  code, AFAIK, zero values suffice for missing #defines.)
+
+July 21, 1999
+  Now reader transparently reads either-endianness data
+  from an either-endianness object.
+  Updated dwarf.h and libdwarf.h to recognize
+  GNU egcs dwarf extensions and to print the egcs eh_frame
+  section.
+
+June 10, 1999
+  gnu configure version of libdwarf made available for the
+  first time.  
+  Still allows only same-endian-as-host in objects.
+  
+August, 1994
+  libdwarf source made available for ftp on sgigate.sgi.com
+	/ftp/pub
+
+June, 1994
+  Consumer interface changed completely, following
+  "Candy Machine Interfaces" chapter from
+   "Writing Solid Code" by Steve Maguire (Microsoft Press).
+
+April,  1993
+  Initial version of libdwarf  for dwarf version 2
+  written at sgi.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/README	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,136 @@
+To build libdwarf.a, type
+        ./configure
+        make
+
+To use dwarf or libdwarf, you may want to install dwarf.h and
+libdwarf.h somewhere convenient, and you may need the libdwarf
+in the accompanying libdwarf directory
+
+Multi Threading, or using threads with libdwarf (Thread Safety):
+  Nothing in libdwarf does any locking.  Every Dwarf_Debug
+  (such as returned by dwarf_init()) is fully independent
+  of all other Dwarf_Debug-s.  However, calls to libdwarf can
+  change a Dwarf_Debug. So it is unsafe to have two different
+  threads accessing a single Dwarf_Debug simultaneously.
+  It is therefore sufficient to ensure than any one Dwarf_Debug
+  is only accessed from a single thread.
+
+Warnings like
+ "warning: cast from pointer to integer of different size"
+at compile time are to be expected in dwarf_frame.c and
+dwarf_frame2.c.   Do not be alarmed.
+
+If your headers are not in the expected places,
+use the configure script to access them (and to add other ld
+or C flags).
+For example
+        ./configure  CPPFLAGS="-I/home/davea/inc" CFLAGS="-I/home/davea/inc"
+Set both CFLAGS and CPPFLAGS so that configure works properly.
+
+It is now possible to request shared library build with
+	--enable-shared
+(--enable-nonshared is on by default).
+
+TARGET DEPENDENCIES of .debug_frame:
+dwarf.h
+  These should be revised if you have more than the defined
+  63 'normal' registers.  It's not harmful to have these too large!
+  Too small will lead to errors reading .debug_frame and .eh_frame.
+  DW_FRAME_HIGHEST_NORMAL_REGISTER
+  DW_FRAME_LAST_REG_NUM
+
+  These you might revise, but can safely ignore if simply
+  using dwarfdump.  If using the producer code you will want
+  to get these exactly right for your architecture.
+  DW_FRAME_RA_COL
+  DW_FRAME_STATIC_LINK
+  DW_FRAME_CFA_COL
+
+libdwarf.h
+  The DW_FRAME_REG_INITIAL_VALUE #define should be set to
+  the value approprate to your archtecture. See libdwarf.h
+  for details.
+
+  If DW_REG_TABLE_SIZE is not set large enough attempts to 
+  fill in the .debug_frame tables will get an error. 
+  Should be at least as large as DW_FRAME_LAST_REG_NUM.
+  If it's too large nothing is harmed (but some extra space taken
+  at run time).
+
+
+The .debug_frame is so very architecture dependent
+and because the host (where libdwarf/dwarfdump are executed)
+and target (the objects read) could be different.
+It's currently not supported to have dwarfdump/libdwarf determine
+the architecture on-the-fly and do-the-right-thing.
+Just setting DW_FRAME_LAST_REG_NUM and DW_FRAME_HIGHEST_NORMAL_REGISTER
+and DW_REG_TABLE_SIZE high enough will likely suffice for most
+purposes and most compilers/architectures..
+See comments in dwarf.h/libdwarf.h.
+
+It's perfectly safe to ignore the above suggestions as long
+as libdwarf does not get a DW_DLE_DF_REG_NUM_TOO_HIGH error.
+(which would only happen on reading .debug_frame or .eh_frame data).
+
+If you intend to use the libdwarf dwarf-producer code
+for .debug_frame information
+you must do a thorough analysys and revise dwarf.h
+substantially to match the output target archtecture.
+
+In general, in the producer code, numbers are copied from and
+to integers with memcpy().  In case of endianness problems,
+constants set in dwarf_producer_init() can fix the problems.
+If one wants to produce a *different-endian* output the best
+solution is to change the integer memcpy calls to call thru a
+new dbg-based function pointer and have it 'do the right thing'
+to adjust endianness.  Set the function pointer correctly in
+dwarf_producer_init() and the rest of the code will just call
+thru the function pointer.  Tedious work to find and change the
+memcpy calls to be dbg->de_memcpy(), but once done the code is
+no longer endian dependent (right now there is no way to ask
+for cross-endian: a new flag needed or ?).
+
+leb128 numbers are endian-independent, so nothing need be
+done with those for cross-endian support (the storage
+of leb128 on disk is always little-endian).
+
+The .ps files are postscript. So those who cannot deal with mm
+format files but do have a postscript printer (or have
+ghostscript) can print the documents.  
+This form was chosen before pdf format existed...
+
+libdwarf2.1.ps documents a way for a debugger to read dwarf information.
+libdwarf2p.1.ps documents a way for a compiler to generate dwarf information.
+dwarf.v2.ps documents Dwarf Version 2.
+index.v2.ps is an index to dwarf.v2.ps.
+indexDW.v2  is a plain text index of dwarf #defines to dwarf.v2.ps
+mips_extensions.ps documents the mips/sgi extensions to dwarf.
+
+The commands used to generate the postscript were:
+ pr -t -e libdwarf2.1.mm | tbl | psroff -t -mm >libdwarf2.1.ps
+ pr -t -e  libdwarf2p.1.mm | tbl | psroff -t -mm >libdwarf2p.1.ps
+ pic dwarf.v2.mm | tbl | psroff -t -mm >dwarf.v2.ps 2> newIndex
+ pic index.v2.mm | tbl | psroff -t -mm >index.v2.ps
+
+pic is a picture processing tool (ATT command).
+tbl is a table-processing tool.
+(part of Documentor's Work Bench on ATT-like systems).
+tbl and pic are available on linux.
+
+psroff is a name for a troff-like processor, part of
+Documentor's Work Bench on IRIX. Substitute a
+troff-like or nroff-like processor.
+
+The index.v2.mm was generated by the dwarf-document writer
+using some local ATT/USL tools (which SGI does not have, so
+there is no way I know of to regenerate this).
+
+To use dwarf or libdwarf, you may want to install dwarf.h and
+libdwarf.h somewhere convenient.
+
+You will also need libelf (libelf.a and/or libelf.so) and
+libelf.h installed. These are available from GNU repositories.
+
+$Source: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/libdwarf/RCS/README,v $
+$Revision: 1.10 $
+$Date: 2006/03/30 18:04:52 $
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/bldDWindex.sh	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,24 @@
+sed -n -e '/^%%Page.*/p' -e '/.*DW_.*/p' <dwarf.v2.ps  |
+sed -n  -e '/^%%Page.*/p' -e 's/.*\(DW_[a-z_A-Z]*\).*/\1/p' |
+nawk '  /^%%Page/{ p = $2  } \
+	 /DW_/	{ printf "%-30s  %04d \n",$1,p \
+	}'   | sort  -u  |
+nawk ' BEGIN {h = "xx"}  		\
+         {  				\
+	    done = 0 ; 			\
+            if ( $1 != h ) {     	\
+	 	  if(h != "xx") { 	\
+			printf "%-30s %s\n",h, pgs ; \
+			h = $1 ;	\
+			tv = $2 + 0 ;   \
+			done = 1  ;     \
+			pgs = "" tv 	\
+ 		  }		 	\
+	     }				\
+	     h = $1 ;                   \
+	     if(done == 0 ) {  		\
+		tv = $2 + 0 ;           \
+		pgs = pgs ", "  tv      \
+	     }    			\
+	  } 				\
+          END { printf "%-30s %s\n",h,pgs }  '  
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/cmplrs/dwarf_addr_finder.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,55 @@
+/*
+   dwarf_addr_finder.h
+   $Source: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/include/cmplrs/RCS/dwarf_addr_finder.h,v $
+   $Date: 2002/06/11 17:49:06 $
+
+   Defines user interface.
+
+*/
+
+/* return codes for functions
+*/
+#define DW_DLV_NO_ENTRY -1
+#define DW_DLV_OK        0
+#define DW_DLV_ERROR     1
+
+
+/* the following are the 'section' number passed to the called-back
+   function.
+   The called-back application must translate this to the 
+   appropriate elf section number/pointer.
+
+   Putting this burden on the application avoids having to store
+   the numbers in the Dwarf_Debug structure (thereby saving space
+   for most consumers).
+*/
+#define DW_SECTION_INFO      0
+#define DW_SECTION_FRAME     1
+#define DW_SECTION_ARANGES   2
+#define DW_SECTION_LINE      3
+#define DW_SECTION_LOC       4  /* .debug_loc */
+
+/* section is one of the above codes: it specifies a section.
+   secoff is the offset in the dwarf section.
+   existingAddr is the value at the specified offset (so the
+	called back routine can sanity check the proceedings).
+   It's up to the caller to know the size of an address (4 or 8)
+   and update the right number of bytes.
+*/
+typedef int (*Dwarf_addr_callback_func)   (int /*section*/, 
+        Dwarf_Off /*secoff*/, Dwarf_Addr /*existingAddr*/);
+
+/* call this to do the work: it calls back thru cb_func
+   once per each address to be modified.
+   Once this returns you are done.
+   Returns DW_DLV_OK if finished ok.
+   Returns DW_DLV_ERROR if there was some kind of error, in which
+	the dwarf error number was passed back thu the dwerr ptr.
+   Returns DW_DLV_NO_ENTRY if there are no relevant dwarf sections,
+	so there were no addresses to be modified (and none
+	called back).
+*/
+int _dwarf_addr_finder(dwarf_elf_handle elf_file_ptr,
+                Dwarf_addr_callback_func cb_func,
+                int *dwerr);
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/config.guess	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1504 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
+#   Inc.
+
+timestamp='2006-11-15'
+
+# This file 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    sh5el) machine=sh5le-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit ;;
+    *:OpenBSD:*:*)
+	UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+	echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+	exit ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit ;;
+    *:SolidBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+	exit ;;
+    macppc:MirBSD:*:*)
+	echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit ;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit ;;
+    arm:riscos:*:*|arm:RISCOS:*:*)
+	echo arm-unknown-riscos
+	exit ;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit ;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7; exit ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c &&
+	  dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+	  SYSTEM_NAME=`$dummy $dummyarg` &&
+	    { echo "$SYSTEM_NAME"; exit; }
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix     # uname -m gives an 8 hex-code CPU id
+	exit ;;               # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+		then
+			echo "$SYSTEM_NAME"
+		else
+			echo rs6000-ibm-aix3.2.5
+		fi
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit ;;                             # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    eval $set_cc_for_build
+
+	    # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+	    # 32-bit code.  hppa64-hp-hpux* has the same kernel and a compiler
+	    # generating 64-bit code.  GNU and HP use different nomenclature:
+	    #
+	    # $ CC_FOR_BUILD=cc ./config.guess
+	    # => hppa2.0w-hp-hpux11.23
+	    # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+	    # => hppa64-hp-hpux11.23
+
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+		grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+		{ echo "$SYSTEM_NAME"; exit; }
+	echo unknown-hitachi-hiuxwe2
+	exit ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit ;;
+    *:FreeBSD:*:*)
+	case ${UNAME_MACHINE} in
+	    pc98)
+		echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    amd64)
+		echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	    *)
+		echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+	esac
+	exit ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit ;;
+    i*:windows32*:*)
+    	# uname -m includes "-pc" on this system.
+    	echo ${UNAME_MACHINE}-mingw32
+	exit ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit ;;
+    x86:Interix*:[3456]*)
+	echo i586-pc-interix${UNAME_RELEASE}
+	exit ;;
+    EM64T:Interix*:[3456]* | authenticamd:Interix*:[3456]*)
+	echo x86_64-unknown-interix${UNAME_RELEASE}
+	exit ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit ;;
+    amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    avr32*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-gnu
+	exit ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^CPU/{
+		s: ::g
+		p
+	    }'`"
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^CPU/{
+		s: ::g
+		p
+	    }'`"
+	test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+	;;
+    or32:Linux:*:*)
+	echo or32-unknown-linux-gnu
+	exit ;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit ;;
+    vax:Linux:*:*)
+	echo ${UNAME_MACHINE}-dec-linux-gnu
+	exit ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC)
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n '
+	    /^LIBC/{
+		s: ::g
+		p
+	    }'`"
+	test x"${LIBC}" != x && {
+		echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+		exit
+	}
+	test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; }
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit ;;
+    i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit ;;
+    i*86:*:5:[678]*)
+    	# UnixWare 7.x, OpenUNIX and OpenServer 6.
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && { echo i486-ncr-sysv4; exit; } ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit ;;
+    i*86:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo ${UNAME_MACHINE}-stratus-vos
+	exit ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit ;;
+    SX-8:SUPER-UX:*:*)
+	echo sx8-nec-superux${UNAME_RELEASE}
+	exit ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms ; exit ;;
+	    I*) echo ia64-dec-vms ; exit ;;
+	    V*) echo vax-dec-vms ; exit ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit ;;
+    i*86:skyos:*:*)
+	echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+	exit ;;
+    i*86:rdos:*:*)
+	echo ${UNAME_MACHINE}-pc-rdos
+	exit ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix\n"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
+	{ echo "$SYSTEM_NAME"; exit; }
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit ;;
+    c34*)
+	echo c34-convex-bsd
+	exit ;;
+    c38*)
+	echo c38-convex-bsd
+	exit ;;
+    c4*)
+	echo c4-convex-bsd
+	exit ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+and
+  http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/config.h.in	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,109 @@
+/* config.h.in.  Generated from configure.in by autoheader.  */
+
+/* Define to 1 if you have the <alloca.h> header file. */
+#undef HAVE_ALLOCA_H
+
+/* Define 1 if want producer to build with 32/64bit section offsets per dwarf3
+   */
+#undef HAVE_DWARF2_99_EXTENSION
+
+/* Define to 1 if the elf64_getehdr function is in libelf.a. */
+#undef HAVE_ELF64_GETEHDR
+
+/* Define to 1 if the elf64_getshdr function is in libelf.a. */
+#undef HAVE_ELF64_GETSHDR
+
+/* Define to 1 if you have the <elfaccess.h> header file. */
+#undef HAVE_ELFACCESS_H
+
+/* Define to 1 if you have the <elf.h> header file. */
+#undef HAVE_ELF_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <libelf.h> header file. */
+#undef HAVE_LIBELF_H
+
+/* Define to 1 if you have the <libelf/libelf.h> header file. */
+#undef HAVE_LIBELF_LIBELF_H
+
+/* Define 1 if off64 is defined via libelf with GNU_SOURCE. */
+#undef HAVE_LIBELF_OFF64_OK
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define 1 if want producer to build with only 32bit section offsets per
+   strict dwarf2 */
+#undef HAVE_OLD_DWARF2_32BIT_OFFSET
+
+/* Define 1 if plain libelf builds. */
+#undef HAVE_RAW_LIBELF_OK
+
+/* Define 1 if R_IA_64_DIR32LSB is defined (might be enum value). */
+#undef HAVE_R_IA_64_DIR32LSB
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/ia64/elf.h> header file. */
+#undef HAVE_SYS_IA64_ELF_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* See if __uint32_t is predefined in the compiler. */
+#undef HAVE___UINT32_T
+
+/* Define 1 if __uint32_t is in sgidefs.h. */
+#undef HAVE___UINT32_T_IN_SGIDEFS_H
+
+/* Define 1 if sys/types.h defines __uint32_t. */
+#undef HAVE___UINT32_T_IN_SYS_TYPES_H
+
+/* See if __uint64_t is predefined in the compiler. */
+#undef HAVE___UINT64_T
+
+/* Define 1 if is in sgidefs.h. */
+#undef HAVE___UINT64_T_IN_SGIDEFS_H
+
+/* Define 1 if sys/types.h defines __uint64_t. */
+#undef HAVE___UINT64_T_IN_SYS_TYPES_H
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if your processor stores words with the most significant byte
+   first (like Motorola and SPARC, unlike Intel and VAX). */
+#undef WORDS_BIGENDIAN
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/config.sub	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1619 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
+#   Inc.
+
+timestamp='2006-11-07'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit ;;
+    --version | -v )
+       echo "$version" ; exit ;;
+    --help | --h* | -h )
+       echo "$usage"; exit ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit ;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
+  uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
+  storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco6)
+		os=-sco5v6
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco5v6*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+	| bfin \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| m32c | m32r | m32rle | m68000 | m68k | m88k \
+	| maxq | mb | microblaze | mcore \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mips64vr5900 | mips64vr5900el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| mt \
+	| msp430 \
+	| nios | nios2 \
+	| ns16k | ns32k \
+	| or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| score \
+	| sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+	| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+	| spu | strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+	ms1)
+		basic_machine=mt-unknown
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* | avr32-* \
+	| bfin-* | bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| m32c-* | m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mips64vr5900-* | mips64vr5900el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| mt-* \
+	| msp430-* \
+	| nios-* | nios2-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+	| sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16c)
+		basic_machine=cr16c-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	ms1-*)
+		basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	openrisc | openrisc-*)
+		basic_machine=or32-unknown
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pc98)
+		basic_machine=i386-pc
+		;;
+	pc98-*)
+		basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rdos)
+		basic_machine=i386-pc
+		os=-rdos
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sde)
+		basic_machine=mipsisa32-sde
+		os=-elf
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh5el)
+		basic_machine=sh5le-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+	      | -openbsd* | -solidbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
+	      | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+	      | -skyos* | -haiku* | -rdos* | -toppers*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+        score-*)
+		os=-elf
+		;;
+        spu-*)
+		os=-elf
+		;;
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+        c4x-* | tic4x-*)
+        	os=-coff
+		;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-haiku)
+		os=-haiku
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/configure	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,5247 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="libdwarf.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# if HAVE_STDLIB_H
+#  include <stdlib.h>
+# endif
+#endif
+#if HAVE_STRING_H
+# if !STDC_HEADERS && HAVE_MEMORY_H
+#  include <memory.h>
+# endif
+# include <string.h>
+#endif
+#if HAVE_STRINGS_H
+# include <strings.h>
+#endif
+#if HAVE_INTTYPES_H
+# include <inttypes.h>
+#else
+# if HAVE_STDINT_H
+#  include <stdint.h>
+# endif
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA RANLIB ac_ct_RANLIB AR ac_ct_AR build_shared build_nonshared LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+	      localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$0" : 'X\(//\)[^/]' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+ac_env_CC_set=${CC+set}
+ac_env_CC_value=$CC
+ac_cv_env_CC_set=${CC+set}
+ac_cv_env_CC_value=$CC
+ac_env_CFLAGS_set=${CFLAGS+set}
+ac_env_CFLAGS_value=$CFLAGS
+ac_cv_env_CFLAGS_set=${CFLAGS+set}
+ac_cv_env_CFLAGS_value=$CFLAGS
+ac_env_LDFLAGS_set=${LDFLAGS+set}
+ac_env_LDFLAGS_value=$LDFLAGS
+ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
+ac_cv_env_LDFLAGS_value=$LDFLAGS
+ac_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_env_CPPFLAGS_value=$CPPFLAGS
+ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
+ac_cv_env_CPPFLAGS_value=$CPPFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+			  [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+			  [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Optional Features:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-shared         build shared library libdwarf.so (default is NO)
+  --enable-nonshared      build archive library libdwarf.a (default is YES)
+
+Some influential environment variables:
+  CC          C compiler command
+  CFLAGS      C compiler flags
+  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
+              nonstandard directory <lib dir>
+  CPPFLAGS    C/C++ preprocessor flags, e.g. -I<include dir> if you have
+              headers in a nonstandard directory <include dir>
+  CPP         C preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+	   test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+	"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=$`echo $ac_var`
+	echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+	       sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+	ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+          ac_config_headers="$ac_config_headers config.h"
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="gcc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="${ac_tool_prefix}cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+  ac_ct_CC=$CC
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  CC=$ac_ct_CC
+else
+  CC="$ac_cv_prog_CC"
+fi
+
+fi
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+       ac_prog_rejected=yes
+       continue
+     fi
+    ac_cv_prog_CC="cc"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# != 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+  fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$CC"; then
+  if test -n "$ac_tool_prefix"; then
+  for ac_prog in cl
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+  echo "$as_me:$LINENO: result: $CC" >&5
+echo "${ECHO_T}$CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+    test -n "$CC" && break
+  done
+fi
+if test -z "$CC"; then
+  ac_ct_CC=$CC
+  for ac_prog in cl
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_CC"; then
+  ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_CC="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+  echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
+echo "${ECHO_T}$ac_ct_CC" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  test -n "$ac_ct_CC" && break
+done
+
+  CC=$ac_ct_CC
+fi
+
+fi
+
+
+test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&5
+echo "$as_me: error: no acceptable C compiler found in \$PATH
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+
+# Provide some information about the compiler.
+echo "$as_me:$LINENO:" \
+     "checking for C compiler version" >&5
+ac_compiler=`set X $ac_compile; echo $2`
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
+  (eval $ac_compiler --version </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
+  (eval $ac_compiler -v </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
+  (eval $ac_compiler -V </dev/null >&5) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.exe b.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
+echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
+ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
+  (eval $ac_link_default) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # Find the output, starting from the most likely.  This scheme is
+# not robust to junk in `.', hence go to wildcards (a.*) only as a last
+# resort.
+
+# Be careful to initialize this variable, since it used to be cached.
+# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
+ac_cv_exeext=
+# b.out is created by i960 compilers.
+for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
+	;;
+    conftest.$ac_ext )
+	# This is the source file.
+	;;
+    [ab].out )
+	# We found the default executable, but exeext='' is most
+	# certainly right.
+	break;;
+    *.* )
+	ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	# FIXME: I believe we export ac_cv_exeext for Libtool,
+	# but it would be cool to find out if it's true.  Does anybody
+	# maintain Libtool? --akim.
+	export ac_cv_exeext
+	break;;
+    * )
+	break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
+See \`config.log' for more details." >&5
+echo "$as_me: error: C compiler cannot create executables
+See \`config.log' for more details." >&2;}
+   { (exit 77); exit 77; }; }
+fi
+
+ac_exeext=$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_file" >&5
+echo "${ECHO_T}$ac_file" >&6
+
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether the C compiler works" >&5
+echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
+# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+  if { ac_try='./$ac_file'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { echo "$as_me:$LINENO: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+  fi
+fi
+echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6
+
+rm -f a.out a.exe conftest$ac_cv_exeext b.out
+ac_clean_files=$ac_clean_files_save
+# Check the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
+echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
+echo "$as_me:$LINENO: result: $cross_compiling" >&5
+echo "${ECHO_T}$cross_compiling" >&6
+
+echo "$as_me:$LINENO: checking for suffix of executables" >&5
+echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'.  For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+  test -f "$ac_file" || continue
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+    *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+	  export ac_cv_exeext
+	  break;;
+    * ) break;;
+  esac
+done
+else
+  { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest$ac_cv_exeext
+echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
+echo "${ECHO_T}$ac_cv_exeext" >&6
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+echo "$as_me:$LINENO: checking for suffix of object files" >&5
+echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
+if test "${ac_cv_objext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+  case $ac_file in
+    *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+    *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+       break;;
+  esac
+done
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&5
+echo "$as_me: error: cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
+echo "${ECHO_T}$ac_cv_objext" >&6
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
+echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
+if test "${ac_cv_c_compiler_gnu+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+#ifndef __GNUC__
+       choke me
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_compiler_gnu=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_compiler_gnu=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
+echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
+GCC=`test $ac_compiler_gnu = yes && echo yes`
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+CFLAGS="-g"
+echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
+echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_g+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_g=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_prog_cc_g=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
+echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
+if test "${ac_cv_prog_cc_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_prog_cc_stdc=no
+ac_save_CC=$CC
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+     char **p;
+     int i;
+{
+  return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+  char *s;
+  va_list v;
+  va_start (v,p);
+  s = g (p, va_arg (v,int));
+  va_end (v);
+  return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default.  It has
+   function prototypes and stuff, but not '\xHH' hex character constants.
+   These don't provoke an error unfortunately, instead are silently treated
+   as 'x'.  The following induces an error, until -std1 is added to get
+   proper ANSI mode.  Curiously '\x00'!='x' always comes out true, for an
+   array size at least.  It's necessary to write '\x00'==0 to get something
+   that's true only with -std1.  */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0]  ||  f (e, argv, 1) != argv[1];
+  ;
+  return 0;
+}
+_ACEOF
+# Don't try gcc -ansi; that turns off useful extensions and
+# breaks some systems' header files.
+# AIX			-qlanglvl=ansi
+# Ultrix and OSF/1	-std1
+# HP-UX 10.20 and later	-Ae
+# HP-UX older versions	-Aa -D_HPUX_SOURCE
+# SVR4			-Xc -D__EXTENSIONS__
+for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+  CC="$ac_save_CC $ac_arg"
+  rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_prog_cc_stdc=$ac_arg
+break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext
+done
+rm -f conftest.$ac_ext conftest.$ac_objext
+CC=$ac_save_CC
+
+fi
+
+case "x$ac_cv_prog_cc_stdc" in
+  x|xno)
+    echo "$as_me:$LINENO: result: none needed" >&5
+echo "${ECHO_T}none needed" >&6 ;;
+  *)
+    echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
+echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
+    CC="$CC $ac_cv_prog_cc_stdc" ;;
+esac
+
+# Some people use a C++ compiler to compile C.  Since we use `exit',
+# in C++ we need to declare it.  In case someone uses the same compiler
+# for both compiling C and C++ we need to have the C++ compiler decide
+# the declaration of exit, since it's the most demanding environment.
+cat >conftest.$ac_ext <<_ACEOF
+#ifndef __cplusplus
+  choke me
+#endif
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  for ac_declaration in \
+   '' \
+   'extern "C" void std::exit (int) throw (); using std::exit;' \
+   'extern "C" void std::exit (int); using std::exit;' \
+   'extern "C" void exit (int) throw ();' \
+   'extern "C" void exit (int);' \
+   'void exit (int);'
+do
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+#include <stdlib.h>
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+continue
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_declaration
+int
+main ()
+{
+exit (42);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  break
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+done
+rm -f conftest*
+if test -n "$ac_declaration"; then
+  echo '#ifdef __cplusplus' >>confdefs.h
+  echo $ac_declaration      >>confdefs.h
+  echo '#endif'             >>confdefs.h
+fi
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
+echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
+if test "${ac_cv_c_bigendian+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  # See if sys/param.h defines the BYTE_ORDER macro.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  # It does; now see whether it defined to BIG_ENDIAN or not.
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+#include <sys/param.h>
+
+int
+main ()
+{
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_c_bigendian=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+# It does not; compile a test program.
+if test "$cross_compiling" = yes; then
+  # try to guess the endianness by grepping values into an object file
+  ac_cv_c_bigendian=unknown
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
+short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+int
+main ()
+{
+ _ascii (); _ebcdic ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+  ac_cv_c_bigendian=yes
+fi
+if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+  if test "$ac_cv_c_bigendian" = unknown; then
+    ac_cv_c_bigendian=no
+  else
+    # finding both strings is unlikely to happen, but who knows?
+    ac_cv_c_bigendian=unknown
+  fi
+fi
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+int
+main ()
+{
+  /* Are we little or big endian?  From Harbison&Steele.  */
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+  u.l = 1;
+  exit (u.c[sizeof (long) - 1] == 1);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_c_bigendian=no
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_c_bigendian=yes
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
+echo "${ECHO_T}$ac_cv_c_bigendian" >&6
+case $ac_cv_c_bigendian in
+  yes)
+
+cat >>confdefs.h <<\_ACEOF
+#define WORDS_BIGENDIAN 1
+_ACEOF
+ ;;
+  no)
+     ;;
+  *)
+    { { echo "$as_me:$LINENO: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&5
+echo "$as_me: error: unknown endianness
+presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
+   { (exit 1); exit 1; }; } ;;
+esac
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+  if test "${ac_cv_prog_CPP+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+      # Double quotes because CPP needs to be expanded
+    for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+    do
+      ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  break
+fi
+
+    done
+    ac_cv_prog_CPP=$CPP
+
+fi
+  CPP=$ac_cv_prog_CPP
+else
+  ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+  # Use a header file that comes with gcc, so configuring glibc
+  # with a fresh cross-compiler works.
+  # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+  # <limits.h> exists even on freestanding compilers.
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp. "Syntax error" is here to catch this case.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+		     Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  :
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+  # OK, works on sane cases.  Now check whether non-existent headers
+  # can be detected and how.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  # Broken: success on invalid input.
+continue
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+  :
+else
+  { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+    then ac_cv_prog_egrep='grep -E'
+    else ac_cv_prog_egrep='egrep'
+    fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+if test $ac_cv_c_compiler_gnu = yes; then
+    echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5
+echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6
+if test "${ac_cv_prog_gcc_traditional+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+    ac_pattern="Autoconf.*'x'"
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sgtty.h>
+Autoconf TIOCGETP
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "$ac_pattern" >/dev/null 2>&1; then
+  ac_cv_prog_gcc_traditional=yes
+else
+  ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+  if test $ac_cv_prog_gcc_traditional = no; then
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <termio.h>
+Autoconf TCGETA
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "$ac_pattern" >/dev/null 2>&1; then
+  ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+  fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5
+echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6
+  if test $ac_cv_prog_gcc_traditional = yes; then
+    CC="$CC -traditional"
+  fi
+fi
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f $ac_dir/shtool; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&5
+echo "$as_me: error: cannot find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+ac_config_guess="$SHELL $ac_aux_dir/config.guess"
+ac_config_sub="$SHELL $ac_aux_dir/config.sub"
+ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure.
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5
+echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in
+  ./ | .// | /cC/* | \
+  /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+  ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \
+  /usr/ucb/* ) ;;
+  *)
+    # OSF1 and SCO ODT 3.0 have their own names for install.
+    # Don't use installbsd from OSF since it installs stuff as root
+    # by default.
+    for ac_prog in ginstall scoinst install; do
+      for ac_exec_ext in '' $ac_executable_extensions; do
+	if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
+	  if test $ac_prog = install &&
+	    grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  elif test $ac_prog = install &&
+	    grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+	    # program-specific install script used by HP pwplus--don't use.
+	    :
+	  else
+	    ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+	    break 3
+	  fi
+	fi
+      done
+    done
+    ;;
+esac
+done
+
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL=$ac_cv_path_install
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL=$ac_install_sh
+  fi
+fi
+echo "$as_me:$LINENO: result: $INSTALL" >&5
+echo "${ECHO_T}$INSTALL" >&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+  echo "$as_me:$LINENO: result: $RANLIB" >&5
+echo "${ECHO_T}$RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+  ac_ct_RANLIB=$RANLIB
+  # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_RANLIB"; then
+  ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_RANLIB="ranlib"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+  test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
+fi
+fi
+ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+  echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
+echo "${ECHO_T}$ac_ct_RANLIB" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  RANLIB=$ac_ct_RANLIB
+else
+  RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="${ac_tool_prefix}ar"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  echo "$as_me:$LINENO: result: $AR" >&5
+echo "${ECHO_T}$AR" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+  ac_ct_AR=$AR
+  # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_ac_ct_AR+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="ar"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+
+fi
+fi
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
+echo "${ECHO_T}$ac_ct_AR" >&6
+else
+  echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+  AR=$ac_ct_AR
+else
+  AR="$ac_cv_prog_AR"
+fi
+
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_header_stdc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "memchr" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "free" >/dev/null 2>&1; then
+  :
+else
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+		   (('a' <= (c) && (c) <= 'i') \
+		     || ('j' <= (c) && (c) <= 'r') \
+		     || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+  int i;
+  for (i = 0; i < 256; i++)
+    if (XOR (islower (i), ISLOWER (i))
+	|| toupper (i) != TOUPPER (i))
+      exit(2);
+  exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  :
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+		  inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  eval "$as_ac_Header=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+
+
+
+
+for ac_header in alloca.h elf.h elfaccess.h libelf.h libelf/libelf.h  sys/types.h sys/ia64/elf.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+    ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+    (
+      cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists.  ##
+## ------------------------------------------ ##
+_ASBOX
+    ) |
+      sed "s/^/$as_me: WARNING:     /" >&2
+    ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+echo "$as_me:$LINENO: checking for elf64_getehdr in -lelf" >&5
+echo $ECHO_N "checking for elf64_getehdr in -lelf... $ECHO_C" >&6
+if test "${ac_cv_lib_elf_elf64_getehdr+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lelf  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char elf64_getehdr ();
+int
+main ()
+{
+elf64_getehdr ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_elf_elf64_getehdr=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_elf_elf64_getehdr=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_elf_elf64_getehdr" >&5
+echo "${ECHO_T}$ac_cv_lib_elf_elf64_getehdr" >&6
+if test $ac_cv_lib_elf_elf64_getehdr = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ELF64_GETEHDR 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for elf64_getshdr in -lelf" >&5
+echo $ECHO_N "checking for elf64_getshdr in -lelf... $ECHO_C" >&6
+if test "${ac_cv_lib_elf_elf64_getshdr+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lelf  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char elf64_getshdr ();
+int
+main ()
+{
+elf64_getshdr ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_elf_elf64_getshdr=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_elf_elf64_getshdr=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_elf_elf64_getshdr" >&5
+echo "${ECHO_T}$ac_cv_lib_elf_elf64_getshdr" >&6
+if test $ac_cv_lib_elf_elf64_getshdr = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ELF64_GETSHDR 1
+_ACEOF
+
+fi
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+__uint32_t p; p = 3;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE___UINT32_T 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+__uint64_t p; p = 3;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE___UINT64_T 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+int
+main ()
+{
+  __uint32_t p; p = 3;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE___UINT32_T_IN_SYS_TYPES_H 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sys/types.h>
+int
+main ()
+{
+  __uint64_t p; p = 3;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE___UINT64_T_IN_SYS_TYPES_H 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <elf.h>
+int
+main ()
+{
+  int p; p = R_IA_64_DIR32LSB;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_R_IA_64_DIR32LSB 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#include <libelf.h>
+
+int
+main ()
+{
+  int p; p = 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_RAW_LIBELF_OK 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#define _GNU_SOURCE
+#include <libelf.h>
+
+int
+main ()
+{
+  off64_t  p; p = 0;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LIBELF_OFF64_OK 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sgidefs.h>
+int
+main ()
+{
+  __uint32_t p; p = 27;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE___UINT32_T_IN_SGIDEFS_H 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sgidefs.h>
+int
+main ()
+{
+  __uint64_t p; p = 27;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE___UINT64_T_IN_SGIDEFS_H 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <sgidefs.h>
+int
+main ()
+{
+  __uint64_t p; p = 27;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE___UINT64_T_IN_SGIDEFS_H 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+build_nonshared=libdwarf.a
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+   build_shared=libdwarf.so
+
+else
+    build_shared=none
+
+fi;
+# Check whether --enable-nonshared or --disable-nonshared was given.
+if test "${enable_nonshared+set}" = set; then
+  enableval="$enable_nonshared"
+   build_nonshared=libdwarf.a
+
+		 build_nonshared=none
+
+fi;
+
+
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <elf.h>
+int
+main ()
+{
+  int p; p = R_IA_64_DIR32LSB;
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+	 { ac_try='test -z "$ac_c_werror_flag"
+			 || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+	 { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_OLD_DWARF2_32BIT_OFFSET 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DWARF2_99_EXTENSION 1
+_ACEOF
+
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+          ac_config_files="$ac_config_files Makefile"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[	 ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[	 ]*$//;
+}'
+fi
+
+DEFS=-DHAVE_CONFIG_H
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+	 sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+		   instantiate the configuration file FILE
+  --header=FILE[:TEMPLATE]
+		   instantiate the configuration header FILE
+
+Configuration files:
+$config_files
+
+Configuration headers:
+$config_headers
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+INSTALL="$INSTALL"
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "config.h" ) CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+  test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@CC@,$CC,;t t
+s,@CFLAGS@,$CFLAGS,;t t
+s,@LDFLAGS@,$LDFLAGS,;t t
+s,@CPPFLAGS@,$CPPFLAGS,;t t
+s,@ac_ct_CC@,$ac_ct_CC,;t t
+s,@EXEEXT@,$EXEEXT,;t t
+s,@OBJEXT@,$OBJEXT,;t t
+s,@CPP@,$CPP,;t t
+s,@EGREP@,$EGREP,;t t
+s,@INSTALL_PROGRAM@,$INSTALL_PROGRAM,;t t
+s,@INSTALL_SCRIPT@,$INSTALL_SCRIPT,;t t
+s,@INSTALL_DATA@,$INSTALL_DATA,;t t
+s,@RANLIB@,$RANLIB,;t t
+s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
+s,@AR@,$AR,;t t
+s,@ac_ct_AR@,$ac_ct_AR,;t t
+s,@build_shared@,$build_shared,;t t
+s,@build_nonshared@,$build_nonshared,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+  case $INSTALL in
+  [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+  *) ac_INSTALL=$ac_top_builddir$INSTALL ;;
+  esac
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+				     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+s,@INSTALL@,$ac_INSTALL,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+#
+# CONFIG_HEADER section.
+#
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s,^\([	 ]*\)#\([	 ]*define[	 ][	 ]*\)'
+ac_dB='[	 ].*$,\1#\2'
+ac_dC=' '
+ac_dD=',;t'
+# ac_u turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_uA='s,^\([	 ]*\)#\([	 ]*\)undef\([	 ][	 ]*\)'
+ac_uB='$,\1#\2define\3'
+ac_uC=' '
+ac_uD=',;t'
+
+for ac_file in : $CONFIG_HEADERS; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  test x"$ac_file" != x- && { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 # Do quote $f, to prevent DOS paths from being IFS'd.
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+  # Remove the trailing spaces.
+  sed 's/[	 ]*$//' $ac_file_inputs >$tmp/in
+
+_ACEOF
+
+# Transform confdefs.h into two sed scripts, `conftest.defines' and
+# `conftest.undefs', that substitutes the proper values into
+# config.h.in to produce config.h.  The first handles `#define'
+# templates, and the second `#undef' templates.
+# And first: Protect against being on the right side of a sed subst in
+# config.status.  Protect against being in an unquoted here document
+# in config.status.
+rm -f conftest.defines conftest.undefs
+# Using a here document instead of a string reduces the quoting nightmare.
+# Putting comments in sed scripts is not portable.
+#
+# `end' is used to avoid that the second main sed command (meant for
+# 0-ary CPP macros) applies to n-ary macro definitions.
+# See the Autoconf documentation for `clear'.
+cat >confdef2sed.sed <<\_ACEOF
+s/[\\&,]/\\&/g
+s,[\\$`],\\&,g
+t clear
+: clear
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*\)\(([^)]*)\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1\2${ac_dC}\3${ac_dD},gp
+t end
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\)$,${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD},gp
+: end
+_ACEOF
+# If some macros were called several times there might be several times
+# the same #defines, which is useless.  Nevertheless, we may not want to
+# sort them, since we want the *last* AC-DEFINE to be honored.
+uniq confdefs.h | sed -n -f confdef2sed.sed >conftest.defines
+sed 's/ac_d/ac_u/g' conftest.defines >conftest.undefs
+rm -f confdef2sed.sed
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >>conftest.undefs <<\_ACEOF
+s,^[	 ]*#[	 ]*undef[	 ][	 ]*[a-zA-Z_][a-zA-Z_0-9]*,/* & */,
+_ACEOF
+
+# Break up conftest.defines because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #define templates only if necessary.' >>$CONFIG_STATUS
+echo '  if grep "^[	 ]*#[	 ]*define" $tmp/in >/dev/null; then' >>$CONFIG_STATUS
+echo '  # If there are no defines, we may have an empty if/fi' >>$CONFIG_STATUS
+echo '  :' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.defines >/dev/null
+do
+  # Write a limited-size here document to $tmp/defines.sed.
+  echo '  cat >$tmp/defines.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#define' lines.
+  echo '/^[	 ]*#[	 ]*define/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.defines >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/defines.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.defines >conftest.tail
+  rm -f conftest.defines
+  mv conftest.tail conftest.defines
+done
+rm -f conftest.defines
+echo '  fi # grep' >>$CONFIG_STATUS
+echo >>$CONFIG_STATUS
+
+# Break up conftest.undefs because some shells have a limit on the size
+# of here documents, and old seds have small limits too (100 cmds).
+echo '  # Handle all the #undef templates' >>$CONFIG_STATUS
+rm -f conftest.tail
+while grep . conftest.undefs >/dev/null
+do
+  # Write a limited-size here document to $tmp/undefs.sed.
+  echo '  cat >$tmp/undefs.sed <<CEOF' >>$CONFIG_STATUS
+  # Speed up: don't consider the non `#undef'
+  echo '/^[	 ]*#[	 ]*undef/!b' >>$CONFIG_STATUS
+  # Work around the forget-to-reset-the-flag bug.
+  echo 't clr' >>$CONFIG_STATUS
+  echo ': clr' >>$CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.undefs >>$CONFIG_STATUS
+  echo 'CEOF
+  sed -f $tmp/undefs.sed $tmp/in >$tmp/out
+  rm -f $tmp/in
+  mv $tmp/out $tmp/in
+' >>$CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.undefs >conftest.tail
+  rm -f conftest.undefs
+  mv conftest.tail conftest.undefs
+done
+rm -f conftest.undefs
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    echo "/* Generated by configure.  */" >$tmp/config.h
+  else
+    echo "/* $ac_file.  Generated by configure.  */" >$tmp/config.h
+  fi
+  cat $tmp/in >>$tmp/config.h
+  rm -f $tmp/in
+  if test x"$ac_file" != x-; then
+    if diff $ac_file $tmp/config.h >/dev/null 2>&1; then
+      { echo "$as_me:$LINENO: $ac_file is unchanged" >&5
+echo "$as_me: $ac_file is unchanged" >&6;}
+    else
+      ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+      { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+      rm -f $ac_file
+      mv $tmp/config.h $ac_file
+    fi
+  else
+    cat $tmp/config.h
+    rm -f $tmp/config.h
+  fi
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/configure.in	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,85 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(libdwarf.h)
+AC_CONFIG_HEADER(config.h)
+
+AC_PROG_CC
+AC_C_BIGENDIAN
+AC_GCC_TRADITIONAL
+AC_PROG_INSTALL
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+AC_CHECK_TOOL(AR, ar)
+
+dnl AC_ARFLAGS
+
+AC_CHECK_HEADERS(alloca.h elf.h elfaccess.h libelf.h libelf/libelf.h  sys/types.h sys/ia64/elf.h)
+
+AC_CHECK_LIB(elf,elf64_getehdr,
+  AC_DEFINE(HAVE_ELF64_GETEHDR,1,
+	[Define to 1 if the elf64_getehdr function is in libelf.a.]))
+AC_CHECK_LIB(elf,elf64_getshdr,
+  AC_DEFINE(HAVE_ELF64_GETSHDR,1,
+	[Define to 1 if the elf64_getshdr function is in libelf.a.]))
+AC_TRY_COMPILE( ,  __uint32_t p; p = 3; ,AC_DEFINE(HAVE___UINT32_T,1,
+	[See if __uint32_t is predefined in the compiler.]))
+AC_TRY_COMPILE( ,  __uint64_t p; p = 3; ,AC_DEFINE(HAVE___UINT64_T,1,
+	[See if __uint64_t is predefined in the compiler.]))
+AC_TRY_COMPILE([#include <sys/types.h>],[  __uint32_t p; p = 3;] ,
+  AC_DEFINE(HAVE___UINT32_T_IN_SYS_TYPES_H,1,
+	[Define 1 if sys/types.h defines __uint32_t.]))
+AC_TRY_COMPILE([#include <sys/types.h>],[  __uint64_t p; p = 3;] ,
+  AC_DEFINE(HAVE___UINT64_T_IN_SYS_TYPES_H,1,
+	[Define 1 if sys/types.h defines __uint64_t.]))
+dnl checking for ia 64 types, which might be enums, using HAVE_R_IA_64_DIR32LSB
+dnl to stand in for a small set.
+AC_TRY_COMPILE([#include <elf.h>],[  int p; p = R_IA_64_DIR32LSB;] ,
+  AC_DEFINE(HAVE_R_IA_64_DIR32LSB,1,
+	[Define 1 if  R_IA_64_DIR32LSB is defined (might be enum value).]))
+
+AC_TRY_COMPILE([
+#include <libelf.h>
+],[  int p; p = 0; ] ,
+  AC_DEFINE(HAVE_RAW_LIBELF_OK,1,
+	[Define 1 if plain libelf builds.]))
+AC_TRY_COMPILE([
+#define _GNU_SOURCE
+#include <libelf.h>
+],[  off64_t  p; p = 0;] ,
+  AC_DEFINE(HAVE_LIBELF_OFF64_OK,1,
+	[Define 1 if  off64 is defined via libelf with GNU_SOURCE.]))
+
+dnl the existence of sgidefs.h does not prove it's truly SGI, nor
+dnl prove that __uint32_t or __uint64_t is defined therein.
+AC_TRY_COMPILE([#include <sgidefs.h>],[  __uint32_t p; p = 27;] ,
+  AC_DEFINE(HAVE___UINT32_T_IN_SGIDEFS_H,1,
+        [Define 1 if __uint32_t is in sgidefs.h.])) 
+AC_TRY_COMPILE([#include <sgidefs.h>],[  __uint64_t p; p = 27;] ,
+  AC_DEFINE(HAVE___UINT64_T_IN_SGIDEFS_H,1,
+        [Define 1 if __uint64_t is in sgidefs.h.])) 
+AC_TRY_COMPILE([#include <sgidefs.h>],[  __uint64_t p; p = 27;] ,
+  AC_DEFINE(HAVE___UINT64_T_IN_SGIDEFS_H,1,
+        [Define 1 if  is in sgidefs.h.])) 
+
+AC_SUBST(build_shared,[])
+AC_SUBST(build_nonshared,[libdwarf.a])
+AC_ARG_ENABLE(shared,AC_HELP_STRING([--enable-shared],
+		[build shared library libdwarf.so (default is NO)]),
+		[ AC_SUBST(build_shared,[libdwarf.so]) ],
+		[  AC_SUBST(build_shared,[none]) ])
+AC_ARG_ENABLE(nonshared,AC_HELP_STRING([--enable-nonshared],
+		[build archive library libdwarf.a (default is YES)]),
+		[ AC_SUBST(build_nonshared,[libdwarf.a]) ]
+		[ AC_SUBST(build_nonshared,[none]) ])
+
+
+dnl Just assume, if old ia64 R_IA_64_DIR32LSB name present, 
+dnl compatibility with cygnus before
+dnl HAVE_DWARF2_99_EXTENSION defined.
+dnl Only applies to producer code, as consumer adapts itself.
+dnl This is not the right test, really.
+AC_TRY_COMPILE([#include <elf.h>],[  int p; p = R_IA_64_DIR32LSB;] ,
+  AC_DEFINE(HAVE_OLD_DWARF2_32BIT_OFFSET,1,
+	[Define 1 if want producer to build with only 32bit section offsets per strict dwarf2] ),
+  AC_DEFINE(HAVE_DWARF2_99_EXTENSION,1,
+	[Define 1 if want producer to build with 32/64bit section offsets per dwarf3] )) 
+
+AC_OUTPUT(Makefile)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1012 @@
+/*
+  Copyright (C) 2000,2001,2003,2004,2005,2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002,2007 Sun Microsystems, Inc. All rights reserved.
+  Portions Copyright 2007 David Anderson. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+#ifndef __DWARF_H
+#define __DWARF_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+        dwarf.h   DWARF  debugging information values
+        $Revision: 1.41 $    $Date: 2006/04/17 00:09:56 $
+
+        The comment "DWARF3" appears where there are
+        new entries from DWARF3 as of 2004, "DWARF3f"
+        where there are new entries as of the November 2005
+        public review document and other comments apply
+        where extension entries appear.
+
+        Extensions part of DWARF4 are marked DWARF4.
+
+        A few extension names have omitted the 'vendor id'
+        (See chapter 7, "Vendor Extensibility"). Please
+        always use a 'vendor id' string in extension names.
+
+        Vendors should use a vendor string in names and
+        whereever possible avoid duplicating values used by
+        other vendor extensions
+
+*/
+
+
+#define DW_TAG_array_type               0x01
+#define DW_TAG_class_type               0x02
+#define DW_TAG_entry_point              0x03
+#define DW_TAG_enumeration_type         0x04
+#define DW_TAG_formal_parameter         0x05
+#define DW_TAG_imported_declaration     0x08
+#define DW_TAG_label                    0x0a
+#define DW_TAG_lexical_block            0x0b
+#define DW_TAG_member                   0x0d
+#define DW_TAG_pointer_type             0x0f
+#define DW_TAG_reference_type           0x10
+#define DW_TAG_compile_unit             0x11
+#define DW_TAG_string_type              0x12
+#define DW_TAG_structure_type           0x13
+#define DW_TAG_subroutine_type          0x15
+#define DW_TAG_typedef                  0x16
+#define DW_TAG_union_type               0x17
+#define DW_TAG_unspecified_parameters   0x18
+#define DW_TAG_variant                  0x19
+#define DW_TAG_common_block             0x1a
+#define DW_TAG_common_inclusion         0x1b
+#define DW_TAG_inheritance              0x1c
+#define DW_TAG_inlined_subroutine       0x1d
+#define DW_TAG_module                   0x1e
+#define DW_TAG_ptr_to_member_type       0x1f
+#define DW_TAG_set_type                 0x20
+#define DW_TAG_subrange_type            0x21
+#define DW_TAG_with_stmt                0x22
+#define DW_TAG_access_declaration       0x23
+#define DW_TAG_base_type                0x24
+#define DW_TAG_catch_block              0x25
+#define DW_TAG_const_type               0x26
+#define DW_TAG_constant                 0x27
+#define DW_TAG_enumerator               0x28
+#define DW_TAG_file_type                0x29
+#define DW_TAG_friend                   0x2a
+#define DW_TAG_namelist                 0x2b
+        /* Early releases of this header had the following
+           misspelled with a trailing 's' */
+#define DW_TAG_namelist_item            0x2c /* DWARF3/2 spelling */
+#define DW_TAG_namelist_items           0x2c /* SGI misspelling/typo */
+#define DW_TAG_packed_type              0x2d
+#define DW_TAG_subprogram               0x2e
+        /* The DWARF2 document had two spellings of the following
+           two TAGs, DWARF3 specifies the longer spelling. */
+#define DW_TAG_template_type_parameter  0x2f /* DWARF3/2 spelling*/
+#define DW_TAG_template_type_param      0x2f /* DWARF2   spelling*/
+#define DW_TAG_template_value_parameter 0x30 /* DWARF3/2 spelling*/
+#define DW_TAG_template_value_param     0x30 /* DWARF2   spelling*/
+#define DW_TAG_thrown_type              0x31
+#define DW_TAG_try_block                0x32
+#define DW_TAG_variant_part             0x33
+#define DW_TAG_variable                 0x34
+#define DW_TAG_volatile_type            0x35
+#define DW_TAG_dwarf_procedure          0x36  /* DWARF3 */
+#define DW_TAG_restrict_type            0x37  /* DWARF3 */
+#define DW_TAG_interface_type           0x38  /* DWARF3 */
+#define DW_TAG_namespace                0x39  /* DWARF3 */
+#define DW_TAG_imported_module          0x3a  /* DWARF3 */
+#define DW_TAG_unspecified_type         0x3b  /* DWARF3 */
+#define DW_TAG_partial_unit             0x3c  /* DWARF3 */
+#define DW_TAG_imported_unit            0x3d  /* DWARF3 */
+				 /* Do not use DW_TAG_mutable_type */
+#define DW_TAG_mutable_type 0x3e /* Withdrawn from DWARF3 by DWARF3f. */
+#define DW_TAG_condition                0x3f  /* DWARF3f */
+#define DW_TAG_shared_type              0x40  /* DWARF3f */
+#define DW_TAG_lo_user                  0x4080
+
+#define DW_TAG_MIPS_loop                0x4081
+
+/* HP extensions: ftp://ftp.hp.com/pub/lang/tools/WDB/wdb-4.0.tar.gz  */
+#define DW_TAG_HP_array_descriptor      0x4090 /* HP */
+
+/* GNU extensions.  The first 3 missing the GNU_. */
+#define DW_TAG_format_label             0x4101 /* GNU. Fortran. */
+#define DW_TAG_function_template        0x4102 /* GNU. For C++ */
+#define DW_TAG_class_template           0x4103 /* GNU. For C++ */
+#define DW_TAG_GNU_BINCL                0x4104 /* GNU */
+#define DW_TAG_GNU_EINCL                0x4105 /* GNU */
+
+/* ALTIUM extensions */
+	/* DSP-C/Starcore __circ qualifier */
+#define DW_TAG_ALTIUM_circ_type         0x5101 /* ALTIUM */
+	/* Starcore __mwa_circ qualifier */ 
+#define DW_TAG_ALTIUM_mwa_circ_type     0x5102 /* ALTIUM */
+	/* Starcore __rev_carry qualifier */
+#define DW_TAG_ALTIUM_rev_carry_type    0x5103 /* ALTIUM */
+	/* M16 __rom qualifier */
+#define DW_TAG_ALTIUM_rom               0x5111 /* ALTIUM */
+
+/* The following 3 are extensions to support UPC */
+#define DW_TAG_upc_shared_type          0x8765 /* UPC */
+#define DW_TAG_upc_strict_type          0x8766 /* UPC */
+#define DW_TAG_upc_relaxed_type         0x8767 /* UPC */
+
+/* PGI (STMicroelectronics) extensions. */
+#define DW_TAG_PGI_kanji_type           0xa000 /* PGI */
+#define DW_TAG_PGI_interface_block      0xa020 /* PGI */
+/* The following are SUN extensions */
+#define DW_TAG_SUN_function_template	0x4201 /* SUN */
+#define DW_TAG_SUN_class_template	0x4202 /* SUN */
+#define DW_TAG_SUN_struct_template	0x4203 /* SUN */
+#define DW_TAG_SUN_union_template	0x4204 /* SUN */
+#define DW_TAG_SUN_indirect_inheritance	0x4205 /* SUN */
+#define DW_TAG_SUN_codeflags            0x4206 /* SUN */
+#define DW_TAG_SUN_memop_info           0x4207 /* SUN */
+#define DW_TAG_SUN_omp_child_func       0x4208 /* SUN */
+#define DW_TAG_SUN_rtti_descriptor	0x4209 /* SUN */
+#define	DW_TAG_SUN_dtor_info		0x420a /* SUN */
+#define	DW_TAG_SUN_dtor			0x420b /* SUN */
+#define	DW_TAG_SUN_f90_interface	0x420c /* SUN */
+#define DW_TAG_SUN_fortran_vax_structure 0x420d /* SUN */
+#define	DW_TAG_SUN_hi	        	0x42ff /* SUN */
+    
+
+#define DW_TAG_hi_user                  0xffff
+
+#define DW_children_no                  0
+#define DW_children_yes                 1
+
+
+
+#define DW_FORM_addr                    0x01
+#define DW_FORM_block2                  0x03
+#define DW_FORM_block4                  0x04
+#define DW_FORM_data2                   0x05
+#define DW_FORM_data4                   0x06
+#define DW_FORM_data8                   0x07
+#define DW_FORM_string                  0x08
+#define DW_FORM_block                   0x09
+#define DW_FORM_block1                  0x0a
+#define DW_FORM_data1                   0x0b
+#define DW_FORM_flag                    0x0c
+#define DW_FORM_sdata                   0x0d
+#define DW_FORM_strp                    0x0e
+#define DW_FORM_udata                   0x0f
+#define DW_FORM_ref_addr                0x10
+#define DW_FORM_ref1                    0x11
+#define DW_FORM_ref2                    0x12
+#define DW_FORM_ref4                    0x13
+#define DW_FORM_ref8                    0x14
+#define DW_FORM_ref_udata               0x15
+#define DW_FORM_indirect                0x16
+
+#define DW_AT_sibling                           0x01
+#define DW_AT_location                          0x02
+#define DW_AT_name                              0x03
+#define DW_AT_ordering                          0x09
+#define DW_AT_subscr_data                       0x0a
+#define DW_AT_byte_size                         0x0b
+#define DW_AT_bit_offset                        0x0c
+#define DW_AT_bit_size                          0x0d
+#define DW_AT_element_list                      0x0f
+#define DW_AT_stmt_list                         0x10
+#define DW_AT_low_pc                            0x11
+#define DW_AT_high_pc                           0x12
+#define DW_AT_language                          0x13
+#define DW_AT_member                            0x14
+#define DW_AT_discr                             0x15
+#define DW_AT_discr_value                       0x16
+#define DW_AT_visibility                        0x17
+#define DW_AT_import                            0x18
+#define DW_AT_string_length                     0x19
+#define DW_AT_common_reference                  0x1a
+#define DW_AT_comp_dir                          0x1b
+#define DW_AT_const_value                       0x1c
+#define DW_AT_containing_type                   0x1d
+#define DW_AT_default_value                     0x1e
+#define DW_AT_inline                            0x20
+#define DW_AT_is_optional                       0x21
+#define DW_AT_lower_bound                       0x22
+#define DW_AT_producer                          0x25
+#define DW_AT_prototyped                        0x27
+#define DW_AT_return_addr                       0x2a
+#define DW_AT_start_scope                       0x2c
+#define DW_AT_bit_stride                        0x2e /* DWARF3 name */
+#define DW_AT_stride_size                       0x2e /* DWARF2 name */
+#define DW_AT_upper_bound                       0x2f
+#define DW_AT_abstract_origin                   0x31
+#define DW_AT_accessibility                     0x32
+#define DW_AT_address_class                     0x33
+#define DW_AT_artificial                        0x34
+#define DW_AT_base_types                        0x35
+#define DW_AT_calling_convention                0x36
+#define DW_AT_count                             0x37
+#define DW_AT_data_member_location              0x38
+#define DW_AT_decl_column                       0x39
+#define DW_AT_decl_file                         0x3a
+#define DW_AT_decl_line                         0x3b
+#define DW_AT_declaration                       0x3c
+#define DW_AT_discr_list                        0x3d
+#define DW_AT_encoding                          0x3e
+#define DW_AT_external                          0x3f
+#define DW_AT_frame_base                        0x40
+#define DW_AT_friend                            0x41
+#define DW_AT_identifier_case                   0x42
+#define DW_AT_macro_info                        0x43
+#define DW_AT_namelist_item                     0x44
+#define DW_AT_priority                          0x45
+#define DW_AT_segment                           0x46
+#define DW_AT_specification                     0x47
+#define DW_AT_static_link                       0x48
+#define DW_AT_type                              0x49
+#define DW_AT_use_location                      0x4a
+#define DW_AT_variable_parameter                0x4b
+#define DW_AT_virtuality                        0x4c
+#define DW_AT_vtable_elem_location              0x4d
+#define DW_AT_allocated                         0x4e /* DWARF3 */
+#define DW_AT_associated                        0x4f /* DWARF3 */
+#define DW_AT_data_location                     0x50 /* DWARF3 */
+#define DW_AT_byte_stride                       0x51 /* DWARF3f */
+#define DW_AT_stride                            0x51 /* DWARF3 (do not use) */
+#define DW_AT_entry_pc                          0x52 /* DWARF3 */
+#define DW_AT_use_UTF8                          0x53 /* DWARF3 */
+#define DW_AT_extension                         0x54 /* DWARF3 */
+#define DW_AT_ranges                            0x55 /* DWARF3 */
+#define DW_AT_trampoline                        0x56 /* DWARF3 */
+#define DW_AT_call_column                       0x57 /* DWARF3 */
+#define DW_AT_call_file                         0x58 /* DWARF3 */
+#define DW_AT_call_line                         0x59 /* DWARF3 */
+#define DW_AT_description                       0x5a /* DWARF3 */
+#define DW_AT_binary_scale                      0x5b /* DWARF3f */
+#define DW_AT_decimal_scale                     0x5c /* DWARF3f */
+#define DW_AT_small                             0x5d /* DWARF3f */
+#define DW_AT_decimal_sign                      0x5e /* DWARF3f */
+#define DW_AT_digit_count                       0x5f /* DWARF3f */
+#define DW_AT_picture_string                    0x60 /* DWARF3f */
+#define DW_AT_mutable                           0x61 /* DWARF3f */
+#define DW_AT_threads_scaled                    0x62 /* DWARF3f */
+#define DW_AT_explicit                          0x63 /* DWARF3f */
+#define DW_AT_object_pointer                    0x64 /* DWARF3f */
+#define DW_AT_endianity                         0x65 /* DWARF3f */
+#define DW_AT_elemental                         0x66 /* DWARF3f */
+#define DW_AT_pure                              0x67 /* DWARF3f */
+#define DW_AT_recursive                         0x68 /* DWARF3f */
+
+
+/* HP extensions. */
+#define DW_AT_HP_block_index                    0x2000  /* HP */
+
+/* Follows extension so dwarfdump prints the most-likely-useful name. */
+#define DW_AT_lo_user                           0x2000
+
+#define DW_AT_MIPS_fde                          0x2001 /* MIPS/SGI */
+#define DW_AT_MIPS_loop_begin                   0x2002 /* MIPS/SGI */
+#define DW_AT_MIPS_tail_loop_begin              0x2003 /* MIPS/SGI */
+#define DW_AT_MIPS_epilog_begin                 0x2004 /* MIPS/SGI */
+#define DW_AT_MIPS_loop_unroll_factor           0x2005 /* MIPS/SGI */
+#define DW_AT_MIPS_software_pipeline_depth      0x2006 /* MIPS/SGI */
+#define DW_AT_MIPS_linkage_name                 0x2007 /* MIPS/SGI */
+#define DW_AT_MIPS_stride                       0x2008 /* MIPS/SGI */
+#define DW_AT_MIPS_abstract_name                0x2009 /* MIPS/SGI */
+#define DW_AT_MIPS_clone_origin                 0x200a /* MIPS/SGI */
+#define DW_AT_MIPS_has_inlines                  0x200b /* MIPS/SGI */
+#define DW_AT_MIPS_stride_byte                  0x200c /* MIPS/SGI */
+#define DW_AT_MIPS_stride_elem                  0x200d /* MIPS/SGI */
+#define DW_AT_MIPS_ptr_dopetype                 0x200e /* MIPS/SGI */
+#define DW_AT_MIPS_allocatable_dopetype         0x200f /* MIPS/SGI */
+#define DW_AT_MIPS_assumed_shape_dopetype       0x2010 /* MIPS/SGI */
+#define DW_AT_MIPS_assumed_size                 0x2011 /* MIPS/SGI */
+
+/* HP extensions. */
+#define DW_AT_HP_unmodifiable                   0x2001 /* conflict: MIPS */
+#define DW_AT_HP_actuals_stmt_list              0x2010 /* conflict: MIPS */
+#define DW_AT_HP_proc_per_section               0x2011 /* conflict: MIPS */
+#define DW_AT_HP_raw_data_ptr                   0x2012 /* HP */
+#define DW_AT_HP_pass_by_reference              0x2013 /* HP */
+#define DW_AT_HP_opt_level                      0x2014 /* HP */
+#define DW_AT_HP_prof_version_id                0x2015 /* HP */
+#define DW_AT_HP_opt_flags                      0x2016 /* HP */
+#define DW_AT_HP_cold_region_low_pc             0x2017 /* HP */
+#define DW_AT_HP_cold_region_high_pc            0x2018 /* HP */
+#define DW_AT_HP_all_variables_modifiable       0x2019 /* HP */
+#define DW_AT_HP_linkage_name                   0x201a /* HP */
+#define DW_AT_HP_prof_flags                     0x201b /* HP */
+
+
+/* GNU extensions. */
+#define DW_AT_sf_names                          0x2101 /* GNU */
+#define DW_AT_src_info                          0x2102 /* GNU */
+#define DW_AT_mac_info                          0x2103 /* GNU */
+#define DW_AT_src_coords                        0x2104 /* GNU */
+#define DW_AT_body_begin                        0x2105 /* GNU */
+#define DW_AT_body_end                          0x2106 /* GNU */
+#define DW_AT_GNU_vector                        0x2107 /* GNU */
+
+
+/* ALTIUM extension: ALTIUM Compliant location lists (flag) */
+#define DW_AT_ALTIUM_loclist    0x2300          /* ALTIUM  */
+
+/* PGI (STMicroelectronics) extensions. */
+#define DW_AT_PGI_lbase                         0x3a00 /* PGI */
+#define DW_AT_PGI_soffset                       0x3a01 /* PGI */
+#define DW_AT_PGI_lstride                       0x3a02 /* PGI */
+
+
+/* UPC extension */
+#define DW_AT_upc_threads_scaled                0x3210 /* UPC */
+
+/* Sun extensions */
+#define DW_AT_SUN_template			0x2201 /* SUN */
+#define DW_AT_VMS_rtnbeg_pd_address             0x2201 /* VMS */
+#define DW_AT_SUN_alignment			0x2202 /* SUN */
+#define DW_AT_SUN_vtable			0x2203 /* SUN */
+#define DW_AT_SUN_count_guarantee		0x2204 /* SUN */
+#define DW_AT_SUN_command_line			0x2205 /* SUN */
+#define DW_AT_SUN_vbase				0x2206 /* SUN */
+#define DW_AT_SUN_compile_options		0x2207 /* SUN */
+#define DW_AT_SUN_language			0x2208 /* SUN */
+#define DW_AT_SUN_browser_file			0x2209 /* SUN */
+#define DW_AT_SUN_vtable_abi                    0x2210 /* SUN */
+#define DW_AT_SUN_func_offsets                  0x2211 /* SUN */
+#define DW_AT_SUN_cf_kind                       0x2212 /* SUN */
+#define DW_AT_SUN_vtable_index                  0x2213 /* SUN */
+#define DW_AT_SUN_omp_tpriv_addr                0x2214 /* SUN */
+#define DW_AT_SUN_omp_child_func                0x2215 /* SUN */
+#define DW_AT_SUN_func_offset                   0x2216 /* SUN */
+#define DW_AT_SUN_memop_type_ref                0x2217 /* SUN */
+#define DW_AT_SUN_profile_id                    0x2218 /* SUN */
+#define DW_AT_SUN_memop_signature               0x2219 /* SUN */
+#define DW_AT_SUN_obj_dir                       0x2220 /* SUN */
+#define DW_AT_SUN_obj_file                      0x2221 /* SUN */
+#define DW_AT_SUN_original_name                 0x2222 /* SUN */
+#define DW_AT_SUN_hwcprof_signature             0x2223 /* SUN */
+#define DW_AT_SUN_amd64_parmdump                0x2224 /* SUN */
+#define DW_AT_SUN_part_link_name                0x2225 /* SUN */
+#define DW_AT_SUN_link_name                     0x2226 /* SUN */
+#define DW_AT_SUN_pass_with_const		0x2227 /* SUN */
+#define	DW_AT_SUN_return_with_const		0x2228 /* SUN */
+#define DW_AT_SUN_import_by_name                0x2229 /* SUN */
+#define DW_AT_SUN_f90_pointer                   0x222a /* SUN */
+#define DW_AT_SUN_pass_by_ref                   0x222b /* SUN */
+#define DW_AT_SUN_f90_allocatable               0x222c /* SUN */
+#define DW_AT_SUN_f90_assumed_shape_array       0x222d /* SUN */
+#define DW_AT_SUN_c_vla                         0x222e /* SUN */
+#define DW_AT_SUN_return_value_ptr		0x2230 /* SUN */
+#define	DW_AT_SUN_dtor_start          		0x2231 /* SUN */
+#define	DW_AT_SUN_dtor_length          		0x2232 /* SUN */
+#define	DW_AT_SUN_dtor_state_initial  		0x2233 /* SUN */
+#define	DW_AT_SUN_dtor_state_final    		0x2234 /* SUN */
+#define	DW_AT_SUN_dtor_state_deltas   		0x2235 /* SUN */
+#define	DW_AT_SUN_import_by_lname               0x2236 /* SUN */
+#define	DW_AT_SUN_f90_use_only                  0x2237 /* SUN */
+#define DW_AT_SUN_namelist_spec			0x2238 /* SUN */
+#define DW_AT_SUN_is_omp_child_func		0x2239 /* SUN */
+#define DW_AT_SUN_fortran_main_alias		0x223a /* SUN */
+#define DW_AT_SUN_fortran_based                 0x223b /* SUN */
+
+
+#define DW_AT_hi_user                           0x3fff
+
+#define DW_OP_addr                      0x03
+#define DW_OP_deref                     0x06
+#define DW_OP_const1u                   0x08
+#define DW_OP_const1s                   0x09
+#define DW_OP_const2u                   0x0a
+#define DW_OP_const2s                   0x0b
+#define DW_OP_const4u                   0x0c
+#define DW_OP_const4s                   0x0d
+#define DW_OP_const8u                   0x0e
+#define DW_OP_const8s                   0x0f
+#define DW_OP_constu                    0x10
+#define DW_OP_consts                    0x11
+#define DW_OP_dup                       0x12
+#define DW_OP_drop                      0x13
+#define DW_OP_over                      0x14
+#define DW_OP_pick                      0x15
+#define DW_OP_swap                      0x16
+#define DW_OP_rot                       0x17
+#define DW_OP_xderef                    0x18
+#define DW_OP_abs                       0x19
+#define DW_OP_and                       0x1a
+#define DW_OP_div                       0x1b
+#define DW_OP_minus                     0x1c
+#define DW_OP_mod                       0x1d
+#define DW_OP_mul                       0x1e
+#define DW_OP_neg                       0x1f
+#define DW_OP_not                       0x20
+#define DW_OP_or                        0x21
+#define DW_OP_plus                      0x22
+#define DW_OP_plus_uconst               0x23
+#define DW_OP_shl                       0x24
+#define DW_OP_shr                       0x25
+#define DW_OP_shra                      0x26
+#define DW_OP_xor                       0x27
+#define DW_OP_bra                       0x28
+#define DW_OP_eq                        0x29
+#define DW_OP_ge                        0x2a
+#define DW_OP_gt                        0x2b
+#define DW_OP_le                        0x2c
+#define DW_OP_lt                        0x2d
+#define DW_OP_ne                        0x2e
+#define DW_OP_skip                      0x2f
+#define DW_OP_lit0                      0x30
+#define DW_OP_lit1                      0x31
+#define DW_OP_lit2                      0x32
+#define DW_OP_lit3                      0x33
+#define DW_OP_lit4                      0x34
+#define DW_OP_lit5                      0x35
+#define DW_OP_lit6                      0x36
+#define DW_OP_lit7                      0x37
+#define DW_OP_lit8                      0x38
+#define DW_OP_lit9                      0x39
+#define DW_OP_lit10                     0x3a
+#define DW_OP_lit11                     0x3b
+#define DW_OP_lit12                     0x3c
+#define DW_OP_lit13                     0x3d
+#define DW_OP_lit14                     0x3e
+#define DW_OP_lit15                     0x3f
+#define DW_OP_lit16                     0x40
+#define DW_OP_lit17                     0x41
+#define DW_OP_lit18                     0x42
+#define DW_OP_lit19                     0x43
+#define DW_OP_lit20                     0x44
+#define DW_OP_lit21                     0x45
+#define DW_OP_lit22                     0x46
+#define DW_OP_lit23                     0x47
+#define DW_OP_lit24                     0x48
+#define DW_OP_lit25                     0x49
+#define DW_OP_lit26                     0x4a
+#define DW_OP_lit27                     0x4b
+#define DW_OP_lit28                     0x4c
+#define DW_OP_lit29                     0x4d
+#define DW_OP_lit30                     0x4e
+#define DW_OP_lit31                     0x4f
+#define DW_OP_reg0                      0x50
+#define DW_OP_reg1                      0x51
+#define DW_OP_reg2                      0x52
+#define DW_OP_reg3                      0x53
+#define DW_OP_reg4                      0x54
+#define DW_OP_reg5                      0x55
+#define DW_OP_reg6                      0x56
+#define DW_OP_reg7                      0x57
+#define DW_OP_reg8                      0x58
+#define DW_OP_reg9                      0x59
+#define DW_OP_reg10                     0x5a
+#define DW_OP_reg11                     0x5b
+#define DW_OP_reg12                     0x5c
+#define DW_OP_reg13                     0x5d
+#define DW_OP_reg14                     0x5e
+#define DW_OP_reg15                     0x5f
+#define DW_OP_reg16                     0x60
+#define DW_OP_reg17                     0x61
+#define DW_OP_reg18                     0x62
+#define DW_OP_reg19                     0x63
+#define DW_OP_reg20                     0x64
+#define DW_OP_reg21                     0x65
+#define DW_OP_reg22                     0x66
+#define DW_OP_reg23                     0x67
+#define DW_OP_reg24                     0x68
+#define DW_OP_reg25                     0x69
+#define DW_OP_reg26                     0x6a
+#define DW_OP_reg27                     0x6b
+#define DW_OP_reg28                     0x6c
+#define DW_OP_reg29                     0x6d
+#define DW_OP_reg30                     0x6e
+#define DW_OP_reg31                     0x6f
+#define DW_OP_breg0                     0x70
+#define DW_OP_breg1                     0x71
+#define DW_OP_breg2                     0x72
+#define DW_OP_breg3                     0x73
+#define DW_OP_breg4                     0x74
+#define DW_OP_breg5                     0x75
+#define DW_OP_breg6                     0x76
+#define DW_OP_breg7                     0x77
+#define DW_OP_breg8                     0x78
+#define DW_OP_breg9                     0x79
+#define DW_OP_breg10                    0x7a
+#define DW_OP_breg11                    0x7b
+#define DW_OP_breg12                    0x7c
+#define DW_OP_breg13                    0x7d
+#define DW_OP_breg14                    0x7e
+#define DW_OP_breg15                    0x7f
+#define DW_OP_breg16                    0x80
+#define DW_OP_breg17                    0x81
+#define DW_OP_breg18                    0x82
+#define DW_OP_breg19                    0x83
+#define DW_OP_breg20                    0x84
+#define DW_OP_breg21                    0x85
+#define DW_OP_breg22                    0x86
+#define DW_OP_breg23                    0x87
+#define DW_OP_breg24                    0x88
+#define DW_OP_breg25                    0x89
+#define DW_OP_breg26                    0x8a
+#define DW_OP_breg27                    0x8b
+#define DW_OP_breg28                    0x8c
+#define DW_OP_breg29                    0x8d
+#define DW_OP_breg30                    0x8e
+#define DW_OP_breg31                    0x8f
+#define DW_OP_regx                      0x90
+#define DW_OP_fbreg                     0x91
+#define DW_OP_bregx                     0x92
+#define DW_OP_piece                     0x93
+#define DW_OP_deref_size                0x94
+#define DW_OP_xderef_size               0x95
+#define DW_OP_nop                       0x96
+#define DW_OP_push_object_address       0x97 /* DWARF3 */
+#define DW_OP_call2                     0x98 /* DWARF3 */
+#define DW_OP_call4                     0x99 /* DWARF3 */
+#define DW_OP_call_ref                  0x9a /* DWARF3 */
+#define DW_OP_form_tls_address          0x9b /* DWARF3f */
+#define DW_OP_call_frame_cfa            0x9c /* DWARF3f */
+#define DW_OP_bit_piece                 0x9d /* DWARF3f */
+
+
+    /* GNU extensions. */
+#define DW_OP_GNU_push_tls_address      0xe0 /* GNU */
+
+/* Follows extension so dwarfdump prints the most-likely-useful name. */
+#define DW_OP_lo_user                   0xe0
+
+    /* HP extensions. */
+#define DW_OP_HP_unknown                0xe0 /* HP conflict: GNU */
+#define DW_OP_HP_is_value               0xe1 /* HP */
+#define DW_OP_HP_fltconst4              0xe2 /* HP */
+#define DW_OP_HP_fltconst8              0xe3 /* HP */
+#define DW_OP_HP_mod_range              0xe4 /* HP */
+#define DW_OP_HP_unmod_range            0xe5 /* HP */
+#define DW_OP_HP_tls                    0xe6 /* HP */
+
+#define DW_OP_hi_user                   0xff
+
+#define DW_ATE_address                  0x1
+#define DW_ATE_boolean                  0x2
+#define DW_ATE_complex_float            0x3
+#define DW_ATE_float                    0x4
+#define DW_ATE_signed                   0x5
+#define DW_ATE_signed_char              0x6
+#define DW_ATE_unsigned                 0x7
+#define DW_ATE_unsigned_char            0x8
+#define DW_ATE_imaginary_float          0x9  /* DWARF3 */
+#define DW_ATE_packed_decimal           0xa  /* DWARF3f */
+#define DW_ATE_numeric_string           0xb  /* DWARF3f */
+#define DW_ATE_edited                   0xc  /* DWARF3f */
+#define DW_ATE_signed_fixed             0xd  /* DWARF3f */
+#define DW_ATE_unsigned_fixed           0xe  /* DWARF3f */
+#define DW_ATE_decimal_float            0xf  /* DWARF3f */
+
+
+/* ALTIUM extensions. x80, x81 */
+#define DW_ATE_ALTIUM_fract           0x80 /* ALTIUM __fract type */
+
+/* Follows extension so dwarfdump prints the most-likely-useful name. */
+#define DW_ATE_lo_user                  0x80
+
+/* Shown here to help dwarfdump build script. */
+#define DW_ATE_ALTIUM_accum           0x81 /* ALTIUM __accum type */
+
+/* HP Floating point extensions. */
+#define DW_ATE_HP_float80             0x80 /* (80 bit). HP */
+
+
+#define DW_ATE_HP_complex_float80     0x81 /* Complex (80 bit). HP  */
+#define DW_ATE_HP_float128            0x82 /* (128 bit). HP */
+#define DW_ATE_HP_complex_float128    0x83 /* Complex (128 bit). HP */
+#define DW_ATE_HP_floathpintel        0x84 /* (82 bit IA64). HP */
+#define DW_ATE_HP_imaginary_float80   0x85 /* HP */
+#define DW_ATE_HP_imaginary_float128  0x86 /* HP */
+
+/* Sun extensions */
+#define DW_ATE_SUN_interval_float       0x91
+#define DW_ATE_SUN_imaginary_float      0x92 /* Obsolete: See DW_ATE_imaginary_float */
+
+#define DW_ATE_hi_user                  0xff
+
+
+/* Decimal Sign codes. */
+#define DW_DS_unsigned                  0x01 /* DWARF3f */
+#define DW_DS_leading_overpunch         0x02 /* DWARF3f */
+#define DW_DS_trailing_overpunch        0x03 /* DWARF3f */
+#define DW_DS_leading_separate          0x04 /* DWARF3f */
+
+#define DW_DS_trailing_separate         0x05 /* DWARF3f */
+
+/* Endian code name. */
+#define DW_END_default                  0x00 /* DWARF3f */
+#define DW_END_big                      0x01 /* DWARF3f */
+#define DW_END_little                   0x02 /* DWARF3f */
+
+#define DW_END_lo_user                  0x40 /* DWARF3f */
+#define DW_END_hi_user                  0xff /* DWARF3f */
+
+/* for use with DW_TAG_SUN_codeflags
+ * If DW_TAG_SUN_codeflags is accepted as a dwarf standard, then
+ * standard dwarf ATCF entries start at 0x01
+ */
+#define DW_ATCF_lo_user                 0x40 /* SUN */
+#define DW_ATCF_SUN_mop_bitfield        0x41 /* SUN */
+#define DW_ATCF_SUN_mop_spill           0x42 /* SUN */
+#define DW_ATCF_SUN_mop_scopy           0x43 /* SUN */
+#define DW_ATCF_SUN_func_start          0x44 /* SUN */
+#define DW_ATCF_SUN_end_ctors           0x45 /* SUN */
+#define DW_ATCF_SUN_branch_target       0x46 /* SUN */
+#define DW_ATCF_SUN_mop_stack_probe     0x47 /* SUN */
+#define DW_ATCF_SUN_func_epilog         0x48 /* SUN */
+#define DW_ATCF_hi_user                 0xff /* SUN */   
+
+/* Accessibility code name. */
+#define DW_ACCESS_public                0x01
+#define DW_ACCESS_protected             0x02
+#define DW_ACCESS_private               0x03
+
+/* Visibility code name. */
+#define DW_VIS_local                    0x01
+#define DW_VIS_exported                 0x02
+#define DW_VIS_qualified                0x03
+
+/* Virtuality code name. */
+#define DW_VIRTUALITY_none              0x00
+#define DW_VIRTUALITY_virtual           0x01
+#define DW_VIRTUALITY_pure_virtual      0x02
+
+#define DW_LANG_C89                     0x0001
+#define DW_LANG_C                       0x0002
+#define DW_LANG_Ada83                   0x0003
+#define DW_LANG_C_plus_plus             0x0004
+#define DW_LANG_Cobol74                 0x0005
+#define DW_LANG_Cobol85                 0x0006
+#define DW_LANG_Fortran77               0x0007
+#define DW_LANG_Fortran90               0x0008
+#define DW_LANG_Pascal83                0x0009
+#define DW_LANG_Modula2                 0x000a
+#define DW_LANG_Java                    0x000b /* DWARF3 */
+#define DW_LANG_C99                     0x000c /* DWARF3 */
+#define DW_LANG_Ada95                   0x000d /* DWARF3 */
+#define DW_LANG_Fortran95               0x000e /* DWARF3 */
+#define DW_LANG_PLI                     0x000f /* DWARF3 */
+#define DW_LANG_ObjC                    0x0010 /* DWARF3f */
+#define DW_LANG_ObjC_plus_plus          0x0011 /* DWARF3f */
+#define DW_LANG_UPC                     0x0012 /* DWARF3f */
+#define DW_LANG_D                       0x0013 /* DWARF3f */
+#define DW_LANG_lo_user                 0x8000
+#define DW_LANG_Mips_Assembler          0x8001 /* MIPS   */
+#define DW_LANG_Upc                     0x8765 /* UPC, use
+                                        DW_LANG_UPC instead. */
+/* ALTIUM extension */
+#define DW_LANG_ALTIUM_Assembler        0x9101  /* ALTIUM */
+
+/* Sun extensions */
+#define DW_LANG_SUN_Assembler           0x9001 /* SUN */
+
+#define DW_LANG_hi_user                 0xffff
+
+/* Identifier case name. */
+#define DW_ID_case_sensitive            0x00
+#define DW_ID_up_case                   0x01
+#define DW_ID_down_case                 0x02
+#define DW_ID_case_insensitive          0x03
+
+/* Calling Convention Name. */
+#define DW_CC_normal                    0x01
+#define DW_CC_program                   0x02
+#define DW_CC_nocall                    0x03
+#define DW_CC_lo_user                   0x40
+
+/* ALTIUM extensions. */
+/* Function is an interrupt handler, return address on system stack. */
+#define DW_CC_ALTIUM_interrupt          0x65  /* ALTIUM*/
+
+/* Near function model, return address on system stack. */
+#define DW_CC_ALTIUM_near_system_stack  0x66  /*ALTIUM */
+
+/* Near function model, return address on user stack. */
+#define DW_CC_ALTIUM_near_user_stack    0x67  /* ALTIUM */  
+
+/* Huge function model, return address on user stack.  */
+#define DW_CC_ALTIUM_huge_user_stack    0x68  /* ALTIUM */    
+
+
+#define DW_CC_hi_user                   0xff
+
+/* Inline Code Name. */
+#define DW_INL_not_inlined              0x00
+#define DW_INL_inlined                  0x01
+#define DW_INL_declared_not_inlined     0x02
+#define DW_INL_declared_inlined         0x03
+
+/* Ordering Name. */
+#define DW_ORD_row_major                0x00
+#define DW_ORD_col_major                0x01
+
+/* Discriminant Descriptor Name. */
+#define DW_DSC_label                    0x00
+#define DW_DSC_range                    0x01
+
+/* Line number standard opcode name. */
+#define DW_LNS_copy                     0x01
+#define DW_LNS_advance_pc               0x02
+#define DW_LNS_advance_line             0x03
+#define DW_LNS_set_file                 0x04
+#define DW_LNS_set_column               0x05
+#define DW_LNS_negate_stmt              0x06
+#define DW_LNS_set_basic_block          0x07
+#define DW_LNS_const_add_pc             0x08
+#define DW_LNS_fixed_advance_pc         0x09
+#define DW_LNS_set_prologue_end         0x0a /* DWARF3 */
+#define DW_LNS_set_epilogue_begin       0x0b /* DWARF3 */
+#define DW_LNS_set_isa                  0x0c /* DWARF3 */
+
+/* Line number extended opcode name. */
+#define DW_LNE_end_sequence             0x01
+#define DW_LNE_set_address              0x02
+#define DW_LNE_define_file              0x03
+
+/* HP extensions. */
+#define DW_LNE_HP_negate_is_UV_update       0x11 /* 17 HP */
+#define DW_LNE_HP_push_context              0x12 /* 18 HP */
+#define DW_LNE_HP_pop_context               0x13 /* 19 HP */
+#define DW_LNE_HP_set_file_line_column      0x14 /* 20 HP */
+#define DW_LNE_HP_set_routine_name          0x15 /* 21 HP */
+#define DW_LNE_HP_set_sequence              0x16 /* 22 HP */
+#define DW_LNE_HP_negate_post_semantics     0x17 /* 23 HP */
+#define DW_LNE_HP_negate_function_exit      0x18 /* 24 HP */
+#define DW_LNE_HP_negate_front_end_logical  0x19 /* 25 HP */
+#define DW_LNE_HP_define_proc               0x20 /* 32 HP */
+
+#define DW_LNE_lo_user                  0x80 /* DWARF3 */
+#define DW_LNE_hi_user                  0xff /* DWARF3 */
+
+/* Macro information. */
+#define DW_MACINFO_define               0x01
+#define DW_MACINFO_undef                0x02
+#define DW_MACINFO_start_file           0x03
+#define DW_MACINFO_end_file             0x04
+#define DW_MACINFO_vendor_ext           0xff
+
+#define DW_CFA_advance_loc        0x40
+#define DW_CFA_offset             0x80
+#define DW_CFA_restore            0xc0
+#define DW_CFA_extended           0
+
+#define DW_CFA_nop              0x00
+#define DW_CFA_set_loc          0x01
+#define DW_CFA_advance_loc1     0x02
+#define DW_CFA_advance_loc2     0x03
+#define DW_CFA_advance_loc4     0x04
+#define DW_CFA_offset_extended  0x05
+#define DW_CFA_restore_extended 0x06
+#define DW_CFA_undefined        0x07
+#define DW_CFA_same_value       0x08
+#define DW_CFA_register         0x09
+#define DW_CFA_remember_state   0x0a
+#define DW_CFA_restore_state    0x0b
+#define DW_CFA_def_cfa          0x0c
+#define DW_CFA_def_cfa_register 0x0d
+#define DW_CFA_def_cfa_offset   0x0e
+#define DW_CFA_def_cfa_expression 0x0f     /* DWARF3 */
+#define DW_CFA_expression       0x10       /* DWARF3 */
+#define DW_CFA_cfa_offset_extended_sf 0x11 /* DWARF3 */
+#define DW_CFA_def_cfa_sf       0x12       /* DWARF3 */
+#define DW_CFA_def_cfa_offset_sf 0x13      /* DWARF3 */
+#define DW_CFA_val_offset        0x14      /* DWARF3f */
+#define DW_CFA_val_offset_sf     0x15      /* DWARF3f */
+#define DW_CFA_val_expression    0x16      /* DWARF3f */
+
+#define DW_CFA_lo_user           0x1c
+#define DW_CFA_low_user          0x1c  /* Incorrect spelling, do not use. */
+
+/* SGI/MIPS extension. */
+#define DW_CFA_MIPS_advance_loc8 0x1d   /* MIPS */
+
+/* GNU extensions. */
+#define DW_CFA_GNU_window_save   0x2d  /* GNU */
+#define DW_CFA_GNU_args_size     0x2e /* GNU  */
+#define DW_CFA_GNU_negative_offset_extended  0x2f /* GNU */
+
+#define DW_CFA_high_user         0x3f
+
+/* GNU exception header encoding.  See the Generic
+   Elf Specification of the Linux Standard Base (LSB). 
+   http://refspecs.freestandards.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/dwarfext.html
+   The upper 4 bits indicate how the value is to be applied. 
+   The lower 4 bits indicate the format of the data.
+*/
+#define DW_EH_PE_absptr	  0x00  /* GNU */
+#define DW_EH_PE_uleb128  0x01  /* GNU */
+#define DW_EH_PE_udata2	  0x02  /* GNU */
+#define DW_EH_PE_udata4	  0x03  /* GNU */
+#define DW_EH_PE_udata8	  0x04  /* GNU */
+#define DW_EH_PE_sleb128  0x09  /* GNU */
+#define DW_EH_PE_sdata2   0x0A  /* GNU */
+#define DW_EH_PE_sdata4	  0x0B  /* GNU */
+#define DW_EH_PE_sdata8	  0x0C  /* GNU */
+
+#define DW_EH_PE_pcrel	  0x10  /* GNU */
+#define DW_EH_PE_textrel  0x20  /* GNU */
+#define DW_EH_PE_datarel  0x30  /* GNU */
+#define DW_EH_PE_funcrel  0x40  /* GNU */
+#define DW_EH_PE_aligned  0x50  /* GNU */
+
+#define DW_EH_PE_omit     0xff  /* GNU.  Means  no value present. */
+
+
+/* Mapping from machine registers and pseudo-regs into the .debug_frame table.
+   DW_FRAME entries are machine specific. These describe
+   MIPS/SGI R3000, R4K, R4400.
+   And (simultaneously) a mapping from hardware register number to
+   the number used in the table to identify that register.
+
+   The CFA (Canonical Frame Address) described in DWARF is called
+   the Virtual Frame Pointer on MIPS/SGI machines.
+
+                             Rule describes:
+*/
+/* Column used for CFA. Assumes reg 0 never appears as
+   a register in DWARF info.  */
+#define DW_FRAME_CFA_COL 0  
+
+#define DW_FRAME_REG1   1  /* integer reg 1 */
+#define DW_FRAME_REG2   2  /* integer reg 2 */
+#define DW_FRAME_REG3   3  /* integer reg 3 */
+#define DW_FRAME_REG4   4  /* integer reg 4 */
+#define DW_FRAME_REG5   5  /* integer reg 5 */
+#define DW_FRAME_REG6   6  /* integer reg 6 */
+#define DW_FRAME_REG7   7  /* integer reg 7 */
+#define DW_FRAME_REG8   8  /* integer reg 8 */
+#define DW_FRAME_REG9   9  /* integer reg 9 */
+#define DW_FRAME_REG10  10 /* integer reg 10 */
+#define DW_FRAME_REG11  11 /* integer reg 11 */
+#define DW_FRAME_REG12  12 /* integer reg 12 */
+#define DW_FRAME_REG13  13 /* integer reg 13 */
+#define DW_FRAME_REG14  14 /* integer reg 14 */
+#define DW_FRAME_REG15  15 /* integer reg 15 */
+#define DW_FRAME_REG16  16 /* integer reg 16 */
+#define DW_FRAME_REG17  17 /* integer reg 17 */
+#define DW_FRAME_REG18  18 /* integer reg 18 */
+#define DW_FRAME_REG19  19 /* integer reg 19 */
+#define DW_FRAME_REG20  20 /* integer reg 20 */
+#define DW_FRAME_REG21  21 /* integer reg 21 */
+#define DW_FRAME_REG22  22 /* integer reg 22 */
+#define DW_FRAME_REG23  23 /* integer reg 23 */
+#define DW_FRAME_REG24  24 /* integer reg 24 */
+#define DW_FRAME_REG25  25 /* integer reg 25 */
+#define DW_FRAME_REG26  26 /* integer reg 26 */
+#define DW_FRAME_REG27  27 /* integer reg 27 */
+#define DW_FRAME_REG28  28 /* integer reg 28 */
+#define DW_FRAME_REG29  29 /* integer reg 29 */
+#define DW_FRAME_REG30  30 /* integer reg 30 */
+#define DW_FRAME_REG31  31 /* integer reg 31, aka ra */
+
+        /* MIPS1, 2 have only some of these 64-bit registers.
+        ** MIPS1  save/restore takes 2 instructions per 64-bit reg, and
+        ** in that case, the register is considered stored after the second
+        ** swc1.
+        */
+#define DW_FRAME_FREG0  32 /* 64-bit floating point reg 0 */
+#define DW_FRAME_FREG1  33 /* 64-bit floating point reg 1 */
+#define DW_FRAME_FREG2  34 /* 64-bit floating point reg 2 */
+#define DW_FRAME_FREG3  35 /* 64-bit floating point reg 3 */
+#define DW_FRAME_FREG4  36 /* 64-bit floating point reg 4 */
+#define DW_FRAME_FREG5  37 /* 64-bit floating point reg 5 */
+#define DW_FRAME_FREG6  38 /* 64-bit floating point reg 6 */
+#define DW_FRAME_FREG7  39 /* 64-bit floating point reg 7 */
+#define DW_FRAME_FREG8  40 /* 64-bit floating point reg 8 */
+#define DW_FRAME_FREG9  41 /* 64-bit floating point reg 9 */
+#define DW_FRAME_FREG10 42 /* 64-bit floating point reg 10 */
+#define DW_FRAME_FREG11 43 /* 64-bit floating point reg 11 */
+#define DW_FRAME_FREG12 44 /* 64-bit floating point reg 12 */
+#define DW_FRAME_FREG13 45 /* 64-bit floating point reg 13 */
+#define DW_FRAME_FREG14 46 /* 64-bit floating point reg 14 */
+#define DW_FRAME_FREG15 47 /* 64-bit floating point reg 15 */
+#define DW_FRAME_FREG16 48 /* 64-bit floating point reg 16 */
+#define DW_FRAME_FREG17 49 /* 64-bit floating point reg 17 */
+#define DW_FRAME_FREG18 50 /* 64-bit floating point reg 18 */
+#define DW_FRAME_FREG19 51 /* 64-bit floating point reg 19 */
+#define DW_FRAME_FREG20 52 /* 64-bit floating point reg 20 */
+#define DW_FRAME_FREG21 53 /* 64-bit floating point reg 21 */
+#define DW_FRAME_FREG22 54 /* 64-bit floating point reg 22 */
+#define DW_FRAME_FREG23 55 /* 64-bit floating point reg 23 */
+#define DW_FRAME_FREG24 56 /* 64-bit floating point reg 24 */
+#define DW_FRAME_FREG25 57 /* 64-bit floating point reg 25 */
+#define DW_FRAME_FREG26 58 /* 64-bit floating point reg 26 */
+#define DW_FRAME_FREG27 59 /* 64-bit floating point reg 27 */
+#define DW_FRAME_FREG28 60 /* 64-bit floating point reg 28 */
+#define DW_FRAME_FREG29 61 /* 64-bit floating point reg 29 */
+#define DW_FRAME_FREG30 62 /* 64-bit floating point reg 30 */
+#define DW_FRAME_FREG31 63 /* 64-bit floating point reg 31 */
+
+/*  ***IMPORTANT NOTE, TARGET DEPENDENCY ****
+    The following 4 #defines are dependent on 
+    the target cpu(s) that you apply libdwarf to.
+    Ensure that DW_FRAME_UNDEFINED_VAL  and DW_FRAME_SAME_VAL
+    do not conflict with the range [0-DW_FRAME_STATIC_LINK].
+    The value 63 works for MIPS cpus at least up to the R16000.
+
+    For a cpu with more than 63 real registers
+    DW_FRAME_HIGHEST_NORMAL_REGISTER
+    must be increased for things to work properly!
+    Also ensure that DW_FRAME_UNDEFINED_VAL DW_FRAME_SAME_VAL
+    are not in the range [0-DW_FRAME_STATIC_LINK]
+
+    Having DW_FRAME_HIGHEST_NORMAL_REGISTER be higher than
+    is strictly needed is safe.
+
+*/
+
+#ifndef DW_FRAME_HIGHEST_NORMAL_REGISTER
+#define DW_FRAME_HIGHEST_NORMAL_REGISTER 63
+#endif
+/* This is the number of columns in the Frame Table. 
+   This constant should
+   be kept in sync with DW_REG_TABLE_SIZE defined in libdwarf.h 
+   It must also be large enough to be beyond the highest 
+   compiler-defined-register (meaning DW_FRAME_RA_COL DW_FRAME_STATIC_LINK
+   in the MIPS/IRIX case */
+#ifndef DW_FRAME_LAST_REG_NUM
+#define DW_FRAME_LAST_REG_NUM   (DW_FRAME_HIGHEST_NORMAL_REGISTER + 3)
+#endif
+
+
+/* Column recording ra (return addrress from a function call). 
+   This is common to many architectures, but as a 'simple register'
+   is not necessarily adequate for all architectures.
+   For MIPS/IRIX this register number is actually recorded on disk
+   in the .debug_frame section.
+   */
+#define DW_FRAME_RA_COL  (DW_FRAME_HIGHEST_NORMAL_REGISTER + 1)
+
+/* Column recording static link applicable to up-level      
+   addressing, as in IRIX mp code, pascal, etc.
+   This is common to many architectures but
+   is not necessarily adequate for all architectures.
+   For MIPS/IRIX this register number is actually recorded on disk
+   in the .debug_frame section.
+*/
+#define DW_FRAME_STATIC_LINK (DW_FRAME_HIGHEST_NORMAL_REGISTER + 2)
+
+
+
+/*
+  DW_FRAME_UNDEFINED_VAL and  DW_FRAME_SAME_VAL  are
+  never on disk, just generated by libdwarf. See libdwarf.h
+  for their values.
+*/
+
+
+
+#define DW_CHILDREN_no               0x00
+#define DW_CHILDREN_yes              0x01
+
+#define DW_ADDR_none            0
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* __DWARF_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf.v2.mm	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,7699 @@
+'\"#ident	"%W%"
+'\" $Source: /plroot/cmplrs.src/v7.4.5m/.RCS/PL/libdwarf/RCS/dwarf.v2.mm,v $
+'\"
+'\" $Revision: 1.2 $
+'\"
+'\" DESCRIPTION
+'\"
+'\"	Requirements for 
+'\"
+'\" COMPILATION
+'\"
+'\"	pic file.mm | tbl | troff -mm
+'\"
+'\"	local mileage may vary
+'\"
+'\" AUTHOR
+'\"
+'\"	UNIX International Programming Languages SIG
+'\"
+'\" COPYRIGHT
+'\"
+'\"	Copyright (c) 1992,1993, UNIX International
+'\"
+'\"	Permission to use, copy, modify, and distribute this documentation for
+'\"	any purpose and without fee is hereby granted, provided that the above
+'\"	copyright notice appears in all copies and that both that copyright
+'\"	notice and this permission notice appear in supporting documentation,
+'\"	and that the name UNIX International not be used in advertising or
+'\"	publicity pertaining to distribution of the software without specific,
+'\"	written prior permission.  UNIX International makes no representations
+'\"	about the suitability of this documentation for any purpose.  It is
+'\"	provided "as is" without express or implied warranty.
+'\"	
+'\"	UNIX INTERNATIONAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+'\"	DOCUMENTATION, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+'\"	FITNESS.  IN NO EVENT SHALL UNIX INTERNATIONAL BE LIABLE FOR ANY
+'\"	SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+'\"	RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+'\"	CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+'\"	CONNECTION WITH THE USE OR PERFORMANCE OF THIS DOCUMENTATION.
+'\"	
+'\"	NOTICE:
+'\"	
+'\"	UNIX International is making this documentation available as a
+'\"	reference point for the industry.  While UNIX International believes
+'\"	that this specification is well defined in this first release of the
+'\"	document, minor changes may be made prior to products meeting this
+'\"	specification being made available from UNIX System Laboratories or 
+'\"	UNIX International members.
+'\"
+'\" $Log$
+'\" Revision 1.1  1994/05/18 18:50:42  davea
+'\" Initial revision
+'\"
+'\"
+'\"     Abbrevs for funny typeset words
+.pl-0.25i
+.ds aX U\s-2NIX\s+2
+.ds iX \*(aX International
+.ds uL \s-2AT&T\ USL\s+2
+'\"
+'\"  uI should be set to 1 if the publication and copyright page is needed.
+.nr uI 1
+'\"
+'\"     Make the appropriate replacements in this section!
+'\"
+'\"     Set the ND date to the current date.
+'\"     tT is the formal document title
+'\"     tP is the name of the Project (if appropriate)
+'\"     tD is the short document title
+'\"     tE is the work group name (may be the same as the project name)
+.ds tT DWARF Debugging Information Format 
+.ds tP 
+'\"             Document name (i.e., without project name)
+.ds tD DWARF Debugging Information Format
+.ds tE Programming Languages SIG
+'\"
+'\"     Define headers and footers macro
+'\"
+.ds fA Revision: 2.0.0
+'\"
+'\"     fB null to remove page numbers on cover page
+.ds fB
+.ds fC July 27, 1993
+.ds fE Industry Review Draft
+.ds fF \*(tD
+.PH "''''"
+.PF "''\*(fE''"
+.tr ~
+.SA 1
+.S 10
+.nr Ej 1
+.nr Hs 5
+.nr Hu 1
+.nr Hb 5
+.ds HP +2 +2 +1 +0 +0 +0 +0
+.ds HF 3 3 3 3 3 1 1
+.if n .ds HF 1 1 1 1 1 1 1 1
+'\"
+'\"     First page, print title and authors
+'\"
+.S +4
+.DS C
+
+
+
+
+
+
+\fB\*(tT
+
+\s-2\*(tP\s+2\fP
+
+.DE
+.S
+.sp 3i
+\*(iX
+.br
+\*(tE
+.br
+\*(fA (\*(fC)
+.SK
+.if \n(uI\{ 
+.DS C
+.in -.25i
+.B "Published by:"
+.R
+
+\*(iX
+Waterview Corporate Center
+20 Waterview Boulevard
+Parsippany, NJ  07054
+
+for further information, contact:
+Vice President of Marketing
+
+Phone:	+1 201-263-8400
+Fax:	+1 201-263-8401
+.DE
+.P
+Copyright \(co 1992, 1993 \*(iX, Inc.
+.P
+Permission to use, copy, modify, and distribute this
+documentation for any purpose and without fee is hereby granted, provided
+that the above copyright notice appears in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation, and that the name \*(iX not be used in 
+advertising or publicity pertaining to distribution of the software 
+without specific, written prior permission.  \*(iX makes
+no representations about the suitability of this documentation for any 
+purpose.  It is provided "as is" without express or implied warranty.
+.P
+UNIX INTERNATIONAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS DOCUMENTATION, 
+INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.  IN NO 
+EVENT SHALL UNIX INTERNATIONAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR 
+CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF 
+USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 
+PERFORMANCE OF THIS DOCUMENTATION.
+.sp 2l
+.if \n(uI\{
+NOTICE:
+.P
+\*(iX is making this documentation available as a
+reference point for the industry.  
+While \*(iX believes that this specification is well
+defined in this first release of the document,
+minor changes may be made prior to products meeting this specification
+being made available from \*(aX System Laboratories or \*(iX members.
+.sp 1l \}
+Trademarks:
+.P
+Intel386 is a trademark of Intel Corporation.
+.br
+\*(aX\(rg is a registered trademark of \*(aX System Laboratories 
+in the United States and other countries.
+.br
+.OH "'''\s10\\\\*(tE\s0'"
+.EH "'\s10\\\\*(tD\s0'''"
+.SK
+'\".VM 0 2
+.PF "''\s10\\\\*(fE\s0''"
+.OF "'\s10\\\\*(fA'\\\\*(fB'\\\\*(fC\s0'"
+.EF "'\s10\\\\*(fA'\\\\*(fB'\\\\*(fC\s0'"
+'\" -----------------------------------------------------------------------
+'\".
+'\"     Reset page numbers
+'\"
+.nr P 1
+.nr % 1
+'\"
+'\"     Define headers and footers
+'\"
+.FH
+'\"     Turn on the page numbering in the footers
+.ds fB Page %
+'\"
+'\"     MACROEND
+'\"
+.if n .fp 2 R
+.if n .fp 3 R
+.tr ~  
+\fR
+.S 11
+.SA 1
+.tr ~
+.OP
+.ds | |
+.ds ~ ~
+.ds ' '
+.if t .ds Cw \&\f(CW
+.if n .ds Cw \fB
+.de Cf		\" Place every other arg in Cw font, beginning with first
+.if \\n(.$=1 \&\*(Cw\\$1\fP
+.if \\n(.$=2 \&\*(Cw\\$1\fP\\$2
+.if \\n(.$=3 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP
+.if \\n(.$=4 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4
+.if \\n(.$=5 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP
+.if \\n(.$=6 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6
+.if \\n(.$=7 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP
+.if \\n(.$=8 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8
+.if \\n(.$=9 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8\*(Cw
+..
+'\" macros used by index generating tool
+.deIX
+.ie '\\n(.z'' .tm .Index: \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9	\\n%
+.el \\!.ix \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
+..
+.deix
+.ie '\\n(.z'' .tm .Index: \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9	\\n%
+.el \\!.ix \\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \\$7 \\$8 \\$9
+..
+.ta .5i +.5i +.5i +.5i +.5i +.5i +.5i +.5i
+.HU "FOREWORD"
+This document specifies the second generation of symbolic debugging
+information based on the DWARF format that 
+has been developed by the \*(iX
+Programming Languages Special Interest Group (SIG).
+It is being circulated for industry review.  
+The first version of the DWARF specification was published
+by \*(iX in January, 1992.  The current version adds significant
+new functionality, but its main thrust is to achieve a much
+denser encoding of the DWARF information.  Because of the new
+encoding, DWARF Version 2 is not binary compatible with
+DWARF Version 1.
+.P 
+At this point, the SIG believes that this document sufficiently
+supports the debugging needs of C, C++, FORTRAN 77, 
+Fortran90, Modula2 and Pascal, and we have
+released it for public comment.  We will accept comments on this
+document until September 30, 1994.  Comments may be directed via email
+to the SIG mailing list (plsig@ui.org).  If you are unable
+to send email, paper mail, FAX, or machine readable copy 
+on \*(aX, MS-DOS, or Macintosh compatible media can be 
+sent to \*(iX at the address listed below, 
+and will be forwarded to the SIG.
+.SP
+.SP
+.SP
+.in +20
+UNIX International
+.br
+Waterview Corporate Center
+.br
+20 Waterview Boulevard
+.br
+Parsippany, NJ 07054
+.br
+Phone:	+1 201-263-8400
+.br
+Fax:	+1 201-263-8401
+.br
+.in -20
+.nr H1 0
+.OP
+.H 1 "INTRODUCTION"
+\fR
+This document defines the format for the information generated by
+compilers, assemblers and linkage editors that is necessary for symbolic,
+source-level debugging.  The debugging information format does not favor the
+design of any compiler or debugger.  Instead, the goal is to create a method of
+communicating an accurate picture of the source program to any debugger in a
+form that is economically extensible to different languages while retaining
+backward compatibility.
+.P
+The design of the debugging information format is open-ended, allowing for the
+addition of new debugging information to accommodate new languages or
+debugger capabilities while remaining compatible with other languages or
+different debuggers.
+.H 2 "Purpose and Scope"
+The debugging information format described in this document is designed to
+meet the symbolic, source-level debugging needs of 
+different languages in a unified fashion by
+requiring language independent debugging information whenever possible.
+.IX C++ %caa
+.IX virtual functions
+.IX Fortran
+Individual needs, such as C++ virtual functions or Fortran common blocks are
+accommodated by creating attributes that are used only for those
+languages.  The \*(iX \*(tE believes 
+that this document sufficiently covers the 
+.IX languages
+debugging information needs of C, C++, FORTRAN77, Fortran90, 
+Modula2 and Pascal.
+.IX C %c
+.IX Modula2
+.IX Pascal
+.IX FORTRAN77
+.IX Fortran90
+.P
+This document describes DWARF Version 2, the second generation of debugging
+.IX Version 2
+information based on the DWARF format.  While DWARF Version 2 provides
+new debugging information not available in Version 1, the primary focus
+of the changes for Version 2 is the representation of the information,
+rather than the information content itself.  The basic structure of 
+the Version 2 format remains as in Version 1: the debugging information
+is represented as a series of debugging information entries, each containing
+one or more attributes (name/value pairs). 
+.IX debugging information entries
+.IX attributes
+The Version 2 representation, however,
+is much more compact than the Version 1 representation.
+.IX Version 1
+In some cases, this greater density has been achieved at the expense
+of additional complexity or greater difficulty in producing and processing
+the DWARF information.  We believe that the reduction in I/O and in
+memory paging should more than make up for any increase in processing time.
+.P
+Because the representation of information has changed from Version 1 to
+Version 2, Version 2 DWARF information is not binary compatible
+.IX compatibility
+with Version 1 information.  To make it easier for consumers to
+support both Version 1 and Version 2 DWARF information, the Version
+2 information has been moved to a different object file section,
+.Cf .debug_info .
+.IX \f(CW.debug_info\fP %debugai
+.P
+The intended audience for this document are the developers of 
+both producers and consumers of debugging information, typically
+language compilers, debuggers and other tools that need to interpret
+a binary program in terms of its original source.
+.H 2 "Overview"
+There are two major pieces to the description of the DWARF format in
+this document.  The first piece is the informational content
+of the debugging entries.  The second piece
+is the way the debugging information is encoded and 
+represented in an object file.
+.P
+The informational content is described in sections two
+through six.
+Section two describes the overall structure of
+the information and attributes that are common to many or all of
+the different debugging information entries.  
+Sections three, four and five describe the specific debugging
+information entries and how they communicate the
+necessary information about the source program to a debugger.
+Section six describes debugging information contained
+outside of the debugging information entries, themselves.
+The encoding of the DWARF information is
+presented in section seven.
+.P
+Section eight describes some future directions for the DWARF
+specification.
+.P
+In the following sections, text in normal font describes required aspects
+of the DWARF format.  Text in \fIitalics\fP is explanatory or supplementary 
+material, and not part of the format definition itself.
+.H 2 "Vendor Extensibility"
+.IX vendor extensions
+This document does not attempt to cover all interesting languages or even
+to cover all of the interesting debugging information needs for its primary
+target languages (C, C++, FORTRAN77, Fortran90, Modula2, Pascal). 
+Therefore the document provides
+vendors a way to define their own debugging information tags, attributes,
+base type encodings, location operations, language names,
+calling conventions and call frame instructions
+by reserving a portion of the name space and valid values 
+for these constructs for vendor specific additions.  Future versions
+of this document will not use names or values reserved for vendor specific
+additions.  All names and values not reserved for vendor additions, however,
+are reserved for future versions of this document.  See section 7 for
+details.
+.H 2 "Changes from Version 1"
+The following is a list of the major changes made to the DWARF Debugging
+Information Format since Version 1 of the format was published (January
+.IX Version 1
+20, 1992).  The list is not meant to be exhaustive.
+.BL
+.LI
+Debugging information entries have been moved from the 
+.Cf .debug
+.IX \f(CW.debug\fP %debugaaa
+to the 
+.Cf .debug_info
+.IX \f(CW.debug_info\fP %debugai
+section of an object file.
+.LI
+.IX tags
+.IX attributes, names
+.IX attributes, forms
+The tag, attribute names and attribute forms encodings have been moved
+out of the debugging information itself to a separate abbreviations table.
+.IX abbreviations table
+.LI
+Explicit sibling pointers have been made optional.  Each
+.IX debugging information entries, siblings
+entry now specifies (through the abbreviations table) whether
+or not it has children.
+.IX debugging information entries, child entries
+.LI
+New more compact attribute forms have been added, including a variable
+length constant data form.  Attribute values may now have any 
+.IX variable length data
+.IX attributes, forms
+.IX attributes, values
+form within a given class of forms.
+.LI
+Location descriptions have been replaced by a new, more compact
+and more expressive format.
+.IX locations, descriptions
+There is now a way of expressing multiple locations for an object
+whose location changes during its lifetime.
+.IX locations, lists
+.LI
+There is a new format for line number information
+that provides information
+for code contributed to a compilation unit from an included file.
+Line number information is now in the 
+.IX line number information
+.Cf .debug_line
+.IX \f(CW.debug_line\fP %debugali
+section of an object file.
+.LI
+The representation of the type of a declaration has been
+reworked.
+.IX declarations, types of
+.LI
+A new section provides an encoding for pre-processor macro information.
+.IX macro information
+.IX pre-processor
+.LI
+Debugging information entries now provide for the representation
+of non-defining declarations of objects, functions or types.
+.IX declarations, non-defining
+.LI
+More complete support for Modula2 and Pascal has been added.
+.LI
+There is now a way of describing locations for segmented address spaces.
+.IX segmented address space
+.IX address space, segmented
+.LI
+A new section provides an encoding for information about call
+frame activations.
+.IX call frame information
+.IX activations
+.LI
+The representation of enumeration and array types has been
+.IX enumerations
+.IX arrays
+reworked so that DWARF presents only a single way of
+representing lists of items.
+.LI
+Support has been added for C++ templates and exceptions.
+.IX C++ %caa
+.IX templates
+.IX exceptions
+.LE
+.OP
+.H 1 "GENERAL DESCRIPTION"
+.H 2   "The Debugging Information Entry"
+DWARF uses a series of debugging information entries to define a
+.IX debugging information entries
+low-level representation of a source program. Each debugging
+information entry is described by an identifying tag and
+contains a series of attributes. 
+The tag specifies the class to which an entry
+belongs, and the attributes define the specific characteristics
+of the entry.
+.P
+.nr aX \n(Fg+1
+The set of required tag names is listed in Figure \n(aX.
+.IX tags
+The debugging information entries they identify are described in sections three, four and five.
+.P
+The debugging information entries in DWARF Version 2 are intended
+to exist in the 
+.Cf .debug_info
+section of an object file.
+.IX \f(CW.debug_info\fP %debugai
+.DF
+.TS
+center box;
+lf(CW) lf(CW)
+. 
+DW_TAG_access_declaration	DW_TAG_array_type
+DW_TAG_base_type	DW_TAG_catch_block
+DW_TAG_class_type	DW_TAG_common_block
+DW_TAG_common_inclusion	DW_TAG_compile_unit
+DW_TAG_const_type	DW_TAG_constant
+DW_TAG_entry_point	DW_TAG_enumeration_type
+DW_TAG_enumerator	DW_TAG_file_type
+DW_TAG_formal_parameter	DW_TAG_friend
+DW_TAG_imported_declaration	DW_TAG_inheritance
+DW_TAG_inlined_subroutine	DW_TAG_label
+DW_TAG_lexical_block	DW_TAG_member
+DW_TAG_module	DW_TAG_namelist
+DW_TAG_namelist_item	DW_TAG_packed_type
+DW_TAG_pointer_type	DW_TAG_ptr_to_member_type
+DW_TAG_reference_type	DW_TAG_set_type
+DW_TAG_string_type	DW_TAG_structure_type
+DW_TAG_subprogram	DW_TAG_subrange_type
+DW_TAG_subroutine_type	DW_TAG_template_type_param
+DW_TAG_template_value_param	DW_TAG_thrown_type
+DW_TAG_try_block	DW_TAG_typedef
+DW_TAG_union_type	DW_TAG_unspecified_parameters
+DW_TAG_variable	DW_TAG_variant
+DW_TAG_variant_part	DW_TAG_volatile_type
+DW_TAG_with_stmt
+.TE
+.FG "Tag names"
+.DE
+.H 2 "Attribute Types"
+Each attribute value is characterized by an attribute name.
+.IX attributes
+.IX attributes, names
+The set of attribute names is 
+.nr aX \n(Fg+1
+listed in Figure \n(aX.
+.DF
+.TS
+center box;
+lf(CW) lf(CW)
+. 
+DW_AT_abstract_origin	DW_AT_accessibility
+DW_AT_address_class	DW_AT_artificial
+DW_AT_base_types	DW_AT_bit_offset
+DW_AT_bit_size	DW_AT_byte_size
+DW_AT_calling_convention	DW_AT_common_reference
+DW_AT_comp_dir	DW_AT_const_value
+DW_AT_containing_type	DW_AT_count
+DW_AT_data_member_location	DW_AT_decl_column
+DW_AT_decl_file	DW_AT_decl_line
+DW_AT_declaration	DW_AT_default_value
+DW_AT_discr	DW_AT_discr_list
+DW_AT_discr_value	DW_AT_encoding
+DW_AT_external	DW_AT_frame_base
+DW_AT_friend	DW_AT_high_pc
+DW_AT_identifier_case	DW_AT_import
+DW_AT_inline	DW_AT_is_optional
+DW_AT_language	DW_AT_location
+DW_AT_low_pc	DW_AT_lower_bound
+DW_AT_macro_info	DW_AT_name
+DW_AT_namelist_item	DW_AT_ordering
+DW_AT_priority	DW_AT_producer
+DW_AT_prototyped	DW_AT_return_addr
+DW_AT_segment	DW_AT_sibling
+DW_AT_specification	DW_AT_start_scope
+DW_AT_static_link	DW_AT_stmt_list
+DW_AT_stride_size	DW_AT_string_length
+DW_AT_type	DW_AT_upper_bound
+DW_AT_use_location	DW_AT_variable_parameter
+DW_AT_virtuality	DW_AT_visibility
+DW_AT_vtable_elem_location
+.TE	
+.FG "Attribute names"
+.DE
+.P
+The permissible values for an attribute belong to one or more classes
+.IX attributes, values
+.IX attributes, forms
+of attribute value forms.  Each form class may be represented in one or more
+ways.  For instance, some attribute values consist of a single piece
+of constant data.  ``Constant data'' is the class of attribute value
+that those attributes may have.  There are several representations
+of constant data, however (one, two, four, eight bytes and variable
+length data).  The particular representation for any given instance
+of an attribute is encoded along with the attribute name as part
+of the information that guides the interpretation of a debugging
+information entry.   Attribute value forms may belong
+to one of the following classes.
+.VL 18
+.LI address
+.IX attributes, addresses
+Refers to some location in the address space of the described program.
+.LI block
+.IX attributes, blocks
+An arbitrary number of uninterpreted bytes of data.
+.LI constant
+.IX attributes, constants
+One, two, four or eight bytes of uninterpreted data, or data encoded
+in the variable length format known as LEB128 (see section 7.6).
+.IX variable length data
+.IX LEB128
+.LI flag
+.IX attributes, flags
+A small constant that indicates the presence or absence of an attribute.
+.LI reference
+.IX attributes, references
+Refers to some member of the set of debugging information entries that describe
+the program.  There are two types of reference.  The first is an
+offset relative to the beginning of the compilation unit in
+which the reference occurs and must refer to an entry within
+that same compilation unit.  The second type of reference
+is the address of any debugging information entry within
+the same executable or shared object; it may refer to an entry
+in a different compilation unit from the unit containing the
+reference.
+.LI string
+.IX attributes, strings
+A null-terminated sequence of zero or more (non-null) bytes.
+Data in this form are generally printable strings.  Strings
+may be represented directly in the debugging information entry
+or as an offset in a separate string table.
+.LE
+.P
+There are no limitations on the ordering of attributes within a debugging
+.IX attributes, ordering
+information entry, but to prevent ambiguity,
+no more than one attribute with a given name may appear in any debugging
+information entry.
+.H 2 "Relationship of Debugging Information Entries"
+.I
+A variety of needs can be met by permitting a single debugging
+information entry to ``own'' an arbitrary number of other debugging
+entries and by permitting the same debugging information entry to be
+one of many owned by another debugging information entry.
+This makes it possible to describe, for example,
+the static block structure within
+a source file, show the members of a structure, union, or class, and associate
+declarations with source files or source files with shared objects.
+.P
+.R
+The ownership relation
+of debugging information entries is achieved naturally
+.IX debugging information entries
+because the debugging information is represented as a tree.
+The nodes of the tree are the debugging information entries
+themselves.  The child entries of any node are exactly those
+.IX debugging information entries, child entries
+debugging information entries owned by that node.\*F
+.FS
+While the ownership relation of the debugging information
+entries is represented as a tree, other relations among
+the entries exist, for example, a pointer from an entry
+representing a variable to another entry representing
+the type of that variable.  If all such relations are
+taken into account, the debugging entries form a graph,
+not a tree.
+.FE
+.P
+The tree itself is represented by flattening it in prefix
+order.  Each debugging information entry
+is defined either to have child entries or not to have child entries
+(see section 7.5.3).
+If an entry is defined not to have children, the next physically
+succeeding entry is the sibling of the prior entry.  If an entry
+.IX debugging information entries, siblings
+is defined to have children, the next physically succeeding entry
+is the first child of the prior entry.  Additional children of the parent
+entry are represented as siblings of the first child.  A chain
+of sibling entries is terminated by a null entry.
+.IX debugging information entries, null entries
+.P
+In cases where a producer of debugging information
+feels that it will be important for consumers of that information
+to quickly scan chains of sibling entries, ignoring the children
+of individual siblings, that producer may attach an
+.Cf AT_sibling
+attribute to any debugging information entry.  The value of
+this attribute is a reference to the sibling entry of the
+entry to which the attribute is attached.
+.H 2 "Location Descriptions"
+.I
+The debugging information must provide consumers a way to find the location
+of program variables, determine the bounds of dynamic arrays and strings
+and possibly to find the base address of a subroutine's stack frame or
+the return address of a subroutine.  Furthermore, to meet the needs
+of recent computer architectures and optimization techniques, the debugging
+information must be able to describe the location of an object
+whose location changes over the object's lifetime.
+.P
+.R
+Information about the location of program objects is provided by
+location descriptions.  Location
+.IX locations, descriptions
+descriptions can be either of two forms: 
+.AL
+.LI
+\fILocation expressions\fP which are a language independent representation of 
+addressing rules
+.IX locations, expressions
+of arbitrary complexity built from a few basic
+building blocks, or \fIoperations\fP.  They are sufficient for describing
+the location of any object as long as its lifetime is either static
+or the same as the lexical block that owns it, and it does not move throughout 
+its lifetime.  
+.LI
+\fILocation lists\fP which are used to describe objects that 
+.IX locations, lists
+have a limited lifetime or change their location throughout their
+lifetime.  Location lists are more completely described below.
+.LE
+.P
+The two forms are distinguished in a context sensitive manner.  As the value
+of an attribute, a location expression is 
+encoded as a block and a location list is encoded as a constant offset into
+a location list table.
+.P
+.I
+Note: The Version 1 concept of "location descriptions" was replaced in Version 2 
+with this new abstraction because it is denser and more descriptive.  
+.IX Version 1
+.IX Version 2
+.R
+.H 3 "Location Expressions"
+A location expression consists of zero or more location operations.
+.IX locations, expressions
+An expression with zero operations 
+is used to denote an object that is
+present in the source code but not present in the object code
+(perhaps because of optimization).  
+.IX optimized code
+The location operations fall into two categories, register names and
+addressing operations.  Register names always appear alone and indicate
+that the referred object is contained inside a particular 
+register.  Addressing operations are memory address computation 
+rules.  All location operations are encoded as a stream of opcodes that
+are each followed by zero or more literal operands.  The number of operands
+is determined by the opcode.
+.H 3 "Register Name Operators"
+.IX locations, register name operators
+The following operations can be used to name a register.
+.P
+.I
+Note that the 
+register number represents a DWARF specific mapping of numbers onto
+the actual registers of a given architecture.
+The mapping should be chosen to gain optimal density and 
+should be shared by all users of a given architecture. 
+The \*(tE recommends
+that this mapping be defined by the ABI\*F
+.IX ABI
+.FS
+\fISystem V Application Binary Interface\fP, consisting of the generic
+interface and processor supplements for each target architecture.
+.FE
+authoring committee for each
+architecture.
+.R
+.AL
+.LI
+.Cf DW_OP_reg0 , " DW_OP_reg1" ", ..., " DW_OP_reg31
+.br
+The
+\f(CWDW_OP_reg\fP\fIn\fP
+operations encode the names of up to 32 registers, numbered from
+0 through 31, inclusive.  The object addressed is in register \fIn\fP.
+.LI
+.Cf DW_OP_regx
+.br
+The
+.Cf DW_OP_regx
+operation has a single unsigned LEB128 literal operand that encodes the 
+name of a register.
+.LE
+.H 3 "Addressing Operations"
+.IX locations, stack
+Each addressing operation represents a postfix operation on a simple stack 
+machine.  Each element of the stack is the size of an
+address on the target machine.
+The value on the top of the stack after
+``executing'' the location expression is taken to be the result (the address
+of the object, or the value of the array bound, or the length of a
+dynamic string).  In the case of locations used for structure members, 
+.IX members, locations
+the computation assumes that the base address of the containing structure
+has been pushed on the stack before evaluation of the addressing operation.
+.R
+.H 4 "Literal Encodings"
+.IX locations, literal encodings
+The following operations all push a value onto the addressing stack.
+.AL
+.LI
+.Cf DW_OP_lit0 , " DW_OP_lit1" ", ..., " DW_OP_lit31
+.br
+The
+\f(CWDW_OP_lit\fP\fIn\fP operations encode the unsigned 
+literal values from 0 through 31, inclusive.
+.LI
+.Cf DW_OP_addr
+.br
+The
+.Cf DW_OP_addr
+operation has a single operand that encodes a
+machine address and whose size is the size of an address on the
+target machine.
+.LI
+.Cf DW_OP_const1u
+.br
+The single operand of the
+.Cf DW_OP_const1u
+operation provides a 1-byte unsigned integer constant.
+.LI
+.Cf DW_OP_const1s
+.br
+The single operand of the
+.Cf DW_OP_const1s
+operation provides a
+1-byte signed integer constant.
+.LI
+.Cf DW_OP_const2u
+.br
+The single operand of the
+.Cf DW_OP_const2u
+operation provides a
+2-byte unsigned integer constant.
+.LI
+.Cf DW_OP_const2s
+.br
+The single operand of the
+.Cf DW_OP_const2s
+operation provides a
+2-byte signed integer constant.
+.LI
+.Cf DW_OP_const4u
+.br
+The single operand of the
+.Cf DW_OP_const4u
+operation provides a
+4-byte unsigned integer constant.
+.LI
+.Cf DW_OP_const4s
+.br
+The single operand of the
+.Cf DW_OP_const4s
+operation provides a
+4-byte signed integer constant.
+.LI
+.Cf DW_OP_const8u
+.br
+The single operand of the
+.Cf DW_OP_const8u
+operation provides an
+8-byte unsigned integer constant.
+.LI
+.Cf DW_OP_const8s
+.br
+The single operand of the
+.Cf DW_OP_const8s
+operation provides an
+8-byte signed integer constant.
+.LI
+.Cf DW_OP_constu
+.br
+The single operand of the
+.Cf DW_OP_constu
+operation provides an
+unsigned LEB128 integer constant.
+.LI
+.Cf DW_OP_consts
+.br
+The single operand of the
+.Cf DW_OP_consts
+operation provides a
+signed LEB128 integer constant.
+.LE
+.H 4 "Register Based Addressing"
+.IX locations, register based addressing
+The following operations push a value onto the stack that 
+is the result of adding the contents of a register with 
+a given signed offset.  
+.AL
+.LI
+.Cf DW_OP_fbreg
+.br
+The
+\f(CWDW_OP_fbreg\fP
+operation provides a signed LEB128 offset from the address specified 
+by the location descriptor in the 
+.Cf DW_AT_frame_base 
+attribute of the current 
+.IX subroutines, frame base
+function.  \fI(This is typically a "stack pointer" register 
+plus or minus some
+offset.  On more sophisticated systems it might be a location list that
+adjusts the offset according to changes in the stack pointer as
+the PC changes.)\fP
+.LI
+.Cf DW_OP_breg0 , " DW_OP_breg1" ", ..., " DW_OP_breg31
+.br
+The single operand of the
+\f(CWDW_OP_breg\fP\fIn\fP
+operations provides a signed LEB128 offset from the specified register.
+.LI
+.Cf DW_OP_bregx
+.br
+The
+.Cf DW_OP_bregx
+operation has two operands:  a signed LEB128 offset from the specified register
+which is defined with an unsigned LEB128 number.
+.LE
+.H 4 "Stack Operations"
+.IX locations, stack
+The following operations 
+manipulate the ``location stack.''
+Location operations that index the location stack assume that
+the top of the stack (most recently added entry) has index 0.
+.AL
+.LI
+.Cf DW_OP_dup
+.br
+The
+.Cf DW_OP_dup 
+operation duplicates the value at the top of the location stack.
+.LI
+.Cf DW_OP_drop
+.br
+The
+.Cf DW_OP_drop 
+operation pops the value at the top of the stack.
+.LI
+.Cf DW_OP_pick
+.br
+The single operand of the
+.Cf DW_OP_pick
+operation provides a 1-byte index.  The stack entry with the specified index
+(0 through 255, inclusive) is pushed on the stack.
+.LI
+.Cf DW_OP_over
+.br
+The
+.Cf DW_OP_over
+operation duplicates the entry currently second in the stack
+at the top of the stack.  This is equivalent to an
+.Cf DW_OP_pick
+operation, with index 1.
+.LI
+.Cf DW_OP_swap
+.br
+The
+.Cf DW_OP_swap
+operation swaps the top two stack entries.   The entry at
+the top of the stack becomes the second stack entry, and
+the second entry becomes the top of the stack.
+.LI
+.Cf DW_OP_rot
+.br
+The
+.Cf DW_OP_rot
+operation rotates the first three stack entries.   The entry at
+the top of the stack becomes the third stack entry, the second entry
+becomes the top of the stack, and the third entry becomes the second
+entry.
+.LI
+.Cf DW_OP_deref
+.br
+The
+.Cf DW_OP_deref
+operation pops the top stack entry and treats it as an address.
+The value retrieved from that address is pushed.  The size of the
+data retrieved from the dereferenced address is the size of an address
+on the target machine.
+.LI
+.Cf DW_OP_deref_size
+.br
+The
+.Cf DW_OP_deref_size
+operation behaves like the 
+.Cf DW_OP_deref
+operation: it 
+pops the top stack entry and treats it as an address.
+The value retrieved from that address is pushed.  
+In the 
+.Cf DW_OP_deref_size
+operation, however,
+the size in bytes of the
+data retrieved from the dereferenced address is specified by the
+single operand.  This operand is a 1-byte unsigned integral constant
+whose value may not be larger than the size of an address on
+the target machine.  The data retrieved is zero extended to the size
+of an address on the target machine before being pushed on
+the expression stack.
+.LI
+.Cf DW_OP_xderef
+.br
+The
+.Cf DW_OP_xderef
+.IX address space, multiple
+operation provides an extended dereference mechanism.  The entry at the
+top of the stack is treated as an address.  The second stack entry
+is treated as an ``address space identifier'' for those architectures
+that support multiple address spaces.  The top two stack elements
+are popped, a data item is retrieved through an implementation-defined
+address calculation and pushed as the new stack top.  The size of the
+data retrieved from the dereferenced address is the size of an address
+on the target machine.
+.LI
+.Cf DW_OP_xderef_size
+.br
+The
+.Cf DW_OP_xderef_size
+operation behaves like the 
+.Cf DW_OP_xderef
+operation: the entry at the
+top of the stack is treated as an address.  The second stack entry
+is treated as an ``address space identifier'' for those architectures
+that support multiple address spaces.  The top two stack elements
+are popped, a data item is retrieved through an implementation-defined
+address calculation and pushed as the new stack top.  
+In the 
+.Cf DW_OP_xderef_size
+operation, however,
+the size in bytes of the
+data retrieved from the dereferenced address is specified by the
+single operand.  This operand is a 1-byte unsigned integral constant
+whose value may not be larger than the size of an address on
+the target machine.  The data retrieved is zero extended to the size
+of an address on the target machine before being pushed on
+the expression stack.
+.LE
+.H 4 "Arithmetic and Logical Operations"
+.IX locations, arithmetic operations
+.IX locations, logical operations
+The following provide arithmetic and logical operations.
+The arithmetic operations perform ``addressing arithmetic,''
+that is, unsigned arithmetic that wraps on an address-sized 
+boundary.  The operations do not cause an exception on overflow.
+.AL
+.LI
+.Cf DW_OP_abs
+.br
+The
+.Cf DW_OP_abs
+operation pops the top stack entry and pushes its absolute value.
+.LI
+.Cf DW_OP_and
+.br
+The
+.Cf DW_OP_and
+operation pops the top two stack values, performs a bitwise \fIand\fP 
+operation on the two, and pushes the result.
+.LI
+.Cf DW_OP_div
+.br
+The
+.Cf DW_OP_div
+operation pops the top two stack values, divides the former second entry
+by the former top of the stack 
+using signed division, 
+and pushes the result.
+.LI
+.Cf DW_OP_minus
+.br
+The
+.Cf DW_OP_minus
+operation pops the top two stack values, subtracts the former top of the stack
+from the former second entry, and pushes the result.
+.LI
+.Cf DW_OP_mod
+.br
+The
+.Cf DW_OP_mod
+operation pops the top two stack values and pushes the result of the 
+calculation: former second stack entry modulo the former top of the
+stack.
+.LI
+.Cf DW_OP_mul
+.br
+The
+.Cf DW_OP_mul
+operation pops the top two stack entries, multiplies them together,
+and pushes the result.
+.LI
+.Cf DW_OP_neg
+.br
+The
+.Cf DW_OP_neg
+operation pops the top stack entry, and pushes its negation.
+.LI
+.Cf DW_OP_not
+.br
+The
+.Cf DW_OP_not
+operation pops the top stack entry, and pushes its bitwise complement.
+.LI
+.Cf DW_OP_or
+.br
+The
+.Cf DW_OP_or
+operation pops the top two stack entries, performs a bitwise \fIor\fP 
+operation on the two, and pushes the result.
+.LI
+.Cf DW_OP_plus
+.br
+The
+.Cf DW_OP_plus
+operation pops the top two stack entries, adds them together,
+and pushes the result.
+.LI
+.Cf DW_OP_plus_uconst
+.br
+The
+.Cf DW_OP_plus_uconst
+operation pops the top stack entry, adds it to the unsigned LEB128
+constant operand and pushes the result.
+.I
+This operation is supplied specifically to be able to encode more field
+offsets in two bytes than can be done with "\f(CWDW_OP_lit\fP\fIn\fP\f(CW DW_OP_add\fP".
+.R
+.LI
+.Cf DW_OP_shl
+.br
+The
+.Cf DW_OP_shl
+operation pops the top two stack entries, shifts the former second
+entry left by the number of bits specified by the former top of
+the stack, and pushes the result.
+.LI
+.Cf DW_OP_shr
+.br
+The
+.Cf DW_OP_shr
+operation pops the top two stack entries, shifts the former second
+entry right (logically) by the number of bits specified by the former top of
+the stack, and pushes the result.
+.LI
+.Cf DW_OP_shra
+.br
+The
+.Cf DW_OP_shra
+operation pops the top two stack entries, shifts the former second
+entry right (arithmetically) by the number of bits specified by the former top of
+the stack, and pushes the result.
+.LI
+.Cf DW_OP_xor
+.br
+The
+.Cf DW_OP_xor
+operation pops the top two stack entries, performs the logical 
+\fIexclusive-or\fP operation on the two, and pushes the result.
+.LE
+.H 4 "Control Flow Operations"
+.IX locations, control flow operations
+The following operations provide simple control of the flow of a location
+expression.
+.AL
+.LI 
+Relational operators
+.br
+The six relational operators each pops the top two stack values,
+compares the former top of the stack with the former second entry,
+and pushes the constant value 1 onto the stack if the result of the
+operation is true or the constant value 0 if the result of the operation
+is false.  The comparisons are done as signed operations.  The six
+operators are 
+.Cf DW_OP_le
+(less than or equal to),
+.Cf DW_OP_ge
+(greater than or equal to),
+.Cf DW_OP_eq
+(equal to),
+.Cf DW_OP_lt
+(less than),
+.Cf DW_OP_gt
+(greater than) and
+.Cf DW_OP_ne
+(not equal to).
+.LI
+.Cf DW_OP_skip
+.br
+.Cf DW_OP_skip
+is an unconditional branch.  Its
+single operand is a 2-byte signed integer constant.
+The 2-byte constant is the number of bytes of the location
+expression to skip from the current operation, beginning after the
+2-byte constant.
+.LI
+.Cf DW_OP_bra
+.br
+.Cf DW_OP_bra
+is a conditional branch.  Its
+single operand is a 2-byte signed integer constant.
+This operation pops the top of stack.  If the value
+popped is not the constant 0, the 2-byte constant operand is the number
+of bytes of the location 
+expression to skip from the current operation, beginning after the
+2-byte constant.
+.LE
+.H 4 "Special Operations"
+.IX locations, special operations
+There are two special operations currently defined:
+.AL
+.LI
+.Cf DW_OP_piece
+.br
+.I
+Many compilers store a single variable in sets of registers, or store
+a variable partially in memory and partially in registers.  
+.Cf DW_OP_piece
+provides a way of describing how large a part of a variable
+a particular addressing expression refers to.
+.R
+.P
+.Cf DW_OP_piece
+takes a single argument which is an unsigned LEB128 number.  The number
+describes the size in bytes of the piece of the object referenced
+by the addressing expression whose result is at the top of
+the stack.
+.LI
+.Cf DW_OP_nop
+.br
+The 
+.Cf DW_OP_nop
+operation is a place holder.  It has no effect on the location stack or
+any of its values.
+.LE
+.H 3 "Sample Stack Operations"
+.IX locations, examples
+.I
+The stack operations defined in section 2.4.3.3 are fairly
+.IX locations, stack
+conventional, but the following examples illustrate their behavior
+graphically.
+.R
+.DS
+.TS
+box expand center tab(;);
+l s l l s
+lf(CW) lf(CW) lf(CW) lf(CW) lf(CW)
+.
+Before;Operation;After;
+_
+0;17;DW_OP_dup;0;17
+1;29;;1;17
+2;1000;;2;29
+;;;3;1000
+_
+0;17;DW_OP_drop;0;29
+1;29;;1;1000
+2;1000;;;;
+_
+0;17;DW_OP_pick 2;0;1000
+1;29;;1;17
+2;1000;;2;29
+;;;3;1000
+_
+0;17;DW_OP_over;0;29
+1;29;;1;17
+2;1000;;2;29
+;;;3;1000
+_
+0;17;DW_OP_swap;0;29
+1;29;;1;17
+2;1000;;2;1000
+_
+0;17;DW_OP_rot;0;29
+1;29;;1;1000
+2;1000;;2;17
+.TE
+.DE
+.H 3 "Example Location Expressions"
+.I
+.IX locations, examples
+The addressing expression represented by a location expression, 
+if evaluated, generates the
+runtime address of the value of a symbol except where the
+.Cf DW_OP_reg n,
+or
+.Cf DW_OP_regx
+operations are used.
+.P
+Here are some examples of how location operations are used to form location
+expressions:
+.R
+.DS
+\f(CWDW_OP_reg3\fI
+	The value is in register 3.
+
+\f(CWDW_OP_regx 54\fI
+	The value is in register 54.
+
+\f(CWDW_OP_addr 0x80d0045c\fI
+	The value of a static variable is
+	at machine address 0x80d0045c.
+
+\f(CWDW_OP_breg11 44\fI
+	Add 44 to the value in
+	register 11 to get the address of an
+	automatic variable instance.
+
+\f(CWDW_OP_fbreg -50\fI
+	Given an \f(CWDW_AT_frame_base\fI value of
+	"\f(CWOPBREG31 64\fI," this example 
+	computes the address of a local variable
+	that is -50 bytes from a logical frame 
+	pointer that is computed by adding
+	64 to the current stack pointer (register 31).
+
+\f(CWDW_OP_bregx 54 32 DW_OP_deref\fI
+	A call-by-reference parameter
+	whose address is in the
+	word 32 bytes from where register
+	54 points.  
+
+\f(CWDW_OP_plus_uconst 4\fI
+	A structure member is four bytes
+	from the start of the structure
+	instance.  The base address is
+	assumed to be already on the stack.
+
+\f(CWDW_OP_reg3 DW_OP_piece 4 DW_OP_reg10 DW_OP_piece 2\fI
+	A variable whose first four bytes reside
+	in register 3 and whose next two bytes
+	reside in register 10.\fR
+.DE
+.H 3 "Location Lists"
+.IX locations, lists
+Location lists are used in place of location expressions whenever
+the object whose location is being described can change location
+during its lifetime.  Location lists are contained in a separate
+object file section called
+.Cf .debug_loc.
+.IX \f(CW.debug_loc\fP %debugalo
+A location list is indicated by a location
+attribute whose value is represented as a
+constant offset from the beginning of the 
+.Cf .debug_loc
+section to the first byte of the list for the object in question.
+.P
+Each entry in a location list consists of:
+.AL
+.LI
+A beginning address.  This address is relative to the base address
+of the compilation unit referencing this location list.  It marks
+the beginning of the address range over which the location is valid.
+.LI
+An ending address, again relative to the base address
+of the compilation unit referencing this location list.  It marks
+the first address past the end of the address range over 
+which the location is valid.
+.LI
+A location expression describing the location of the object over the
+range specified by the beginning and end addresses.
+.LE
+.P
+Address ranges may overlap.  When they do, they describe a situation
+in which an object exists simultaneously in more than one place.
+If all of the address ranges 
+in a given location list do not collectively cover the entire
+range over which the object in question is defined, it is assumed
+that the object is not available for the portion of the range that is not
+covered.
+.IX optimized code
+.P
+The end of any given location list is marked by a 0 for the beginning
+address and a 0 for the end address; no location description is present.
+A location list containing
+only such a 0 entry describes an object that exists in the source
+code but not in the executable program. 
+.H 2 "Types of Declarations"
+.IX declarations, types of
+Any debugging information entry describing a declaration that
+has a type has a
+.Cf DW_AT_type
+attribute, whose value is a reference to another debugging
+information entry.  The entry referenced may describe
+.IX base types
+.IX types, base
+a base type, that is, a type that is not defined in terms
+.IX user-defined types
+.IX types, user-defined
+of other data types, or it may describe a user-defined type,
+such as an array, structure or enumeration.  Alternatively,
+the entry referenced may describe a type modifier: constant,
+packed, pointer, reference or volatile, which in turn will reference
+another entry describing a type or type modifier (using a
+.IX type modifiers
+.IX types, modifiers
+.IX types, packed
+.IX types, constant
+.IX types, pointer
+.IX types, reference
+.IX types, volatile
+.Cf DW_AT_type
+attribute of its own).  See section 5 for descriptions of
+the entries describing base types, user-defined types and
+type modifiers.
+.H 2 "Accessibility of Declarations"
+.I
+.IX accessibility
+.IX declarations, accessibility
+Some languages, notably C++ and Ada, have the concept of
+.IX C++ %caa
+the accessibility of an object or of some other program entity.
+The accessibility specifies which classes of other program objects
+are permitted access to the object in question.
+.R
+.P
+The accessibility of a declaration is represented by a
+.Cf DW_AT_accessibility
+attribute, whose value is a constant drawn from the set of codes
+.nr aX \n(Fg+1
+listed in Figure \n(aX.
+.DF
+.TS
+box center;
+lf(CW)
+. 
+DW_ACCESS_public
+DW_ACCESS_private
+DW_ACCESS_protected
+.TE
+.FG "Accessibility codes"
+.DE
+.H 2 "Visibility of Declarations"
+.I
+.IX Modula2
+.IX visibility
+.IX declarations, visibility
+Modula2 has the concept of the visibility of a declaration.
+The visibility specifies which declarations are to be visible outside
+of the module in which they are declared.
+.R
+.P
+The visibility of a declaration is represented by a
+.Cf DW_AT_visibility
+attribute, whose value is a constant drawn from the set of codes
+.nr aX \n(Fg+1
+listed in Figure \n(aX.
+.DF
+.TS
+box center;
+lf(CW)
+. 
+DW_VIS_local
+DW_VIS_exported
+DW_VIS_qualified
+.TE
+.FG "Visibility codes"
+.DE
+.H 2 "Virtuality of Declarations"
+.I
+.IX C++ %caa
+.IX virtuality
+.IX virtual functions
+C++ provides for virtual and pure virtual structure or class
+member functions and for virtual base classes.
+.P
+.R
+The virtuality of a declaration is represented by a
+.Cf DW_AT_virtuality
+attribute, whose value is a constant drawn from the set of codes
+.nr aX \n(Fg+1
+listed in Figure \n(aX.
+.DF
+.TS
+box center;
+lf(CW)
+. 
+DW_VIRTUALITY_none
+DW_VIRTUALITY_virtual
+DW_VIRTUALITY_pure_virtual
+.TE
+.FG "Virtuality codes"
+.DE
+.H 2 "Artificial Entries"
+.I
+.IX artificial entries
+A compiler may wish to generate debugging information entries
+for objects or types that were not actually declared
+in the source of the application.  An example is a formal parameter
+entry to represent the hidden 
+.Cf this
+parameter that most C++ implementations pass as the first argument
+to non-static member functions.
+.R
+.P
+Any debugging information entry representing the declaration of an
+object or type artificially generated by a compiler and 
+not explicitly declared by the source program may have a
+.Cf DW_AT_artificial 
+attribute.  The value of this attribute is a flag.
+.H 2 "Target-Specific Addressing Information"
+.I
+.IX segmented address space
+.IX address space, segmented
+In some systems, addresses are specified as offsets within a given
+segment rather than as locations within a single flat address space.
+.R
+.P
+Any debugging information entry that contains a description of the
+location of an object or subroutine may have a
+.Cf DW_AT_segment
+attribute, whose value is a location description.  The description
+evaluates to the segment value of the item being described.  If
+the entry containing the 
+.Cf DW_AT_segment
+attribute has a
+.Cf DW_AT_low_pc
+or 
+.Cf DW_AT_high_pc
+attribute, or a location description that evaluates to an address,
+.IX locations, descriptions
+.IX addresses, offset portion
+then those values represent the offset portion of the address
+within the segment specified by
+.Cf DW_AT_segment .
+.P
+If an entry has no
+.Cf DW_AT_segment
+attribute, it inherits the segment value from its parent entry.
+If none of the entries in the chain of parents for this entry
+back to its containing compilation unit entry have 
+.Cf DW_AT_segment
+attributes, then the entry is assumed to exist within a flat
+address space.  Similarly, if the entry has a
+.IX flat address space
+.IX address space, flat
+.Cf DW_AT_segment
+attribute containing an empty location description, that entry
+is assumed to exist within a flat address space.
+.P
+.I
+Some systems support different classes of addresses.  The address
+class may affect the way a pointer is dereferenced or the way
+a subroutine is called.
+.P
+.R
+Any debugging information entry representing a pointer or reference
+type or a subroutine or subroutine type may have a
+.IX types, pointer
+.IX types, reference
+.IX subroutines
+.IX subroutines, types
+.Cf DW_AT_address_class
+.IX addresses, class
+attribute, whose value is a constant.  The set of permissible
+values is specific to each target architecture.  The value
+.Cf DW_ADDR_none ,
+however, is common to all encodings, and means that no address class
+has been specified.
+.P
+.I
+For example, the Intel386\(tm processor might use the following
+values:
+.R
+.DF
+.TS
+box center;
+l l l
+lf(CW) lf(CW) l
+. 
+Name	Value	Meaning
+_
+DW_ADDR_none	0	no class specified
+DW_ADDR_near16	1	16-bit offset, no segment
+DW_ADDR_far16	2	16-bit offset, 16-bit segment
+DW_ADDR_huge16	3	16-bit offset, 16-bit segment
+DW_ADDR_near32	4	32-bit offset, no segment
+DW_ADDR_far32	5	32-bit offset, 16-bit segment
+.TE
+.FG "Example address class codes"
+.DE
+.H 2 "Non-Defining Declarations"
+.IX declarations, non-defining
+.IX declarations, defining
+A debugging information entry representing a program object or type
+typically represents the defining declaration of that object or type.  In
+certain contexts, however, a debugger might need information about a
+declaration of a subroutine, object or type that is not also a 
+definition to evaluate an expression correctly. 
+.P
+.I
+As an example, consider the following fragment of C code:
+.DS
+\f(CWvoid myfunc()
+{
+        int     x;
+        {
+                extern float x;
+                g(x);
+        }
+}\fP
+.DE
+.P
+ANSI-C scoping rules require that the value of the variable \f(CWx\fP
+passed to the function \f(CWg\fP is the value of the global variable
+\f(CWx\fP rather than of the local version.
+.R
+.P
+Debugging information entries that represent non-defining declarations
+of a program object or type have a
+.Cf DW_AT_declaration
+attribute, whose value is a flag.
+.H 2 "Declaration Coordinates"
+.I
+It is sometimes useful in a debugger to be able to associate a declaration
+with its occurrence in the program source.  
+.P
+.R
+.IX declarations, coordinates
+Any debugging information entry representing the declaration of 
+an object, module, subprogram or type may have 
+.Cf DW_AT_decl_file ,
+.Cf DW_AT_decl_line 
+and
+.Cf DW_AT_decl_column
+attributes, each of whose value is a constant.
+.P
+The value of the 
+.Cf DW_AT_decl_file 
+attribute corresponds
+to a file number from the statement information table for the compilation
+.IX line number information
+unit containing this debugging information entry and represents the
+source file in which the declaration appeared (see section 6.2).
+.IX source, files
+The value 0 indicates that no source file has been specified.
+.P
+The value of the
+.Cf DW_AT_decl_line
+attribute represents the source line number at which the first
+.IX source, lines
+character of the identifier of the declared object appears.
+The value 0 indicates that no source line has been specified.
+.P
+The value of the
+.Cf DW_AT_decl_column
+attribute represents the source column number at which the first
+.IX source, columns
+character of the identifier of the declared object appears.
+The value 0 indicates that no column has been specified.
+.H 2 "Identifier Names"
+.IX identifiers, names
+Any debugging information entry representing a program entity that
+has been given a name may have a
+.Cf DW_AT_name
+attribute, whose value is a string representing the name as it appears
+in the source program.  A debugging information entry containing
+no name attribute, or containing a name attribute whose value consists
+of a name containing a single null byte,
+represents a program entity for which no name was given in the source.
+.I
+.P
+Note that since the names of program objects
+described by DWARF are the names as they appear in the source program,
+implementations of language translators that use some form of mangled
+name (as do many implementations of C++) should use the unmangled
+.IX C++ %caa
+form of the name in the DWARF 
+.Cf DW_AT_name
+attribute, including the keyword
+.Cf operator ,
+if present.  Sequences of multiple whitespace characters may be compressed.
+.R
+.OP
+.H 1 "PROGRAM SCOPE ENTRIES"
+This section describes debugging information entries that relate
+to different levels of program scope: compilation unit, module,
+subprogram, and so on.  These entries may be thought of as
+bounded by ranges of text addresses within the program.
+.H 2   "Compilation Unit Entries"
+An object file may be derived from one or more compilation units.  Each
+such compilation unit will be described by a debugging information 
+entry with the tag \f(CWDW_TAG_compile_unit\fP.
+.I
+.P
+A compilation unit typically represents the text and data contributed
+.IX compilation units
+to an executable by a single relocatable object file.  It may
+be derived from several source files, including pre-processed ``include
+files.''
+.R
+.P
+The compilation unit entry may have the following attributes:
+.AL
+.LI
+A 
+.Cf DW_AT_low_pc
+attribute whose value is the
+relocated address of the first machine instruction generated for that 
+compilation unit.
+.LI
+A
+.Cf DW_AT_high_pc
+attribute whose value is the
+relocated address of the first location
+past the last machine instruction generated for that compilation unit.
+.P
+.I
+The address may be beyond the last valid instruction in the executable,
+of course, for this and other similar attributes.
+.R
+.P
+The presence of low and high pc attributes in a compilation unit entry
+imply that the code generated for that compilation unit is
+contiguous and exists totally within the boundaries specified
+by those two attributes.  If that is not the case, no low
+and high pc attributes should be produced.
+.IX address space, contiguous
+.LI
+A
+.Cf DW_AT_name
+attribute whose value is a
+null-terminated string containing the full or relative path name of
+the primary source file from which the compilation unit was derived.
+.IX source, files
+.LI
+A 
+.Cf DW_AT_language
+attribute whose constant value is
+.IX languages
+a code indicating the source language of the compilation unit.
+.nr aX \n(Fg+1
+The set of language names and their meanings are 
+given in Figure \n(aX.
+.DF
+.TS
+box center;
+lf(CW) lf(R)
+. 
+DW_LANG_C	Non-ANSI C, such as K&R
+DW_LANG_C89	ISO/ANSI C
+DW_LANG_C_plus_plus	C++
+DW_LANG_Fortran77	FORTRAN77
+DW_LANG_Fortran90	Fortran90
+DW_LANG_Modula2	Modula2
+DW_LANG_Pascal83	ISO/ANSI Pascal
+.TE
+.FG "Language names"
+.DE
+.LI
+A
+.Cf DW_AT_stmt_list
+attribute whose value is a reference to
+line number information for this compilation unit.
+.IX line number information
+.P
+This information is placed in a separate object file section from the debugging
+information entries themselves.  The value of the statement list attribute
+is the offset in the \f(CW.debug_line\fP section of the first byte of the 
+line number information for this compilation unit.  See section 6.2.
+.LI
+A
+.Cf DW_AT_macro_info
+attribute whose value is a reference to the macro information for this
+compilation unit.
+.IX macro information
+.P
+This information is placed in a separate object file section from the debugging
+information entries themselves.  The value of the macro information attribute
+is the offset in the \f(CW.debug_macinfo\fP section of the first byte of the 
+macro information for this compilation unit.  See section 6.3.
+.LI
+A
+.Cf DW_AT_comp_dir
+attribute whose value is a null-terminated string containing
+the current working directory of the compilation command that
+produced this compilation unit in whatever form makes sense
+for the host system.
+.P
+.I
+The suggested form for the value of the \f(CWDW_AT_comp_dir\fP
+attribute on \*(aX systems is ``hostname\f(CW:\fPpathname''.  If no
+hostname is available, the suggested form is ``\f(CW:\fPpathname''.
+.R
+.LI
+A
+.Cf DW_AT_producer
+attribute whose value is a null-terminated string containing information
+about the compiler that produced the compilation unit.  The
+actual contents of the string will be specific to each producer,
+but should begin with the name of the compiler vendor or some
+other identifying character sequence that should avoid
+confusion with other producer values.
+.LI
+A
+.Cf DW_AT_identifier_case
+.IX identifiers, case
+attribute whose constant value is a code describing the treatment of
+identifiers within this compilation unit.  The set of identifier case
+.nr aX \n(Fg+1
+codes is given in Figure \n(aX.
+.DF
+.TS
+box center;
+lf(CW)
+. 
+DW_ID_case_sensitive
+DW_ID_up_case
+DW_ID_down_case
+DW_ID_case_insensitive
+.TE
+.FG "Identifier case codes"
+.DE
+.P
+.Cf DW_ID_case_sensitive 
+is the default for all compilation units that do not have this attribute.
+It indicates that names given as the values of 
+.Cf DW_AT_name
+attributes in debugging information entries for the compilation unit
+reflect the names as they appear in the source program.
+The debugger should be sensitive to the case of identifier names
+when doing identifier lookups.
+.P
+.Cf DW_ID_up_case
+means that the producer of the debugging information for this compilation
+unit converted all source names to upper case.  The values of the
+name attributes may not reflect the names as they appear in the source
+program.  The debugger should convert all names to upper case
+when doing lookups.
+.P
+.Cf DW_ID_down_case
+means that the producer of the debugging information for this compilation
+unit converted all source names to lower case.  The values of the
+name attributes may not reflect the names as they appear in the source
+program.  The debugger should convert all names to lower case when
+doing lookups.
+.P
+.Cf DW_ID_case_insensitive 
+means that the values of the name attributes reflect the names
+as they appear in the source program but that a case insensitive
+lookup should be used to access those names.
+.LI
+A
+.Cf DW_AT_base_types
+.IX base types
+.IX types, base
+attribute whose value is a reference.  This attribute points to
+a debugging information entry representing another compilation
+unit.  It may be used to specify the compilation unit containing
+the base type entries used by entries in the current compilation
+unit (see section 5.1).
+.P
+.I
+This attribute provides a consumer a way to find the definition
+of base types for a compilation unit that does not itself
+contain such definitions.  This allows a consumer, for example,
+to interpret a type conversion to a base type correctly.
+.R
+.LE
+.R
+.P
+A compilation unit entry 
+owns debugging information entries that represent the declarations made in
+the corresponding compilation unit.
+.H 2 "Module Entries"
+.I
+Several languages have the concept of a ``module.''  
+.IX modules
+.P
+.R
+A module is
+represented by a debugging information entry with the tag
+.Cf DW_TAG_module .
+Module entries may own other debugging information entries describing
+program entities whose declaration scopes end at the end of the module
+itself.
+.P
+If the module has a name, the module entry has a 
+.Cf DW_AT_name 
+attribute whose
+value is a null-terminated string containing the module name as it appears
+in the source program.
+.P
+If the module contains initialization code, the module entry
+has a 
+.Cf DW_AT_low_pc
+attribute whose value is the
+relocated address of the first machine instruction generated for that 
+initialization code.  It also has a 
+.Cf DW_AT_high_pc
+attribute whose value is
+the relocated address of the first location past the last machine
+instruction generated for the initialization code.
+.P
+If the module has been assigned a priority, it may have a
+.Cf DW_AT_priority
+attribute.  The value of this attribute is a reference to another
+.IX modules, priority
+debugging information entry describing a variable with a constant
+value.  The value of this variable is the actual constant
+value of the module's priority, represented as it would be on the
+target architecture.
+.P
+.I
+.IX Modula2
+.IX modules, definition
+A Modula2 definition module may be represented by a module entry
+containing a
+.Cf DW_AT_declaration
+attribute.
+.R
+.H 2   "Subroutine and Entry Point Entries"
+.IX subroutines
+.IX entry points
+The following tags exist to describe debugging information
+entries for subroutines and entry points:
+.VL 30
+.LI \f(CWDW_TAG_subprogram\fP
+A global or file static subroutine or function.
+.LI \f(CWDW_TAG_inlined_subroutine\fP
+A particular inlined instance of a subroutine or function.
+.LI \f(CWDW_TAG_entry_point\fP
+A Fortran entry point.
+.LE
+.H 3 "General Subroutine and Entry Point Information"
+The subroutine or entry point entry has a 
+.Cf DW_AT_name 
+attribute
+whose value is a null-terminated string containing the subroutine or entry
+point name as it appears in the source program.
+.P
+If the name of the subroutine described by an entry with the tag
+.Cf DW_TAG_subprogram
+is visible outside of its containing compilation unit, that
+entry has a
+.Cf DW_AT_external
+attribute, whose value is a flag.
+.IX declarations, external
+.I
+.P
+.IX members, functions
+.IX subroutines, members
+Additional attributes for functions that are members of a class or
+structure are described in section 5.5.5.
+.P
+A common debugger feature is to allow the debugger user to call a
+subroutine within the subject program.  In certain cases, however,
+the generated code for a subroutine will not obey the standard calling
+conventions for the target architecture and will therefore not
+.IX calling conventions
+be safe to call from within a debugger.
+.R
+.P
+A subroutine entry may contain a
+.Cf DW_AT_calling_convention
+attribute, whose value is a constant.  If this attribute is not
+present, or its value is the constant
+.Cf DW_CC_normal ,
+then the subroutine may be safely called by obeying the ``standard''
+calling conventions of the target architecture.  If the value of
+the calling convention attribute is the constant
+.Cf DW_CC_nocall ,
+the subroutine does not obey standard calling conventions, and it
+may not be safe for the debugger to call this subroutine.
+.P
+If the semantics of the language of the compilation unit 
+containing the subroutine entry distinguishes between ordinary subroutines
+.IX main programs
+and subroutines that can serve as the ``main program,'' that is, subroutines
+that cannot be called directly following the ordinary calling conventions,
+then the debugging information entry for such a subroutine may have a
+calling convention attribute whose value is the constant
+.Cf DW_CC_program .
+.P
+.I
+The 
+.Cf DW_CC_program 
+value is intended to support Fortran main programs.
+It is not intended as a way of finding the entry address for the program.
+.R
+.H 3 "Subroutine and Entry Point Return Types"
+.IX subroutines, return types
+.IX entry points, return types
+If the subroutine or entry point is a function that returns a value, then
+its debugging information entry has a
+.Cf DW_AT_type
+attribute to denote the type returned by that function.
+.P
+.I
+Debugging information entries for C 
+.Cf void
+.IX C %c
+functions should not have an attribute for the return type.
+.P
+In ANSI-C there is a difference between the types of functions
+declared using function prototype style declarations and those
+declared using non-prototype declarations.  
+.IX subroutines, prototypes
+.P
+.R
+A subroutine entry
+declared with a function prototype style declaration may have a
+.Cf DW_AT_prototyped
+attribute, whose value is a flag.
+.H 3 "Subroutine and Entry Point Locations"
+.IX subroutines, locations
+.IX entry points, locations
+A subroutine entry has a
+.Cf DW_AT_low_pc
+attribute whose value is the relocated address of the first machine instruction
+generated for the subroutine.
+It also has a
+.Cf DW_AT_high_pc
+attribute whose value is the relocated address of the
+first location past the last machine instruction generated
+for the subroutine.  
+.P
+.I
+Note that for the low and high pc attributes to have meaning, DWARF
+makes the assumption that the code for a single subroutine is allocated
+in a single contiguous block of memory.
+.IX address space, contiguous
+.R
+.P
+An entry point has a
+.Cf DW_AT_low_pc
+attribute whose value is the relocated address of the first machine instruction
+generated for the entry point.
+.P
+Subroutines and entry points may also have 
+.Cf DW_AT_segment 
+and 
+.Cf DW_AT_address_class
+.IX segmented address space
+.IX address space, segmented
+.IX addresses, class
+attributes, as appropriate, to specify which segments the code
+for the subroutine resides in and the addressing mode to be used
+in calling that subroutine.
+.P
+A subroutine entry representing a subroutine declaration
+that is not also a definition does not have low and high pc attributes.
+.IX declarations, non-defining
+.H 3 "Declarations Owned by Subroutines and Entry Points"
+.IX subroutines, declarations owned by
+.IX entry points, declarations owned by
+The declarations enclosed by a subroutine or entry point
+are represented by debugging information entries that are
+owned by the subroutine or entry point entry.
+Entries representing the formal parameters of the subroutine or
+entry point appear in
+the same order as the corresponding declarations in the source program.
+.IX attributes, ordering
+.IX parameters, formal
+.P
+.I
+There is no ordering requirement on entries for declarations that are
+children of subroutine or entry point entries but that do not represent
+formal parameters.  The formal parameter entries may be interspersed
+with other entries used by formal parameter entries, such as type entries.
+.R
+.P
+The unspecified parameters of a variable parameter list
+.IX parameters, unspecified
+are represented by a debugging information entry with the tag 
+.Cf DW_TAG_unspecified_parameters .
+.P
+The entry for a subroutine or entry point that includes a Fortran 
+.IX Fortran
+.IX common blocks
+common block has a child entry with the tag
+.Cf DW_TAG_common_inclusion .
+The common inclusion entry has a
+.Cf DW_AT_common_reference
+attribute whose value is a reference to the debugging entry for
+the common block being included (see section 4.2).
+.H 3 "Low-Level Information"
+A subroutine or entry point entry may have a
+.Cf DW_AT_return_addr
+.IX subroutines, return addresses
+attribute, whose value is a location description.
+The location calculated is the place where the return address for 
+the subroutine or entry point is stored.
+.P
+A subroutine or entry point entry may also have a
+.Cf DW_AT_frame_base
+.IX subroutines, frame base
+attribute, whose value is a location description that
+computes the ``frame base'' for the subroutine or entry point.
+.P
+.I
+The frame base for a procedure is typically an address fixed
+relative to the first unit of storage allocated for the procedure's
+stack frame.  The 
+.Cf DW_AT_frame_base
+attribute can be used in several ways:
+.AL
+.LI
+In procedures that need location lists to locate local variables, the
+.Cf DW_AT_frame_base
+can hold the needed location list, while all variables'
+location descriptions can be simpler location expressions involving the frame 
+base.
+.LI
+It can be used as a key in resolving "up-level" addressing with nested
+routines.  (See 
+.Cf DW_AT_static_link ,
+below)
+.LE
+.P
+Some languages support nested subroutines.  In such languages, it is possible
+.IX subroutines, nested
+to reference the local variables of an outer subroutine from within
+an inner subroutine.  The 
+.Cf DW_AT_static_link 
+and 
+.Cf DW_AT_frame_base 
+attributes allow debuggers to support this same kind of referencing.
+.R
+.P
+If a subroutine or entry point is nested, it may have a
+.Cf DW_AT_static_link
+attribute, whose value is a location description that
+computes the frame base of the relevant instance of the subroutine
+that immediately encloses the subroutine or entry point.
+.P
+In the context of supporting nested subroutines, the 
+.Cf DW_AT_frame_base
+attribute value should obey the following constraints:
+.AL
+.LI
+It should compute a value that does not change during the life of the procedure,
+and
+.LI
+The computed value should be unique among instances of the same subroutine.
+(For typical 
+.Cf DW_AT_frame_base 
+use, this means that a recursive
+subroutine's stack frame must have non-zero size.)
+.LE
+.P
+.I
+If a debugger is attempting to resolve an up-level reference to a variable, it
+uses the nesting structure of DWARF to determine which subroutine is the lexical
+parent and the 
+.Cf DW_AT_static_link
+value to identify the appropriate active frame
+of the parent.  It can then attempt to find the reference within the context
+of the parent. 
+.R
+.H 3 "Types Thrown by Exceptions"
+.I
+In C++ a subroutine may declare a set of types for which
+.IX C++ %caa
+.IX exceptions
+that subroutine may generate or ``throw'' an exception.
+.P
+.R
+If a subroutine explicitly declares that it may throw an
+exception for one or more types, each such type is
+represented by a debugging information entry with the tag
+.Cf DW_TAG_thrown_type .
+Each such entry is a child of the entry representing the
+subroutine that may throw this type.  All thrown type entries
+should follow all entries representing the formal parameters
+of the subroutine and precede all entries representing the
+local variables or lexical blocks contained in the subroutine.
+Each thrown type entry contains a
+.Cf DW_AT_type
+attribute, whose value is a reference to an entry describing
+the type of the exception that may be thrown.
+.H 3 "Function Template Instantiations"
+.I
+.IX C++ %caa
+.IX templates
+In C++ a function template is a generic
+definition of a function that
+is instantiated differently when called with values
+of different types.  DWARF does not represent the generic
+template definition, but does represent each instantiation.
+.R
+.P
+A template instantiation is represented by a debugging information
+entry with the tag
+.Cf DW_TAG_subprogram .
+With three exceptions,
+such an entry will contain the same attributes and have the same
+types of child entries as would an entry for a subroutine 
+defined explicitly
+using the instantiation types.  The exceptions are:
+.AL
+.LI 
+Each formal parameterized type declaration appearing in the
+template definition is represented by a debugging information entry
+with the tag 
+.Cf DW_TAG_template_type_parameter .
+Each such entry has a 
+.Cf DW_AT_name
+attribute, whose value is a null-terminated
+string containing the name of the formal type parameter as it
+appears in the source program.  The template type parameter
+entry also has a 
+.Cf DW_AT_type
+attribute describing the actual type by
+which the formal is replaced for this instantiation.
+All template type parameter entries should appear before
+the entries describing the instantiated formal parameters
+to the function.
+.LI
+.IX compilation units
+If the compiler has generated a special compilation unit
+to hold the template instantiation and that compilation unit
+has a different name
+from the compilation unit containing the template definition,
+the name attribute for the debugging entry representing
+that compilation unit should be empty or omitted.
+.LI
+.IX declarations, coordinates
+If the subprogram entry representing the template instantiation
+or any of its child entries
+contain declaration coordinate attributes, those attributes
+should refer to the source for the template definition, not
+to any source generated artificially by the compiler for this
+instantiation.
+.LE
+.H 3 "Inline Subroutines"
+.IX subroutines, inline
+A declaration or a definition of an inlinable subroutine
+is represented by a debugging information entry with the tag
+.Cf DW_TAG_subprogram .
+The entry for a subroutine that is explicitly declared
+to be available for inline expansion or that was expanded inline
+implicitly by the compiler has a
+.Cf DW_AT_inline 
+attribute whose value is a constant.  The set of values 
+for the 
+.Cf DW_AT_inline
+.nr aX \n(Fg+1
+attribute is given in Figure \n(aX.
+.DF
+.TS
+box center;
+l l
+lf(CW) l
+. 
+Name	Meaning
+_
+DW_INL_not_inlined	Not declared inline nor inlined by the compiler
+DW_INL_inlined	Not declared inline but inlined by the compiler
+DW_INL_declared_not_inlined	Declared inline but not inlined by the compiler
+DW_INL_declared_inlined	Declared inline and inlined by the compiler
+.TE
+.FG "Inline codes"
+.DE
+.H 4 "Abstract Instances"
+For the remainder of this discussion,
+any debugging information entry that is owned (either directly or
+indirectly) by a debugging information entry that contains the 
+.Cf DW_AT_inline
+attribute will be referred to as an ``abstract instance entry.''
+Any subroutine entry that contains a
+.Cf DW_AT_inline 
+attribute will be known as an ``abstract instance root.''
+Any set of abstract instance entries that are all children (either directly
+or indirectly) of some abstract instance root, together with the root itself,
+will be known as an ``abstract instance tree.''
+.P
+A debugging information entry that is a member of an abstract instance
+tree should not contain a
+.Cf DW_AT_high_pc , 
+.Cf DW_AT_low_pc , 
+.Cf DW_AT_location ,
+.Cf DW_AT_return_addr , 
+.Cf DW_AT_start_scope ,
+or
+.Cf DW_AT_segment 
+attribute.
+.P
+.I
+It would not make sense to put these attributes
+into abstract instance entries since
+such entries do not represent actual (concrete) instances and thus
+do not actually exist at run-time.
+.P
+.R
+The rules for the relative location of entries belonging to abstract instance 
+trees are exactly
+the same as for other similar types of entries that are not abstract.
+Specifically, the rule that requires that an entry representing a
+declaration be a direct child of the entry representing the scope of
+the declaration applies equally to both abstract and
+non-abstract entries.  Also, the ordering rules for formal parameter entries,
+member entries, and so on, all apply regardless of whether or not a given entry
+is abstract.
+.H 4 "Concrete Inlined Instances"
+.IX subroutines, inlined
+Each inline expansion of an inlinable subroutine is represented
+by a debugging information entry with the tag
+.Cf DW_TAG_inlined_subroutine .
+Each such entry should be a direct child of the entry that represents the
+scope within which the inlining occurs.
+.P
+Each inlined subroutine entry contains a 
+.Cf DW_AT_low_pc
+attribute, representing the address of the first
+instruction associated with the given inline
+expansion.   Each inlined subroutine entry also contains a
+.Cf DW_AT_high_pc
+attribute, representing the
+address of the first location past the last instruction associated with
+the inline expansion.
+.P
+For the remainder of this discussion,
+any debugging information entry that is owned (either directly or indirectly)
+by a debugging information entry with the tag 
+.Cf DW_TAG_inlined_subroutine 
+will be referred to as a ``concrete inlined instance entry.''
+Any entry that has the tag 
+.Cf DW_TAG_inlined_subroutine
+will be known as
+a ``concrete inlined instance root.''
+Any set of concrete inlined instance entries that are all children (either
+directly or indirectly) of some concrete inlined instance root, together
+with the root itself, will be known as a ``concrete inlined instance
+tree.''
+.P
+Each concrete inlined instance tree is uniquely associated with one (and
+only one) abstract instance tree.
+.P
+.I
+Note, however, that the reverse is not true.  Any given abstract instance
+tree may be associated with several different concrete inlined instance
+trees, or may even be associated with zero concrete inlined instance
+trees.
+.P
+.R
+Also, each separate entry within a given concrete inlined instance tree is
+uniquely associated with one particular entry in the associated abstract
+instance tree.  In other words, there is a one-to-one mapping from entries
+in a given concrete inlined instance tree to the entries in the associated
+abstract instance tree.
+.P
+.I
+Note, however, that the reverse is not true.  A given abstract instance
+tree that is associated with a given concrete inlined instance tree
+may (and quite probably will) contain more entries than the associated
+concrete inlined instance tree (see below).
+.R
+.P
+Concrete inlined instance entries do not have most of the attributes (except
+for 
+.Cf DW_AT_low_pc , 
+.Cf DW_AT_high_pc ,
+.Cf DW_AT_location ,
+.Cf DW_AT_return_addr ,
+.Cf DW_AT_start_scope
+and
+.Cf DW_AT_segment )
+that such entries
+would otherwise normally have.  In place of these omitted attributes,
+each concrete inlined instance entry has a
+.Cf DW_AT_abstract_origin 
+attribute that 
+may be used to obtain the missing information (indirectly) from
+the associated abstract instance entry.  The value of the abstract
+origin attribute is a reference to the associated abstract instance entry.
+.P
+For each pair of entries that are associated via a
+.Cf DW_AT_abstract_origin
+attribute, both members of the pair will have the same tag.  So, for
+example, an entry with the tag 
+.Cf DW_TAG_local_variable 
+can only be associated
+with another entry that also has the tag 
+.Cf DW_TAG_local_variable.
+The only exception to this rule is that the root of a concrete
+instance tree (which must always have the tag 
+.Cf DW_TAG_inlined_subroutine )
+can only be associated with the root of its associated abstract
+instance tree (which must have the tag
+.Cf DW_TAG_subprogram ).
+.P
+In general, the structure and content of any given concrete
+instance tree will be directly analogous to the structure and content
+of its associated abstract instance tree.
+There are two exceptions to this general rule however.
+.AL
+.LI
+.IX anonymous types
+No entries representing anonymous types are ever made a part
+of any concrete instance inlined tree.
+.LI
+.IX members
+No entries representing members of structure, union or class
+types are ever made a part of any concrete inlined instance tree.
+.LE
+.P
+.I
+Entries that represent members and anonymous types are omitted from concrete
+inlined instance trees because they would simply be redundant duplicates of
+the corresponding entries in the associated abstract instance trees.  If
+any entry within a concrete inlined instance tree needs to refer to an
+anonymous type that was declared within the scope of the
+relevant inline function, the reference should simply refer to the abstract
+instance entry for the given anonymous type.
+.R
+.P
+.IX declarations, coordinates
+If an entry within a concrete inlined instance tree contains
+attributes describing the declaration coordinates of
+that entry,
+then those attributes should refer to the file, line and column
+of the original declaration of the subroutine, not to the
+point at which it was inlined.
+.H 4 "Out-of-Line Instances of Inline Subroutines"
+.IX subroutines, out-of-line
+Under some conditions, compilers may need to generate concrete executable
+instances of inline subroutines other than at points where those subroutines
+are actually called.  For the remainder of this discussion,
+such concrete instances of inline subroutines will
+be referred to as ``concrete out-of-line instances.'' 
+.P
+.I
+In C++, for example, taking the address of a function declared to be inline
+can necessitate the generation of a concrete out-of-line
+instance of the given function.
+.P
+.R
+The DWARF representation of a concrete out-of-line instance of an inline
+subroutine is essentially the same as for a concrete inlined instance of
+that subroutine (as described in the preceding section).  The representation
+of such a concrete out-of-line instance makes use of 
+.Cf DW_AT_abstract_origin
+attributes in exactly the same way as they are used for a concrete inlined
+instance (that is, as references to corresponding entries 
+within the associated
+abstract instance tree) and, as for concrete instance trees, the
+entries for anonymous types and for all members are omitted.
+.P
+The differences between the DWARF representation of a concrete out-of-line
+instance of a given subroutine and the representation of a concrete inlined
+instance of that same subroutine are as follows:
+.AL
+.LI
+The root entry for a concrete out-of-line instance of a given
+inline subroutine has the same tag as does its associated
+(abstract) inline subroutine entry (that is, it does not have the
+tag 
+.Cf DW_TAG_inlined_subroutine ).
+.LI
+The root entry for a concrete out-of-line instance tree is
+always directly owned by the same parent entry that
+also owns the root entry of the associated abstract instance.
+.LE
+.H 2   "Lexical Block Entries"
+.I
+.IX lexical blocks
+A lexical block is a bracketed sequence of source statements that may
+contain any number of declarations.  In some languages (C and C++)
+blocks can be nested within other blocks to any depth.  
+.P
+.R
+A lexical block is represented by a debugging information entry
+with the tag
+.Cf DW_TAG_lexical_block .
+.P
+The lexical block entry has a 
+.Cf DW_AT_low_pc
+attribute whose value is the
+relocated address of the first machine instruction generated for the lexical
+block.
+The lexical block entry also has a 
+.Cf DW_AT_high_pc
+attribute whose value is the
+relocated address of the first location
+past the last machine instruction generated for the lexical block.
+.P
+If a name has been given to the lexical block in the source program,
+then the corresponding lexical block entry has a 
+.Cf DW_AT_name 
+attribute
+whose value is a null-terminated string containing the name of the
+lexical block as it appears in the source program.  
+.P
+.I
+This is not the
+same as a C or C++ label (see below).
+.R
+.P
+The lexical block entry owns debugging information entries that
+describe the declarations within that lexical block.
+There is one such debugging information entry for each local declaration
+of an identifier or inner lexical block.
+.H 2   "Label Entries"
+.I
+.IX labels
+A label is a way of identifying a source statement.  A labeled statement
+is usually the target of one or more ``go to'' statements.
+.P
+.R
+A label is represented by a debugging information entry
+with the tag 
+.Cf DW_TAG_label .
+The entry for a label should be owned by
+the debugging information entry representing the scope within which the name
+of the label could be legally referenced within the source program.
+.P
+The label entry has a 
+.Cf DW_AT_low_pc
+attribute whose value is the
+relocated address of the first machine instruction generated for the
+statement identified by the label in the source program.
+The label entry also has a 
+.Cf DW_AT_name 
+attribute
+whose value is a null-terminated string containing the name of the
+label as it appears in the source program.
+.H 2 "With Statement Entries"
+.I
+.IX with statements
+.IX Pascal
+.IX Modula2
+Both Pascal and Modula support the concept of a ``with'' statement. 
+The with statement specifies a sequence of executable statements
+within which the fields of a record variable may be referenced, unqualified
+by the name of the record variable.
+.P
+.R
+A with statement is represented by a debugging information entry with
+the tag
+.Cf DW_TAG_with_stmt .
+A with statement entry has a 
+.Cf DW_AT_low_pc
+attribute whose value is the relocated
+address of the first machine instruction generated for the body of
+the with statement.  A with statement entry also has a 
+.Cf DW_AT_high_pc
+attribute whose value is the relocated
+address of the first location after the last machine instruction generated for the body of
+the statement.
+.P
+The with statement entry has a 
+.Cf DW_AT_type
+attribute, denoting
+the type of record whose fields may be referenced without full qualification
+within the body of the statement.  It also has a
+.Cf DW_AT_location
+attribute, describing how to find the base address
+of the record object referenced within the body of the with statement.
+.H 2 "Try and Catch Block Entries"
+.I
+.IX C++ %caa
+.IX exceptions
+.IX try blocks
+.IX catch blocks
+In C++ a lexical block may be designated as a ``catch block.''
+A catch block is an exception handler that handles exceptions
+thrown by an immediately preceding ``try block.''  A catch block
+designates the type of the exception that it can handle.
+.R
+.P
+A try block is represented by a debugging information entry
+with the tag
+.Cf DW_TAG_try_block .
+A catch block is represented by a debugging information entry
+with the tag
+.Cf DW_TAG_catch_block .
+Both try and catch block entries contain a
+.Cf DW_AT_low_pc
+attribute whose value is the
+relocated address of the first machine instruction generated for that 
+block.  These entries also contain a
+.Cf DW_AT_high_pc
+attribute whose value is the
+relocated address of the first location
+past the last machine instruction generated for that block.
+.P
+Catch block entries have at least one child entry,
+an entry representing the type of exception accepted
+by that catch block.  This child entry will have one of the tags
+.Cf DW_TAG_formal_parameter
+or
+.Cf DW_TAG_unspecified_parameters ,
+.IX parameters, formal
+.IX parameters, unspecified
+and will have the same form as other parameter entries.
+.P
+The first sibling of each try block entry will be a catch block
+entry.
+.OP
+.H 1 "DATA OBJECT AND OBJECT LIST ENTRIES"
+This section presents the debugging information entries that
+describe individual data objects: variables, parameters and
+constants, and lists of those objects that may be grouped
+in a single declaration, such as a common block.
+.H 2   "Data Object Entries"
+.IX variables
+.IX parameters, formal
+.IX constants
+Program variables, formal parameters and constants are represented
+by debugging information entries with the tags
+.Cf DW_TAG_variable ,
+.Cf DW_TAG_formal_parameter
+and
+.Cf DW_TAG_constant ,
+respectively. 
+.P
+.I
+The tag
+.Cf DW_TAG_constant
+is used for languages that distinguish between variables
+that may have constant value and true named constants.
+.R
+.P
+The debugging information entry for a program variable, formal
+parameter or constant may have the following attributes:
+.AL
+.LI
+A 
+.Cf DW_AT_name 
+attribute whose value is a null-terminated
+string containing the data object name as it appears in the source program.
+.P
+.IX anonymous unions
+.IX unions, anonymous
+.IX C++ %caa
+If a variable entry describes a C++ anonymous union, the name
+attribute is omitted or consists of a single zero byte.
+.LI
+If the name of a variable is visible outside of its enclosing 
+compilation unit, the variable entry has a
+.Cf DW_AT_external
+.IX declarations, external
+attribute, whose value is a flag.
+.I
+.P
+.IX members, static data
+The definitions of C++ static data members
+of structures or classes are represented by variable entries flagged
+as external.
+.IX C %c
+.IX C++ %caa
+Both file static and local variables in C and C++ are represented 
+by non-external variable entries.
+.R
+.LI
+A
+.Cf DW_AT_location
+attribute, whose value describes the location of a variable or parameter
+at run-time.
+.P
+.IX declarations, non-defining
+A data object entry representing a non-defining declaration of the object
+will not have a location attribute, and will have the
+.Cf DW_AT_declaration
+attribute.
+.P
+In a variable entry representing the definition of the variable
+(that is, with no
+.Cf DW_AT_declaration
+attribute)
+if no location attribute is present, or if
+the location attribute is present but describes
+a null entry (as described in section 2.4), the variable
+is assumed to exist in the source code but not in the executable
+program (but see number 9, below).
+.IX optimized code
+.P
+The location of a variable may be further specified with a
+.Cf DW_AT_segment
+attribute, if appropriate.
+.IX segmented address space
+.IX address space, segmented
+.LI
+A 
+.Cf DW_AT_type
+attribute describing the type of the variable, constant or formal
+parameter.
+.LI
+.IX members, static data
+.IX declarations, defining
+If the variable entry represents the defining declaration for a C++ static
+data member of a structure, class or union, the entry has a
+.Cf DW_AT_specification
+attribute, whose value is a reference to the debugging information
+entry representing the declaration of this data member.  The
+referenced entry will be a child of some class, structure or
+union type entry.
+.IX classes
+.IX structures
+.IX unions
+.P
+Variable entries containing the 
+.Cf DW_AT_specification
+attribute do not need to duplicate information provided by the
+declaration entry referenced by the specification attribute.
+In particular, such variable entries do not need to contain
+attributes for the name or type of the data member whose
+definition they represent.
+.LI
+.I
+Some languages distinguish between parameters whose value in the
+calling function can be modified by the callee (variable parameters), 
+and parameters whose value in the calling function cannot be modified
+by the callee (constant parameters).
+.P
+.R
+If a formal parameter entry represents a parameter whose value
+in the calling function may be modified by the callee, that entry
+may have a
+.Cf DW_AT_variable_parameter
+attribute, whose value is a flag.  The absence of this attribute
+implies that the parameter's value in the calling function cannot
+be modified by the callee.
+.IX parameters, variable
+.LI
+.I
+Fortran90 has the concept of an optional parameter.
+.IX Fortran90
+.P
+.R
+.IX parameters, optional
+If a parameter entry represents an optional parameter, it has a
+.Cf DW_AT_is_optional
+attribute, whose value is a flag.
+.LI
+.IX parameters, default value
+A formal parameter entry describing a formal parameter that has a default
+value may have a
+.Cf DW_AT_default_value
+attribute.  The value of this attribute is a reference to the
+debugging information entry for a variable or subroutine.  The
+default value of the parameter is the value of the variable (which
+may be constant) or the value returned by the subroutine.  If the
+value of the
+.Cf DW_AT_default_value
+attribute is 0, it means that no default value has been specified.
+.LI
+.IX constants
+An entry describing a variable whose value is constant
+and not represented by an object in the address space of the program,
+or an entry describing a named constant,
+does not have a location attribute.  Such entries have a
+.Cf DW_AT_const_value
+attribute, whose value may be a string or any of the constant
+data or data block forms, as appropriate for the representation
+of the variable's value.  The value of this attribute is the actual
+constant value of the variable, represented as it would be
+on the target architecture.
+.LI
+.IX scope
+.IX declarations, scope
+If the scope of an object begins sometime after the low pc value
+for the scope most closely enclosing the object, the
+object entry may have a
+.Cf DW_AT_start_scope
+attribute.  The value of this attribute is the offset in bytes of the beginning
+of the scope for the object from the low pc value of the debugging
+information entry that defines its scope.
+.P
+.I
+The scope of a variable may begin somewhere in the middle of a lexical
+block in a language that allows executable code in a 
+block before a variable declaration, or where one declaration
+containing initialization code may change the scope of a subsequent
+declaration.  For example, in the following C code:
+.DS
+\f(CWfloat x = 99.99;
+
+int myfunc()
+{
+	float f = x;
+	float x = 88.99;
+
+	return 0;
+}\fP
+.DE
+.P
+ANSI-C scoping rules require that the value of the variable \f(CWx\fP
+assigned to the variable \f(CWf\fP in the initialization sequence
+is the value of the global variable \f(CWx\fP, rather than the local \f(CWx\fP,
+because the scope of the local variable \f(CWx\fP only starts after the full
+declarator for the local \f(CWx\fP.
+.R
+.LE
+.P
+.H 2 "Common Block Entries"
+.IX common blocks
+.IX Fortran
+A Fortran common block may be described by a debugging information
+entry with the tag
+.Cf DW_TAG_common_block .
+The common block entry has a
+.Cf DW_AT_name 
+attribute whose value is a null-terminated
+string containing the common block name as it appears in the source program.
+It also has a
+.Cf DW_AT_location
+attribute whose value describes the location of the beginning of the
+common block.  The common block entry owns debugging information
+entries describing the variables contained within the common block.
+.H 2 "Imported Declaration Entries"
+.I 
+.IX declarations, imported
+.IX imports
+Some languages support the concept of importing into a given
+module declarations made in a different module.
+.R
+.P
+An imported declaration is represented by a debugging information
+entry with the tag
+.Cf DW_TAG_imported_declaration .
+The entry for the imported declaration has a 
+.Cf DW_AT_name 
+attribute whose value
+is a null-terminated string containing the name of the entity
+whose declaration is being imported as it appears in the source
+program.  The imported declaration entry also has a
+.Cf DW_AT_import
+attribute, whose value is a reference to the debugging information
+entry representing the declaration that is being imported.
+.H 2 "Namelist Entries"
+.I
+.IX namelists
+.IX Fortran90
+At least one language, Fortran90, has the concept of a namelist.
+A namelist is an ordered list of the names of some set of declared objects.
+The namelist object itself may be used as a replacement for the 
+list of names in various contexts.
+.R
+.P
+A namelist is represented by a debugging information entry with
+the tag
+.Cf DW_TAG_namelist .
+If the namelist itself has a name, the namelist entry has a
+.Cf DW_AT_name
+attribute, whose value is a null-terminated string containing the namelist's
+name as it appears in the source program.
+.P
+Each name that is part of the namelist is represented by a debugging
+information entry with the tag 
+.Cf DW_TAG_namelist_item .
+Each such entry is a child of the namelist entry, and all of
+the namelist item entries for a given namelist are ordered as were
+the list of names they correspond to in the source program.
+.P
+Each namelist item entry contains a
+.Cf DW_AT_namelist_item
+attribute whose value is a reference to the debugging information
+entry representing the declaration of the item whose name
+appears in the namelist.
+.OP
+.H 1 "TYPE ENTRIES"
+This section presents the debugging information entries
+that describe program types: base types, modified types
+and user-defined types.
+.P
+If the scope of the declaration of a named type begins sometime after 
+.IX scope
+.IX declarations, scope
+the low pc value
+for the scope most closely enclosing the declaration, the
+declaration may have a
+.Cf DW_AT_start_scope
+attribute.  The value of this attribute is the offset in bytes of the beginning
+of the scope for the declaration from the low pc value of the debugging
+information entry that defines its scope.
+.H 2 "Base Type Entries"
+.I
+.IX base types
+.IX types, base
+A base type is a data type that is not defined in terms of
+other data types.  Each programming language has a set of
+base types that are considered to be built into that language.
+.R
+.P
+A base type is represented by a debugging information entry
+with the tag
+.Cf DW_TAG_base_type .
+A base type entry has a 
+.Cf DW_AT_name 
+attribute whose value is a null-terminated
+string describing the name of the base type as recognized by
+the programming language of the compilation unit containing
+the base type entry.
+.P
+A base type entry also has a
+.Cf DW_AT_encoding
+attribute describing how the base type is encoded and is
+to be interpreted.  The value of this attribute is a constant.
+The set of values and their meanings for the 
+.Cf DW_AT_encoding
+.nr aX \n(Fg+1
+attribute is given in Figure \n(aX.
+.DF
+.TS
+box center;
+l l
+lf(CW) l
+. 
+Name	Meaning
+_
+DW_ATE_address	linear machine address
+DW_ATE_boolean	true or false
+DW_ATE_complex_float	complex floating-point number
+DW_ATE_float	floating-point number
+DW_ATE_signed	signed binary integer
+DW_ATE_signed_char	signed character
+DW_ATE_unsigned	unsigned binary integer
+DW_ATE_unsigned_char	unsigned character
+.TE
+.FG "Encoding attribute values"
+.DE
+.P
+All encodings assume the representation that is ``normal'' for
+the target architecture.
+.P
+A base type entry has a
+.Cf DW_AT_byte_size
+attribute, whose value is a constant,
+describing the size in bytes of the storage
+unit used to represent an object of the given type.
+.P
+If the value of an object of the given type does not
+fully occupy the storage unit described by the byte size attribute,
+the base type entry may have a
+.Cf DW_AT_bit_size
+attribute and a
+.Cf DW_AT_bit_offset
+attribute, both of whose values are constants.
+The bit size attribute describes the actual size in bits used
+to represent a value of the given type.  The bit offset
+attribute describes the offset in bits of the high order
+bit of a value of the given type from the high order bit
+of the storage unit used to contain that value.
+.I
+.P
+For example, the C type 
+.Cf int
+on a machine that uses 32-bit integers would be
+represented by a base type entry with a name
+attribute whose value was ``\f(CWint\fP,'' an
+encoding attribute whose value was 
+.Cf DW_ATE_signed
+and a byte size attribute whose value was
+.Cf 4 .
+.R
+.H 2 "Type Modifier Entries"
+.IX type modifiers
+.IX types, modifiers
+A base or user-defined type may be modified in different
+ways in different languages.  A type modifier is represented
+in DWARF by a debugging information entry with one of the
+.nr aX \n(Fg+1
+tags given in Figure \n(aX.
+.DF
+.TS
+box center;
+l l
+lf(CW) l
+. 
+Tag	Meaning
+_
+DW_TAG_const_type	C or C++ const qualified type
+DW_TAG_packed_type	Pascal packed type
+DW_TAG_pointer_type	The address of the object whose type is being modified
+DW_TAG_reference_type	A C++ reference to the object whose type is being modified
+DW_TAG_volatile_type	C or C++ volatile qualified type
+.TE
+.FG "Type modifier tags"
+.DE
+.P
+.IX types, constant
+.IX types, packed
+.IX types, volatile
+.IX types, pointer
+.IX types, reference
+Each of the type modifier entries has a
+.Cf DW_AT_type
+attribute, whose value is a reference to a debugging information
+entry describing a base type, a user-defined type or another type 
+modifier.
+.P
+A modified type entry describing a pointer or reference type
+may have a 
+.IX addresses, class
+.Cf DW_AT_address_class 
+attribute
+to describe how objects having the given pointer or reference type
+ought to be dereferenced.
+.P
+When multiple type modifiers are chained together to modify
+a base or user-defined type, they are ordered as if part of
+a right-associative expression involving the base or user-defined
+type.
+.I
+.P
+As examples of how type modifiers are ordered, take the following
+C declarations:
+.R
+.DS
+.ta .5i +.5i +.5i +.5i +.5i +.5i +.5i +.5i
+\f(CWconst char * volatile p;\fP
+        \fIwhich represents a volatile pointer to a constant character.\fP
+        \fIThis is encoded in DWARF as:\fP
+        \f(CWDW_TAG_volatile_type \(-> 
+		DW_TAG_pointer_type \(->
+			DW_TAG_const_type \(->
+				DW_TAG_base_type\fP
+
+\f(CWvolatile char * const p;\fP
+        \fIon the other hand, represents a constant pointer
+        to a volatile character.\fP
+        \fIThis is encoded as:\fP
+        \f(CWDW_TAG_const_type \(-> 
+		DW_TAG_pointer_type \(->
+			DW_TAG_volatile_type \(->
+				DW_TAG_base_type\fP
+
+.DE
+.R
+.H 2 "Typedef Entries"
+.IX typedefs
+Any arbitrary type named via a typedef is represented
+by a debugging information entry with the tag 
+.Cf DW_TAG_typedef .
+The typedef entry has a 
+.Cf DW_AT_name 
+attribute whose value is a null-terminated
+string containing the name of the typedef as it appears in the
+source program.
+The typedef entry also contains a 
+.Cf DW_AT_type
+attribute.
+.P
+If the debugging information entry for a typedef represents a 
+declaration of the type that is not also a definition,
+it does not contain a type attribute.
+.IX declarations, non-defining
+.H 2     "Array Type Entries"
+.I
+.IX arrays
+Many languages share the concept of an ``array,'' which is a
+table of components of identical type.
+.P
+.R
+An array type is represented by a debugging information entry with
+the tag 
+.Cf DW_TAG_array_type .
+.P
+If a name has been given to the array type in the source program, then the
+corresponding array type entry has a 
+.Cf DW_AT_name 
+attribute whose value is a
+null-terminated string containing the array type name as it appears in the
+source program.
+.P
+.IX arrays, ordering
+The array type entry describing a multidimensional array may have a
+.Cf DW_AT_ordering
+attribute whose constant value is interpreted to mean either
+row-major or column-major ordering of array elements.
+The set of values and their meanings for the ordering attribute
+.nr aX \n(Fg+1
+are listed in Figure \n(aX.
+If no ordering attribute is present, the default ordering for
+the source language (which is indicated by the
+.Cf DW_AT_language
+attribute of the enclosing compilation unit entry)
+is assumed.
+.DF
+.TS
+box center;
+lf(CW)
+. 
+DW_ORD_col_major
+DW_ORD_row_major
+.TE
+.FG "Array ordering"
+.DE
+.P
+The ordering attribute may optionally appear on one-dimensional arrays; it
+will be ignored.
+.P
+An array type entry has a 
+.Cf DW_AT_type
+attribute describing the type
+of each element of the array.
+.P
+.IX arrays, stride
+If the amount of storage allocated to hold each element of an object of
+the given array type is different from the amount of storage that is normally
+allocated to hold an individual object of the indicated element type, then
+the array type entry has a
+.Cf DW_AT_stride_size 
+attribute, whose constant value
+represents the size in bits of each element of the array.
+.P
+If the size of the entire array can be determined statically at compile
+time, the array type entry may have a
+.Cf DW_AT_byte_size 
+attribute, whose constant value represents the total size in bytes of an
+instance of the array type.
+.P
+.I
+Note that if the size of the array can be determined statically at
+compile time, this value can usually be computed by multiplying
+the number of array elements by the size of each element.
+.P
+.R
+Each array dimension is described by a debugging information
+entry with either the tag
+.IX subranges
+.IX enumerations
+.IX arrays, dimensions
+.Cf DW_TAG_subrange_type
+or the tag
+.Cf DW_TAG_enumeration_type .
+These entries are children of the array type entry and are
+ordered to reflect the appearance of the dimensions in the source
+program (i.e. leftmost dimension first, next to leftmost second,
+and so on).
+.P
+.I
+.IX C %c
+In languages, such as ANSI-C, in which there is no concept of a
+``multidimensional array,'' 
+an array of arrays may be represented by a debugging information entry
+for a multidimensional array.
+.R
+.H 2     "Structure, Union, and Class Type Entries"
+.I
+The languages C, C++, and Pascal, among others, 
+allow the programmer to define types that
+are collections of related components.  In C and C++, these collections are
+called ``structures.''  In Pascal, they are called ``records.''  The components
+may be of different types.  The components are called ``members'' in C and
+C++, and ``fields'' in Pascal.
+.P
+.IX structures
+.IX classes
+.IX unions
+.IX records
+.IX C %c
+.IX C++ %caa
+.IX Pascal
+The components of these collections each exist in their own space in
+computer memory.  The components of a C or C++ ``union'' all coexist in
+the same memory.
+.P
+Pascal and other languages have a ``discriminated union,'' also called a
+.IX variants
+.IX discriminated unions
+``variant record.''  Here, selection of a number of alternative substructures
+(``variants'') is based on the value of a component that is not part of any of
+those substructures (the ``discriminant'').
+.P
+Among the languages discussed in this document,
+the ``class'' concept is unique to C++.  A class is similar to a structure.
+A C++ class or structure may have ``member functions'' which are subroutines
+that are within the scope of a class or structure.
+.R
+.H 3 "General Structure Description"
+Structure, union, and class types are represented by 
+debugging information entries with the tags
+.Cf DW_TAG_structure_type ,
+.Cf DW_TAG_union_type 
+and 
+.Cf DW_TAG_class_type ,
+respectively.
+If a name has been given to the structure, union, or class in the source
+program, then the corresponding structure type, union type, or class type
+entry has a 
+.Cf DW_AT_name 
+attribute whose value is a null-terminated string
+containing the type name as it appears in the source program.
+.P
+If the size of an instance of the
+structure type, union type, or class type entry can be determined
+statically at compile time, the entry has a
+.Cf DW_AT_byte_size 
+attribute whose constant value is the number of bytes required to
+hold an instance of the structure, union, or class, and any padding bytes.
+.I
+.P
+.IX structures, incomplete
+.IX classes, incomplete
+.IX unions, incomplete
+For C and C++, an incomplete structure, union or class type is represented
+by a structure, union or class entry that does not have
+a byte size attribute and that has a
+.Cf DW_AT_declaration
+attribute.
+.R
+.P
+The members of a structure, union, or class are represented by
+debugging information entries that are owned by the corresponding
+structure type, union type, or class type entry and appear in the same
+order as the corresponding declarations in the source program.
+.P
+.I
+.IX declarations, defining
+.IX members, static data
+.IX members, data
+.IX members, functions
+Data member declarations occurring within the declaration of a structure,
+union or class type are considered to be ``definitions'' of those members,
+with the exception of C++ ``static'' data members, whose definitions
+appear outside of the declaration of the enclosing structure, union
+or class type.  Function member declarations appearing within a structure,
+union or class type declaration are definitions only if the body
+of the function also appears within the type declaration.
+.R
+.P
+.IX declarations, non-defining
+If the definition for a given member of the structure, union or class
+does not appear within the body of the declaration, that member
+also has a debugging information entry describing its definition.
+That entry will have a
+.Cf DW_AT_specification
+attribute referencing 
+the debugging entry owned by the
+body of the structure, union or class debugging entry and representing
+a non-defining declaration of the data or function member.  The 
+referenced entry will
+not have information about the location of that member (low and high
+pc attributes for function members, location descriptions for data
+members) and will have a
+.Cf DW_AT_declaration
+attribute.
+.H 3 "Derived Classes and Structures"
+.IX classes, derived
+.IX structures, derived
+.IX inheritance
+The class type or structure type entry that describes a derived class 
+or structure owns debugging information entries describing each of
+the classes or structures it is derived from, ordered as they were
+in the source program.  Each such entry has the tag
+.Cf DW_TAG_inheritance .
+.P
+An inheritance entry has a 
+.Cf DW_AT_type
+attribute whose
+value is a reference to the debugging information entry describing
+the structure or class from which the parent structure or class
+of the inheritance entry is derived.  It also has a
+.Cf DW_AT_data_member_location
+attribute, whose value is a location description describing
+the location of the beginning of
+the data members contributed to the entire class by this
+subobject relative to the beginning address of the data members of the
+entire class.
+.P
+.IX accessibility
+.IX virtuality
+.IX classes, virtual base
+An inheritance entry may have a
+.Cf DW_AT_accessibility
+attribute.
+If no accessibility attribute is present,
+private access is assumed.
+If the structure or class referenced by the inheritance entry serves
+as a virtual base class, the inheritance entry has a
+.Cf DW_AT_virtuality
+attribute.
+.P 
+.I
+In C++, a derived class may contain access declarations that
+change the accessibility of individual class members from
+the overall accessibility specified by the inheritance declaration.
+A single access declaration may refer to a set of overloaded
+names.
+.R
+.P
+If a derived class or structure contains access declarations,
+.IX access declarations
+.IX C++ %caa
+each such declaration may be represented by a debugging information
+entry with the tag
+.Cf DW_TAG_access_declaration .
+Each such entry is a child of the structure or class type entry.
+.P
+An access declaration entry has a 
+.Cf DW_AT_name 
+attribute, whose value
+is a null-terminated string representing the name used in the
+declaration in the source program, including any class or structure
+qualifiers.
+.P
+An access declaration entry also has a 
+.Cf DW_AT_accessibility
+attribute
+describing the declared accessibility of the named entities.
+.H 3 "Friends"
+.IX friends
+.IX classes, friends
+Each ``friend'' declared by
+a structure, union or class type may be represented by
+a debugging information entry that is a child of the structure,
+union or class type entry; the friend entry has the tag
+.Cf DW_TAG_friend.
+.P
+A friend entry has a
+.Cf DW_AT_friend 
+attribute, whose value is a reference to the debugging information
+entry describing the declaration of the friend.
+.H 3 "Structure Data Member Entries"
+.IX members, data
+A data member (as opposed to a member function) is represented by
+a debugging information entry with the tag
+.Cf DW_TAG_member .
+The member entry for a named member has a 
+.Cf DW_AT_name 
+attribute
+whose value is a null-terminated string containing the member name
+as it appears in the source program.  If the member entry describes
+a C++ anonymous union, the name attribute is omitted or consists
+of a single zero byte.
+.IX unions, anonymous
+.IX anonymous unions
+.P
+The structure data member entry has a 
+.Cf DW_AT_type
+attribute
+to denote the type of that member.
+.P
+If the member entry is defined in the structure or class body, it has a
+.Cf DW_AT_data_member_location
+attribute whose value is a location
+description that describes the location of that
+member relative to the base address of the structure, union, or class that
+most closely encloses the corresponding member declaration.
+.I
+.P
+.IX locations, expressions
+.IX locations, descriptions
+The addressing expression represented by the location 
+description for a structure data member expects the base address
+of the structure data member to be on the expression stack
+before being evaluated.
+.P
+.IX unions
+The location description for a data member of a union may be omitted,
+since all data members of a union begin at the same address.
+.R
+.P
+.IX bit fields
+.IX members, bit fields
+If the member entry describes a bit field, then that entry has the following
+attributes:
+.AL
+.LI
+A
+.Cf DW_AT_byte_size
+attribute whose constant value is the number of bytes that
+contain an instance of the bit field and any padding bits.
+.P
+.I
+The byte size attribute may be omitted if the size of the object containing
+the bit field can be inferred from the type attribute of the data
+member containing the bit field.
+.R
+.LI
+A
+.Cf DW_AT_bit_offset
+attribute whose constant value is the number of bits
+to the left of the leftmost (most significant) bit of the bit field value.
+.LI
+A
+.Cf DW_AT_bit_size
+attribute whose constant value is the number of bits occupied
+by the bit field value.
+.LE
+.P
+The location description for a bit field calculates the address of
+an anonymous object containing the bit field.  The address is
+relative to the structure, union, or class that
+most closely encloses the bit field declaration.  The number
+of bytes in this anonymous object is the value of the byte
+size attribute of the bit field.  The offset (in bits)
+from the most significant bit of the
+anonymous object to the most significant bit of the bit field is the
+value of the bit offset attribute.
+.I
+.P
+For example, take one possible representation of the following
+structure definition in both big and little endian byte orders:
+.DS
+\f(CW
+struct S {
+	int   j:5;
+	int   k:6;
+	int   m:5;
+	int   n:8;
+};\fP
+.DE
+.P
+In both cases, the location descriptions for the debugging information
+entries for \f(CWj\fP, \f(CWk\fP, \f(CWm\fP and \f(CWn\fP
+describe the address of
+the same 32-bit word that contains all three members.  
+(In the big-endian case,
+the location description addresses the most significant byte, in
+the little-endian case, the least significant). 
+The following diagram shows the structure layout and lists the bit
+offsets for each case.  The offsets
+are from the most significant bit of the object addressed by the location
+description. 
+.PS
+bitht = .3
+boxht = bitht
+bitwid = .11
+nibwid = .75 * bitwid
+bytewid = 8 * bitwid
+boxwid = bytewid
+define nibble X	# nibble(len, "label", hi-left, hi-right, lo-left, lo-right, any)
+N:	box width $1*nibwid $2 $7
+	{ if $3 >= 0 then % "\s-4\|$3\s0" at N.w + (0,bitht/3) ljust %
+	} # curly on separate line for pic bug
+	{ if $4 >= 0 then % "\s-4\|$4\s0" at N.e + (0,bitht/3) rjust %
+	} 
+	{ if $5 >= 0 then % "\s-4\|$5\s0" at N.w - (0,bitht/3) ljust %
+	}
+	{ if $6 >= 0 then % "\s-4$6\|\s0" at N.e - (0,bitht/3) rjust %
+	}
+X
+define tbox X # tbox(width,"label", any)
+T:	box width $1*nibwid ht 1/6 $3 invis
+	{ $2 at T.w ljust
+	}
+X
+.PE
+.DS
+.PS
+	down
+H:	tbox(20,"Bit Offsets:")
+	tbox(20,"\f(CW    j:0\fP")
+	tbox(20,"\f(CW    k:5\fP")
+	tbox(20,"\f(CW    m:11\fP")
+	tbox(20,"\f(CW    n:16\fP")
+	right
+H:	tbox(32, "Big-Endian", with .w at H.e)
+H:	nibble(5,"\f(CWj\fP",0,-1,31,-1,with .nw at H.sw)
+H:	nibble(6,"\f(CWk\fP",-1,-1,26,-1)
+H:	nibble(5,"\f(CWm\fP",-1,-1,20,-1)
+H:	nibble(8,"\f(CWn\fP",-1,-1,15,-1)
+H:	nibble(8,"\fIpad\fP",-1,-1,7,0)
+.PE
+.DE
+.DS
+.PS
+	down
+H:	tbox(20,"Bit Offsets:")
+	tbox(20,"\f(CW    j:27\fP")
+	tbox(20,"\f(CW    k:21\fP")
+	tbox(20,"\f(CW    m:16\fP")
+	tbox(20,"\f(CW    n:8\fP")
+	right
+H:	tbox(32, "Little-Endian", with .w at H.e)
+H:	nibble(8,"\f2pad\fP",-1,-1,31,-1, with .nw at H.sw)
+H:	nibble(8,"\f(CWn\fP",-1,-1,23,-1)
+H:	nibble(5,"\f(CWm\fP",-1,-1,15,-1)
+H:	nibble(6,"\f(CWk\fP",-1,-1,10,-1)
+H:	nibble(5,"\f(CWj\fP",-1,0,4,0)
+.PE
+.DE
+.R
+.H 3 "Structure Member Function Entries"
+.IX subroutines, members
+.IX members, functions
+.IX members, locations
+A member function is represented in the debugging information by a
+debugging information entry with the tag 
+.Cf DW_TAG_subprogram .
+The member function entry may contain the same attributes and follows
+the same rules as non-member global subroutine entries (see section 3.3).
+.P
+.IX virtuality
+.IX virtual functions
+If the member function entry describes a virtual function, then that entry
+has a 
+.Cf DW_AT_virtuality 
+attribute.
+.P
+An entry for a virtual function also has a
+.Cf DW_AT_vtable_elem_location
+attribute whose value contains a location
+description yielding the address of the slot for the function
+within the virtual function table for the enclosing class or structure.
+.P
+.IX declarations, defining
+If a subroutine entry represents the defining declaration
+of a member function and that definition appears outside
+of the body of the enclosing class or structure declaration,
+the subroutine entry has a
+.Cf DW_AT_specification
+attribute, whose value is a reference to the debugging information
+entry representing the declaration of this function member.  The
+referenced entry will be a child of some class or structure
+type entry.
+.P
+Subroutine entries containing the 
+.Cf DW_AT_specification
+attribute do not need to duplicate information provided by the
+declaration entry referenced by the specification attribute.
+In particular, such entries do not need to contain
+attributes for the name or return type of the function member whose
+definition they represent.
+.H 3 "Class Template Instantiations"
+.I
+.IX C++ %caa
+.IX templates
+In C++ a class template is a generic
+definition of a class type that
+is instantiated differently when an instance of the class
+is declared or defined.  The generic description of the class
+may include both parameterized types and parameterized constant
+values.  DWARF does not represent the generic
+template definition, but does represent each instantiation.
+.R
+.P
+A class template instantiation is represented by a debugging information
+with the tag
+.Cf DW_TAG_class_type .
+With four exceptions,
+such an entry will contain the same attributes and have the same
+types of child entries as would an entry for a class type defined 
+explicitly using the instantiation types and values.
+The exceptions are:
+.AL
+.LI 
+Each formal parameterized type declaration appearing in the
+template definition is represented by a debugging information entry
+with the tag 
+.Cf DW_TAG_template_type_parameter .
+Each such entry has a 
+.Cf DW_AT_name 
+attribute, whose value is a null-terminated
+string containing the name of the formal type parameter as it
+appears in the source program.  The template type parameter
+entry also has a 
+.Cf DW_AT_type
+attribute describing the actual type by
+which the formal is replaced for this instantiation.
+.LI
+Each formal parameterized value declaration appearing
+in the templated definition is represented by a debugging information
+entry with the tag
+.Cf DW_TAG_template_value_parameter .
+Each such entry has a 
+.Cf DW_AT_name 
+attribute, whose value is a null-terminated
+string containing the name of the formal value parameter as it
+appears in the source program.  The template value parameter
+entry also has a 
+.Cf DW_AT_type
+attribute describing the type of the parameterized
+value.  Finally, the template value parameter entry has a
+.Cf DW_AT_const_value
+attribute, whose value is the actual constant value of the value
+parameter for this instantiation as represented on the target
+architecture.
+.LI
+.IX compilation units
+If the compiler has generated a special compilation unit
+to hold the template instantiation and that compilation unit
+has a different name
+from the compilation unit containing the template definition,
+the name attribute for the debugging entry representing
+that compilation unit should be empty or omitted.
+.LI
+.IX declarations, coordinates
+If the class type entry representing the template instantiation
+or any of its child entries
+contain declaration coordinate attributes, those attributes
+should refer to the source for the template definition, not
+to any source generated artificially by the compiler.
+.LE
+.H 3 "Variant Entries"
+.IX variants
+.IX discriminated unions
+A variant part of a structure is represented by a debugging
+information entry with the tag
+.Cf DW_TAG_variant_part
+and is owned by the corresponding structure type
+entry. 
+.P
+.IX discriminants
+If the variant part has a discriminant, the discriminant is represented
+by a separate debugging information entry which is a child of 
+the variant part entry.  This entry has the form of a structure data member
+entry.
+The variant part entry will have a
+.Cf DW_AT_discr
+attribute whose value is a
+reference to the member entry for the discriminant.  
+.P
+If the variant part
+does not have a discriminant (tag field), the variant part entry has a 
+.Cf DW_AT_type
+attribute to represent the tag type.
+.P
+Each variant of a particular variant part is represented by a debugging
+information entry with the tag
+.Cf DW_TAG_variant 
+and is a child of the variant part entry.  The value that selects a 
+given variant may be represented in one of three ways.  The
+variant entry may have a
+.Cf DW_AT_discr_value
+attribute whose value represents a single case label.  
+The value of this attribute
+is encoded as an LEB128 number.  The number is signed if the tag
+type for the variant part containing this variant is
+a signed type.   The number is unsigned if the tag type is an unsigned type.
+.P
+Alternatively, the variant entry may contain a
+.Cf DW_AT_discr_list
+attribute, whose value represents a list of discriminant values.
+This list is represented by any of the block forms and may contain
+a mixture of case labels and label ranges.  Each item on the list
+is prefixed with a discriminant value descriptor that determines whether
+the list item represents a single label or a label range.
+A single case label is represented as an LEB128 
+number as defined above
+for the
+.Cf DW_AT_discr_value
+attribute.  A label range is represented by two LEB128 numbers,
+the low value of the range followed by the high value.  Both values
+follow the rules for signedness just described.  
+The discriminant value descriptor is a constant that may have
+.nr aX \n(Fg+1
+one of the values given in Figure \n(aX.
+.DF
+.TS
+center box;
+lf(CW)
+.
+DW_DSC_label
+DW_DSC_range
+.TE
+.FG "Discriminant descriptor values"
+.DE
+.P
+If a variant entry has neither a
+.Cf DW_AT_discr_value
+attribute nor a
+.Cf DW_AT_discr_list
+attribute, or if it has a
+.Cf DW_AT_discr_list
+attribute with 0 size, the variant is a default variant.
+.P
+The components selected by a particular variant are represented
+by debugging information entries owned by the corresponding variant
+entry and appear in the same order as the corresponding declarations in
+the source program.
+.H 2     "Enumeration Type Entries"
+.I
+.IX enumerations
+An ``enumeration type'' is a scalar that can assume one of a fixed number of
+symbolic values.
+.P
+.R
+An enumeration type is represented by a debugging information entry
+with the tag
+.Cf DW_TAG_enumeration_type .
+.P
+If a name has been given to the enumeration type in the source program,
+then the corresponding enumeration type entry has a 
+.Cf DW_AT_name 
+attribute
+whose value is a null-terminated string containing the enumeration type
+name as it appears in the source program.
+These entries also have a 
+.Cf DW_AT_byte_size 
+attribute whose
+constant value is the number of bytes required to hold an
+instance of the enumeration.
+.P
+Each enumeration literal is represented by a debugging information
+entry with the tag
+.Cf DW_TAG_enumerator .
+Each such entry is a child of the enumeration type entry, and
+the enumerator entries appear in the same order as the declarations of
+the enumeration literals in the source program.
+.P
+Each enumerator entry has a 
+.Cf DW_AT_name 
+attribute, whose value is
+a null-terminated string containing the name of the enumeration
+literal as it appears in the source program.  Each enumerator
+entry also has a
+.Cf DW_AT_const_value
+attribute, whose value is the actual numeric value of the enumerator
+as represented on the target system.
+.H 2     "Subroutine Type Entries"
+.I
+.IX subroutines, types
+It is possible in C to declare pointers to subroutines that return a value
+of a specific type.  In both ANSI C and C++, it is possible to declare
+pointers to subroutines that not only return a value of a specific type,
+but accept only arguments of specific types.  The type of such pointers
+would be described with a ``pointer to'' modifier applied to a user-defined
+type.  
+.R
+.P
+A subroutine type is represented by a debugging information entry
+with the tag
+.Cf DW_TAG_subroutine_type .
+If a name has been given to the subroutine type in the source program,
+then the corresponding subroutine type entry has a 
+.Cf DW_AT_name 
+attribute
+whose value is a null-terminated string containing the subroutine type
+name as it appears in the source program.
+.P
+.IX subroutines, return types
+If the subroutine type describes a function that returns a value, then
+the subroutine type entry has a 
+.Cf DW_AT_type
+attribute
+to denote the type returned by the subroutine.
+If the types of the arguments are necessary to describe the subroutine type,
+then the corresponding subroutine type entry owns debugging
+information entries that describe the arguments.
+These debugging information entries appear in the order
+that the corresponding argument types appear in the source program.
+.P
+.I
+.IX C %c
+.IX subroutines, prototypes
+In ANSI-C there is a difference between the types of functions
+declared using function prototype style declarations and those
+declared using non-prototype declarations.  
+.P
+.R
+A subroutine entry
+declared with a function prototype style declaration may have a
+.Cf DW_AT_prototyped
+attribute, whose value is a flag.
+.P
+Each debugging information entry
+owned by a subroutine type entry has a tag whose value has one of
+two possible interpretations.  
+.AL
+.LI
+.IX parameters, formal
+Each debugging information entry that is owned by a subroutine type entry and
+that defines a single argument of a specific type has the tag
+.Cf DW_TAG_formal_parameter .
+.P
+The formal parameter entry has a type attribute
+to denote the type of the corresponding formal parameter.
+.LI
+The unspecified parameters of a variable parameter list are represented by a
+debugging information entry owned by the subroutine type entry with the tag
+.Cf DW_TAG_unspecified_parameters .
+.IX parameters, unspecified
+.LE
+.H 2     "String Type Entries"
+.I
+.IX string types
+.IX Fortran
+A ``string'' is a sequence of characters that have specific semantics and
+operations that separate them from arrays of characters.  
+Fortran is one of
+the languages that has a string type.
+.R
+.P
+A string type is represented by a debugging information entry
+with the tag 
+.Cf DW_TAG_string_type .
+If a name has been given to the string type in the source program,
+then the corresponding string type entry has a 
+.Cf DW_AT_name 
+attribute
+whose value is a null-terminated string containing the string type
+name as it appears in the source program.
+.P
+The string type entry may have a
+.Cf DW_AT_string_length
+attribute whose value is a location description
+yielding the location where the length of the string
+is stored in the program.  The string type entry may also have a
+.Cf DW_AT_byte_size 
+attribute, whose constant value is the size in bytes of the data
+to be retrieved from the location referenced by the string length
+attribute.  If no byte size attribute is present, the size of the
+data to be retrieved is the same as the size of an address on
+the target machine.
+.P
+If no string length attribute is present, the string type entry may have
+a 
+.Cf DW_AT_byte_size 
+attribute, whose constant value is the length in bytes of
+the string.
+.H 2 "Set Entries"
+.I
+Pascal provides the concept of a ``set,'' which represents a group of
+values of ordinal type.
+.P
+.R
+.IX Pascal
+.IX set types
+A set is represented by a debugging information entry
+with the tag
+.Cf DW_TAG_set_type .
+If a name has been given to the set type,
+then the set type entry has a 
+.Cf DW_AT_name 
+attribute
+whose value is a null-terminated string containing the set type name
+as it appears in the source program.
+.P
+The set type entry has a 
+.Cf DW_AT_type
+attribute to denote the type 
+of an element of the set.  
+.P
+If the amount of storage allocated to hold each element of an object of
+the given set type is different from the amount of storage that is normally
+allocated to hold an individual object of the indicated element type, then
+the set type entry has a 
+.Cf DW_AT_byte_size 
+attribute, whose constant value
+represents the size in bytes of an instance of the set type.
+.H 2 "Subrange Type Entries"
+.I
+Several languages support the concept of a ``subrange'' type object.
+These objects can represent a subset of the values that an
+object of the basis type for the subrange can represent.
+Subrange type entries may also be used to represent the bounds
+of array dimensions.
+.R
+.P
+.IX subranges
+A subrange type is represented by a debugging information entry
+with the tag
+.Cf DW_TAG_subrange_type .
+If a name has been given to the subrange type,
+then the subrange type entry has a 
+.Cf DW_AT_name 
+attribute
+whose value is a null-terminated string containing the subrange type name
+as it appears in the source program.
+.P
+The subrange entry may have a 
+.Cf DW_AT_type
+attribute to describe
+the type of object of whose values this subrange is a subset.
+.P
+If the amount of storage allocated to hold each element of an object of
+the given subrange type is different from the amount of storage that is normally
+allocated to hold an individual object of the indicated element type, then
+the subrange type entry has a
+.Cf DW_AT_byte_size 
+attribute, whose constant value
+represents the size in bytes of each element of the subrange type.
+.P
+The subrange entry may have the attributes
+.Cf DW_AT_lower_bound
+and
+.Cf DW_AT_upper_bound
+to describe, respectively, the lower and upper bound values
+of the subrange.
+The 
+.Cf DW_AT_upper_bound
+attribute may be replaced by a
+.Cf DW_AT_count
+attribute, whose value describes the number of elements in
+the subrange rather than the value of the last element.
+If a bound or count value is described by a constant
+not represented in the program's address space and can
+be represented by one of the constant attribute forms, then the value
+of the lower or upper bound or count attribute may be one of the constant
+types.  Otherwise, the value of the lower or upper bound or count
+attribute is a reference to a debugging information entry describing
+an object containing the bound value or itself describing a constant
+value. 
+.P
+If either the lower or upper bound or count values are missing, the
+bound value is assumed to be a language-dependent default
+constant.
+.P
+.I
+.IX C %c
+.IX C++ %caa
+.IX Fortran
+The default lower bound value for C or C++ is 0.  For Fortran,
+it is 1.  No other default values are currently defined by DWARF.
+.R
+.P
+If the subrange entry has no type attribute describing the basis
+type, the basis type is assumed to be the same as the object
+described by the lower bound attribute (if it references an object).
+If there is no lower bound attribute, or it does not reference
+an object, the basis type is the type of the upper bound or count
+attribute
+(if it references an object).  If there is no upper bound or count attribute
+or it does not reference an object, the type is assumed to be
+the same type, in the source language
+of the compilation unit containing the subrange entry,
+as a signed integer with the same size
+as an address on the target machine.
+.H 2 "Pointer to Member Type Entries"
+.I
+In C++, a pointer to a data or function member of a class or
+structure is a unique type.  
+.P
+.R
+.IX C++ %caa
+.IX members, pointers to
+.IX pointers to members
+A debugging information entry
+representing the type of an object that is a pointer to a structure
+or class member has the tag
+.Cf DW_TAG_ptr_to_member_type .
+.P
+If the pointer to member type has a name, the pointer to member entry
+has a 
+.Cf DW_AT_name 
+attribute, whose value is a null-terminated string
+containing the type name as it appears in the source program.
+.P
+The pointer to member entry has a
+.Cf DW_AT_type
+attribute to describe
+the type of the class or structure member to which objects
+of this type may point.
+.P
+The pointer to member entry also has a
+.Cf DW_AT_containing_type
+attribute, whose value is a reference to a debugging information
+entry for the class or structure to whose members objects of
+this type may point.
+.P
+Finally, the pointer to member entry has a
+.Cf DW_AT_use_location
+attribute whose value is a location description that computes
+the address of the member of the class or structure to which the
+pointer to member type entry can point.
+.P
+.I
+The method used to find the address of a given member
+of a class or structure is common to any instance of that
+class or structure and to any instance of the pointer or
+member type.  The method is thus associated
+with the type entry, rather than with each instance of the type.
+.P
+The 
+.Cf DW_AT_use_location
+expression, however, cannot be used on its own, but must
+be used in conjunction with the location expressions for
+a particular object of the given pointer to member type
+and for a particular structure or class instance.  The 
+.Cf DW_AT_use_location
+attribute expects two values to be pushed onto the location expression
+stack before the
+.Cf DW_AT_use_location
+expression is evaluated.  The first value pushed should be
+the value of the pointer to member object itself.
+The second value pushed should be the base address of the entire
+structure or union instance containing the member whose
+address is being calculated.
+.P
+So, for an expression like
+.DS
+	\f(CWobject.*mbr_ptr\fP
+.DE
+where \f(CWmbr_ptr\fP has some pointer to member type,
+a debugger should:
+.AL
+.LI
+Push the value of 
+.Cf mbr_ptr
+onto the location expression stack.
+.LI
+Push the base address of
+.Cf object 
+onto the location expression stack.
+.LI
+Evaluate the 
+.Cf DW_AT_use_location
+expression for the type of 
+.Cf mbr_ptr .
+.LE
+.R
+.H 2 "File Type Entries"
+.I
+Some languages, such as Pascal, provide a first class data type
+to represent files.
+.R
+.P
+.IX Pascal
+.IX file types
+A file type is represented by a debugging information entry
+with the tag
+.Cf DW_TAG_file_type.
+If the file type has a name, the file type entry
+has a 
+.Cf DW_AT_name 
+attribute, whose value is a null-terminated string
+containing the type name as it appears in the source program.
+.P
+The file type entry has a 
+.Cf DW_AT_type
+attribute describing the type
+of the objects contained in the file.
+.P
+The file type entry also has a 
+.Cf DW_AT_byte_size 
+attribute, whose value
+is a constant representing the size in bytes of an instance
+of this file type. 
+.OP
+.H 1 "OTHER DEBUGGING INFORMATION"
+This section describes debugging information that
+is not represented in the form of debugging information
+entries and is not contained within the 
+.Cf .debug_info
+section.
+.H 2 "Accelerated Access"
+.I
+.IX accelerated access
+A debugger frequently needs to find the debugging information for
+a program object defined outside of the compilation unit
+where the debugged program is currently stopped.  Sometimes
+it will know only the name of the object; sometimes only the address.
+To find the debugging information
+associated with a global object by name, using the DWARF debugging information
+entries alone, a debugger would need
+to run through all entries at the highest scope within each
+compilation unit.  For lookup by address, for a subroutine,
+a debugger can use the low and high pc attributes
+of the compilation unit entries to quickly narrow down the search,
+but these attributes only cover 
+the range of addresses for the text associated with a compilation
+unit entry.  To find the debugging information associated with a
+data object, an exhaustive search would be needed.
+Furthermore, any search through debugging information entries for
+different compilation units within a large program
+would potentially require the access of many memory pages,
+probably hurting debugger performance.
+.R
+.P
+To make lookups of program objects by name or by address faster,
+a producer of DWARF information may provide two different types
+of tables containing information about the debugging information
+entries owned by a particular compilation unit entry in a more condensed
+format.
+.H 3 "Lookup by Name"
+.IX lookup, by name
+For lookup by name, a table is maintained in a separate
+object file section called
+.Cf .debug_pubnames .
+.IX \f(CW.debug_pubnames\fP %debugap
+The table consists of sets of variable length entries, each
+set describing the names of global objects whose definitions
+or declarations are represented by debugging information entries
+owned by a single compilation unit.  Each set begins
+with a header containing four values: the total length of the entries
+for that set, not including the length field itself, a version number,
+the offset from the beginning of the
+.Cf .debug_info
+.IX \f(CW.debug_info\fP %debugai
+section of the compilation unit entry referenced by the set and
+the size in bytes of the contents of the
+.Cf .debug_info
+section generated to represent that compilation unit. This
+header is followed by a variable number of offset/name pairs.
+Each pair consists of the offset from the beginning of the compilation
+unit entry corresponding to the current set to the 
+debugging information entry for
+the given object, followed by a null-terminated character
+string representing the name of the object as given by
+the
+.Cf DW_AT_name
+attribute of the referenced debugging entry.
+Each set of names is terminated by zero.
+.P
+.IX C++ %caa
+.IX members, static data
+In the case of the name of a static data member or function member
+of a C++ structure, class or union, the name presented
+in the 
+.Cf .debug_pubnames
+section is not the simple name given by the
+.Cf DW_AT_name 
+attribute of the referenced debugging entry, but rather
+the fully class qualified name of the data or function member.
+.IX identifiers, names
+.H 3 "Lookup by Address"
+.IX lookup, by address
+For lookup by address, a table is maintained in a separate
+object file section called
+.Cf .debug_aranges .
+.IX \f(CW.debug_aranges\fP %debugaar
+The table consists of sets of variable length entries, each
+set describing the portion of the program's address space that
+is covered by a single compilation unit.  Each set begins
+with a header containing five values: 
+.AL
+.LI
+The total length of the entries
+for that set, not including the length field itself.
+.LI
+A version number.
+.LI
+The offset from the beginning of the
+.Cf .debug_info
+.IX \f(CW.debug_info\fP %debugai
+section of the compilation unit entry referenced by the set. 
+.LI
+The size in bytes of an address on the target architecture.  For
+segmented addressing, this is the size of the offset portion of the
+.IX addresses, offset portion
+.IX addresses, size of
+address.
+.LI
+.IX address space, segmented
+.IX segmented address space
+The size in bytes of a segment descriptor on the target architecture.
+If the target system uses a flat address space, this value is 0.
+.LE
+.P
+This
+header is followed by a variable number of address
+range descriptors.  Each descriptor is a pair consisting of 
+the beginning address
+of a range of text or data covered by some entry owned
+by the corresponding compilation unit entry, followed by the length
+of that range.  A particular set is terminated by an entry consisting
+of two zeroes.  By scanning the table, a debugger can quickly
+decide which compilation unit to look in to find the debugging information
+for an object that has a given address.
+.H 2 "Line Number Information"
+.I
+.IX line number information
+A source-level debugger will need to know how to associate statements in
+the source files with the corresponding machine instruction addresses in
+the executable object or the shared objects used by that executable
+object.  Such an association would make it possible for the debugger user
+to specify machine instruction addresses in terms of source statements.
+This would be done by specifying the line number and the source file
+containing the statement.  The debugger can also use this information to
+display locations in terms of the source files and to single step from
+statement to statement.
+.R
+.P
+As mentioned in section 3.1, above, 
+the line number information generated for a compilation unit
+is represented in the \f(CW.debug_line\fP section of an object file and is
+referenced by a corresponding compilation unit debugging information entry
+in the \f(CW.debug_info\fP section.
+.IX \f(CW.debug_info\fP %debugai
+.IX \f(CW.debug_line\fP %debugali
+.I
+.P
+If space were not a consideration, the information
+provided in the 
+.Cf .debug_line
+section could be represented as a large matrix,
+with one row for each instruction in the emitted
+object code.  The matrix would have columns for:
+.DL
+.LI
+the source file name
+.LI
+the source line number
+.LI
+the source column number
+.LI
+whether this instruction is the beginning of a source statement
+.LI
+whether this instruction is the beginning of a basic block.
+.LE
+.P
+Such a matrix, however, would be impractically large.  We shrink it with
+two techniques.  First, we delete from the matrix each row whose file,
+line and source column information is identical with that of its predecessors.
+Second, we design a byte-coded language for a state machine and store a stream
+of bytes in the object file instead of the matrix.  This language can be
+much more compact than the matrix.  When a consumer of the statement
+information executes, it must ``run'' the state machine to generate
+the matrix for each compilation unit it is interested in.  The concept
+of an encoded matrix also leaves room for expansion.  In the future,
+columns can be added to the matrix to encode other things that are
+related to individual instruction addresses.
+.R
+.H 3 "Definitions"
+.IX line number information, definitions
+The following terms are used in the description of the line number information
+format:
+.VL 20
+.LI "state machine"
+The hypothetical machine used by a consumer of the line number information 
+to expand the byte-coded instruction stream into a 
+matrix of line number information.
+.LI "statement program"
+A series of byte-coded line number information instructions representing one
+compilation unit.
+.LI "basic block"
+A sequence of instructions that is entered only at the first instruction
+and exited only at the last instruction.  We define a procedure invocation
+to be an exit from a basic block.
+.LI "sequence"
+A series of contiguous target machine instructions.  One compilation
+unit may emit multiple sequences (that is, not all instructions within
+a compilation unit are assumed to be contiguous).
+.LI "sbyte"
+Small signed integer.
+.LI "ubyte"
+Small unsigned integer.
+.LI "uhalf"
+Medium unsigned integer.
+.LI "sword"
+Large signed integer.
+.LI "uword"
+Large unsigned integer.
+.LI "LEB128"
+.IX LEB128
+Variable length signed and unsigned data.  See section 7.6.
+.LE
+.H 3 "State Machine Registers"
+.IX line number information, state machine registers
+The statement information state machine has the following registers:
+.VL 20
+.LI "\f(CWaddress\fP"
+The program-counter value corresponding to a machine instruction generated
+by the compiler.
+.LI "\f(CWfile\fP"
+An unsigned integer indicating the identity of the source file corresponding
+to a machine instruction.
+.IX source, files
+.LI "\f(CWline\fP"
+.IX source, lines
+An unsigned integer indicating a source line number.  Lines are numbered
+beginning at 1.  The compiler may emit the value 0 in cases where an
+instruction cannot be attributed to any source line.
+.LI "\f(CWcolumn\fP"
+.IX source, columns
+An unsigned integer indicating a column number within a source line.
+Columns are numbered beginning at 1.  The value 0 is reserved to indicate
+that a statement begins at the ``left edge'' of the line.
+.LI "\f(CWis_stmt\fP"
+A boolean indicating that the current instruction is the beginning of a
+statement.
+.LI "\f(CWbasic_block\fP"
+A boolean indicating that the current instruction is the beginning of
+a basic block.
+.LI "\f(CWend_sequence\fP"
+A boolean indicating that the current address is that of the first
+byte after the end of a sequence of target machine instructions.
+.LE
+.P
+At the beginning of each sequence within a statement program, the
+state of the registers is:
+.DS
+.TS
+;
+lf(CW) l.
+address	0
+file	1
+line	1
+column	0
+is_stmt	determined by \f(CWdefault_is_stmt\fP in the statement program prologue
+basic_block	``false''
+end_sequence	``false''
+.TE
+.DE
+.H 3 "Statement Program Instructions"
+The state machine instructions in a statement program belong to one
+of three categories:
+.VL 20
+.LI "special opcodes"
+.IX line number information, special opcodes
+These have a ubyte opcode field and no arguments. 
+Most of the instructions in a statement program are special opcodes.
+.LI "standard opcodes"
+.IX line number information, standard opcodes
+These have a ubyte opcode field which may be followed by zero or more
+LEB128 arguments (except for 
+.Cf DW_LNS_fixed_advance_pc ,
+see below).
+The opcode implies the number of arguments and their 
+meanings, but the statement program prologue also specifies the number 
+of arguments for each standard opcode.
+.LI "extended opcodes"
+.IX line number information, extended opcodes
+These have a multiple byte format.  The first byte is zero;
+the next bytes are an unsigned LEB128 integer giving the number of bytes
+in the instruction itself (does not include the first zero byte or the size).
+The remaining bytes are the instruction itself.
+.LE
+.H 3 "The Statement Program Prologue"
+.IX line number information, prologue
+The optimal encoding of line number information depends to a certain
+degree upon the architecture of the target machine.  The statement program
+prologue provides information used by consumers in decoding the statement
+program instructions for a particular compilation unit and also provides
+information used throughout the rest of the statement program.  The statement
+program for each compilation unit begins with a prologue containing the
+following fields in order:
+.AL
+.LI
+.Cf total_length 
+(uword)
+.br
+The size in bytes of the statement information for this compilation unit
+(not including the 
+.Cf total_length
+field itself).
+.LI
+.Cf version
+(uhalf)
+.br
+Version identifier for the statement information format.
+.LI
+.Cf prologue_length 
+(uword)
+.br
+The number of bytes following the 
+.Cf prologue_length
+field to the beginning of the first byte of the statement program itself.
+.LI
+.Cf minimum_instruction_length
+(ubyte)
+.br
+The size in bytes of the smallest target machine instruction.  Statement
+program opcodes that alter the 
+.Cf address 
+register first multiply their operands by this value.
+.LI
+.Cf default_is_stmt
+(ubyte)
+.br
+The initial value of the 
+.Cf is_stmt
+register.  
+.P
+.I
+A simple code generator
+that emits machine instructions in the order implied by the source program
+would set this to ``true,'' and every entry in the matrix would represent
+a statement boundary.  A pipeline scheduling code generator would set
+this to ``false'' and emit a specific statement program opcode for each
+instruction that represented a statement boundary.
+.R
+.LI
+.Cf line_base 
+(sbyte)
+.br
+This parameter affects the meaning of the special opcodes.  See below.
+.LI
+.Cf line_range 
+(ubyte)
+.br
+This parameter affects the meaning of the special opcodes.  See below.
+.LI
+.Cf opcode_base
+(ubyte)
+.br
+The number assigned to the first special opcode.
+.LI
+.Cf standard_opcode_lengths
+(array of ubyte)
+.br
+This array specifies the number of LEB128 operands for each of
+the standard opcodes.  The first element of the array corresponds
+to the opcode whose value is 1, and the last element corresponds
+to the opcode whose value is 
+.Cf "opcode_base - 1" . 
+By increasing
+.Cf opcode_base , 
+and adding elements to this array, new standard opcodes
+can be added, while allowing consumers who do not know about these
+new opcodes to be able to skip them.
+.LI
+.Cf include_directories
+(sequence of path names)
+.br
+The sequence contains an entry for each path that was searched
+for included source files in this compilation.  (The paths include
+those directories specified explicitly by the user for the compiler
+to search and those the compiler searches without explicit direction).
+Each path entry is either a full
+path name or is relative to the current directory of the compilation.
+The current directory of the compilation is understood to be the first entry
+and is not explicitly represented.  
+Each entry is a null-terminated
+string containing a full path name.  The last entry is followed by
+a single null byte.
+.LI
+.Cf file_names
+(sequence of file entries)
+.br
+.IX source, files
+The sequence contains an entry for each source file that contributed
+to the statement information for this compilation unit or is
+used in other contexts, such as in a declaration coordinate
+or a macro file inclusion.  Each entry
+has a null-terminated string containing the file name, 
+an unsigned LEB128 number representing the directory index of the
+directory in which the file was found, 
+an unsigned LEB128 number representing the time of last modification for
+the file and an unsigned LEB128 number representing the length in
+bytes of the file.  A compiler may choose to emit LEB128(0) for the
+time and length fields to indicate that this information is not
+available.  The last entry is followed by a single null byte.
+.P
+The directory index represents an entry in the
+.Cf include_directories
+section.  The index is LEB128(0) if the file was found in
+the current directory of the compilation, LEB128(1) if it was
+found in the first directory in the
+.Cf include_directories
+section, and so on.  The directory index is ignored for file names
+that represent full path names.
+.P
+The statement program assigns numbers to each of the file entries
+in order, beginning with 1, and uses those numbers instead of file
+names in the 
+.Cf file 
+register.
+.P
+A compiler may generate a single null byte for the file names field
+and define file names using the extended opcode
+.Cf DEFINE_FILE .
+.LE
+.H 3 "The Statement Program"
+As stated before, the goal of a statement program is to build a 
+matrix representing
+one compilation unit, which may have produced multiple sequences of
+target-machine instructions. Within a sequence, addresses may only increase.
+(Line numbers may decrease in cases of pipeline scheduling.)
+.H 4 "Special Opcodes"
+.IX line number information, special opcodes
+Each 1-byte special opcode has the following effect on the state machine:
+.AL
+.LI
+Add a signed integer to the 
+.Cf line 
+register.
+.LI
+Multiply an unsigned integer by the 
+.Cf minimum_instruction_length
+field of the statement program prologue and 
+add the result to the 
+.Cf address 
+register.
+.LI
+Append a row to the matrix using the current values of the state machine
+registers.
+.LI
+Set the 
+.Cf basic_block 
+register to ``false.''
+.LE
+.P
+All of the special opcodes do those same four things; 
+they differ from one another
+only in what values they add to the 
+.Cf line 
+and 
+.Cf address 
+registers.
+.P
+.I
+Instead of assigning a fixed meaning to each special opcode, the statement
+program uses several
+parameters in the prologue to configure the instruction set. There are two
+reasons for this.
+First, although the opcode space available for special opcodes now
+ranges from 10 through 255, the lower bound may increase if one adds new
+standard opcodes. Thus, the 
+.Cf opcode_base
+field of the statement program
+prologue gives the value of the first special opcode.
+Second, the best choice of special-opcode meanings depends on the target
+architecture.  For example, for a RISC machine where the compiler-generated code
+interleaves instructions from different lines to schedule the pipeline,
+it is important to be able to add a negative value to the 
+.Cf line 
+register
+to express the fact that a later instruction may have been emitted for an
+earlier source line.  For a machine where pipeline scheduling never occurs,
+it is advantageous to trade away the ability to decrease the 
+.Cf line 
+register
+(a standard opcode provides an alternate way to decrease the line number) in
+return for the ability to add larger positive values to the 
+.Cf address
+register.  To permit this variety of strategies, the statement program prologue 
+defines a 
+.Cf line_base
+field that specifies the minimum value which a special opcode can add
+to the 
+.Cf line
+register and a 
+.Cf line_range
+field that defines the range of
+values it can add to the 
+.Cf line 
+register.
+.R
+.P
+A special opcode value is chosen based on the amount that needs to
+be added to the 
+.Cf line
+and 
+.Cf address
+registers.  The maximum line increment
+for a special opcode is the value of the 
+.Cf line_base
+field in the
+prologue, plus the value of the 
+.Cf line_range 
+field, minus 1 
+(\f(CWline base + line range - 1\fP).  If the desired line increment
+is greater than the maximum line increment, a standard opcode
+must be used instead of a special opcode.
+The ``address advance'' is calculated by dividing the desired address
+increment by the 
+.Cf minimum_instruction_length
+field from the
+prologue.  The special opcode is then calculated using the following
+formula:
+.br
+        \f(CWopcode = (desired line increment - line_base) +
+.br
+                (line_range * address advance) + opcode_base\fP
+.br
+If the resulting opcode is greater than 255, a standard opcode
+must be used instead.
+.P
+To decode a special opcode, subtract the 
+.Cf opcode_base
+from
+the opcode itself.  The amount to increment the 
+.Cf address 
+register is
+the adjusted opcode divided by the 
+.Cf line_range .
+The amount to
+increment the 
+.Cf line 
+register is the 
+.Cf line_base
+plus the result
+of the adjusted opcode modulo the 
+.Cf line_range .
+That is,
+.br
+	\f(CWline increment = line_base + (adjusted opcode % line_range)\fP
+.br
+.P
+.I
+As an example, suppose that the 
+.Cf opcode_base 
+is 16, 
+.Cf line_base
+is -1 and 
+.Cf line_range
+is 4.
+This means that we can use a special opcode whenever two successive
+rows in the matrix have source line numbers differing by any value within
+the range [-1, 2] (and, because of the limited number of opcodes available,
+when the difference between addresses is within the range [0, 59]).
+.P
+The opcode mapping would be:
+.R
+.DS
+.TS
+box center;
+l l l
+nf(CW) nf(CW) nf(CW)
+.
+Opcode	Line advance	Address advance
+_
+16	-1	0
+17	0	0
+18	1	0
+19	2	0
+20	-1	1
+21	0	1
+22	1	1
+23	2	1
+...	...	...
+253	0	59
+254	1	59
+255	2	59
+.TE
+.DE
+.P
+There is no requirement that the expression \f(CW255 - line_base + 1\fP be an
+integral multiple of 
+.Cf line_range .
+.H 4 "Standard Opcodes"
+.IX line number information, standard opcodes
+There are currently 9 standard ubyte opcodes.  In the future 
+additional ubyte opcodes may be defined by setting the 
+.Cf opcode_base
+field in the statement program
+prologue to a value greater than 10.
+.AL
+.LI
+.Cf DW_LNS_copy 
+.br
+Takes no arguments.  Append a row to the matrix using the current values of
+the state-machine registers.  Then set the 
+.Cf basic_block
+register to ``false.''
+.LI
+.Cf DW_LNS_advance_pc
+.br
+Takes a single unsigned LEB128 operand,
+multiplies it by the
+.Cf minimum_instruction_length
+field of the prologue, and adds the result to the
+.Cf address
+register of the state machine.
+.LI
+.Cf DW_LNS_advance_line
+.br
+Takes a single signed LEB128 operand and adds
+that value to the 
+.Cf line
+register of the state machine.
+.LI
+.Cf DW_LNS_set_file 
+.br
+Takes a single unsigned LEB128 operand and stores
+it in the 
+.Cf file
+register of the state machine.
+.LI
+.Cf DW_LNS_set_column
+.br
+Takes a single unsigned LEB128 operand and stores
+it in the 
+.Cf column 
+register of the state machine.
+.LI
+.Cf DW_LNS_negate_stmt
+.br
+Takes no arguments.
+Set the 
+.Cf is_stmt
+register of the state machine to the
+logical negation of its current value.
+.LI
+.Cf DW_LNS_set_basic_block
+.br
+Takes no arguments.  Set the 
+.Cf basic_block 
+register of the state machine to ``true.''
+.LI
+.Cf DW_LNS_const_add_pc
+.br
+Takes no arguments.
+Add to the 
+.Cf address 
+register of the state machine the
+address increment value corresponding to special
+opcode 255.
+.P
+.I
+The motivation for 
+.Cf DW_LNS_const_add_pc 
+is this:  when the statement program needs
+to advance the address by a small amount, it can use a single special
+opcode, which occupies a single byte.  When it needs to advance the
+address by up to twice the range of the last special opcode, it can use
+.Cf DW_LNS_const_add_pc 
+followed by a special opcode, for a total of two bytes.
+Only if it needs to advance the address by more than twice that range
+will it need to use both
+.Cf DW_LNS_advance_pc
+and a special opcode, requiring three or more bytes.
+.R
+.LI
+.Cf DW_LNS_fixed_advance_pc
+.br
+Takes a single uhalf operand.  Add to the 
+.Cf address 
+register of the state machine the value of the (unencoded) operand.
+This is the only extended opcode that takes an argument that is not
+a variable length number.
+.P
+.I
+The motivation for 
+.Cf DW_LNS_fixed_advance_pc
+is this:  existing assemblers cannot emit 
+.Cf DW_LNS_advance_pc
+or special opcodes because they cannot encode LEB128 numbers
+or judge when the computation of a special opcode overflows and requires
+the use of 
+.Cf DW_LNS_advance_pc .
+Such assemblers, however,  can use
+.Cf DW_LNS_fixed_advance_pc
+instead, sacrificing compression. 
+.R
+.LE
+.H 4 "Extended Opcodes"
+.IX line number information, extended opcodes
+There are three extended opcodes currently defined.  The first byte
+following the length field of the encoding for each contains a sub-opcode.
+.AL
+.LI
+\f(CWDW_LNE_end_sequence\fP 
+.br
+Set the 
+.Cf end_sequence 
+register of the state machine
+to ``true'' and append a row to the matrix using the
+current values of the state-machine registers.  Then
+reset the registers to the initial values specified
+above.
+.P
+Every statement program sequence must end with a
+.Cf DW_LNE_end_sequence
+instruction which creates a
+row whose address is that of the byte after the last target machine instruction
+of the sequence.
+.LI
+\f(CWDW_LNE_set_address\fP
+.br
+Takes a single relocatable address as an operand.  The size of the
+operand is the size appropriate to hold an address on the target machine.
+Set the 
+.Cf address 
+register to the value given by the
+relocatable address. 
+.P
+.I
+All of the other statement program opcodes that affect the 
+.Cf address 
+register add a delta to it. 
+This instruction stores a relocatable value into it instead.
+.R
+.LI
+\f(CWDW_LNE_define_file\fP
+.br
+.IX source, files
+Takes 4 arguments.  The first is a null terminated string containing a
+source file name.  The second is an
+unsigned LEB128 number representing the directory index of the
+directory in which the file was found.
+The third is an unsigned LEB128 number representing
+the time of last modification of the file.  The fourth is an unsigned
+LEB128 number representing the length in bytes of the file.
+The time and length fields may contain LEB128(0) if the information is
+not available.
+.P
+The directory index represents an entry in the
+.Cf include_directories
+section of the statement program prologue.  
+The index is LEB128(0) if the file was found in
+the current directory of the compilation, LEB128(1) if it was
+found in the first directory in the
+.Cf include_directories
+section, and so on.  The directory index is ignored for file names
+that represent full path names.
+.P
+The files are numbered, starting at 1,
+in the order in which they appear; the names in the prologue
+come before names defined by the
+.Cf DW_LNE_define_file
+instruction.
+These numbers are used in the the 
+.Cf file 
+register of the state machine.
+.LE
+.P
+.I
+Appendix 3 gives some sample statement programs.
+.R
+.H 2 "Macro Information"
+.I
+.IX macro information
+.IX pre-processor
+.IX C %c
+.IX C++ %caa
+Some languages, such as C and C++, provide a way to replace text
+in the source program with macros defined either in the source
+file itself, or in another file included by the source file.
+Because these macros are not themselves defined in the target
+language, it is difficult to represent their definitions
+using the standard language constructs of DWARF.  The debugging
+information therefore reflects the state of the source after
+the macro definition has been expanded, rather than as the
+programmer wrote it.
+The macro information table provides a way of preserving the original
+source in the debugging information.
+.R
+.P
+As described in section 3.1, the macro information for a given
+compilation unit is represented in the
+.Cf .debug_macinfo
+.IX \f(CW.debug_macinfo\fP %debugam
+section of an object file.  The macro information for each compilation
+unit is represented as a series of ``macinfo'' entries.  Each
+macinfo entry consists of a ``type code'' and up to two additional
+operands.  The series of entries for a given compilation unit
+ends with an entry containing a type code of 0.
+.H 3 "Macinfo Types"
+The valid macinfo types are as follows:
+.VL 30
+.LI \f(CWDW_MACINFO_define\fP
+A macro definition.
+.LI \f(CWDW_MACINFO_undef\fP
+A macro un-definition.
+.LI \f(CWDW_MACINFO_start_file\fP
+The start of a new source file inclusion.
+.LI \f(CWDW_MACINFO_end_file\fP
+The end of the current source file inclusion.
+.LI \f(CWDW_MACINFO_vendor_ext\fP
+Vendor specific macro information directives that do not fit
+into one of the standard categories.
+.LE
+.H 4 "Define and Undefine Entries"
+.IX macro information, define and undefine entries
+All 
+.Cf DW_MACINFO_define
+and 
+.Cf DW_MACINFO_undef
+entries have two operands.
+The first operand encodes the line number of the source line
+.IX source, lines
+on which the relevant defining or undefining
+pre-processor directives appeared.
+.P 
+The second operand consists of a null-terminated character string.
+In the case of a 
+.Cf DW_MACINFO_undef 
+entry, the value of this
+string will be simply the name of the pre-processor
+symbol which was undefined at the indicated source line.
+.P
+In the case of a 
+.Cf DW_MACINFO_define
+entry, the value of this
+string will be the name of the pre-processor symbol
+that was defined at the indicated source line,
+followed immediately by the macro formal parameter
+list including the surrounding parentheses (in the
+case of a function-like macro) followed by the
+definition string for the macro.  If there is no
+formal parameter list, then the name of the defined
+macro is followed directly by its definition string.
+.P
+In the case of a function-like macro definition, no
+whitespace characters should appear between the
+name of the defined macro and the following left
+parenthesis.  Also, no whitespace characters should
+appear between successive formal parameters in the
+formal parameter list.  (Successive formal parameters
+should, however, be separated by commas.)  Also, exactly
+one space character
+should separate the right parenthesis which terminates
+the formal parameter list and the following definition
+string.
+.P
+In the case of a ``normal'' (i.e. non-function-like)
+macro definition, exactly one space character
+should separate the name of the defined macro from the following definition
+text.
+.H 4 "Start File Entries"
+.IX macro information, start file entries
+Each 
+.Cf DW_MACINFO_start_file
+entry also has two operands.  The first operand
+encodes the line number of the
+source line on which the inclusion pre-processor
+directive occurred.
+.P
+.IX source, files
+The second operand encodes a
+source file name index.  This index corresponds to a file
+number in the statement information table for the relevant
+compilation unit.  This index
+indicates (indirectly) the name of the file
+which is being included by the inclusion directive on
+the indicated source line.
+.H 4 "End File Entries"
+.IX macro information, end file entries
+A 
+.Cf DW_MACINFO_end_file 
+entry has no operands.  The presence of the entry marks the end of
+the current source file inclusion.
+.H 4 "Vendor Extension Entries"
+.IX macro information, vendor extensions
+.IX vendor extensions
+A
+.Cf DW_MACINFO_vendor_ext
+entry has two operands.
+The first is a constant.  The second is a null-terminated
+character string.
+The meaning and/or significance of these operands is
+intentionally left undefined by this specification.
+.P
+A consumer must be able to totally ignore all
+.Cf DW_MACINFO_vendor_ext
+entries that it does not understand.
+.H 3 "Base Source Entries"
+.IX macro information, base source entries
+In addition to producing a matched pair of
+.Cf DW_MACINFO_start_file 
+and 
+.Cf DW_MACINFO_end_file
+entries for 
+each inclusion directive actually processed during
+compilation, a producer should generate such a matched
+pair also for the ``base'' source file submitted to the
+compiler for compilation.  If the base source file
+.IX source, files
+for a compilation is submitted to the compiler via
+some means other than via a named disk file (e.g. via
+the standard input \fIstream\fP on a UNIX system) then the
+compiler should still produce this matched pair of
+.Cf DW_MACINFO_start_file
+and 
+.Cf DW_MACINFO_end_file 
+entries for
+the base source file, however, the file name indicated
+(indirectly) by the 
+.Cf DW_MACINFO_start_file
+entry of the
+pair should reference a statement information file name entry consisting
+of a null string.
+.H 3 "Macinfo Entries for Command Line Options"
+.IX macro information, command line options
+In addition to producing
+.Cf DW_MACINFO_define 
+and
+.Cf DW_MACINFO_undef
+entries for each of the define and
+undefine directives processed during compilation, the
+DWARF producer should generate a 
+.Cf DW_MACINFO_define 
+or
+.Cf DW_MACINFO_undef
+entry for each pre-processor symbol
+which is defined or undefined by some
+means other than via a define or undefine directive
+within the compiled source text.  In particular,
+pre-processor symbol definitions and un-definitions
+which occur as a result of command line options
+(when invoking the compiler) should be represented by
+their own 
+.Cf DW_MACINFO_define
+and 
+.Cf DW_MACINFO_undef
+entries.
+.P
+All such 
+.Cf DW_MACINFO_define
+and 
+.Cf DW_MACINFO_undef
+entries representing compilation options should appear 
+before the first 
+.Cf DW_MACINFO_start_file
+entry for that compilation unit and should encode the value
+0 in their line number operands.
+.H 3 " General Rules and Restrictions"
+.IX line number information, general rules
+All macinfo entries within a 
+.Cf .debug_macinfo 
+section for a given compilation unit should appear in the same order
+in which the directives were processed by the compiler.
+.P
+All macinfo entries representing command line options
+should appear in the same order as the relevant command
+line options were given to the compiler.  In the case
+where the compiler itself implicitly supplies one or
+more macro definitions or un-definitions in addition
+to those which may be specified on the command line,
+macinfo entries should also be produced for these
+implicit definitions and un-definitions, and
+these entries should also appear in the proper order
+relative to each other and to any definitions or
+undefinitions given explicitly by the user on the
+command line.
+.H 2 "Call Frame Information"
+.IX call frame information
+.IX activations
+.I
+Debuggers often need to be able to view and modify the state of any
+subroutine activation that is on the call stack.  An activation
+consists of:
+.BL
+.LI
+A code location that is within the subroutine.  This location is
+either the place where the program stopped when the debugger got
+control (e.g. a breakpoint), or is a place where a subroutine
+made a call or was interrupted by an asynchronous event (e.g. a
+signal).
+.LI
+An area of memory that is allocated on a stack called a ``call
+frame.''  The call frame is identified by an address on the
+stack.  We refer to this address as the Canonical Frame Address or CFA.
+.LI
+A set of registers that are in use by the subroutine at the code
+location.
+.LE
+.P
+Typically, a set of registers are designated to be preserved across a
+call.  If a callee wishes to use such a register, it saves the value
+that the register had at entry time in its call frame and restores it
+on exit.  The code that allocates space on the call frame stack and
+performs the save operation is called the subroutine's prologue, and the
+code that performs the restore operation and deallocates the frame is
+called its epilogue.  Typically, the prologue code is physically at the
+beginning of a subroutine and the epilogue code is at the end.
+.P
+To be able to view or modify an activation that is not on the top of
+the call frame stack, the debugger must ``virtually unwind'' the stack of
+activations until it finds the activation of interest. 
+A debugger unwinds a
+stack in steps.  Starting with the current activation it restores any
+registers that were preserved by the current activation and computes the
+predecessor's CFA and code location.  This has the logical effect of
+returning from the current subroutine to its predecessor.  We say that
+the debugger virtually unwinds the stack because it preserves enough
+information to be able to ``rewind'' the stack back to the state it was
+in before it attempted to unwind it.
+.P
+The unwinding operation needs to know where registers are saved and how
+to compute the predecessor's CFA and code location.  When considering
+an architecture-independent way of encoding this information one has to
+consider a number of special things.
+.BL
+.LI
+Prologue and epilogue code is not always in distinct blocks at the
+beginning and end of a subroutine.  It is common to duplicate the
+epilogue code at the site of each return from the code.  Sometimes
+a compiler breaks up the register save/unsave operations and moves
+them into the body of the subroutine to just where they are needed.
+.LI
+Compilers use different ways to manage the call frame.  Sometimes
+they use a frame pointer register, sometimes not.
+.LI
+The algorithm to compute the CFA changes as you progress through
+the prologue and epilogue code.  (By definition, the CFA value
+does not change.)
+.LI
+Some subroutines have no call frame.
+.LI
+Sometimes a register is saved in another register that by
+convention does not need to be saved.
+.LI
+Some architectures have special instructions that
+perform some or all of the register management in one instruction,
+leaving special information on the stack that indicates how
+registers are saved.
+.LI
+Some architectures treat return address values
+specially.  For example, in one architecture, 
+the call instruction guarantees that the low order two
+bits will be zero and the return instruction ignores those bits.
+This leaves two bits of storage that are available to other uses
+that must be treated specially.
+.LE
+.R
+.H 3 "Structure of Call Frame Information"
+.IX call frame information, structure
+DWARF supports virtual unwinding by defining an architecture independent
+basis for recording how procedures save and restore registers throughout
+their lifetimes.  This basis must be augmented on some machines with
+specific information that is defined by either an architecture specific
+ABI authoring committee, a hardware vendor, or a compiler producer.
+.IX ABI
+.IX vendor extensions
+The body defining a specific augmentation is referred to
+below as the ``augmenter.''
+.P
+Abstractly, this mechanism describes a very large table that has the
+following structure:
+.TS
+center;
+l l l l l l
+l s s s s s.
+LOC  CFA   R0   R1   ...  RN
+L0
+L1
+\...
+LN
+.TE
+.P
+The first column indicates an address for every location that contains
+code in a program.  (In shared objects, this is an object-relative
+offset.)  The remaining columns contain virtual unwinding rules that are
+associated with the indicated location.  The first column of the rules
+defines the CFA rule which is a register and a signed offset that are
+added together to compute the CFA value.
+.P
+The remaining columns are labeled by register number.  This includes
+some registers that have special designation on some architectures such
+as the PC and the stack pointer register.  (The actual mapping of
+registers for a particular architecture is performed by the augmenter.)
+The register columns contain rules that describe
+whether a given register has been saved and the rule to find 
+the value for the register in the previous frame.
+.P
+The register rules are:
+.IX call frame information, register rules
+.VL 20
+.LI "undefined"
+A register that has this rule has no value in the
+previous frame.  (By convention, it is not preserved by a callee.)
+.LI "same value"
+This register has not been modified from the
+previous frame.  (By convention, it is preserved by the callee,
+but the callee has not modified it.)
+.LI "offset(N)"
+The previous value of this register is saved at the address CFA+N where
+CFA is the current CFA value and N is a signed offset.
+.LI "register(R)"
+The previous value of this register is stored in
+another register numbered R.
+.LI "architectural"
+The rule is defined externally to this specification by the augmenter.
+.LE
+.P
+.I
+This table would be extremely large if actually constructed as
+described.  Most of the entries at any point in the table are identical
+to the ones above them.  The whole table can be represented quite
+compactly by recording just the differences starting at the beginning
+address of each subroutine in the program.
+.R
+.P
+The virtual unwind information is encoded in a self-contained section
+called 
+.Cf .debug_frame . 
+.IX \f(CW.debug_frame\fP %debugaf
+Entries in a 
+.Cf .debug_frame
+section are aligned on
+.IX call frame information, Common Information Entry
+an addressing unit boundary and come in two forms: A Common Information
+Entry (CIE) and a Frame Description Entry (FDE).
+Sizes of data objects used in the encoding of the 
+.Cf .debug_frame
+section are described in terms of the same data definitions
+used for the line number information (see section 6.2.1).
+.P
+A Common Information Entry holds information that is shared among many
+Frame Descriptors.  There is at least one CIE in every non-empty
+.Cf .debug_frame 
+section.  A CIE contains the following fields, in order:
+.AL
+.LI 
+\f(CWlength\fP
+.br
+A uword constant that gives the number of bytes of the CIE
+structure, not including the length field, itself 
+(length mod <addressing unit size> == 0).
+.LI 
+\f(CWCIE_id\fP
+.br
+A uword constant that is used to distinguish CIEs
+from FDEs.
+.LI
+\f(CWversion\fP
+.br
+A ubyte version number.  This number is specific to the call frame
+information and is independent of the DWARF version number.
+.LI 
+\f(CWaugmentation\fP
+.br
+A null terminated string that identifies the
+augmentation to this CIE or to the FDEs that use
+it.  If a reader encounters an augmentation string that is
+unexpected, then only the following fields can be read:
+CIE: 
+.Cf length , 
+.Cf CIE_id , 
+.Cf version , 
+.Cf augmentation ;
+FDE:
+.Cf length , 
+.Cf CIE_pointer , 
+.Cf initial_location , 
+.Cf address_range .
+If there is no augmentation, this value is a zero byte.
+.LI 
+\f(CWcode_alignment_factor\fP
+.br
+An unsigned LEB128 constant that is factored out
+of all advance location instructions (see below).
+.LI 
+\f(CWdata_alignment_factor\fP
+.br
+A signed LEB128 constant that is factored out
+of all offset instructions (see below.)
+.LI 
+\f(CWreturn_address_register\fP
+.br
+A ubyte constant that indicates
+which column in the rule table represents the return address
+of the function.  Note that this column might not correspond
+to an actual machine register.
+.LI 
+\f(CWinitial_instructions\fP
+.br
+A sequence of rules that are interpreted to
+create the initial setting of each column in the table.
+.LI 
+\f(CWpadding\fP
+.br
+Enough 
+.Cf DW_CFA_nop
+instructions to make the size of this entry
+match the 
+.Cf length
+value above.
+.LE
+.P
+An FDE contains the following fields, in order:
+.IX call frame information, Frame Description Entry
+.AL
+.LI 
+\f(CWlength\fP
+.br
+A uword constant that gives the number of bytes of the header
+and instruction stream for this function (not including the length
+field itself) (length mod <addressing unit size> == 0).
+.LI 
+\f(CWCIE_pointer\fP
+.br
+A uword constant offset into the
+.Cf .debug_frame 
+section that denotes the CIE that is associated with this FDE.
+.LI 
+\f(CWinitial_location\fP
+An addressing-unit sized constant indicating
+the address of the first location associated with this table entry.
+.LI 
+\f(CWaddress_range\fP
+.br
+An addressing unit sized constant indicating the
+number of bytes of program instructions described by this entry.
+.LI 
+\f(CWinstructions\fP
+.br
+A sequence of table defining instructions that are
+described below.
+.LE
+.H 3 "Call Frame Instructions"
+.IX call frame information, instructions
+Each call frame instruction is defined to
+take 0 or more operands.  Some of the operands may be
+encoded as part of the opcode (see section 7.23).
+The instructions are as follows:
+.AL
+.LI 
+.Cf DW_CFA_advance_loc
+takes a single argument that represents a constant delta.
+The required action is to
+create a new table row with a location value that
+is computed by taking the current entry's location value and
+adding (delta * \f(CWcode_alignment_factor\fP).  All other values in the
+new row are initially identical to the current row.
+.LI 
+.Cf DW_CFA_offset
+takes two arguments: 
+an unsigned LEB128 constant representing a factored offset
+and a register number.  The required action is
+to change the rule for the register indicated by the register
+number to be an offset(N) rule with a value of
+(N = factored offset * \f(CWdata_alignment_factor\fP).
+.LI 
+.Cf DW_CFA_restore
+takes a single argument that represents a register number.
+The required action is
+to change the rule for the indicated register 
+to the rule assigned it by the \f(CWinitial_instructions\fP in the CIE.
+.LI 
+.Cf DW_CFA_set_loc
+takes a single argument that represents an address.
+The required action is to create a new table row
+using the specified address as the location. 
+All other values in the
+new row are initially identical to the current row.
+The new location value should always be greater than the current
+one.
+.LI 
+.Cf DW_CFA_advance_loc1
+takes a single ubyte argument that represents a constant delta.
+This instruction is identical to 
+.Cf DW_CFA_advance_loc
+except for the encoding and size of the delta argument.
+.LI 
+.Cf DW_CFA_advance_loc2
+takes a single uhalf argument that represents a constant delta.
+This instruction is identical to 
+.Cf DW_CFA_advance_loc
+except for the encoding and size of the delta argument.
+.LI 
+.Cf DW_CFA_advance_loc4
+takes a single uword argument that represents a constant delta.
+This instruction is identical to 
+.Cf DW_CFA_advance_loc
+except for the encoding and size of the delta argument.
+.LI 
+.Cf DW_CFA_offset_extended
+takes two unsigned LEB128 arguments representing a register number
+and a factored offset.
+This instruction is identical to 
+.Cf DW_CFA_offset
+except for the encoding and size of the register argument.
+.LI 
+.Cf DW_CFA_restore_extended
+takes a single unsigned LEB128 argument that represents a register number.
+This instruction is identical to 
+.Cf DW_CFA_restore
+except for the encoding and size of the register argument.
+.LI 
+.Cf DW_CFA_undefined
+takes a single unsigned LEB128 argument that represents a register number.
+The required action is to set the rule for the specified register
+to ``undefined.''
+.LI 
+.Cf DW_CFA_same_value
+takes a single unsigned LEB128 argument that represents a register number.
+The required action is to set the rule for the specified register
+to ``same value.''
+.LI 
+.Cf DW_CFA_register
+takes two unsigned LEB128 arguments representing register numbers.
+The required action is to set the rule for the first register
+to be the second register.
+.LI 
+\f(CWDW_CFA_remember_state\fP
+.LI 
+\f(CWDW_CFA_restore_state\fP
+.br
+These instructions define a stack of information.  Encountering the 
+.Cf DW_CFA_remember_state
+instruction means to save the rules for every register
+on the current row on the stack.  Encountering the
+.Cf DW_CFA_restore_state
+instruction means to pop the set of rules
+off the stack and place them in the current row.  
+.I
+(This
+operation is useful for compilers that move epilogue
+code into the body of a function.)
+.R
+.LI
+.Cf DW_CFA_def_cfa
+takes two unsigned LEB128 arguments representing a
+register number and an offset.
+The required action is to define the current CFA rule
+to use the provided register and offset.
+.LI 
+.Cf DW_CFA_def_cfa_register
+takes a single unsigned LEB128 argument representing a register
+number.  The required action is to define the current CFA
+rule to use the provided register (but to keep the old offset).
+.LI 
+.Cf DW_CFA_def_cfa_offset
+takes a single unsigned LEB128 argument representing an offset.
+The required action is to define the current CFA
+rule to use the provided offset (but to keep the old register).
+.LI 
+.Cf DW_CFA_nop
+has no arguments and no required actions.  It is used as padding
+to make the FDE an appropriate size.
+.LE
+.H 3 "Call Frame Instruction Usage"
+.IX call frame information, usage
+.I
+To determine the virtual unwind rule set for a given location (L1), one
+searches through the FDE headers looking at the 
+.Cf initial_location
+and
+.Cf address_range
+values to see if L1 is contained in the FDE.  If so, then:
+.AL
+.LI
+Initialize a register set by reading the 
+.Cf initial_instructions
+field of the associated CIE.
+.LI
+Read and process the FDE's instruction sequence until a
+.Cf DW_CFA_advance_loc ,
+.Cf DW_CFA_set_loc ,
+or the end of the instruction stream is
+encountered.
+.LI
+If a 
+.Cf DW_CFA_advance_loc
+or 
+.Cf DW_CFA_set_loc
+instruction was encountered, then
+compute a new location value (L2).  If L1 >= L2 then process the
+instruction and go back to step 2.
+.LI
+The end of the instruction stream can be thought of as a
+.br
+\f(CWDW_CFA_set_loc( initial_location + address_range )\fP 
+.br
+instruction.  
+Unless the FDE is ill-formed, L1 should be less than L2 at this point.
+.LE
+.P
+The rules in the register set now apply to location L1.
+.P
+For an example, see Appendix 5.
+.R
+.OP
+.H 1 "DATA REPRESENTATION"
+This section describes the binary representation of the debugging
+information entry itself, of the
+attribute types and of other fundamental elements described above.
+.H 2 "Vendor Extensibility"
+.IX vendor extensions
+To reserve a portion of the DWARF name space and ranges of
+enumeration values for use for vendor specific extensions,
+.IX tags
+.IX types, base
+.IX base types
+.IX locations, expressions
+.IX calling conventions
+.IX call frame information
+special labels are reserved for tag names, attribute names,
+base type encodings, location operations, language names,
+calling conventions and call frame instructions.
+The labels denoting the beginning and end of the reserved value
+range for vendor specific extensions consist of the appropriate prefix (
+.Cf DW_TAG ,
+.Cf DW_AT ,
+.Cf DW_ATE ,
+.Cf DW_OP ,
+.Cf DW_LANG ,
+.CF DW_CC
+or
+.Cf DW_CFA
+respectively) followed by 
+.Cf _lo_user
+or 
+.Cf _hi_user .
+For example, for entry tags, the special labels are
+.Cf DW_TAG_lo_user
+and
+.Cf DW_TAG_hi_user .
+Values in the range between \fIprefix\fP\f(CW_lo_user\fP and
+\fIprefix\fP\f(CW_hi_user\fP
+inclusive, are reserved for vendor specific extensions.
+Vendors may use values in this range without
+conflicting with current or future system-defined values.
+All other values are reserved for use by the system.
+.P
+Vendor defined tags, attributes, base type encodings, location atoms, 
+language names, calling conventions and call frame instructions, 
+conventionally use the form
+\fIprefix\f(CW_\fIvendor_id\f(CW_\fIname\fR, where \fIvendor_id\fP is some 
+identifying character sequence chosen so as to avoid conflicts with other
+vendors.
+.P
+.IX compatibility
+To ensure that extensions added by one vendor may be safely ignored
+by consumers that do not understand those extensions, 
+the following rules should be followed:
+.AL
+.LI
+New attributes should be added in such a way that a debugger may recognize
+the format of a new attribute value without knowing the content of that
+attribute value.
+.LI
+The semantics of any new attributes should not alter the semantics of
+previously existing attributes.
+.LI
+The semantics of any new tags
+should not conflict with the semantics of previously existing tags.
+.LE
+.H 2 "Reserved Error Values"
+.IX error values
+As a convenience for consumers of DWARF information,
+the value 0 is reserved in the encodings for attribute names, attribute
+forms, base type encodings, location operations, languages,
+statement program opcodes, macro information entries and tag names
+to represent an error condition or unknown value.  DWARF does
+not specify names for these reserved values, since they do not
+represent valid encodings for the given type and should not appear
+in DWARF debugging information.
+.H 2 "Executable Objects and Shared Objects"
+The relocated addresses in the debugging information for an executable
+object are virtual addresses and the relocated addresses in the
+debugging information for a shared object are offsets relative to
+the start of the lowest segment used by that shared object.
+.P
+.I
+This requirement makes the debugging information for shared objects
+position independent.
+Virtual addresses in a shared object may be calculated by adding the
+offset to the base address at which the object was attached.
+This offset is available in the run-time linker's data structures.
+.H 2 "File Constraints"
+All debugging information entries in a relocatable object file, 
+executable object or shared
+object are required to be physically contiguous.
+.H 2 "Format of Debugging Information"
+.IX Version 2
+For each compilation unit compiled with a DWARF Version 2 producer,
+.IX compilation units
+.IX compilation units, header
+a contribution is made to the
+.Cf .debug_info
+.IX \f(CW.debug_info\fP %debugai
+section of the object file.  Each such contribution consists of
+a compilation unit header followed by a series of debugging information
+entries.  Unlike the information encoding for DWARF Version 1, Version 2
+.IX Version 1
+debugging information entries do not themselves contain the debugging
+information entry tag or the attribute name and form encodings for
+each attribute.  Instead, each debugging information entry begins with
+a code that represents an entry in a separate abbreviations table.
+This code is followed directly by a series of attribute values.
+The appropriate entry in the abbreviations table guides the interpretation
+of the information contained directly in the 
+.Cf .debug_info
+section.  Each compilation unit is associated with a particular
+abbreviation table, but multiple compilation units may share
+the same table.  
+.IX abbreviations table
+.I
+.P
+This encoding was based on the observation that typical DWARF producers
+produce a very limited number of different types of debugging information
+entries.  By extracting the common information from those entries
+into a separate table, we are able to compress the generated information.
+.R
+.H 3 "Compilation Unit Header"
+.IX compilation units, header
+The header for the series of debugging information entries contributed
+by a single compilation unit consists of the following information:
+.AL
+.LI
+A 4-byte unsigned integer representing the length of the
+.Cf .debug_info
+contribution for that compilation unit, not including the length field itself.
+.LI
+A 2-byte unsigned integer representing the version of the DWARF information
+for that compilation unit.  For DWARF Version 2, the value in this field is 2.
+.IX Version 2
+.LI
+A 4-byte unsigned offset into the 
+.Cf .debug_abbrev
+.IX \f(CW.debug_abbrev\fP %debugaab
+section.  This offset associates the compilation unit with a particular
+set of debugging information entry abbreviations.
+.LI
+.IX segmented address space
+.IX address space, segmented
+.IX addresses, size of
+A 1-byte unsigned integer representing the size in bytes of an address
+on the target architecture.  If the system uses segmented addressing,
+this value represents the size of the offset portion of an address.
+.IX addresses, offset portion
+.LE
+.P
+.I
+The compilation unit header does not replace the
+.Cf DW_TAG_compile_unit
+debugging information entry.  It is additional information that
+is represented outside the standard DWARF tag/attributes format.
+.R
+.H 3 "Debugging Information Entry"
+Each debugging information entry begins with an unsigned LEB128
+.IX debugging information entries
+number containing the abbreviation code for the entry.
+This code represents an entry within the abbreviation table associated
+with the compilation unit containing this entry.  The abbreviation
+.IX abbreviations table
+code is followed by a series of attribute values.
+.IX attributes, values
+.P
+On some architectures, there are alignment constraints on section boundaries.
+To make it easier to pad debugging information sections to satisfy
+such constraints, the abbreviation code 0 is reserved.  Debugging
+information entries consisting of only the 0 abbreviation code are considered
+null entries.
+.IX debugging information entries, null entries
+.H 3 "Abbreviation Tables"
+.IX abbreviations table
+The abbreviation tables for all compilation units are contained in
+a separate object file section called
+.Cf .debug_abbrev .
+.IX \f(CW.debug_abbrev\fP %debugaab
+As mentioned before, multiple compilation units may share the same
+abbreviation table.  
+.P
+The abbreviation table for a single compilation
+unit consists of a series of abbreviation declarations.
+Each declaration specifies the tag and attributes for a particular
+.IX tags
+.IX attributes
+form of debugging information entry.  Each declaration begins with
+an unsigned LEB128 number representing the abbreviation code itself.
+It is this code that appears at the beginning of a debugging information
+entry in the
+.Cf .debug_info
+section.  As described above, the abbreviation code 0 is reserved for null
+debugging information entries.
+The abbreviation code is followed by another unsigned LEB128
+number that encodes the entry's tag.
+.IX tags
+.nr aX \n(Fg+1
+.nr bX \n(Fg+2
+The encodings for the tag names are given in Figures \n(aX
+and \n(bX.
+.DF
+.TS
+box center;
+l l
+lf(CW) lf(CW)
+. 
+Tag name	Value
+_
+DW_TAG_array_type	0x01
+DW_TAG_class_type	0x02
+DW_TAG_entry_point	0x03
+DW_TAG_enumeration_type	0x04
+DW_TAG_formal_parameter	0x05
+DW_TAG_imported_declaration	0x08
+DW_TAG_label	0x0a
+DW_TAG_lexical_block	0x0b          
+DW_TAG_member	0x0d
+DW_TAG_pointer_type	0x0f
+DW_TAG_reference_type	0x10
+DW_TAG_compile_unit	0x11
+DW_TAG_string_type	0x12
+DW_TAG_structure_type	0x13
+DW_TAG_subroutine_type	0x15
+DW_TAG_typedef	0x16
+DW_TAG_union_type	0x17
+DW_TAG_unspecified_parameters	0x18
+DW_TAG_variant	0x19
+DW_TAG_common_block	0x1a
+DW_TAG_common_inclusion	0x1b
+DW_TAG_inheritance	0x1c
+DW_TAG_inlined_subroutine	0x1d
+DW_TAG_module	0x1e
+DW_TAG_ptr_to_member_type	0x1f
+DW_TAG_set_type	0x20
+DW_TAG_subrange_type	0x21
+DW_TAG_with_stmt	0x22
+DW_TAG_access_declaration	0x23
+DW_TAG_base_type	0x24
+DW_TAG_catch_block	0x25
+DW_TAG_const_type	0x26
+DW_TAG_constant	0x27
+DW_TAG_enumerator	0x28
+DW_TAG_file_type	0x29
+.TE
+.FG "Tag encodings (part 1)"
+.DE
+.DF
+.TS
+box center;
+l l
+lf(CW) lf(CW)
+. 
+Tag name	Value
+_
+DW_TAG_friend	0x2a
+DW_TAG_namelist	0x2b
+DW_TAG_namelist_item	0x2c
+DW_TAG_packed_type	0x2d
+DW_TAG_subprogram	0x2e
+DW_TAG_template_type_param	0x2f
+DW_TAG_template_value_param	0x30
+DW_TAG_thrown_type	0x31
+DW_TAG_try_block	0x32
+DW_TAG_variant_part	0x33
+DW_TAG_variable	0x34
+DW_TAG_volatile_type	0x35
+DW_TAG_lo_user	0x4080
+DW_TAG_hi_user	0xffff
+.TE
+.FG "Tag encodings (part 2)"
+.DE
+.P
+Following the tag encoding is a 1-byte value that determines
+whether a debugging information entry using this abbreviation
+has child entries or not.  If the value is
+.Cf DW_CHILDREN_yes ,
+the next physically succeeding entry of any debugging information
+entry using this abbreviation is the first child of the prior entry.
+If the 1-byte value following the abbreviation's tag encoding
+is
+.Cf DW_CHILDREN_no ,
+the next physically succeeding entry of any debugging information entry
+using this abbreviation is a sibling of the prior entry.  (Either
+the first child or sibling entries may be null entries).
+.IX debugging information entries, siblings
+.IX debugging information entries, child entries
+.IX debugging information entries, null entries
+.nr aX \n(Fg+1
+The encodings for the child determination byte are given in Figure \n(aX.
+(As mentioned in section 2.3, each chain of sibling entries is
+terminated by a null entry).
+.IX debugging information entries, null entries
+.DF
+.TS
+box center;
+l l
+lf(CW) lf(CW)
+. 
+Child determination name	Value
+_
+DW_CHILDREN_no	0
+DW_CHILDREN_yes	1
+.TE
+.FG "Child determination encodings"
+.DE
+.P
+Finally, the child encoding is followed by a series of attribute specifications.
+.IX attributes
+Each attribute specification consists of two parts.  The first part
+is an unsigned LEB128 number representing the attribute's name.
+.IX attributes, names
+The second part is an unsigned LEB128 number representing the
+attribute's form.  The series of attribute specifications ends
+.IX attributes, forms
+with an entry containing 0 for the name and 0 for the form.
+.P
+The attribute form 
+.Cf DW_FORM_indirect
+is a special case.  For attributes with this form, the attribute value
+itself in the
+.Cf .debug_info
+section begins with an unsigned LEB128 number that represents its form.
+This allows producers to choose forms for particular attributes dynamically,
+without having to add a new entry to the abbreviation table.
+.P
+The abbreviations for a given compilation unit end with an entry
+consisting of a 0 byte for the abbreviation code.
+.I
+.P
+See Appendix 2 for a depiction of the organization
+of the debugging information.
+.R
+.H 3 "Attribute Encodings"
+.nr aX \n(Fg+1
+.nr bX \n(Fg+2
+The encodings for the attribute names are given in Figures \n(aX
+and \n(bX.
+.DF
+.TS
+box center;
+l l l
+lf(CW) lf(CW) l
+. 
+Attribute name	Value	Classes
+_
+DW_AT_sibling	0x01	reference
+DW_AT_location	0x02	block, constant
+DW_AT_name	0x03	string
+DW_AT_ordering	0x09	constant
+DW_AT_byte_size	0x0b	constant
+DW_AT_bit_offset	0x0c	constant
+DW_AT_bit_size	0x0d	constant
+DW_AT_stmt_list	0x10	constant
+DW_AT_low_pc	0x11	address
+DW_AT_high_pc	0x12	address
+DW_AT_language	0x13	constant
+DW_AT_discr	0x15	reference
+DW_AT_discr_value	0x16	constant
+DW_AT_visibility	0x17	constant
+DW_AT_import	0x18	reference
+DW_AT_string_length	0x19	block, constant
+DW_AT_common_reference	0x1a	reference
+DW_AT_comp_dir	0x1b	string
+DW_AT_const_value	0x1c	string, constant, block
+DW_AT_containing_type	0x1d	reference
+DW_AT_default_value	0x1e	reference
+DW_AT_inline	0x20	constant
+DW_AT_is_optional	0x21	flag
+DW_AT_lower_bound	0x22	constant, reference
+DW_AT_producer	0x25	string
+DW_AT_prototyped	0x27	flag
+DW_AT_return_addr	0x2a	block, constant
+DW_AT_start_scope	0x2c	constant
+DW_AT_stride_size	0x2e	constant
+DW_AT_upper_bound	0x2f	constant, reference
+.TE
+.FG "Attribute encodings, part 1"
+.DE
+.DF
+.TS
+box center;
+l l l
+lf(CW) lf(CW) l
+. 
+Attribute name	Value	Classes
+_
+DW_AT_abstract_origin	0x31	reference
+DW_AT_accessibility	0x32  	constant
+DW_AT_address_class	0x33	constant
+DW_AT_artificial	0x34	flag
+DW_AT_base_types	0x35	reference
+DW_AT_calling_convention	0x36	constant
+DW_AT_count	0x37	constant, reference
+DW_AT_data_member_location	0x38	block, reference
+DW_AT_decl_column	0x39	constant
+DW_AT_decl_file	0x3a	constant
+DW_AT_decl_line	0x3b	constant
+DW_AT_declaration	0x3c 	flag
+DW_AT_discr_list	0x3d 	block
+DW_AT_encoding	0x3e	constant
+DW_AT_external	0x3f	flag
+DW_AT_frame_base	0x40	block, constant
+DW_AT_friend	0x41	reference
+DW_AT_identifier_case	0x42	constant
+DW_AT_macro_info	0x43	constant
+DW_AT_namelist_item	0x44	block
+DW_AT_priority	0x45 	reference
+DW_AT_segment	0x46	block, constant
+DW_AT_specification	0x47	reference
+DW_AT_static_link	0x48	block, constant
+DW_AT_type	0x49	reference
+DW_AT_use_location	0x4a	block, constant
+DW_AT_variable_parameter	0x4b 	flag
+DW_AT_virtuality	0x4c 	constant
+DW_AT_vtable_elem_location	0x4d	block, reference
+DW_AT_lo_user	0x2000	\(em
+DW_AT_hi_user	0x3fff	\(em
+.TE
+.FG "Attribute encodings, part 2"
+.DE
+.P
+.IX attributes, forms
+The attribute form governs how the value of the attribute is encoded.
+The possible forms may belong to one of the following
+form classes:
+.VL 18
+.LI address
+.IX attributes, addresses
+Represented as an object of appropriate size to hold an 
+address on the target machine (\f(CWDW_FORM_addr\fP).
+This address is relocatable in
+a relocatable object file and is relocated in an 
+executable file or shared object.
+.LI "block"
+.IX attributes, blocks
+Blocks come in four forms.  The first consists of a 1-byte length
+followed by 0 to 255 contiguous information bytes  (\f(CWDW_FORM_block1\fP). 
+The second consists of a 2-byte length
+followed by 0 to 65,535 contiguous information bytes  (\f(CWDW_FORM_block2\fP). 
+The third consists of a 4-byte length
+followed by 0 to 4,294,967,295 contiguous information bytes  (\f(CWDW_FORM_block4\fP). 
+The fourth consists of an unsigned LEB128 length followed by the number
+of bytes specified by the length (\f(CWDW_FORM_block\fP).
+In all forms, the length is the number of information bytes that follow.
+The information bytes may contain any mixture of relocated (or
+relocatable) addresses, references to other debugging information entries or
+data bytes.
+.LI "constant"
+.IX attributes, constants
+There are six forms of constants:
+one, two, four and eight byte values (respectively,
+.Cf DW_FORM_data1 ,
+.Cf DW_FORM_data2 ,
+.Cf DW_FORM_data4 ,
+and
+.Cf DW_FORM_data8 ).
+.IX variable length data
+.IX LEB128
+There are also variable length constant data forms encoded
+using LEB128 numbers (see below).  Both signed (\f(CWDW_FORM_sdata\fP)
+and unsigned (\f(CWDW_FORM_udata\fP) variable length constants are available.
+.LI flag
+.IX attributes, flags
+A flag is represented as a single byte of data (\f(CWDW_FORM_flag\fP). 
+If the flag has value zero, it indicates the absence of the attribute.
+If the flag has a non-zero value, it indicates the presence of
+the attribute.
+.LI reference
+.IX attributes, references
+There are two types of reference.  The first is an
+offset relative to the first byte of the compilation unit header
+for the compilation unit containing the reference.
+The offset must refer to an entry within
+that same compilation unit.  There are five forms for this
+type of reference:
+one, two, four and eight byte offsets (respectively,
+.Cf DW_FORM_ref1 ,
+.Cf DW_FORM_ref2 ,
+.Cf DW_FORM_ref4 ,
+and
+.Cf DW_FORM_ref8 ).
+There are is also an unsigned variable length offset encoded
+using LEB128 numbers (\f(CWDW_FORM_ref_udata\fP).
+.P
+The second type of reference
+is the address of any debugging information entry within
+the same executable or shared object; it may refer to an entry
+in a different compilation unit from the unit containing the
+reference.  This type of reference (\f(CWDW_FORM_ref_addr\fP) is the
+size of an address on the target architecture; it is relocatable
+in a relocatable object file and relocated in an executable file
+or shared object.
+.P
+.I
+The use of compilation unit relative references will reduce
+the number of link-time relocations and so speed up linking.
+.P
+The use of address-type references allows for the commonization
+of information, such as types, across compilation units.
+.R
+.LI string
+.IX attributes, strings
+A string is a sequence of contiguous non-null bytes followed by one null
+byte.  A string may be represented immediately in the debugging information
+entry itself (\f(CWDW_FORM_string\fP), or may be represented as a 4-byte offset
+into a string table contained in the 
+.Cf .debug_str
+.IX \f(CW.debug_str\fP %debugas
+.IX string table
+section of the object file (\f(CWDW_FORM_strp\fP).
+.LE
+.P
+.nr aX \n(Fg+1
+The form encodings are listed in Figure \n(aX.
+.DF
+.TS
+box center;
+l l l
+lf(CW) lf(CW) l
+. 
+Form name	Value	Class
+_
+DW_FORM_addr	0x01	address
+DW_FORM_block2	0x03	block
+DW_FORM_block4	0x04	block
+DW_FORM_data2	0x05	constant
+DW_FORM_data4	0x06	constant
+DW_FORM_data8	0x07	constant
+DW_FORM_string	0x08	string
+DW_FORM_block	0x09	block
+DW_FORM_block1	0x0a	block
+DW_FORM_data1	0x0b	constant
+DW_FORM_flag	0x0c	flag
+DW_FORM_sdata	0x0d	constant
+DW_FORM_strp	0x0e	string
+DW_FORM_udata	0x0f	constant
+DW_FORM_ref_addr	0x10	reference
+DW_FORM_ref1	0x11	reference
+DW_FORM_ref2	0x12	reference
+DW_FORM_ref4	0x13	reference
+DW_FORM_ref8	0x14	reference
+DW_FORM_ref_udata	0x15	reference
+DW_FORM_indirect	0x16	(see section 7.5.3)
+.TE
+.FG "Attribute form encodings"
+.DE
+.H 2 "Variable Length Data"
+.IX variable length data
+.IX LEB128
+The special constant data forms
+.Cf DW_FORM_sdata
+and
+.Cf DW_FORM_udata
+are encoded using ``Little Endian Base 128'' (LEB128)
+numbers. LEB128 is a scheme for encoding integers densely that
+exploits the assumption that most integers are small in magnitude.
+(This encoding is equally suitable whether the target machine
+architecture represents data in big-endian or little-endian order.
+It is ``little endian'' only in the sense that it avoids using space
+to represent the ``big'' end of an unsigned integer, when the big
+end is all zeroes or sign extension bits).
+.P
+.Cf DW_FORM_udata
+(unsigned LEB128) numbers are encoded as follows:
+start at the
+low order end of an unsigned integer and chop it into 7-bit chunks.
+Place each chunk into the low order 7 bits of a byte.  Typically,
+several of the high order bytes will be zero; discard them.  Emit the
+remaining bytes in a stream, starting with the low order byte;
+set the high order bit on each byte except the last emitted byte.
+The high bit of zero on the last byte indicates to the decoder
+that it has encountered the last byte.
+.P
+The integer zero is a special case, consisting of a single zero byte.
+.P
+.I
+.nr aX \n(Fg+1
+Figure \n(aX gives some examples of
+.Cf DW_FORM_udata 
+numbers.  The 
+.Cf 0x80
+in each case is the high order bit of the byte, indicating that
+an additional byte follows:
+.R
+.DF
+.TS
+box center;
+l l l
+nf(CW) lf(CW) lf(CW)
+.
+Number	First byte	Second byte
+_
+2	2	\(em
+127	127	\(em
+128	0+0x80	1  
+129	1+0x80	1
+130	2+0x80	1
+12857	57+0x80	100
+.TE
+.FG "Examples of unsigned LEB128 encodings"
+.DE
+.P
+The encoding for 
+.Cf DW_FORM_sdata
+(signed, 2s complement LEB128) numbers is similar, except that the
+criterion for discarding high order bytes is not whether they are
+zero, but whether they consist entirely of sign extension bits.
+Consider the 32-bit integer 
+.Cf -2 .
+The three high level bytes of the number are sign extension, thus LEB128
+would represent it as a single byte containing the low order 7 bits,
+with the high order bit cleared to indicate the end of the byte
+stream.  Note that there is nothing within the LEB128 representation
+that indicates whether an encoded number is signed or unsigned.
+The decoder must know what type of number to expect.
+.P
+.I
+.nr aX \n(Fg+1
+Figure \n(aX gives some examples of 
+.Cf DW_FORM_sdata 
+numbers.
+.R
+.P
+.I
+Appendix 4 gives algorithms for encoding and decoding these forms.
+.R
+.DF
+.TS
+box center;
+l l l
+nf(CW) lf(CW) lf(CW)
+.
+Number	First byte	Second byte
+_
+2	2	\(em
+-2	0x7e	\(em
+127	127+0x80	0
+-127	1+0x80	0x7f
+128	0+0x80	1
+-128	0+0x80	0x7f
+129	1+0x80	1
+-129	0x7f+0x80	0x7e
+.TE
+.FG "Examples of signed LEB128 encodings"
+.DE
+.H 2 "Location Descriptions"
+.H 3 "Location Expressions"
+.IX locations, descriptions
+.IX locations, expressions
+A location expression is stored in a block of contiguous bytes.
+The bytes form a set of operations.
+Each location operation has a 1-byte code
+that identifies that operation.  Operations can be followed
+by one or more bytes of additional data.  All operations in a
+location expression are concatenated from left to right.
+The encodings for the operations in a location expression
+.IX locations, expressions
+.nr aX \n(Fg+1
+.nr bX \n(Fg+2
+are described in Figures \n(aX and \n(bX.
+.DS
+.TS
+center box;
+l l l l
+lf(CW) lf(CW) l l
+.
+Operation	Code	No. of Operands	Notes
+_
+DW_OP_addr	0x03	1	constant address (size target specific)
+DW_OP_deref	0x06	0
+DW_OP_const1u	0x08	1	1-byte constant
+DW_OP_const1s	0x09	1	1-byte constant
+DW_OP_const2u	0x0a	1	2-byte constant
+DW_OP_const2s	0x0b	1	2-byte constant
+DW_OP_const4u	0x0c	1	4-byte constant
+DW_OP_const4s	0x0d	1	4-byte constant
+DW_OP_const8u	0x0e	1	8-byte constant
+DW_OP_const8s	0x0f	1	8-byte constant
+DW_OP_constu	0x10	1	ULEB128 constant
+DW_OP_consts	0x11	1	SLEB128 constant
+DW_OP_dup	0x12	0	
+DW_OP_drop	0x13	0	
+DW_OP_over	0x14	0	
+DW_OP_pick	0x15	1	1-byte stack index	
+DW_OP_swap	0x16	0	
+DW_OP_rot	0x17	0	
+DW_OP_xderef	0x18	0
+DW_OP_abs	0x19	0
+DW_OP_and	0x1a	0
+DW_OP_div	0x1b	0
+DW_OP_minus	0x1c	0
+DW_OP_mod	0x1d	0
+DW_OP_mul	0x1e	0
+DW_OP_neg	0x1f	0
+DW_OP_not	0x20	0
+DW_OP_or	0x21	0
+DW_OP_plus	0x22	0
+DW_OP_plus_uconst	0x23	1	ULEB128 addend
+DW_OP_shl	0x24	0
+DW_OP_shr	0x25	0
+DW_OP_shra	0x26	0
+.TE
+.FG "Location operation encodings, part 1"
+.DE
+.DS
+.TS
+center box;
+l l l l
+lf(CW) lf(CW) l l
+.
+Operation	Code	No. of Operands	Notes
+_
+DW_OP_xor	0x27	0
+DW_OP_skip	0x2f	1	signed 2-byte constant
+DW_OP_bra	0x28	1	signed 2-byte constant
+DW_OP_eq	0x29	0	
+DW_OP_ge	0x2a	0	
+DW_OP_gt	0x2b	0	
+DW_OP_le	0x2c	0	
+DW_OP_lt	0x2d	0	
+DW_OP_ne	0x2e	0	
+DW_OP_lit0	0x30	0	literals 0..31 = (DW_OP_LIT0|literal)
+DW_OP_lit1	0x31	0	
+\.\.\.				
+DW_OP_lit31	0x4f	0	
+DW_OP_reg0	0x50	0	reg 0..31 = (DW_OP_REG0|regnum)
+DW_OP_reg1	0x51	0
+\.\.\.				
+DW_OP_reg31	0x6f	0
+DW_OP_breg0	0x70	1	SLEB128 offset
+DW_OP_breg1	0x71	1	base reg 0..31 = (DW_OP_BREG0|regnum)
+\.\.\.				
+DW_OP_breg31	0x8f	1
+DW_OP_regx	0x90	1	ULEB128 register
+DW_OP_fbreg	0x91	1	SLEB128 offset
+DW_OP_bregx	0x92	2	ULEB128 register followed by SLEB128 offset
+DW_OP_piece	0x93	1	ULEB128 size of piece addressed
+DW_OP_deref_size	0x94	1	1-byte size of data retrieved
+DW_OP_xderef_size	0x95	1	1-byte size of data retrieved
+DW_OP_nop	0x96	0
+DW_OP_lo_user	0xe0		
+DW_OP_hi_user	0xff		
+.TE
+.FG "Location operation encodings, part 2"
+.DE
+.H 3 "Location Lists"
+.IX locations, lists
+Each entry in a location list consists of two relative addresses
+followed by a 2-byte length, followed by a block of contiguous
+bytes.  The length specifies the number of bytes in the block
+that follows.  The two addresses are the same size as used by
+.Cf DW_FORM_addr
+on the target machine.
+.H 2 "Base Type Encodings"
+.nr aX \n(Fg+1
+.IX base types
+.IX types, base
+The values of the constants used in the
+.Cf DW_AT_encoding
+attribute are given in Figure \n(aX.
+.DF
+.TS
+box center;
+l l
+lf(CW) lf(CW)
+. 
+Base type encoding name	Value
+_
+DW_ATE_address	0x1
+DW_ATE_boolean	0x2
+DW_ATE_complex_float	0x3
+DW_ATE_float	0x4
+DW_ATE_signed	0x5
+DW_ATE_signed_char	0x6
+DW_ATE_unsigned	0x7
+DW_ATE_unsigned_char	0x8
+DW_ATE_lo_user	0x80
+DW_ATE_hi_user	0xff
+.TE
+.FG "Base type encoding values"
+.DE
+.H 2 "Accessibility Codes"
+.nr aX \n(Fg+1
+.IX accessibility
+.IX declarations, accessibility
+The encodings of the constants used in the 
+.Cf DW_AT_accessibility
+attribute are given in Figure \n(aX.
+.DF
+.TS
+box center;
+l l
+lf(CW) lf(CW)
+. 
+Accessibility code name	Value
+_
+DW_ACCESS_public	1
+DW_ACCESS_protected	2
+DW_ACCESS_private	3
+.TE
+.FG "Accessibility encodings"
+.DE
+.H 2 "Visibility Codes"
+.nr aX \n(Fg+1
+The encodings of the constants used in the 
+.Cf DW_AT_visibility
+.IX visibility
+.IX declarations, visibility
+attribute are given in Figure \n(aX.
+.DF
+.TS
+box center;
+l l
+lf(CW) lf(CW)
+. 
+Visibility code name	Value
+_
+DW_VIS_local	1
+DW_VIS_exported	2
+DW_VIS_qualified	3
+.TE
+.FG "Visibility encodings"
+.DE
+.H 2 "Virtuality Codes"
+.nr aX \n(Fg+1
+.IX virtuality
+The encodings of the constants used in the 
+.Cf DW_AT_virtuality
+attribute are given in Figure \n(aX.
+.DF
+.TS
+box center;
+l l
+lf(CW) lf(CW)
+. 
+Virtuality code name	Value
+_
+DW_VIRTUALITY_none	0
+DW_VIRTUALITY_virtual	1
+DW_VIRTUALITY_pure_virtual	2
+.TE
+.FG "Virtuality encodings"
+.DE
+.H 2 "Source Languages"
+.nr aX \n(Fg+1
+.IX languages
+The encodings for source languages are given in Figure \n(aX.
+Names marked with \(dg and their associated
+values are reserved, but the languages
+they represent are not supported in DWARF Version 2.
+.DF
+.TS
+box center;
+l l
+lf(CW) lf(CW)
+. 
+Language name	Value
+_
+DW_LANG_C89	0x0001
+DW_LANG_C	0x0002
+DW_LANG_Ada83\(dg	0x0003
+DW_LANG_C_plus_plus	0x0004
+DW_LANG_Cobol74\(dg	0x0005
+DW_LANG_Cobol85\(dg	0x0006
+DW_LANG_Fortran77	0x0007
+DW_LANG_Fortran90	0x0008
+DW_LANG_Pascal83	0x0009
+DW_LANG_Modula2	0x000a
+DW_LANG_lo_user	0x8000
+DW_LANG_hi_user	0xffff
+.TE
+.FG "Language encodings"
+.DE
+.H 2 "Address Class Encodings"
+.IX addresses, class
+The value of the common address class encoding 
+.Cf DW_ADDR_none
+is 0.
+.H 2 "Identifier Case"
+.IX identifiers, case
+The encodings of the constants used in the 
+.Cf DW_AT_identifier_case
+.nr aX \n(Fg+1
+attribute are given in Figure \n(aX.
+.DF
+.TS
+box center;
+l l
+lf(CW) lf(CW)
+. 
+Identifier Case Name	Value
+_
+DW_ID_case_sensitive	0
+DW_ID_up_case	1
+DW_ID_down_case	2
+DW_ID_case_insensitive	3
+.TE
+.FG "Identifier case encodings"
+.DE
+.H 2 "Calling Convention Encodings"
+.IX calling conventions
+The encodings for the values of the 
+.Cf DW_AT_calling_convention 
+.nr aX \n(Fg+1
+attribute are given in Figure \n(aX.
+.DF
+.TS
+box center;
+l l
+lf(CW) lf(CW)
+. 
+Calling Convention Name	Value
+_
+DW_CC_normal	0x1
+DW_CC_program	0x2
+DW_CC_nocall	0x3
+DW_CC_lo_user	0x40
+DW_CC_hi_user	0xff
+.TE
+.FG "Calling convention encodings"
+.DE
+.H 2 "Inline Codes"
+.IX subroutines, inline
+The encodings of the constants used in the 
+.Cf DW_AT_inline
+.nr aX \n(Fg+1
+attribute are given in Figure \n(aX.
+.DF
+.TS
+box center;
+l l
+lf(CW) lf(CW)
+. 
+Inline Code Name	Value
+_
+DW_INL_not_inlined	0
+DW_INL_inlined	1
+DW_INL_declared_not_inlined	2
+DW_INL_declared_inlined	3
+.TE
+.FG "Inline encodings"
+.DE
+.H 2 "Array Ordering"
+.IX arrays, ordering
+The encodings for the values of the order attributes of arrays
+.nr aX \n(Fg+1
+is given in Figure \n(aX.
+.DF
+.TS
+box center;
+l l
+lf(CW) lf(CW)
+. 
+Ordering name	Value
+_
+DW_ORD_row_major	0
+DW_ORD_col_major	1
+.TE
+.FG "Ordering encodings"
+.DE
+.H 2 "Discriminant Lists"
+.IX variants
+.IX discriminated unions
+.IX discriminants
+The descriptors used in the
+.Cf DW_AT_dicsr_list
+attribute are encoded as 1-byte constants.
+.nr aX \n(Fg+1
+The defined values are presented in Figure \n(aX.
+.DF
+.TS
+box center;
+l l
+lf(CW) lf(CW)
+. 
+Descriptor Name	Value
+_
+DW_DSC_label	0
+DW_DSC_range	1
+.TE
+.FG "Discriminant descriptor encodings"
+.DE
+.H 2 "Name Lookup Table"
+.IX lookup, by name
+Each set of entries in the table of global names contained in the
+.Cf .debug_pubnames
+.IX \f(CW.debug_pubnames\fP %debugap
+section begins with a header consisting of: a 4-byte length containing
+the length of the set of entries for this compilation unit, not including
+the length field itself; a 2-byte version identifier containing
+the value 2 for DWARF Version 2; a 4-byte offset into the 
+.Cf .debug_info 
+section; and a 4-byte length containing the size in bytes
+of the contents of the 
+.Cf .debug_info
+section generated to represent this compilation unit.
+This header is followed by a series of tuples.  
+Each tuple consists of a 4-byte offset
+followed by a string of non-null bytes terminated by one null byte.
+Each set is terminated by a 4-byte word containing the value 0.
+.H 2 "Address Range Table"
+.IX lookup, by address
+Each set of entries in the table of address ranges contained in the
+.Cf .debug_aranges
+.IX \f(CW.debug_aranges\fP %debugaar
+section begins with a header consisting of: a 4-byte length containing
+the length of the set of entries for this compilation unit, not including
+the length field itself; a 2-byte version identifier containing
+the value 2 for DWARF Version 2; a 4-byte offset into the 
+.Cf .debug_info
+section;  a 1-byte unsigned integer containing the size in bytes of an 
+address (or the offset portion of an address for segmented addressing)
+.IX addresses, offset portion
+.IX addresses, size of
+on the target system; and a 1-byte unsigned integer containing the 
+size in bytes of a segment descriptor on the target system.
+This header is followed by a series of tuples.  
+Each tuple consists of an address and a length, each
+in the size appropriate for an address on the target architecture.
+The first tuple following the header in each set begins at
+an offset that is a multiple of the size of a single tuple
+(that is, twice the size of an address).  The header is
+padded, if necessary, to the appropriate boundary.
+Each set of tuples is terminated by a 0 for the address and 0 for the length.
+.H 2 "Line Number Information"
+.IX line number information
+.IX line number information, definitions
+The sizes of the integers used in the line number and
+call frame information sections are as follows:
+.VL 15
+.LI "sbyte"
+Signed 1-byte value.
+.LI "ubyte"
+Unsigned 1-byte value.
+.LI "uhalf"
+Unsigned 2-byte value.
+.LI "sword"
+Signed 4-byte value.
+.LI "uword"
+Unsigned 4-byte value.
+.LI
+.LE
+.P
+.IX Version 2
+The version number in the statement program prologue is 2 for
+DWARF Version 2.
+The boolean values ``true'' and ``false'' used by the statement
+information program are encoded as a single byte containing the
+value 0 for ``false,'' and a non-zero value for ``true.''
+The encodings for the pre-defined standard opcodes are given
+.IX line number information, standard opcodes
+.nr aX \n(Fg+1
+in Figure \n(aX.
+.DF
+.TS
+box center;
+l l
+lf(CW)	lf(CW)
+.
+Opcode Name	Value
+_
+DW_LNS_copy	1
+DW_LNS_advance_pc	2
+DW_LNS_advance_line	3
+DW_LNS_set_file	4
+DW_LNS_set_column	5
+DW_LNS_negate_stmt	6
+DW_LNS_set_basic_block	7
+DW_LNS_const_add_pc	8
+DW_LNS_fixed_advance_pc	9
+.TE
+.FG "Standard Opcode Encodings"
+.DE
+The encodings for the pre-defined extended opcodes are given
+.IX line number information, extended opcodes
+.nr aX \n(Fg+1
+in Figure \n(aX.
+.DF
+.TS
+box center;
+l l
+lf(CW) lf(CW)
+.
+Opcode Name	Value
+_
+DW_LNE_end_sequence	1
+DW_LNE_set_address	2
+DW_LNE_define_file	3
+.TE
+.FG "Extended Opcode Encodings"
+.DE
+.H 2 "Macro Information"
+.IX macro information
+.IX source, files
+The source line numbers and source file indices encoded in the
+macro information section are represented as unsigned LEB128 numbers
+as are the constants in an
+.Cf DW_MACINFO_vendor_ext
+entry.
+The macinfo type is encoded as a single byte.  The encodings are given
+.nr aX \n(Fg+1
+in Figure \n(aX.
+.DF
+.TS
+box center;
+l l
+lf(CW)	lf(CW)
+.
+Macinfo Type Name	Value
+_
+DW_MACINFO_define	1
+DW_MACINFO_undef	2
+DW_MACINFO_start_file	3
+DW_MACINFO_end_file	4
+DW_MACINFO_vendor_ext	255
+.TE
+.FG "Macinfo Type Encodings"
+.DE
+.H 2 "Call Frame Information"
+.IX call frame information
+The value of the CIE id in the CIE header is
+.Cf 0xffffffff .
+The initial value of the CIE version number is 1.
+.P
+Call frame instructions are encoded in one or more bytes.
+.IX call frame information, instructions
+The primary opcode is encoded in the high order two bits of 
+the first byte (that is, opcode = byte >> 6).
+An operand or extended opcode may be encoded in the low order
+6 bits.   Additional operands are encoded in subsequent bytes.
+The instructions and their encodings are presented
+.nr aX \n(Fg+1
+in Figure \n(aX.
+.DS
+.TS
+center box;
+l l l l l
+lf(CW) lf(CW) l l
+lf(CW) lf(CW) l l
+lf(CW) lf(CW) l l
+lf(CW) lf(CW) lf(CW) l.
+Instruction	High 2 Bits	Low 6 Bits	Operand 1	Operand 2
+_
+DW_CFA_advance_loc	0x1	delta		
+DW_CFA_offset	0x2	register	ULEB128 offset
+DW_CFA_restore	0x3	register
+DW_CFA_set_loc	0	0x01	address
+DW_CFA_advance_loc1	0	0x02	1-byte delta
+DW_CFA_advance_loc2	0	0x03	2-byte delta
+DW_CFA_advance_loc4	0	0x04	4-byte delta
+DW_CFA_offset_extended	0	0x05	ULEB128 register	ULEB128 offset
+DW_CFA_restore_extended	0	0x06	ULEB128 register
+DW_CFA_undefined	0	0x07	ULEB128 register
+DW_CFA_same_value	0	0x08	ULEB128 register
+DW_CFA_register	0	0x09	ULEB128 register	ULEB128 register
+DW_CFA_remember_state	0	0x0a
+DW_CFA_restore_state	0	0x0b
+DW_CFA_def_cfa	0	0x0c	ULEB128 register	ULEB128 offset
+DW_CFA_def_cfa_register	0	0x0d	ULEB128 register
+DW_CFA_def_cfa_offset	0	0x0e	ULEB128 offset
+DW_CFA_nop	0	0
+DW_CFA_lo_user	0	0x1c
+DW_CFA_hi_user	0	0x3f
+.TE
+.FG "Call frame instruction encodings"
+.DE
+.H 2 "Dependencies"
+The debugging information in this format is intended to exist in the
+.Cf .debug_abbrev ,
+.Cf .debug_aranges ,
+.Cf .debug_frame ,
+.Cf .debug_info ,
+.Cf .debug_line ,
+.Cf .debug_loc ,
+.Cf .debug_macinfo ,
+.Cf .debug_pubnames 
+and
+.Cf .debug_str
+.IX \f(CW.debug_abbrev\fP %debugaab
+.IX \f(CW.debug_aranges\fP %debugaar
+.IX \f(CW.debug_frame\fP %debugaf
+.IX \f(CW.debug_info\fP %debugai
+.IX \f(CW.debug_line\fP %debugali
+.IX \f(CW.debug_loc\fP %debugalo
+.IX \f(CW.debug_macinfo\fP %debugam
+.IX \f(CW.debug_pubnames\fP %debugap
+.IX \f(CW.debug_str\fP %debugas
+sections of an object file.
+The information is not word-aligned, so the assembler must provide a
+way for the compiler to produce 2-byte and 4-byte quantities without
+alignment restrictions, and the linker must be able to
+relocate a 4-byte reference at an arbitrary alignment.
+In target architectures with 64-bit addresses, the assembler and linker
+must similarly handle 8-byte references at arbitrary alignments.
+.OP
+.H 1 "FUTURE DIRECTIONS"
+The \*(iX \*(tE is working on a specification for a set of interfaces
+for reading DWARF information, that will hide changes in the
+representation of that information from its consumers.  It is
+hoped that using these interfaces will make the transition from
+DWARF Version 1 to Version 2 much simpler and will make it
+easier for a single consumer to support objects using either
+Version 1 or Version 2 DWARF.
+.P
+A draft of this specification is available for review from
+\*(iX. The \*(tE wishes to stress, however, that the specification
+is still in flux.
+.OP
+.HU "Appendix 1 -- Current Attributes by Tag Value"
+.P
+The list below enumerates the attributes that are most applicable to each type
+of debugging information entry.
+DWARF does not in general require that a given debugging information
+entry contain a particular attribute or set of attributes.  Instead, a
+DWARF producer is free to generate any, all, or none of the attributes
+described in the text as being applicable to a given entry.  Other
+attributes (both those defined within this document but not explicitly
+associated with the entry in question, and new, vendor-defined ones)
+may also appear in a given debugging entry.
+Therefore, the list may be
+taken as instructive, but cannot be considered definitive.
+.sp
+.sp
+.DS
+.TS
+box, tab(:) ;
+lfB lfB
+lf(CW) lf(CW) .
+TAG NAME:APPLICABLE ATTRIBUTES
+_
+DW_TAG_access_declaration:DECL\(dg
+:DW_AT_accessibility
+:DW_AT_name
+:DW_AT_sibling
+_
+DW_TAG_array_type:DECL
+:DW_AT_abstract_origin
+:DW_AT_accessibility
+:DW_AT_byte_size
+:DW_AT_declaration
+:DW_AT_name
+:DW_AT_ordering
+:DW_AT_sibling
+:DW_AT_start_scope
+:DW_AT_stride_size
+:DW_AT_type
+:DW_AT_visibility
+_
+DW_TAG_base_type:DW_AT_bit_offset
+:DW_AT_bit_size
+:DW_AT_byte_size
+:DW_AT_encoding
+:DW_AT_name
+:DW_AT_sibling
+_
+DW_TAG_catch_block:DW_AT_abstract_origin
+:DW_AT_high_pc
+:DW_AT_low_pc
+:DW_AT_segment
+:DW_AT_sibling
+.TE
+.DE
+.br
+\(dg
+.Cf DW_AT_decl_column ,
+.Cf DW_AT_decl_file ,
+.Cf DW_AT_decl_line .
+.SK
+.DS
+.B "Appendix 1 (cont'd) -- Current Attributes by Tag Value"
+
+
+
+.TS
+box, tab(:) ;
+lfB lfB
+lf(CW) lf(CW) .
+TAG NAME:APPLICABLE ATTRIBUTES
+_
+DW_TAG_class_type:DECL
+:DW_AT_abstract_origin
+:DW_AT_accessibility
+:DW_AT_byte_size
+:DW_AT_declaration
+:DW_AT_name
+:DW_AT_sibling
+:DW_AT_start_scope
+:DW_AT_visibility
+_
+DW_TAG_common_block:DECL
+:DW_AT_declaration
+:DW_AT_location
+:DW_AT_name
+:DW_AT_sibling
+:DW_AT_visibility
+_
+DW_TAG_common_inclusion:DECL
+:DW_AT_common_reference
+:DW_AT_declaration
+:DW_AT_sibling
+:DW_AT_visibility
+_
+DW_TAG_compile_unit:DW_AT_base_types
+:DW_AT_comp_dir
+:DW_AT_identifier_case
+:DW_AT_high_pc
+:DW_AT_language
+:DW_AT_low_pc
+:DW_AT_macro_info
+:DW_AT_name
+:DW_AT_producer
+:DW_AT_sibling
+:DW_AT_stmt_list
+_
+DW_TAG_const_type:DW_AT_sibling
+:DW_AT_type
+.TE
+.DE
+.br
+.SK
+.DS
+.B "Appendix 1 (cont'd) -- Current Attributes by Tag Value"
+
+
+
+.TS
+box, tab(:) ;
+lfB lfB
+lf(CW) lf(CW) .
+TAG NAME:APPLICABLE ATTRIBUTES
+_
+DW_TAG_constant:DECL
+:DW_AT_accessibility
+:DW_AT_constant_value
+:DW_AT_declaration
+:DW_AT_external
+:DW_AT_name
+:DW_AT_sibling
+:DW_AT_start_scope
+:DW_AT_type
+:DW_AT_visibility
+_
+DW_TAG_entry_point:DW_AT_address_class
+:DW_AT_low_pc
+:DW_AT_name
+:DW_AT_return_addr
+:DW_AT_segment
+:DW_AT_sibling
+:DW_AT_static_link
+:DW_AT_type
+_
+DW_TAG_enumeration_type:DECL
+:DW_AT_abstract_origin
+:DW_AT_accessibility
+:DW_AT_byte_size
+:DW_AT_declaration
+:DW_AT_name
+:DW_AT_sibling
+:DW_AT_start_scope
+:DW_AT_visibility
+_
+DW_TAG_enumerator:DECL
+:DW_AT_const_value
+:DW_AT_name
+:DW_AT_sibling
+_
+DW_TAG_file_type:DECL
+:DW_AT_abstract_origin
+:DW_AT_byte_size
+:DW_AT_name
+:DW_AT_sibling
+:DW_AT_start_scope
+:DW_AT_type
+:DW_AT_visibility
+.TE
+.DE
+.br
+.SK
+.DS
+.B "Appendix 1 (cont'd) -- Current Attributes by Tag Value"
+
+
+
+.TS
+box, tab(:) ;
+lfB lfB
+lf(CW) lf(CW) .
+TAG NAME:APPLICABLE ATTRIBUTES
+_
+DW_TAG_formal_parameter:DECL
+:DW_AT_abstract_origin
+:DW_AT_artificial
+:DW_AT_default_value
+:DW_AT_is_optional
+:DW_AT_location
+:DW_AT_name
+:DW_AT_segment
+:DW_AT_sibling
+:DW_AT_type
+:DW_AT_variable_parameter
+_
+DW_TAG_friend:DECL
+:DW_AT_abstract_origin
+:DW_AT_friend
+:DW_AT_sibling
+_
+DW_TAG_imported_declaration:DECL
+:DW_AT_accessibility
+:DW_AT_import
+:DW_AT_name
+:DW_AT_sibling
+:DW_AT_start_scope
+_
+DW_TAG_inheritance:DECL
+:DW_AT_accessibility
+:DW_AT_data_member_location
+:DW_AT_sibling
+:DW_AT_type
+:DW_AT_virtuality
+_
+DW_TAG_inlined_subroutine:DECL
+:DW_AT_abstract_origin
+:DW_AT_high_pc
+:DW_AT_low_pc
+:DW_AT_segment
+:DW_AT_sibling
+:DW_AT_return_addr
+:DW_AT_start_scope
+_
+DW_TAG_label:DW_AT_abstract_origin
+:DW_AT_low_pc
+:DW_AT_name
+:DW_AT_segment
+:DW_AT_start_scope
+:DW_AT_sibling
+.TE
+.DE
+.br
+.SK
+.DS
+.B "Appendix 1 (cont'd) -- Current Attributes by Tag Value"
+
+
+
+.TS
+box, tab(:) ;
+lfB lfB
+lf(CW) lf(CW) .
+TAG NAME:APPLICABLE ATTRIBUTES
+_
+DW_TAG_lexical_block:DW_AT_abstract_origin
+:DW_AT_high_pc
+:DW_AT_low_pc
+:DW_AT_name
+:DW_AT_segment
+:DW_AT_sibling
+_
+DW_TAG_member:DECL
+:DW_AT_accessibility
+:DW_AT_byte_size
+:DW_AT_bit_offset
+:DW_AT_bit_size
+:DW_AT_data_member_location
+:DW_AT_declaration
+:DW_AT_name
+:DW_AT_sibling
+:DW_AT_type
+:DW_AT_visibility
+_
+DW_TAG_module:DECL
+:DW_AT_accessibility
+:DW_AT_declaration
+:DW_AT_high_pc
+:DW_AT_low_pc
+:DW_AT_name
+:DW_AT_priority
+:DW_AT_segment
+:DW_AT_sibling
+:DW_AT_visibility
+_
+DW_TAG_namelist:DECL
+:DW_AT_accessibility
+:DW_AT_abstract_origin
+:DW_AT_declaration
+:DW_AT_sibling
+:DW_AT_visibility
+_
+DW_TAG_namelist_item:DECL
+:DW_AT_namelist_item
+:DW_AT_sibling
+_
+DW_TAG_packed_type:DW_AT_sibling
+:DW_AT_type
+.TE
+.DE
+.br
+.SK
+.DS
+.B "Appendix 1 (cont'd) -- Current Attributes by Tag Value"
+
+
+
+.TS
+box, tab(:) ;
+lfB lfB
+lf(CW) lf(CW) .
+TAG NAME:APPLICABLE ATTRIBUTES
+_
+DW_TAG_pointer_type:DW_AT_address_class
+:DW_AT_sibling
+:DW_AT_type
+_
+DW_TAG_ptr_to_member_type:DECL
+:DW_AT_abstract_origin
+:DW_AT_address_class
+:DW_AT_containing_type
+:DW_AT_declaration
+:DW_AT_name
+:DW_AT_sibling
+:DW_AT_type
+:DW_AT_use_location
+:DW_AT_visibility
+_
+DW_TAG_reference_type:DW_AT_address_class
+:DW_AT_sibling
+:DW_AT_type
+_
+DW_TAG_set_type:DECL
+:DW_AT_abstract_origin
+:DW_AT_accessibility
+:DW_AT_byte_size
+:DW_AT_declaration
+:DW_AT_name
+:DW_AT_start_scope
+:DW_AT_sibling
+:DW_AT_type
+:DW_AT_visibility
+_
+DW_TAG_string_type:DECL
+:DW_AT_accessibility
+:DW_AT_abstract_origin
+:DW_AT_byte_size
+:DW_AT_declaration
+:DW_AT_name
+:DW_AT_segment
+:DW_AT_sibling
+:DW_AT_start_scope
+:DW_AT_string_length
+:DW_AT_visibility
+.TE
+.DE
+.SK
+.DS
+.B "Appendix 1 (cont'd) -- Current Attributes by Tag Value"
+
+
+
+.TS
+box, tab(:) ;
+lfB lfB
+lf(CW) lf(CW) .
+TAG NAME:APPLICABLE ATTRIBUTES
+_
+DW_TAG_structure_type:DECL
+:DW_AT_abstract_origin
+:DW_AT_accessibility
+:DW_AT_byte_size
+:DW_AT_declaration
+:DW_AT_name
+:DW_AT_sibling
+:DW_AT_start_scope
+:DW_AT_visibility
+_
+DW_TAG_subprogram:DECL
+:DW_AT_abstract_origin
+:DW_AT_accessibility
+:DW_AT_address_class
+:DW_AT_artificial
+:DW_AT_calling_convention
+:DW_AT_declaration
+:DW_AT_external
+:DW_AT_frame_base
+:DW_AT_high_pc
+:DW_AT_inline
+:DW_AT_low_pc
+:DW_AT_name
+:DW_AT_prototyped
+:DW_AT_return_addr
+:DW_AT_segment
+:DW_AT_sibling
+:DW_AT_specification
+:DW_AT_start_scope
+:DW_AT_static_link
+:DW_AT_type
+:DW_AT_visibility
+:DW_AT_virtuality
+:DW_AT_vtable_elem_location
+.TE
+.DE
+.SK
+.DS
+.B "Appendix 1 (cont'd) -- Current Attributes by Tag Value"
+
+
+
+.TS
+box, tab(:) ;
+lfB lfB
+lf(CW) lf(CW) .
+TAG NAME:APPLICABLE ATTRIBUTES
+_
+DW_TAG_subrange_type:DECL
+:DW_AT_abstract_origin
+:DW_AT_accessibility
+:DW_AT_byte_size
+:DW_AT_count
+:DW_AT_declaration
+:DW_AT_lower_bound
+:DW_AT_name
+:DW_AT_sibling
+:DW_AT_type
+:DW_AT_upper_bound
+:DW_AT_visibility
+_
+DW_TAG_subroutine_type:DECL
+:DW_AT_abstract_origin
+:DW_AT_accessibility
+:DW_AT_address_class
+:DW_AT_declaration
+:DW_AT_name
+:DW_AT_prototyped
+:DW_AT_sibling
+:DW_AT_start_scope
+:DW_AT_type
+:DW_AT_visibility
+_
+DW_TAG_template_type_param:DECL
+:DW_AT_name
+:DW_AT_sibling
+:DW_AT_type
+_
+DW_TAG_template_value_param:DECL
+:DW_AT_name
+:DW_AT_const_value
+:DW_AT_sibling
+:DW_AT_type
+_
+DW_TAG_thrown_type:DECL
+:DW_AT_sibling
+:DW_AT_type
+_
+DW_TAG_try_block:DW_AT_abstract_origin
+:DW_AT_high_pc
+:DW_AT_low_pc
+:DW_AT_segment
+:DW_AT_sibling
+.TE
+.DE
+.br
+.SK
+.DS
+.B "Appendix 1 (cont'd) -- Current Attributes by Tag Value"
+
+
+
+.TS
+box, tab(:) ;
+lfB lfB
+lf(CW) lf(CW) .
+TAG NAME:APPLICABLE ATTRIBUTES
+_
+DW_TAG_typedef:DECL
+:DW_AT_abstract_origin
+:DW_AT_accessibility
+:DW_AT_declaration
+:DW_AT_name
+:DW_AT_sibling
+:DW_AT_start_scope
+:DW_AT_type
+:DW_AT_visibility
+_
+DW_TAG_union_type:DECL
+:DW_AT_abstract_origin
+:DW_AT_accessibility
+:DW_AT_byte_size
+:DW_AT_declaration
+:DW_AT_friends
+:DW_AT_name
+:DW_AT_sibling
+:DW_AT_start_scope
+:DW_AT_visibility
+_
+DW_TAG_unspecified_parameters:DECL
+:DW_AT_abstract_origin
+:DW_AT_artificial
+:DW_AT_sibling
+_
+DW_TAG_variable:DECL
+:DW_AT_accessibility
+:DW_AT_constant_value
+:DW_AT_declaration
+:DW_AT_external
+:DW_AT_location
+:DW_AT_name
+:DW_AT_segment
+:DW_AT_sibling
+:DW_AT_specification
+:DW_AT_start_scope
+:DW_AT_type
+:DW_AT_visibility
+.TE
+.DE
+.br
+.SK
+.DS
+.B "Appendix 1 (cont'd) -- Current Attributes by Tag Value"
+
+
+
+.TS
+box, tab(:) ;
+lfB lfB
+lf(CW) lf(CW) .
+TAG NAME:APPLICABLE ATTRIBUTES
+_
+DW_TAG_variant:DECL
+:DW_AT_accessibility
+:DW_AT_abstract_origin
+:DW_AT_declaration
+:DW_AT_discr_list
+:DW_AT_discr_value
+:DW_AT_sibling
+_
+DW_TAG_variant_part:DECL
+:DW_AT_accessibility
+:DW_AT_abstract_origin
+:DW_AT_declaration
+:DW_AT_discr
+:DW_AT_sibling
+:DW_AT_type
+_
+DW_TAG_volatile_type:DW_AT_sibling
+:DW_AT_type
+_
+DW_TAG_with_statement:DW_AT_accessibility
+:DW_AT_address_class
+:DW_AT_declaration
+:DW_AT_high_pc
+:DW_AT_location
+:DW_AT_low_pc
+:DW_AT_segment
+:DW_AT_sibling
+:DW_AT_type
+:DW_AT_visibility
+.TE
+.DE
+.SK
+.OP
+.HU "Appendix 2 -- Organization of Debugging Information"
+The following diagram depicts the relationship of the abbreviation
+tables contained in the 
+.Cf .debug_abbrev
+section to the information contained in the 
+.Cf .debug_info
+section.  Values are given in symbolic form, where possible.
+.DF
+.nf
+.PS
+scale=100
+define t201 |
+[ box invis ht 154 wid 295 with .sw at 0,0
+"\f(CW\s9\&1\f1\s0" at 0,147 ljust
+"\f(CW\s9\&DW_TAG_compile_unit\f1\s0" at 0,133 ljust
+"\f(CW\s9\&DW_CHILDREN_yes\f1\s0" at 0,119 ljust
+"\f(CW\s9\&DW_AT_name          DW_FORM_string\f1\s0" at 0,105 ljust
+"\f(CW\s9\&DW_AT_producer      DW_FORM_string\f1\s0" at 0,91 ljust
+"\f(CW\s9\&DW_AT_compdir       DW_FORM_string\f1\s0" at 0,77 ljust
+"\f(CW\s9\&DW_AT_language      DW_FORM_data1\f1\s0" at 0,63 ljust
+"\f(CW\s9\&DW_AT_low_poc       DW_FORM_addr\f1\s0" at 0,49 ljust
+"\f(CW\s9\&DW_AT_high_pc       DW_FORM_addr\f1\s0" at 0,35 ljust
+"\f(CW\s9\&DW_AT_stmt_list     DW_FORM_indirect\f1\s0" at 0,21 ljust
+"\f(CW\s9\&0                   0\f1\s0" at 0,7 ljust
+] |
+
+define t103 |
+[ box invis ht 42 wid 74 with .sw at 0,0
+"\f(CW\s9\&4\f1\s0" at 0,35 ljust
+"\f(CW\s9\&\"POINTER\"\f1\s0" at 0,21 ljust
+"\f(CW\s9\&\f1\s0" at 0,7 ljust
+] |
+
+define t177 |
+[ box invis ht 28 wid 13 with .sw at 0,0
+"\f(CW\s9\&3\f1\s0" at 0,21 ljust
+"\f(CW\s9\&\f1\s0" at 0,7 ljust
+] |
+
+define t224 |
+[ box invis ht 84 wid 280 with .sw at 0,0
+"\f(CW\s9\&4\f1\s0" at 0,77 ljust
+"\f(CW\s9\&DW_TAG_typedef\f1\s0" at 0,63 ljust
+"\f(CW\s9\&DW_CHILDREN_no\f1\s0" at 0,49 ljust
+"\f(CW\s9\&DW_AT_name          DW_FORM_string\f1\s0" at 0,35 ljust
+"\f(CW\s9\&DW_AT_type          DW_FORM_ref4 \f1\s0" at 0,21 ljust
+"\f(CW\s9\&0                   0            \f1\s0" at 0,7 ljust
+] |
+
+define t149 |
+[ box invis ht 28 wid 51 with .sw at 0,0
+"\f(CW\s9\&4\f1\s0" at 0,21 ljust
+"\f(CW\s9\&\"strp\"\f1\s0" at 0,7 ljust
+] |
+
+define t205 |
+[ box invis ht 98 wid 280 with .sw at 0,0
+"\f(CW\s9\&2\f1\s0" at 0,91 ljust
+"\f(CW\s9\&DW_TAG_base_type\f1\s0" at 0,77 ljust
+"\f(CW\s9\&DW_CHILDREN_no\f1\s0" at 0,63 ljust
+"\f(CW\s9\&DW_AT_name          DW_FORM_string\f1\s0" at 0,49 ljust
+"\f(CW\s9\&DW_AT_encoding      DW_FORM_data1\f1\s0" at 0,35 ljust
+"\f(CW\s9\&DW_AT_byte_size     DW_FORM_data1\f1\s0" at 0,21 ljust
+"\f(CW\s9\&0                   0\f1\s0" at 0,7 ljust
+] |
+
+define t126 |
+[ box invis ht 126 wid 257 with .sw at 0,0
+"\f(CW\s9\&\"myfile.c\"\f1\s0" at 0,119 ljust
+"\f(CW\s9\&\"Best Compiler Corp: Version 1.3\"\f1\s0" at 0,105 ljust
+"\f(CW\s9\&\"mymachine:/home/mydir/src:\"\f1\s0" at 0,91 ljust
+"\f(CW\s9\&DW_LANG_C89\f1\s0" at 0,77 ljust
+"\f(CW\s9\&0x0\f1\s0" at 0,63 ljust
+"\f(CW\s9\&0x55\f1\s0" at 0,49 ljust
+"\f(CW\s9\&DW_FORM_data4\f1\s0" at 0,35 ljust
+"\f(CW\s9\&0x0\f1\s0" at 0,21 ljust
+"\f(CW\s9\&\f1\s0" at 0,7 ljust
+] |
+
+define t219 |
+[ box invis ht 70 wid 260 with .sw at 0,0
+"\f(CW\s9\&3\f1\s0" at 0,63 ljust
+"\f(CW\s9\&DW_TAG_pointer_type\f1\s0" at 0,49 ljust
+"\f(CW\s9\&DW_CHILDREN_no\f1\s0" at 0,35 ljust
+"\f(CW\s9\&DW_AT_type          DW_FORM_ref4\f1\s0" at 0,21 ljust
+"\f(CW\s9\&0                   0\f1\s0" at 0,7 ljust
+] |
+
+define t109 |
+[ box invis ht 42 wid 165 with .sw at 0,0
+"\f(CW\s9\&\"char\"\f1\s0" at 0,35 ljust
+"\f(CW\s9\&DW_ATE_unsigned_char\f1\s0" at 0,21 ljust
+"\f(CW\s9\&1\f1\s0" at 0,7 ljust
+] |
+
+box invis ht 704 wid 680 with .sw at 0,0
+t201 with .nw at 376,657
+box ht 520 wid 320 with .nw at 360,672 
+box ht 208 wid 280 with .nw at 24,208 
+t103 with .nw at 40,353
+t177 with .nw at 40,398
+line  from 360,176 to 680,176 
+line  from 360,280 to 680,280 
+line  from 360,368 to 680,368 
+line  from 360,488 to 680,488 
+t224 with .nw at 376,270
+"\f(CW\s9\&0\f1\s0" at 376,164 ljust
+"\f(CW\s9\&0\f1\s0" at 40,289 ljust
+"\fI\s9\&e2\f1\s0" at 40,317 ljust
+"\fI\s9\&e2:\f1\s0" at 0,389 ljust
+"\f(CW\s9\&2\f1\s0" at 44,176 ljust
+line  from 24,128 to 304,128 
+"\f(CW\s9\&...\f1\s0" at 44,113 ljust
+t149 with .nw at 44,88
+"\fI\s9\&e2\f1\s0" at 44,49 ljust
+"\f(CW\s9\&...\f1\s0" at 44,17 ljust
+box ht 416 wid 280 with .nw at 24,688 
+"\fI\s9\&length\f1\s0" at 44,192 ljust
+"\f(CW\s9\&4\f1\s0" at 48,140
+"\fI\s9\&a1  (abbreviation table offset)\f1\s0" at 44,160 ljust
+"\f(CW\s9\&4\f1\s0" at 44,624
+"\fI\s9\&a1  (abbreviation table offset)\f1\s0" at 40,640 ljust
+t205 with .nw at 376,477
+"\fI\s9\&a1:\f1\s0" at 348,657 rjust
+"\fI\s9\&length\f1\s0" at 40,672 ljust
+"\fR\s10\&Abbreviation Table - .debug_abbrev\f1\s0" at 384,678 ljust
+"\fR\s10\&Compilation Unit 1 - .debug_info\f1\s0" at 68,694 ljust
+"\fR\s10\&Compilation Unit 2 - .debug_info\f1\s0" at 64,218 ljust
+"\f(CW\s9\&2\f1\s0" at 44,656
+"\f(CW\s9\&1\f1\s0" at 44,605
+t126 with .nw at 36,599
+line  from 24,616 to 304,616 
+"\f(CW\s9\&2\f1\s0" at 40,461 ljust
+t219 with .nw at 376,359
+line  from 24,96 to 304,96 
+line  from 24,32 to 304,32 
+t109 with .nw at 40,449
+"\fI\s9\&e1\f1\s0" at 40,373 ljust
+"\fI\s9\&e1:\f1\s0" at 0,461 ljust
+line  from 24,480 to 304,480 
+line  from 24,400 to 304,400 
+line  from 24,360 to 304,360 
+line  from 24,304 to 304,304 
+.PE
+.fi
+.DE
+.SK
+.OP
+.HU "Appendix 3 -- Statement Program Examples"
+.P
+Consider this simple source file and the resulting machine code for
+the Intel 8086 processor:
+.DS
+.S -2
+.TS
+;
+lf(CW) lf(CW) s
+lf(CW) lf(CW) s
+lf(CW) lf(CW) lf(CW)
+lf(CW) lf(CW) lf(CW)
+lf(CW) lf(CW) s
+lf(CW) lf(CW) s
+lf(CW) lf(CW) lf(CW)
+lf(CW) lf(CW) lf(CW)
+lf(CW) lf(CW) lf(CW)
+lf(CW) lf(CW) lf(CW)
+lf(CW) lf(CW) s
+lf(CW) lf(CW) lf(CW)
+lf(CW) lf(CW) lf(CW)
+lf(CW) lf(CW) lf(CW)
+lf(CW) lf(CW) lf(CW)
+lf(CW) lf(CW) s
+lf(CW) lf(CW) lf(CW) 
+lf(CW) lf(CW) lf(CW)
+lf(CW) lf(CW) s
+lf(CW) lf(CW) lf(CW).
+1:	int
+2:	main()
+	0x239:	push pb
+	0x23a:	mov bp,sp
+3:	{
+4:	printf("Omit needless words\en");
+	0x23c:	mov ax,0xaa
+	0x23f:	push ax
+	0x240:	call _printf
+	0x243:	pop cx
+5:	exit(0);
+	0x244:	xor ax,ax
+	0x246:	push ax
+	0x247:	call _exit
+	0x24a:	pop cx
+6:	}
+	0x24b:	pop bp
+	0x24c:	ret
+7:
+	0x24d:
+.TE
+.S +2
+.DE
+.P
+If the statement program prologue specifies the following:
+.DS
+.S -2
+.TS
+;
+lf(CW) lf(CW).
+minimum_instruction_length	1
+opcode_base	10
+line_base	1
+line_range	15
+.TE
+.S +2
+.DE
+.P
+Then one encoding of the statement program would occupy 12 bytes
+(the opcode \f(CWSPECIAL(\fIm\fP, \fIn\fP)\fR indicates the special
+opcode generated for a line increment of \fIm\fP and an address increment
+of \fIn\fP):
+.DS
+.S -2
+.TS
+;
+l l l
+lf(CW) lf(CW) lf(CW).
+Opcode	Operand	Byte Stream
+_
+DW_LNS_advance_pc	LEB128(0x239)	0x2, 0xb9, 0x04
+SPECIAL(2, 0)		0xb
+SPECIAL(2, 3)		0x38
+SPECIAL(1, 8)		0x82
+SPECIAL(1, 7)		0x73
+DW_LNS_advance_pc	LEB128(2)	0x2, 0x2
+DW_LNE_end_sequence		0x0, 0x1, 0x1
+.TE
+.S +2
+.DE
+.P
+An alternate encoding of the same program using standard opcodes to
+advance the program counter would occupy 22 bytes:
+.DS
+.S -2
+.TS
+;
+l l l
+lf(CW) lf(CW) lf(CW).
+Opcode	Operand	Byte Stream
+_
+DW_LNS_fixed_advance_pc	0x239	0x9, 0x39, 0x2
+SPECIAL(2, 0)		0xb
+DW_LNS_fixed_advance_pc	0x3	0x9, 0x3, 0x0
+SPECIAL(2, 0)		0xb
+DW_LNS_fixed_advance_pc	0x8	0x9, 0x8, 0x0
+SPECIAL(1, 0)		0xa
+DW_LNS_fixed_advance_pc	0x7	0x9, 0x7, 0x0
+SPECIAL(1, 0)		0xa
+DW_LNS_fixed_advance_pc	0x2	0x9, 0x2, 0x0
+DW_LNE_end_sequence		0x0, 0x1, 0x1
+.TE
+.S +2
+.DE
+.SK
+.OP
+.HU "Appendix 4 -- Encoding and decoding variable length data"
+.ta .5i +.5i +.5i +.5i +.5i +.5i +.5i +.5i
+.P
+Here are algorithms expressed in a C-like pseudo-code to encode and decode
+signed and unsigned numbers in LEB128:
+.P
+\fBEncode an unsigned integer:\fP
+.br
+.DS
+.S -2
+\f(CWdo
+{		
+	byte = low order 7 bits of value;
+	value >>= 7;
+	if (value != 0)	/* more bytes to come */
+		set high order bit of byte;
+	emit byte;
+} while (value != 0);\fP
+.S +2
+.DE
+.P
+\fBEncode a signed integer:\fP
+.br
+.DS
+.S -2
+\f(CWmore = 1;
+negative = (value < 0);
+size = no. of bits in signed integer;
+while(more)
+{
+	byte = low order 7 bits of value;
+	value >>= 7;
+	/* the following is unnecessary if the implementation of >>=
+	 * uses an arithmetic rather than logical shift for a signed
+	 * left operand
+	 */
+	if (negative)
+		/* sign extend */
+		value |= - (1 << (size - 7));
+	/* sign bit of byte is 2nd high order bit (0x40) */
+	if ((value == 0 && sign bit of byte is clear) ||
+		(value == -1 && sign bit of byte is set))
+		more = 0;
+	else
+		set high order bit of byte;
+	emit byte;
+}\fP
+.S +2
+.DE
+.SK
+.ta .5i +.5i +.5i +.5i +.5i +.5i +.5i +.5i
+.P
+\fBDecode unsigned LEB128 number:\fP
+.br
+.DS
+.S -2
+\f(CWresult = 0;
+shift = 0;
+while(true)
+{
+	byte = next byte in input;
+	result |= (low order 7 bits of byte << shift);
+	if (high order bit of byte == 0)
+		break;
+	shift += 7;
+}\fP
+.S +2
+.DE
+.P
+\fBDecode signed LEB128 number:\fP
+.br
+.DS
+.S -2
+\f(CWresult = 0;
+shift = 0;
+size = no. of bits in signed integer;
+while(true)
+{
+	byte = next byte in input;
+	result |= (low order 7 bits of byte << shift);
+	shift += 7;
+	/* sign bit of byte is 2nd high order bit (0x40) */
+	if (high order bit of byte == 0)
+		break;
+}
+if ((shift < size) && (sign bit of byte is set))
+	/* sign extend */
+	result |= - (1 << shift);\fP
+.S +2
+.DE
+.SK
+.OP
+.HU "Appendix 5 -- Call Frame Information Examples"
+The following example uses a hypothetical RISC machine in the style of
+the Motorola 88000.
+.BL
+.LI
+Memory is byte addressed.
+.LI
+Instructions are all 4-bytes each and word aligned.
+.LI
+Instruction operands are typically of the form:
+.br
+.DS
+	<destination reg> <source reg> <constant>
+.DE
+.LI
+The address for the load and store instructions is computed by
+adding the contents of the source register with the constant.
+.LI
+There are 8 4-byte registers:
+.br
+.DS
+	R0 always 0
+	R1 holds return address on call
+	R2-R3 temp registers (not preserved on call)
+	R4-R6 preserved on call
+	R7 stack pointer.
+.DE
+.LI
+The stack grows in the negative direction.
+.LE
+.P
+The following are two code fragments from a subroutine 
+called \f(CWfoo\fP that
+uses a frame pointer (in addition to the stack pointer.)  The first
+column values are byte addresses.
+.DS
+.S -2
+.TS
+;
+lf(CW) lf(CW) s  s
+lf(CW) lf(CW) lf(CW) lf(CW)
+lf(CW) lf(CW) lf(CW) lf(CW)
+lf(CW) lf(CW) lf(CW) lf(CW)
+lf(CW) lf(CW) lf(CW) lf(CW)
+lf(CW) lf(CW) lf(CW) lf(CW)
+lf(CW) lf(CW) s s
+lf(CW) lf(CW) s s
+lf(CW) lf(CW) s s
+lf(CW) lf(CW) lf(CW) lf(CW).
+	;; start prologue
+foo	sub	R7, R7, <fsize>         ; Allocate frame
+foo+4	store	R1, R7, (<fsize>-4)     ; Save the return address
+foo+8	store	R6, R7, (<fsize>-8)     ; Save R6
+foo+12	add	R6, R7, 0               ; R6 is now the Frame ptr
+foo+16	store	R4, R6, (<fsize>-12)    ; Save a preserve reg.
+	;; This subroutine does not change R5
+	...
+	;; Start epilogue (R7 has been returned to entry value)
+foo+64	load	R4, R6, (<fsize>-12)    ; Restore R4
+foo+68	load	R6, R7, (<fsize>-8)     ; Restore R6
+foo+72	load	R1, R7, (<fsize>-4)     ; Restore return address
+foo+76	add	R7, R7, <fsize>         ; Deallocate frame
+foo+80	jump	R	; Return
+foo+84
+.TE
+.S +2
+.DE
+.SK
+The table for the \f(CWfoo\fP subroutine is as follows.  
+It is followed by the
+corresponding fragments from the 
+.Cf .debug_frame 
+section.
+.DS
+.S -2
+.TS
+tab(|);
+lf(CW) lf(CW) lf(CW) lf(CW) lf(CW) lf(CW) lf(CW) lf(CW) lf(CW) lf(CW) lf(CW).
+Loc|CFA|R0|R1|R2|R3|R4|R5|R6|R7|R8
+foo|[R7]+0|s|u|u|u|s|s|s|s|r1
+foo+4|[R7]+fsize|s|u|u|u|s|s|s|s|r1
+foo+8|[R7]+fsize|s|u|u|u|s|s|s|s|c4
+foo+12|[R7]+fsize|s|u|u|u|s|s|c8|s|c4
+foo+16|[R6]+fsize|s|u|u|u|s|s|c8|s|c4
+foo+20|[R6]+fsize|s|u|u|u|c12|s|c8|s|c4
+...
+foo+64|[R6]+fsize|s|u|u|u|c12|s|c8|s|c4
+foo+68|[R6]+fsize|s|u|u|u|s|s|c8|s|c4
+foo+72|[R7]+fsize|s|u|u|u|s|s|s|s|c4
+foo+76|[R7]+fsize|s|u|u|u|s|s|s|s|r1
+foo+80|[R7]+0|s|u|u|u|s|s|s|s|r1
+.TE
+.TS
+;
+l s
+l l.
+notes:
+1.	R8 is the return address
+2.	s = same_value rule
+3.	u = undefined rule
+4.	rN = register(N) rule
+5.	cN = offset(N) rule
+.sp
+.sp
+.TE
+.S +2
+.DE
+.P
+Common Information Entry (CIE):
+.DS
+.S -2
+.TS
+;
+lf(CW) lf(CW) lf(CW).
+cie	32	; length
+cie+4	0xffffffff	; CIE_id
+cie+8	1 	; version
+cie+9	0	; augmentation
+cie+10	4	; code_alignment_factor
+cie+11	4	; data_alignment_factor
+cie+12	8	; R8 is the return addr.
+cie+13	DW_CFA_def_cfa (7, 0)	; CFA = [R7]+0
+cie+16	DW_CFA_same_value (0)	; R0 not modified (=0)
+cie+18	DW_CFA_undefined (1)	; R1 scratch
+cie+20	DW_CFA_undefined (2)	; R2 scratch
+cie+22	DW_CFA_undefined (3)	; R3 scratch
+cie+24	DW_CFA_same_value (4)	; R4 preserve
+cie+26	DW_CFA_same_value (5)	; R5 preserve
+cie+28	DW_CFA_same_value (6)	; R6 preserve
+cie+30	DW_CFA_same_value (7)	; R7 preserve
+cie+32	DW_CFA_register (8, 1)	; R8 is in R1
+cie+35	DW_CFA_nop	; padding
+cie+36
+.TE
+.S +2
+.DE
+.SK
+.P
+Frame Description Entry (FDE):
+.DS
+.S -2
+.TS
+;
+lf(CW) lf(CW) lf(CW).
+fde	40	; length
+fde+4	cie	; CIE_ptr
+fde+8	foo	; initial_location
+fde+12	84	; address_range
+fde+16	DW_CFA_advance_loc(1)	; instructions
+fde+17	DW_CFA_def_cfa_offset(<fsize>/4)	; assuming <fsize> < 512
+fde+19	DW_CFA_advance_loc(1)
+fde+20	DW_CFA_offset(8,1)
+fde+22	DW_CFA_advance_loc(1)
+fde+23	DW_CFA_offset(6,2)
+fde+25	DW_CFA_advance_loc(1)
+fde+26	DW_CFA_def_cfa_register(6)
+fde+28	DW_CFA_advance_loc(1)
+fde+29	DW_CFA_offset(4,3)
+fde+31	DW_CFA_advance_loc(11)
+fde+32	DW_CFA_restore(4)
+fde+33	DW_CFA_advance_loc(1)
+fde+34	DW_CFA_restore(6)
+fde+35	DW_CFA_def_cfa_register(7)
+fde+37	DW_CFA_advance_loc(1)
+fde+38	DW_CFA_restore(8)
+fde+39	DW_CFA_advance_loc(1)
+fde+40	DW_CFA_def_cfa_offset(0)
+fde+42	DW_CFA_nop	; padding
+fde+43	DW_CFA_nop	; padding
+fde+44
+.TE
+.S +2
+.DE
+.S +1
+
+'\"
+'\"  Table of Contents stuff
+'\"
+.de TP
+.sp 4
+..
+.VM
+.de TY
+.ce 1
+Table of Contents
+.sp
+..
+.nr Lf 1
+.ds Lf List of Figures
+.SK
+.TC 1 1 7 0
Binary file tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf.v2.pdf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_abbrev.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,257 @@
+/*
+
+  Copyright (C) 2000,2001,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* The address of the Free Software Foundation is 
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the above address.
+*/
+
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include "dwarf_abbrev.h"
+
+int
+dwarf_get_abbrev(Dwarf_Debug dbg,
+		 Dwarf_Unsigned offset,
+		 Dwarf_Abbrev * returned_abbrev,
+		 Dwarf_Unsigned * length,
+		 Dwarf_Unsigned * abbr_count, Dwarf_Error * error)
+{
+    Dwarf_Small *abbrev_ptr;
+    Dwarf_Small *abbrev_section_end;
+    Dwarf_Half attr;
+    Dwarf_Half attr_form;
+    Dwarf_Abbrev ret_abbrev;
+    Dwarf_Unsigned labbr_count = 0;
+    Dwarf_Unsigned utmp;
+
+
+    if (dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+    if (dbg->de_debug_abbrev == 0) {
+	/* Loads abbrev section (and .debug_info as we do those
+	   together). */
+	int res = _dwarf_load_debug_info(dbg, error);
+
+	if (res != DW_DLV_OK) {
+	    return res;
+	}
+    }
+
+    if (offset >= dbg->de_debug_abbrev_size) {
+	return (DW_DLV_NO_ENTRY);
+    }
+
+
+    ret_abbrev = (Dwarf_Abbrev) _dwarf_get_alloc(dbg, DW_DLA_ABBREV, 1);
+    if (ret_abbrev == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+    ret_abbrev->ab_dbg = dbg;
+    if (returned_abbrev == 0 || abbr_count == 0) {
+	dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV);
+	_dwarf_error(dbg, error, DW_DLE_DWARF_ABBREV_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+
+    *abbr_count = 0;
+    if (length != NULL)
+	*length = 1;
+
+    abbrev_ptr = dbg->de_debug_abbrev + offset;
+    abbrev_section_end =
+	dbg->de_debug_abbrev + dbg->de_debug_abbrev_size;
+
+    DECODE_LEB128_UWORD(abbrev_ptr, utmp);
+    ret_abbrev->ab_code = (Dwarf_Word) utmp;
+    if (ret_abbrev->ab_code == 0) {
+	*returned_abbrev = ret_abbrev;
+	*abbr_count = 0;
+	if (length) {
+	    *length = 1;
+	}
+	return (DW_DLV_OK);
+    }
+
+    DECODE_LEB128_UWORD(abbrev_ptr, utmp);
+    ret_abbrev->ab_tag = utmp;
+    ret_abbrev->ab_has_child = *(abbrev_ptr++);
+    ret_abbrev->ab_abbrev_ptr = abbrev_ptr;
+
+    do {
+	Dwarf_Unsigned utmp2;
+
+	DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
+	attr = (Dwarf_Half) utmp2;
+	DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
+	attr_form = (Dwarf_Half) utmp2;
+
+	if (attr != 0)
+	    (labbr_count)++;
+
+    } while (abbrev_ptr < abbrev_section_end &&
+	     (attr != 0 || attr_form != 0));
+
+    if (abbrev_ptr > abbrev_section_end) {
+	dwarf_dealloc(dbg, ret_abbrev, DW_DLA_ABBREV);
+	_dwarf_error(dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
+	return (DW_DLV_ERROR);
+    }
+
+    if (length != NULL)
+	*length = abbrev_ptr - dbg->de_debug_abbrev - offset;
+
+    *returned_abbrev = ret_abbrev;
+    *abbr_count = labbr_count;
+    return (DW_DLV_OK);
+}
+
+int
+dwarf_get_abbrev_code(Dwarf_Abbrev abbrev,
+		      Dwarf_Unsigned * returned_code,
+		      Dwarf_Error * error)
+{
+    if (abbrev == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *returned_code = abbrev->ab_code;
+    return (DW_DLV_OK);
+}
+
+int
+dwarf_get_abbrev_tag(Dwarf_Abbrev abbrev,
+		     Dwarf_Half * returned_tag, Dwarf_Error * error)
+{
+    if (abbrev == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *returned_tag = abbrev->ab_tag;
+    return (DW_DLV_OK);
+}
+
+
+int
+dwarf_get_abbrev_children_flag(Dwarf_Abbrev abbrev,
+			       Dwarf_Signed * returned_flag,
+			       Dwarf_Error * error)
+{
+    if (abbrev == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *returned_flag = abbrev->ab_has_child;
+    return (DW_DLV_OK);
+}
+
+
+int
+dwarf_get_abbrev_entry(Dwarf_Abbrev abbrev,
+		       Dwarf_Signed index,
+		       Dwarf_Half * returned_attr_num,
+		       Dwarf_Signed * form,
+		       Dwarf_Off * offset, Dwarf_Error * error)
+{
+    Dwarf_Byte_Ptr abbrev_ptr = 0;
+    Dwarf_Byte_Ptr abbrev_end = 0;
+    Dwarf_Byte_Ptr mark_abbrev_ptr = 0;
+    Dwarf_Half attr = 0;
+    Dwarf_Half attr_form = 0;
+
+    if (index < 0)
+	return (DW_DLV_NO_ENTRY);
+
+    if (abbrev == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DWARF_ABBREV_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    if (abbrev->ab_code == 0) {
+	return (DW_DLV_NO_ENTRY);
+    }
+
+    if (abbrev->ab_dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    abbrev_ptr = abbrev->ab_abbrev_ptr;
+    abbrev_end =
+	abbrev->ab_dbg->de_debug_abbrev +
+	abbrev->ab_dbg->de_debug_abbrev_size;
+
+    for (attr = 1, attr_form = 1;
+	 index >= 0 && abbrev_ptr < abbrev_end && (attr != 0 ||
+						   attr_form != 0);
+	 index--) {
+	Dwarf_Unsigned utmp4;
+
+	mark_abbrev_ptr = abbrev_ptr;
+	DECODE_LEB128_UWORD(abbrev_ptr, utmp4);
+	attr = (Dwarf_Half) utmp4;
+	DECODE_LEB128_UWORD(abbrev_ptr, utmp4);
+	attr_form = (Dwarf_Half) utmp4;
+    }
+
+    if (abbrev_ptr >= abbrev_end) {
+	_dwarf_error(abbrev->ab_dbg, error, DW_DLE_ABBREV_DECODE_ERROR);
+	return (DW_DLV_ERROR);
+    }
+
+    if (index >= 0) {
+	return (DW_DLV_NO_ENTRY);
+    }
+
+    if (form != NULL)
+	*form = attr_form;
+    if (offset != NULL)
+	*offset = mark_abbrev_ptr - abbrev->ab_dbg->de_debug_abbrev;
+
+    *returned_attr_num = (attr);
+    return DW_DLV_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_abbrev.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,45 @@
+/*
+
+  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+
+struct Dwarf_Abbrev_s {
+    Dwarf_Word ab_code;
+    Dwarf_Half ab_tag;
+    Dwarf_Small ab_has_child;
+    Dwarf_Byte_Ptr ab_abbrev_ptr;
+    Dwarf_Debug ab_dbg;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_addr_finder.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,688 @@
+/*
+
+  Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* This code used by SGI-IRIX rqs processing, not needed by
+   any other system or application.
+*/
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#ifdef HAVE_ELF_H
+#include <elf.h>
+#endif
+#include <dwarf.h>
+#include <libdwarf.h>
+#include "dwarf_base_types.h"
+#include "dwarf_alloc.h"
+#include "dwarf_opaque.h"
+#include "dwarf_arange.h"
+#include "dwarf_line.h"
+#include "dwarf_frame.h"
+#include <cmplrs/dwarf_addr_finder.h>
+#include "dwarf_error.h"
+
+typedef unsigned long long ull;
+
+static int do_this_die_and_dealloc(Dwarf_Debug dbg, Dwarf_Die die,
+				   int *errval);
+static int
+  handle_debug_info(Dwarf_Debug dbg, int *errval);
+static int
+  handle_debug_frame(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func, int *errval);
+static int
+  handle_debug_aranges(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func, int *errval);
+static int
+  handle_debug_line(Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_addr_callback_func cb_func, int *errval);
+static int
+  handle_debug_loc(void);
+
+
+static Dwarf_addr_callback_func send_addr_note;
+
+int
+_dwarf_addr_finder(dwarf_elf_handle elf_file_ptr,
+		   Dwarf_addr_callback_func cb_func, int *dwerr)
+{
+
+    Dwarf_Error err = 0;
+    Dwarf_Debug dbg = 0;
+    int res = 0;
+    int errval = 0;
+    int sections_found = 0;
+
+    res = dwarf_elf_init(elf_file_ptr, DW_DLC_READ, /* errhand */ 0,
+			 /* errarg */ 0, &dbg, &err);
+    if (res == DW_DLV_ERROR) {
+	int errv = (int) dwarf_errno(err);
+
+	return errv;
+    }
+    if (res == DW_DLV_NO_ENTRY) {
+	return res;
+    }
+
+    send_addr_note = cb_func;
+
+    res = handle_debug_info(dbg, &errval);
+    switch (res) {
+    case DW_DLV_OK:
+	++sections_found;
+	break;
+    case DW_DLV_NO_ENTRY:
+
+	break;
+    default:
+    case DW_DLV_ERROR:
+	dwarf_finish(dbg, &err);
+	*dwerr = errval;
+	return res;
+    }
+
+    res = handle_debug_aranges(dbg, cb_func, &errval);
+    switch (res) {
+    case DW_DLV_OK:
+	++sections_found;
+	break;
+    case DW_DLV_NO_ENTRY:
+	break;
+    default:
+    case DW_DLV_ERROR:
+	dwarf_finish(dbg, &err);
+	*dwerr = errval;
+	return res;
+    }
+    res = handle_debug_frame(dbg, cb_func, &errval);
+    switch (res) {
+    case DW_DLV_OK:
+	++sections_found;
+	break;
+    case DW_DLV_NO_ENTRY:
+	break;
+    default:
+    case DW_DLV_ERROR:
+	dwarf_finish(dbg, &err);
+	*dwerr = errval;
+	return res;
+    }
+
+    res = handle_debug_loc();	/* does nothing */
+    switch (res) {
+    case DW_DLV_OK:
+	++sections_found;
+	break;
+    case DW_DLV_NO_ENTRY:
+	break;
+    default:
+    case DW_DLV_ERROR:
+	/* IMPOSSIBLE : handle_debug_loc cannot return this */
+	dwarf_finish(dbg, &err);
+	*dwerr = errval;
+	return res;
+    }
+
+
+
+    *dwerr = 0;
+    res = dwarf_finish(dbg, &err);
+    if (res == DW_DLV_ERROR) {
+	*dwerr = (int) dwarf_errno(err);
+	return DW_DLV_ERROR;
+    }
+    if (sections_found == 0) {
+	return DW_DLV_NO_ENTRY;
+    }
+    return DW_DLV_OK;
+
+}
+
+/*
+	Return DW_DLV_OK, ERROR, or NO_ENTRY.
+*/
+static int
+handle_debug_info(Dwarf_Debug dbg, int *errval)
+{
+    Dwarf_Unsigned nxtoff = 1;
+    Dwarf_Unsigned hdr_length;
+    Dwarf_Half version_stamp;
+    Dwarf_Unsigned abbrev_offset;
+    Dwarf_Half addr_size;
+    Dwarf_Error err;
+    int terminate_now = 0;
+    int res = 0;
+    Dwarf_Die sibdie;
+    int sibres;
+    int nres = DW_DLV_OK;
+
+
+    for (nres = dwarf_next_cu_header(dbg, &hdr_length, &version_stamp,
+				     &abbrev_offset,
+				     &addr_size, &nxtoff, &err);
+	 terminate_now == 0 && nres == DW_DLV_OK;
+	 nres = dwarf_next_cu_header(dbg, &hdr_length, &version_stamp,
+				     &abbrev_offset,
+				     &addr_size, &nxtoff, &err)
+	) {
+
+	Dwarf_Die curdie = 0;
+
+	/* try to get the compilation unit die */
+	sibres = dwarf_siblingof(dbg, curdie, &sibdie, &err);
+	if (sibres == DW_DLV_OK) {
+	    res = do_this_die_and_dealloc(dbg, sibdie, errval);
+	    switch (res) {
+	    case DW_DLV_OK:
+		break;
+	    case DW_DLV_NO_ENTRY:
+		break;
+	    default:
+	    case DW_DLV_ERROR:
+		return DW_DLV_ERROR;
+	    }
+	} else if (sibres == DW_DLV_ERROR) {
+	    *errval = (int) dwarf_errno(err);
+	    return DW_DLV_ERROR;
+	} else {
+	    /* NO ENTRY! */
+	    /* impossible? */
+	}
+
+    }
+    if (nres == DW_DLV_ERROR) {
+	int localerr = (int) dwarf_errno(err);
+
+	*errval = localerr;
+	return DW_DLV_ERROR;
+    }
+    return DW_DLV_OK;
+}
+
+static int
+  might_have_addr[] = {
+    DW_AT_high_pc,
+    DW_AT_low_pc,
+};
+static int
+  might_have_locdesc[] = {
+    DW_AT_segment,
+    DW_AT_return_addr,
+    DW_AT_frame_base,
+    DW_AT_static_link,
+    DW_AT_data_member_location,
+    DW_AT_string_length,
+    DW_AT_location,
+    DW_AT_use_location,
+    DW_AT_vtable_elem_location,
+};
+
+/*
+	Return DW_DLV_OK if handling this went ok.
+*/
+static int
+handle_attr_addr(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attrnum,
+		 Dwarf_Error * perr)
+{
+    int res = DW_DLV_OK;
+    Dwarf_Off offset;
+    Dwarf_Addr addr;
+    Dwarf_Half form;
+    int ares;
+
+    Dwarf_Attribute attr;
+
+    ares = dwarf_attr(die, attrnum, &attr, perr);
+    if (ares == DW_DLV_OK) {
+	int formres = dwarf_whatform(attr, &form, perr);
+
+	switch (formres) {
+	case DW_DLV_OK:
+	    break;
+	case DW_DLV_ERROR:
+	case DW_DLV_NO_ENTRY:	/* impossible. */
+	    return formres;
+
+	}
+
+	switch (form) {
+	case DW_FORM_ref_addr:
+	case DW_FORM_addr:
+	    res = dwarf_attr_offset(die, attr, &offset, perr);
+	    if (res == DW_DLV_OK) {
+		ares = dwarf_formaddr(attr, &addr, perr);
+		if (ares == DW_DLV_OK) {
+		    send_addr_note(DW_SECTION_INFO, offset, addr);
+		} else if (ares == DW_DLV_ERROR) {
+		    return ares;
+		}		/* no entry: ok. */
+	    } else {
+		res = DW_DLV_ERROR;	/* NO_ENTRY is impossible. */
+	    }
+	    break;
+
+	default:
+	    /* surprising! An error? */
+
+	    ;			/* do nothing */
+	}
+	dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
+
+    } else {
+	res = ares;
+    }
+    return res;
+}
+
+/*
+	Return DW_DLV_OK if handling this went ok.
+*/
+static int
+handle_attr_locdesc(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attrnum,
+		    Dwarf_Error * perr)
+{
+    int retval = DW_DLV_OK;
+    Dwarf_Attribute attr;
+    Dwarf_Locdesc *llbuf;
+    Dwarf_Signed i;
+    Dwarf_Off offset;
+    Dwarf_Loc *locp;
+    unsigned int entindx;
+    int res;
+    int ares;
+
+
+    ares = dwarf_attr(die, attrnum, &attr, perr);
+    if (ares == DW_DLV_OK) {
+	Dwarf_Half form;
+	int fres = dwarf_whatform(attr, &form, perr);
+
+	if (fres == DW_DLV_OK) {
+	    switch (form) {
+	    case DW_FORM_block1:
+	    case DW_FORM_block2:
+	    case DW_FORM_block4:
+		/* must be location description */
+		res = dwarf_attr_offset(die, attr, &offset, perr);
+		llbuf = 0;
+		if (res == DW_DLV_OK) {
+		    Dwarf_Signed count;
+		    int lres =
+			dwarf_loclist(attr, &llbuf, &count, perr);
+		    if (lres != DW_DLV_OK) {
+			return lres;
+		    }
+		    if (count != 1) {
+			/* this cannot happen! */
+			/* perr? */
+			_dwarf_error(dbg, perr,
+				     DW_DLE_LOCDESC_COUNT_WRONG);
+			retval = DW_DLV_ERROR;
+			return retval;
+		    }
+		    for (i = 0; i < count; ++i) {
+			unsigned int ents = llbuf[i].ld_cents;
+
+			locp = llbuf[i].ld_s;
+			for (entindx = 0; entindx < ents; entindx++) {
+			    Dwarf_Loc *llocp;
+
+			    llocp = locp + entindx;
+			    if (llocp->lr_atom == DW_OP_addr) {
+				send_addr_note(DW_SECTION_INFO, offset +
+					       llocp->lr_offset + 1
+					       /* The offset is the
+					          offset of the atom,
+					          ** and we know the
+					          addr is 1 past it. */
+					       , llocp->lr_number);
+			    }
+			}
+		    }
+
+
+		    if (count > 0) {
+			for (i = 0; i < count; ++i) {
+			    dwarf_dealloc(dbg, llbuf[i].ld_s,
+					  DW_DLA_LOC_BLOCK);
+			}
+			dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC);
+		    }
+		} else {
+		    retval = res;
+		}
+		break;
+
+	    default:
+		/* must be a const offset in debug_loc */
+		;		/* do nothing */
+	    }
+	    dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
+	}			/* else error or no entry */
+	retval = fres;
+    } else {
+	retval = ares;
+    }
+    return retval;
+}
+
+/*
+  Return DW_DLV_OK, or DW_DLV_ERROR
+
+  Handle the addrs in a single die.
+*/
+static int
+process_this_die_attrs(Dwarf_Debug dbg, Dwarf_Die newdie, int *errval)
+{
+    Dwarf_Error err;
+    Dwarf_Half i;
+    Dwarf_Half newattrnum;
+    int res;
+    int tres;
+    Dwarf_Half ltag;
+
+    Dwarf_Off doff;
+    int doffres = dwarf_dieoffset(newdie, &doff, &err);
+
+    if (doffres != DW_DLV_OK) {
+	if (doffres == DW_DLV_ERROR) {
+	    *errval = (int) dwarf_errno(err);
+	}
+	return doffres;
+    }
+    tres = dwarf_tag(newdie, &ltag, &err);
+    if (tres != DW_DLV_OK) {
+	return tres;
+    }
+    if (DW_TAG_compile_unit == ltag) {
+	/* because of the way the dwarf_line code works, we do lines 
+	   only per compile unit. This may turn out to be wrong if
+	   we have lines left unconnected to a CU. of course such 
+	   lines will not, at present, be used by gnome. This is
+	   not ideal as coded due to the dwarf_line.c issue. */
+	int lres;
+
+	lres = handle_debug_line(dbg, newdie, send_addr_note, errval);
+	if (lres == DW_DLV_ERROR) {
+	    return lres;
+	}
+    }
+
+    for (i = 0; i < sizeof(might_have_addr) / sizeof(int); i++) {
+	int resattr;
+	Dwarf_Bool hasattr;
+
+	newattrnum = might_have_addr[i];
+	err = 0;
+	resattr = dwarf_hasattr(newdie, newattrnum, &hasattr, &err);
+	if (DW_DLV_OK == resattr) {
+	    if (hasattr) {
+		res = handle_attr_addr(dbg, newdie, newattrnum, &err);
+		if (res != DW_DLV_OK) {
+		    *errval = (int) dwarf_errno(err);
+		    return DW_DLV_ERROR;
+		}
+	    }
+	} else {
+	    if (resattr == DW_DLV_ERROR) {
+		*errval = (int) dwarf_errno(err);
+		return resattr;
+	    }
+	}
+    }
+    for (i = 0; i < sizeof(might_have_locdesc) / sizeof(int); i++) {
+	int resattr;
+	Dwarf_Bool hasattr;
+
+	newattrnum = might_have_locdesc[i];
+	err = 0;
+	resattr = dwarf_hasattr(newdie, newattrnum, &hasattr, &err);
+	if (DW_DLV_OK == resattr) {
+	    if (hasattr) {
+		res =
+		    handle_attr_locdesc(dbg, newdie, newattrnum, &err);
+		if (res != DW_DLV_OK) {
+		    *errval = (int) dwarf_errno(err);
+		    return DW_DLV_ERROR;
+		}
+	    }
+	} else {
+	    if (resattr == DW_DLV_ERROR) {
+		*errval = (int) dwarf_errno(err);
+		return resattr;
+	    }
+	}
+    }
+
+    return DW_DLV_OK;
+}
+
+/*
+	Handle siblings as a list,
+	Do children by recursing.
+	Effectively this is walking the tree preorder.
+
+	This dealloc's any die passed to it, so the
+	caller should not do that dealloc.
+	It seems more logical to have the one causing
+	the alloc to do the dealloc, but that way this
+	routine became a mess.
+
+*/
+static int
+do_this_die_and_dealloc(Dwarf_Debug dbg, Dwarf_Die die, int *errval)
+{
+
+    Dwarf_Die prevdie = 0;
+    Dwarf_Die newdie = die;
+    Dwarf_Error err = 0;
+    int res = 0;
+    int sibres = DW_DLV_OK;
+    int tres = DW_DLV_OK;
+    Dwarf_Die sibdie;
+
+    while (sibres == DW_DLV_OK) {
+	Dwarf_Die ch_die;
+
+
+	res = process_this_die_attrs(dbg, newdie, errval);
+	switch (res) {
+	case DW_DLV_OK:
+	    break;
+	case DW_DLV_NO_ENTRY:
+	    break;
+	default:
+	case DW_DLV_ERROR:
+	    if (prevdie) {
+		dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
+		prevdie = 0;
+	    }
+	    return DW_DLV_ERROR;
+	}
+
+	tres = dwarf_child(newdie, &ch_die, &err);
+
+	if (tres == DW_DLV_OK) {
+	    res = do_this_die_and_dealloc(dbg, ch_die, errval);
+	    switch (res) {
+	    case DW_DLV_OK:
+		break;
+	    case DW_DLV_NO_ENTRY:
+		break;
+	    default:
+	    case DW_DLV_ERROR:
+		if (prevdie) {
+		    dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
+		    prevdie = 0;
+		}
+		return DW_DLV_ERROR;
+	    }
+	} else if (tres == DW_DLV_ERROR) {
+	    /* An error! */
+	    *errval = (int) dwarf_errno(err);
+	    if (prevdie) {
+		dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
+		prevdie = 0;
+	    }
+	    dwarf_dealloc(dbg, err, DW_DLA_ERROR);
+	    return DW_DLV_ERROR;
+	}			/* else was NO ENTRY */
+	prevdie = newdie;
+	sibdie = 0;
+	sibres = dwarf_siblingof(dbg, newdie, &sibdie, &err);
+	if (prevdie) {
+	    dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
+	    prevdie = 0;
+	}
+	newdie = sibdie;
+
+    }
+    if (sibres == DW_DLV_NO_ENTRY) {
+	return DW_DLV_OK;
+    }
+    /* error. */
+    *errval = (int) dwarf_errno(err);
+    if (prevdie) {
+	dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
+	prevdie = 0;
+    }
+    dwarf_dealloc(dbg, err, DW_DLA_ERROR);
+    return DW_DLV_ERROR;
+
+}
+
+
+static int
+handle_debug_frame(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func,
+		   int *errval)
+{
+    int retval = DW_DLV_OK;
+    int res;
+    Dwarf_Error err;
+    Dwarf_Addr *addrlist;
+    Dwarf_Off *offsetlist;
+    Dwarf_Signed count;
+    int i;
+
+    res =
+	_dwarf_frame_address_offsets(dbg, &addrlist, &offsetlist,
+				     &count, &err);
+    if (res == DW_DLV_OK) {
+	for (i = 0; i < count; i++) {
+	    cb_func(DW_SECTION_FRAME, offsetlist[i], addrlist[i]);
+	}
+	dwarf_dealloc(dbg, offsetlist, DW_DLA_ADDR);
+	dwarf_dealloc(dbg, addrlist, DW_DLA_ADDR);
+    } else if (res == DW_DLV_NO_ENTRY) {
+	retval = res;
+    } else {
+	*errval = (int) dwarf_errno(err);
+	retval = DW_DLV_ERROR;
+    }
+    return retval;
+
+}
+static int
+handle_debug_aranges(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func,
+		     int *errval)
+{
+    int retval = DW_DLV_OK;
+    Dwarf_Error err;
+    Dwarf_Addr *aranges;
+    Dwarf_Signed count;
+    int indx;
+    Dwarf_Off *offsets;
+
+    retval =
+	_dwarf_get_aranges_addr_offsets(dbg, &aranges, &offsets, &count,
+					&err);
+    if (retval == DW_DLV_OK) {
+	if (count == 0) {
+	    retval = DW_DLV_NO_ENTRY;
+	} else {
+	    for (indx = 0; indx < count; indx++) {
+		cb_func(DW_SECTION_ARANGES, offsets[indx],
+			aranges[indx]);
+	    }
+	}
+	dwarf_dealloc(dbg, aranges, DW_DLA_ADDR);
+	dwarf_dealloc(dbg, offsets, DW_DLA_ADDR);
+    } else if (retval == DW_DLV_NO_ENTRY) {
+	;			/* do nothing */
+    } else {
+	*errval = (int) dwarf_errno(err);
+	retval = DW_DLV_ERROR;
+    }
+    return retval;
+}
+static int
+handle_debug_line(Dwarf_Debug dbg, Dwarf_Die cu_die,
+		  Dwarf_addr_callback_func cb_func, int *errval)
+{
+    int retval = DW_DLV_OK;
+    int res;
+    Dwarf_Error err;
+    Dwarf_Addr *addrlist;
+    Dwarf_Off *offsetlist;
+    Dwarf_Unsigned count;
+    Dwarf_Unsigned i;
+
+    res =
+	_dwarf_line_address_offsets(dbg, cu_die, &addrlist, &offsetlist,
+				    &count, &err);
+    if (res == DW_DLV_OK) {
+	for (i = 0; i < count; i++) {
+	    cb_func(DW_SECTION_LINE, offsetlist[i], addrlist[i]);
+
+	}
+	dwarf_dealloc(dbg, offsetlist, DW_DLA_ADDR);
+	dwarf_dealloc(dbg, addrlist, DW_DLA_ADDR);
+    } else if (res == DW_DLV_NO_ENTRY) {
+	retval = res;
+    } else {
+	*errval = (int) dwarf_errno(err);
+	retval = DW_DLV_ERROR;
+    }
+    return retval;
+}
+
+/*
+	We need to add support for this. Currently we do not
+	generate this section.
+	FIX!
+*/
+static int
+handle_debug_loc(void)
+{
+    int retval = DW_DLV_NO_ENTRY;
+
+    return retval;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_alloc.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1240 @@
+/*
+
+  Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007  David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+#undef  DEBUG
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <sys/types.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "malloc_check.h"
+
+/*
+    These files are included to get the sizes
+    of structs to set the ah_bytes_one_struct field
+    of the Dwarf_Alloc_Hdr_s structs for each
+    allocation type.
+*/
+#include "dwarf_line.h"
+#include "dwarf_global.h"
+#include "dwarf_arange.h"
+#include "dwarf_abbrev.h"
+#include "dwarf_die_deliv.h"
+#include "dwarf_frame.h"
+#include "dwarf_loc.h"
+#include "dwarf_funcs.h"
+#include "dwarf_types.h"
+#include "dwarf_vars.h"
+#include "dwarf_weaks.h"
+
+static void _dwarf_free_special_error(Dwarf_Ptr space);
+
+#ifdef DWARF_SIMPLE_MALLOC
+static void _dwarf_simple_malloc_add_to_list(Dwarf_Debug dbg,
+					     Dwarf_Ptr addr,
+					     unsigned long size,
+					     short alloc_type);
+static void _dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg,
+						  Dwarf_Ptr space,
+						  short alloc_type);
+void _dwarf_simple_malloc_botch(int err);
+
+#endif /* DWARF_SIMPLE_MALLOC */
+
+
+
+
+/*
+    This macro adds the size of a pointer to the size of a
+    struct that is given to it.  It rounds up the size to
+    be a multiple of the size of a pointer.  This is done
+    so that every struct returned by _dwarf_get_alloc()
+    can be preceded by a pointer to the chunk it came from.
+    Before allocating, it checks if the size of struct is less than
+    the size of a pointer.  If yes, it returns the size
+    of 2 pointers.  The returned size should be at least
+    the size of 2 pointers, since the first points to the
+    chunk the struct was allocated from, and the second
+    is used to link the free list.
+
+    We want DW_RESERVE to be at least the size of
+    a long long and at least the size of a pointer because
+    our struct has a long long and we want that aligned right.
+    Now Standard C defines long long as 8 bytes, so lets
+    make that standard. It will become unworkable when
+    long long or pointer grows beyound 8 bytes.
+    Unclear what to do with wierd requirements, like
+    36 bit pointers.
+
+
+*/
+#define DW_RESERVE 8
+
+/* Round size up to the next multiple of DW_RESERVE bytes 
+*/
+#define ROUND_SIZE(inputsize)                 \
+        (((inputsize) % (DW_RESERVE)) == 0 ? \
+            (inputsize):                      \
+            ((inputsize)  +                   \
+               (DW_RESERVE) - ((inputsize) % (DW_RESERVE)) ))
+
+#define ROUND_SIZE_WITH_POINTER(i_size) (ROUND_SIZE(i_size) + DW_RESERVE)
+
+/* SMALL_ALLOC is for trivia where allocation is a waste.
+   Things that should be removed, really. */
+#define SMALL_ALLOC 2
+
+/* BASE_ALLOC is where a basic allocation makes sense, but 'not too large'. 
+   No thorough evaluation of this value has been done, though
+   it was found wasteful of memory to have BASE_ALLOC be as large as
+   BIG_ALLOC. */
+#define BASE_ALLOC 64
+
+/* BIG_ALLOC is where a larger-than-BASE_ALLOC 
+   allocation makes sense, but still 'not too large'.
+   No thorough evaluation of this value has been done. */
+#define BIG_ALLOC  128
+
+/* This translates into de_alloc_hdr index 
+** the 0,1,1 entries are special: they don't use the
+** table values at all.
+** Rearranging the DW_DLA values would break binary compatibility
+** so that is not an option.
+*/
+struct ial_s {
+    int ia_al_num;		/* Index into de_alloc_hdr table. */
+
+    /* In bytes, one struct instance. This does not account for extra
+       space needed per block, but that (DW_RESERVE) will be added in
+       later where it is needed (DW_RESERVE space never added in here). 
+     */
+    int ia_struct_size;
+
+
+    /* Number of instances per alloc block. MUST be > 0. */
+    int ia_base_count;
+
+    int (*specialconstructor) (Dwarf_Debug, void *);
+    void (*specialdestructor) (void *);
+};
+
+static const
+struct ial_s index_into_allocated[ALLOC_AREA_INDEX_TABLE_MAX] = {
+    {0, 1, 1, 0, 0},		/* none */
+    {0, 1, 1, 0, 0},		/* 1 DW_DLA_STRING */
+    {1, sizeof(Dwarf_Loc), BASE_ALLOC, 0, 0}
+    ,				/* 2 DW_DLA_LOC */
+    {2, sizeof(Dwarf_Locdesc), BASE_ALLOC, 0, 0}
+    ,				/* 3 DW_DLA_LOCDESC */
+    {0, 1, 1, 0, 0}
+    ,				/* not used *//* 4 DW_DLA_ELLIST */
+    {0, 1, 1, 0, 0}
+    ,				/* not used *//* 5 DW_DLA_BOUNDS */
+    {3, sizeof(Dwarf_Block), BASE_ALLOC, 0, 0}
+    ,				/* 6 DW_DLA_BLOCK */
+    {0, 1, 1, 0, 0}
+    ,				/* the actual dwarf_debug structure *//* 7 DW_DLA_DEBUG */
+    {4, sizeof(struct Dwarf_Die_s), BIG_ALLOC, 0, 0},	/* 8 DW_DLA_DIE 
+							 */
+    {5, sizeof(struct Dwarf_Line_s), BIG_ALLOC, 0, 0},	/* 9
+							   DW_DLA_LINE */
+    {6, sizeof(struct Dwarf_Attribute_s), BIG_ALLOC * 2, 0, 0},
+    /* 10 DW_DLA_ATTR */
+    {0, 1, 1, 0, 0},		/* not used *//* 11 DW_DLA_TYPE */
+    {0, 1, 1, 0, 0},		/* not used *//* 12 DW_DLA_SUBSCR */
+    {7, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0},	/* 13
+								   DW_DLA_GLOBAL 
+								 */
+    {8, sizeof(struct Dwarf_Error_s), BASE_ALLOC, 0, 0},	/* 14
+								   DW_DLA_ERROR 
+								 */
+    {0, 1, 1, 0, 0},		/* 15 DW_DLA_LIST */
+    {0, 1, 1, 0, 0},		/* not used *//* 16 DW_DLA_LINEBUF */
+    {9, sizeof(struct Dwarf_Arange_s), BASE_ALLOC, 0, 0},	/* 17
+								   DW_DLA_ARANGE 
+								 */
+    {10, sizeof(struct Dwarf_Abbrev_s), BIG_ALLOC, 0, 0},	/* 18
+								   DW_DLA_ABBREV 
+								 */
+    {11, sizeof(Dwarf_Frame_Op), BIG_ALLOC, 0, 0}
+    ,				/* 19 DW_DLA_FRAME_OP */
+    {12, sizeof(struct Dwarf_Cie_s), BASE_ALLOC, 0, 0},	/* 20
+							   DW_DLA_CIE */
+    {13, sizeof(struct Dwarf_Fde_s), BASE_ALLOC, 0, 0},	/* 21
+							   DW_DLA_FDE */
+    {0, 1, 1, 0, 0},		/* 22 DW_DLA_LOC_BLOCK */
+    {0, 1, 1, 0, 0},		/* 23 DW_DLA_FRAME_BLOCK */
+    {14, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0},	/* 24
+								   DW_DLA_FUNC 
+								   UNUSED 
+								 */
+    {15, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0},	/* 25
+								   DW_DLA_TYPENAME
+								   UNUSED */
+    {16, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0},	/* 26
+								   DW_DLA_VAR 
+								   UNUSED 
+								 */
+    {17, sizeof(struct Dwarf_Global_s), BASE_ALLOC, 0, 0},	/* 27
+								   DW_DLA_WEAK 
+								   UNUSED 
+								 */
+    {0, 1, 1, 0, 0},		/* 28 DW_DLA_ADDR */
+    {18, sizeof(struct Dwarf_Abbrev_List_s), BIG_ALLOC, 0, 0},
+    /* 29 DW_DLA_ABBREV_LIST */
+
+    {19, sizeof(struct Dwarf_Chain_s), BIG_ALLOC, 0, 0},	/* 30
+								   DW_DLA_CHAIN 
+								 */
+    {20, sizeof(struct Dwarf_CU_Context_s), BASE_ALLOC, 0, 0},
+    /* 31 DW_DLA_CU_CONTEXT */
+    {21, sizeof(struct Dwarf_Frame_s), BASE_ALLOC,
+     _dwarf_frame_constructor,
+     _dwarf_frame_destructor},	/* 32 DW_DLA_FRAME */
+    {22, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
+    /* 33 DW_DLA_GLOBAL_CONTEXT */
+    {23, sizeof(struct Dwarf_File_Entry_s), BASE_ALLOC, 0, 0},	/* 34 */
+    /* 34 DW_DLA_FILE_ENTRY */
+    {24, sizeof(struct Dwarf_Line_Context_s), BASE_ALLOC, 0, 0},
+    /* 35 DW_DLA_LINE_CONTEXT */
+    {25, sizeof(struct Dwarf_Loc_Chain_s), BASE_ALLOC, 0, 0},	/* 36 */
+    /* 36 DW_DLA_LOC_CHAIN */
+
+    /* See use of ABBREV_HASH_TABLE_SIZE below for final dealloc. */
+    {26, ABBREV_HASH_TABLE_SIZE * sizeof(struct Dwarf_Hash_Table_s),
+     BASE_ALLOC, 0, 0},		/* 37 */
+
+
+    /* 37 DW_DLA_HASH_TABLE */
+
+/* The following really use Global struct: used to be unique struct
+   per type, but now merged (11/99).  The opaque types
+   are visible in the interface. The types  for
+   DW_DLA_FUNC,
+   DW_DLA_TYPENAME, DW_DLA_VAR, DW_DLA_WEAK also use
+   the global types.
+  
+*/
+    {27, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
+    /* 38 DW_DLA_FUNC_CONTEXT */
+    {28, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
+    /* 39 DW_DLA_TYPENAME_CONTEXT */
+    {29, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
+    /* 40 DW_DLA_VAR_CONTEXT */
+    {30, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
+    /* 41 DW_DLA_WEAK_CONTEXT */
+    {31, sizeof(struct Dwarf_Global_Context_s), BASE_ALLOC, 0, 0},
+    /* 42 DW_DLA_PUBTYPES_CONTEXT DWARF3 */
+
+};
+
+#ifndef DWARF_SIMPLE_MALLOC
+
+/*
+    This function is given a pointer to the header
+    structure that is used to allocate 1 struct of
+    the type given by alloc_type.  It first checks
+    if a struct is available in its free list.  If
+    not, it checks if 1 is available in its blob, 
+    which is a chunk of memory that is reserved for
+    its use.  If not, it malloc's a chunk.  The
+    initial part of it is used to store the end
+    address of the chunk, and also to keep track 
+    of the number of free structs in that chunk.
+    This information is used for freeing the chunk
+    when all the structs in it are free.
+
+    Assume all input arguments have been validated.
+
+    This function can be used only to allocate 1
+    struct of the given type.
+
+    It returns a pointer to the struct that the
+    user can use.  It returns NULL only when it
+    is out of free structs, and cannot malloc 
+    any more.  The struct returned is zero-ed.
+
+    A pointer to the chunk that the struct belongs
+    to is stored in the bytes preceding the
+    returned address.  Since this pointer it
+    never overwritten, when a struct is allocated
+    from the free_list this pointer does not
+    have to be written.  In the 2 other cases,
+    where the struct is allocated from a new
+    chunk, or the blob, a pointer to the chunk
+    is written.
+*/
+static Dwarf_Ptr
+_dwarf_find_memory(Dwarf_Alloc_Hdr alloc_hdr)
+{
+    /* Pointer to the struct allocated. */
+    Dwarf_Small *ret_mem = 0;
+
+    /* Pointer to info about chunks allocated. */
+    Dwarf_Alloc_Area alloc_area;
+
+    /* Size of chunk malloc'ed when no free structs left. */
+    Dwarf_Signed mem_block_size;
+
+    /* Pointer to block malloc'ed. */
+    Dwarf_Small *mem_block;
+
+    /* 
+       Check the alloc_area from which the last allocation was made
+       (most recent new block). If that is not successful, then search
+       the list of alloc_area's from alloc_header. */
+    alloc_area = alloc_hdr->ah_last_alloc_area;
+    if (alloc_area == NULL || alloc_area->aa_free_structs_in_chunk == 0)
+	for (alloc_area = alloc_hdr->ah_alloc_area_head;
+	     alloc_area != NULL; alloc_area = alloc_area->aa_next) {
+
+	    if (alloc_area->aa_free_structs_in_chunk > 0) {
+		break;		/* found a free entry! */
+	    }
+
+	}
+
+    if (alloc_area != NULL) {
+	alloc_area->aa_free_structs_in_chunk--;
+
+	if (alloc_area->aa_free_list != NULL) {
+	    ret_mem = alloc_area->aa_free_list;
+
+	    /* 
+	       Update the free list.  The initial part of the struct is 
+	       used to hold a pointer to the next struct on the free
+	       list.  In this way, the free list chain is maintained at
+	       0 memory cost. */
+	    alloc_area->aa_free_list =
+		((Dwarf_Free_List) ret_mem)->fl_next;
+	} else if (alloc_area->aa_blob_start < alloc_area->aa_blob_end) {
+	    ret_mem = alloc_area->aa_blob_start;
+
+	    /* 
+	       Store pointer to chunk this struct belongs to in the
+	       first few bytes.  Return pointer to bytes after this
+	       pointer storage. */
+	    *(Dwarf_Alloc_Area *) ret_mem = alloc_area;
+	    ret_mem += DW_RESERVE;
+
+	    alloc_area->aa_blob_start += alloc_hdr->ah_bytes_one_struct;
+	} else {
+	    /* else fall thru , though it should be impossible to fall
+	       thru. And represents a disastrous programming error if
+	       we get here. */
+#ifdef DEBUG
+	    fprintf(stderr, "libdwarf Internal error start %x end %x\n",
+		    (int) alloc_area->aa_blob_start,
+		    (int) alloc_area->aa_blob_end);
+#endif
+	}
+    }
+
+    /* New memory has to malloc'ed since there are no free structs. */
+    if (ret_mem == 0) {
+	Dwarf_Word rounded_area_hdr_size;
+
+	alloc_hdr->ah_chunks_allocated++;
+
+	{			/* this nonsense avoids a warning */
+	    /* CONSTCOND would be better */
+	    unsigned long v = sizeof(struct Dwarf_Alloc_Area_s);
+
+	    rounded_area_hdr_size = ROUND_SIZE(v);
+	}
+
+	/* 
+	   Allocate memory to contain the required number of structs
+	   and the Dwarf_Alloc_Area_s to control it. */
+	mem_block_size = alloc_hdr->ah_bytes_malloc_per_chunk +
+	    rounded_area_hdr_size;
+
+	mem_block = malloc(mem_block_size);
+	if (mem_block == NULL) {
+	    return (NULL);
+	}
+
+
+	/* 
+	   Attach the Dwarf_Alloc_Area_s struct to the list of chunks
+	   malloc'ed for this struct type. Also initialize the fields
+	   of the Dwarf_Alloc_Area_s. */
+	alloc_area = (Dwarf_Alloc_Area) mem_block;
+	alloc_area->aa_prev = 0;
+	if (alloc_hdr->ah_alloc_area_head != NULL) {
+	    alloc_hdr->ah_alloc_area_head->aa_prev = alloc_area;
+	}
+	alloc_area->aa_free_list = 0;
+	alloc_area->aa_next = alloc_hdr->ah_alloc_area_head;
+	alloc_hdr->ah_alloc_area_head = alloc_area;
+
+	alloc_area->aa_alloc_hdr = alloc_hdr;
+	alloc_area->aa_free_structs_in_chunk =
+	    (Dwarf_Sword) alloc_hdr->ah_structs_per_chunk - 1;
+	if (alloc_area->aa_free_structs_in_chunk < 1) {
+	    /* If we get here, there is a disastrous programming error
+	       somewhere. */
+#ifdef DEBUG
+	    fprintf(stderr,
+		    "libdwarf Internal error: free structs in chunk %d\n",
+		    (int) alloc_area->aa_free_structs_in_chunk);
+#endif
+	    return NULL;
+	}
+
+	/* 
+	   The struct returned begins immediately after the
+	   Dwarf_Alloc_Area_s struct. */
+	ret_mem = mem_block + rounded_area_hdr_size;
+	alloc_area->aa_blob_start =
+	    ret_mem + alloc_hdr->ah_bytes_one_struct;
+	alloc_area->aa_blob_end = mem_block + mem_block_size;
+
+	/* 
+	   Store pointer to chunk this struct belongs to in the first
+	   few bytes.  Return pointer to bytes after this pointer
+	   storage. */
+	*(Dwarf_Alloc_Area *) ret_mem = alloc_area;
+	ret_mem += DW_RESERVE;
+    }
+
+    alloc_hdr->ah_last_alloc_area = alloc_area;
+    alloc_hdr->ah_struct_user_holds++;
+    memset(ret_mem, 0, alloc_hdr->ah_bytes_one_struct - DW_RESERVE);
+    return (ret_mem);
+}
+
+#endif /* ndef DWARF_SIMPLE_MALLOC */
+
+/*
+    This function returns a pointer to a region
+    of memory.  For alloc_types that are not
+    strings or lists of pointers, only 1 struct
+    can be requested at a time.  This is indicated
+    by an input count of 1.  For strings, count 
+    equals the length of the string it will
+    contain, i.e it the length of the string
+    plus 1 for the terminating null.  For lists
+    of pointers, count is equal to the number of
+    pointers.  For DW_DLA_FRAME_BLOCK, and
+    DW_DLA_LOC_BLOCK allocation types also, count
+    is the count of the number of structs needed.
+
+    This function cannot be used to allocate a 
+    Dwarf_Debug_s struct.
+
+*/
+Dwarf_Ptr
+_dwarf_get_alloc(Dwarf_Debug dbg,
+		 Dwarf_Small alloc_type, Dwarf_Unsigned count)
+{
+    Dwarf_Alloc_Hdr alloc_hdr;
+
+    Dwarf_Ptr ret_mem;
+
+    Dwarf_Signed size = 0;
+    unsigned int index;
+    unsigned int type = alloc_type;
+
+    if (dbg == NULL) {
+	return (NULL);
+    }
+
+    if (type >= ALLOC_AREA_INDEX_TABLE_MAX) {
+	/* internal error */
+	return NULL;
+    }
+    index = index_into_allocated[type].ia_al_num;
+    /* zero also illegal but not tested for */
+
+    /* If the Dwarf_Debug is not fully set up, we will get index 0 for
+       any type and must do something.  'Not fully set up' can only
+       happen for DW_DLA_ERROR, I (davea) believe, and for that we call 
+       special code here.. */
+
+    if (index == 0) {
+	if (alloc_type == DW_DLA_STRING) {
+	    size = count;
+	} else if (alloc_type == DW_DLA_LIST) {
+	    size = count * sizeof(Dwarf_Ptr);
+	} else if (alloc_type == DW_DLA_FRAME_BLOCK) {
+	    size = count * sizeof(Dwarf_Frame_Op);
+	} else if (alloc_type == DW_DLA_LOC_BLOCK) {
+	    size = count * sizeof(Dwarf_Loc);
+	} else if (alloc_type == DW_DLA_ADDR) {
+	    size = count *
+		(sizeof(Dwarf_Addr) > sizeof(Dwarf_Off) ?
+		 sizeof(Dwarf_Addr) : sizeof(Dwarf_Off));
+	} else if (alloc_type == DW_DLA_ERROR) {
+	    void *m = _dwarf_special_no_dbg_error_malloc();
+
+	    dwarf_malloc_check_alloc_data(m, DW_DLA_ERROR);
+	    return m;
+
+	} else {
+	    /* If we get here, there is a disastrous programming error
+	       somewhere. */
+#ifdef DEBUG
+	    fprintf(stderr,
+		    "libdwarf Internal error: type %d  unexpected\n",
+		    (int) type);
+#endif
+	}
+    } else {
+	alloc_hdr = &dbg->de_alloc_hdr[index];
+	if (alloc_hdr->ah_bytes_one_struct > 0) {
+#ifdef DWARF_SIMPLE_MALLOC
+	    size = alloc_hdr->ah_bytes_one_struct;
+#else
+	    {
+		void *m = _dwarf_find_memory(alloc_hdr);
+
+		dwarf_malloc_check_alloc_data(m, type);
+		if (index_into_allocated[type].specialconstructor) {
+		    int res =
+			index_into_allocated[type].
+			specialconstructor(dbg, m);
+		    if (res != DW_DLV_OK) {
+			/* We leak what we allocated in
+			   _dwarf_find_memory when constructor fails. */
+			return NULL;
+		    }
+		}
+		return m;
+	    }
+#endif
+
+	} else {
+	    /* Special case: should not really happen at all. */
+	    if (type == DW_DLA_ERROR) {
+		/* dwarf_init failure. Because dbg is incomplete we
+		   won't use it to record the malloc. */
+		void *m = _dwarf_special_no_dbg_error_malloc();
+
+		dwarf_malloc_check_alloc_data(m, DW_DLA_ERROR);
+		return m;
+	    } else {
+		/* If we get here, there is a disastrous programming
+		   error somewhere. */
+#ifdef DWARF_SIMPLE_MALLOC
+		_dwarf_simple_malloc_botch(3);
+#endif
+#ifdef DEBUG
+		fprintf(stderr,
+			"libdwarf Internal error: Type %d  unexpected\n",
+			(int) type);
+#endif
+	    }
+	}
+    }
+
+    ret_mem = malloc(size);
+#ifdef DWARF_SIMPLE_MALLOC
+    _dwarf_simple_malloc_add_to_list(dbg, ret_mem, (unsigned long) size,
+				     type);
+#endif
+    if (ret_mem != NULL)
+	memset(ret_mem, 0, size);
+
+    dwarf_malloc_check_alloc_data(ret_mem, type);
+    if (index_into_allocated[type].specialconstructor) {
+	int res =
+	    index_into_allocated[type].specialconstructor(dbg, ret_mem);
+	if (res != DW_DLV_OK) {
+	    /* We leak what we allocated in _dwarf_find_memory when
+	       constructor fails. */
+	    return NULL;
+	}
+    }
+
+    return (ret_mem);
+}
+
+
+
+/*
+    This function is used to deallocate a region of memory
+    that was obtained by a call to _dwarf_get_alloc.  Note
+    that though dwarf_dealloc() is a public function, 
+    _dwarf_get_alloc() isn't.  
+
+    For lists, typically arrays of pointers, it is assumed
+    that the space was allocated by a direct call to malloc,
+    and so a straight free() is done.  This is also the case
+    for variable length blocks such as DW_DLA_FRAME_BLOCK
+    and DW_DLA_LOC_BLOCK.
+
+    For strings, the pointer might point to a string in 
+    .debug_info or .debug_string.  After this is checked,
+    and if found not to be the case, a free() is done,
+    again on the assumption that a malloc was used to
+    obtain the space.
+
+    For other types of structs, a pointer to the chunk that
+    the struct was allocated out of, is present in the bytes
+    preceding the pointer passed in.  For this chunk it is 
+    checked whether all the structs in that chunk are now free.  
+    If so, the entire chunk is free_ed.  Otherwise, the space 
+    is added to the free list for that chunk, and the free count
+    incremented.
+
+    This function does not return anything.
+*/
+void
+dwarf_dealloc(Dwarf_Debug dbg,
+	      Dwarf_Ptr space, Dwarf_Unsigned alloc_type)
+{
+    Dwarf_Alloc_Hdr alloc_hdr;
+    Dwarf_Alloc_Area alloc_area;
+    unsigned int type = alloc_type;
+    unsigned int index;
+
+    if (space == NULL) {
+	return;
+    }
+    if (type == DW_DLA_ERROR) {
+	/* Get pointer to Dwarf_Alloc_Area this struct came from. See
+	   dwarf_alloc.h ROUND_SIZE_WITH_POINTER stuff */
+	alloc_area =
+	    *(Dwarf_Alloc_Area *) ((char *) space - DW_RESERVE);
+	if (alloc_area == 0) {
+	    /* This is the special case of a failed dwarf_init(). Also
+	       (and more signficantly) there are a variety of other
+	       situations where libdwarf does not *know* what dbg is
+	       involved (because of a libdwarf-caller-error) so
+	       libdwarf uses NULL as the dbg. Those too wind up here. */
+	    _dwarf_free_special_error(space);
+	    dwarf_malloc_check_dealloc_data(space, type);
+	    return;
+	}
+
+    }
+    if (dbg == NULL) {
+	/* App error, or an app that failed to succeed in a
+	   dwarf_init() call. */
+	return;
+    }
+    if (type >= ALLOC_AREA_INDEX_TABLE_MAX) {
+	/* internal or user app error */
+	return;
+    }
+
+    index = index_into_allocated[type].ia_al_num;
+    /* 
+       A string pointer may point into .debug_info or .debug_string.
+       Otherwise, they are directly malloc'ed. */
+    dwarf_malloc_check_dealloc_data(space, type);
+    if (index == 0) {
+	if (type == DW_DLA_STRING) {
+	    if ((Dwarf_Small *) space >= dbg->de_debug_info &&
+		(Dwarf_Small *) space <
+		dbg->de_debug_info + dbg->de_debug_info_size)
+		return;
+
+	    if (dbg->de_debug_line != NULL &&
+		(Dwarf_Small *) space >= dbg->de_debug_line &&
+		(Dwarf_Small *) space <
+		dbg->de_debug_line + dbg->de_debug_line_size)
+		return;
+
+	    if (dbg->de_debug_pubnames != NULL &&
+		(Dwarf_Small *) space >= dbg->de_debug_pubnames &&
+		(Dwarf_Small *) space <
+		dbg->de_debug_pubnames + dbg->de_debug_pubnames_size)
+		return;
+
+	    if (dbg->de_debug_frame != NULL &&
+		(Dwarf_Small *) space >= dbg->de_debug_frame &&
+		(Dwarf_Small *) space <
+		dbg->de_debug_frame + dbg->de_debug_frame_size)
+		return;
+
+	    if (dbg->de_debug_str != NULL &&
+		(Dwarf_Small *) space >= dbg->de_debug_str &&
+		(Dwarf_Small *) space <
+		dbg->de_debug_str + dbg->de_debug_str_size)
+		return;
+
+	    if (dbg->de_debug_funcnames != NULL &&
+		(Dwarf_Small *) space >= dbg->de_debug_funcnames &&
+		(Dwarf_Small *) space <
+		dbg->de_debug_funcnames + dbg->de_debug_funcnames_size)
+		return;
+
+	    if (dbg->de_debug_typenames != NULL &&
+		(Dwarf_Small *) space >= dbg->de_debug_typenames &&
+		(Dwarf_Small *) space <
+		dbg->de_debug_typenames + dbg->de_debug_typenames_size)
+		return;
+	    if (dbg->de_debug_pubtypes != NULL &&
+		(Dwarf_Small *) space >= dbg->de_debug_pubtypes &&
+		(Dwarf_Small *) space <
+		dbg->de_debug_pubtypes + dbg->de_debug_pubtypes_size)
+		return;
+
+	    if (dbg->de_debug_varnames != NULL &&
+		(Dwarf_Small *) space >= dbg->de_debug_varnames &&
+		(Dwarf_Small *) space <
+		dbg->de_debug_varnames + dbg->de_debug_varnames_size)
+		return;
+
+	    if (dbg->de_debug_weaknames != NULL &&
+		(Dwarf_Small *) space >= dbg->de_debug_weaknames &&
+		(Dwarf_Small *) space <
+		dbg->de_debug_weaknames + dbg->de_debug_weaknames_size)
+		return;
+
+#ifdef DWARF_SIMPLE_MALLOC
+            _dwarf_simple_malloc_delete_from_list(dbg, space, type);
+#endif
+	    free(space);
+	    return;
+	}
+
+	if (type == DW_DLA_LIST ||
+	    type == DW_DLA_FRAME_BLOCK ||
+	    type == DW_DLA_LOC_BLOCK || type == DW_DLA_ADDR) {
+
+#ifdef DWARF_SIMPLE_MALLOC
+            _dwarf_simple_malloc_delete_from_list(dbg, space, type);
+#endif
+	    free(space);
+	    return;
+	}
+	/* else is an alloc type that is not used */
+	/* app or internal error */
+#ifdef DWARF_SIMPLE_MALLOC
+	_dwarf_simple_malloc_botch(4);
+#endif
+	return;
+
+    }
+    if (index_into_allocated[type].specialdestructor) {
+	index_into_allocated[type].specialdestructor(space);
+    }
+#ifdef DWARF_SIMPLE_MALLOC
+    _dwarf_simple_malloc_delete_from_list(dbg, space, type);
+    free(space);
+#else /* !DWARF_SIMPLE_MALLOC */
+    alloc_hdr = &dbg->de_alloc_hdr[index];
+
+    /* Get pointer to Dwarf_Alloc_Area this struct came from. See
+       dwarf_alloc.h ROUND_SIZE_WITH_POINTER stuff */
+    alloc_area = *(Dwarf_Alloc_Area *) ((char *) space - DW_RESERVE);
+
+    /* ASSERT: alloc_area != NULL If NULL we could abort, let it
+       coredump below, or return, pretending all is well. We go on,
+       letting program crash. Is caller error. */
+
+    /* 
+       Check that the alloc_hdr field of the alloc_area we have is
+       pointing to the right alloc_hdr.  This is used to catch use of
+       incorrect deallocation code by the user. */
+    if (alloc_area->aa_alloc_hdr != alloc_hdr) {
+	/* If we get here, the user has called dwarf_dealloc wrongly or 
+	   there is some other disastrous error. By leaking mem here we 
+	   try to be safe... */
+#ifdef DEBUG
+	fprintf(stderr,
+		"libdwarf Internal error: type %d hdr mismatch %lx %lx "
+		"area ptr %lx\n",
+		(int) type,
+		(long) alloc_area->aa_alloc_hdr,
+		(long) alloc_hdr, (long) alloc_area);
+#endif
+	return;
+    }
+
+    alloc_hdr->ah_struct_user_holds--;
+    alloc_area->aa_free_structs_in_chunk++;
+
+    /* 
+       Give chunk back to malloc only when every struct is freed */
+    if (alloc_area->aa_free_structs_in_chunk ==
+	alloc_hdr->ah_structs_per_chunk) {
+	if (alloc_area->aa_prev != NULL) {
+	    alloc_area->aa_prev->aa_next = alloc_area->aa_next;
+	} else {
+	    alloc_hdr->ah_alloc_area_head = alloc_area->aa_next;
+	}
+
+	if (alloc_area->aa_next != NULL) {
+	    alloc_area->aa_next->aa_prev = alloc_area->aa_prev;
+	}
+
+	alloc_hdr->ah_chunks_allocated--;
+
+	if (alloc_area == alloc_hdr->ah_last_alloc_area) {
+	    alloc_hdr->ah_last_alloc_area = NULL;
+	}
+	memset(alloc_area, 0, sizeof(*alloc_area));
+	free(alloc_area);
+    }
+
+    else {
+	((Dwarf_Free_List) space)->fl_next = alloc_area->aa_free_list;
+	alloc_area->aa_free_list = space;
+    }
+#endif /* !DWARF_SIMPLE_MALLOC */
+}
+
+
+/*
+    Allocates space for a Dwarf_Debug_s struct,
+    since one does not exist.
+*/
+Dwarf_Debug
+_dwarf_get_debug(void
+    )
+{
+    Dwarf_Debug dbg;
+
+    dbg = (Dwarf_Debug) malloc(sizeof(struct Dwarf_Debug_s));
+    if (dbg == NULL)
+	return (NULL);
+    else
+	memset(dbg, 0, sizeof(struct Dwarf_Debug_s));
+
+    return (dbg);
+}
+
+
+/*
+    Sets up the Dwarf_Debug_s struct for all the
+    allocation types currently defined.  
+    Allocation types DW_DLA_STRING, DW_DLA_LIST,
+    DW_DLA_FRAME_BLOCK, DW_DLA_LOC_BLOCK are 
+    malloc'ed directly.
+
+    This routine should be called after _dwarf_setup(),
+    so that information about the sizes of the Dwarf
+    sections can be used to decide the number of
+    structs of each type malloc'ed.
+
+    Also DW_DLA_ELLIST, DW_DLA_BOUNDS, DW_DLA_TYPE,
+    DW_DLA_SUBSCR, DW_DLA_LINEBUF allocation types
+    are currently not used.
+    The ah_bytes_one_struct and ah_structs_per_chunk fields for
+    these types have been set to 1 for efficiency
+    in dwarf_get_alloc().
+ 
+    Ah_alloc_num should be greater than 1 for all
+    types that are currently being used.
+
+    Therefore, for these allocation types the
+    ah_bytes_one_struct, and ah_structs_per_chunk fields do not
+    need to be initialized.
+
+    Being an internal routine, assume proper dbg.
+
+
+
+
+*/
+/* 
+**  Set up all the Dwarf_Alloc_Hdr records.
+*/
+
+Dwarf_Debug
+_dwarf_setup_debug(Dwarf_Debug dbg)
+{
+    int i;
+
+    for (i = 1; i <= MAX_DW_DLA; i++) {
+	const struct ial_s *ialp = &index_into_allocated[i];
+	unsigned int hdr_index = ialp->ia_al_num;
+	Dwarf_Word str_size = ialp->ia_struct_size;
+	Dwarf_Word str_count = ialp->ia_base_count;
+	Dwarf_Word rnded_size = ROUND_SIZE_WITH_POINTER(str_size);
+
+	Dwarf_Alloc_Hdr alloc_hdr = &dbg->de_alloc_hdr[hdr_index];
+
+	alloc_hdr->ah_bytes_one_struct = (Dwarf_Half) rnded_size;
+
+	/* ah_structs_per_chunk must be >0 else we are in trouble */
+	alloc_hdr->ah_structs_per_chunk = str_count;
+	alloc_hdr->ah_bytes_malloc_per_chunk = rnded_size * str_count;
+    }
+    return (dbg);
+}
+
+/*
+    This function prints out the statistics
+    collected on allocation of memory chunks.
+*/
+void
+dwarf_print_memory_stats(Dwarf_Debug dbg)
+{
+    Dwarf_Alloc_Hdr alloc_hdr;
+    Dwarf_Shalf i;
+
+    /* 
+       Alloc types start at 1, not 0. Hence, the first NULL string, and 
+       also a size of MAX_DW_DLA + 1. */
+    char *alloc_type_name[MAX_DW_DLA + 1] = {
+	"",
+	"DW_DLA_STRING",
+	"DW_DLA_LOC",
+	"DW_DLA_LOCDESC",
+	"DW_DLA_ELLIST",
+	"DW_DLA_BOUNDS",
+	"DW_DLA_BLOCK",
+	"DW_DLA_DEBUG",
+	"DW_DLA_DIE",
+	"DW_DLA_LINE",
+	"DW_DLA_ATTR",
+	"DW_DLA_TYPE",
+	"DW_DLA_SUBSCR",
+	"DW_DLA_GLOBAL",
+	"DW_DLA_ERROR",
+	"DW_DLA_LIST",
+	"DW_DLA_LINEBUF",
+	"DW_DLA_ARANGE",
+	"DW_DLA_ABBREV",
+	"DW_DLA_FRAME_OP",
+	"DW_DLA_CIE",
+	"DW_DLA_FDE",
+	"DW_DLA_LOC_BLOCK",
+	"DW_DLA_FRAME_BLOCK",
+	"DW_DLA_FUNC",
+	"DW_DLA_TYPENAME",
+	"DW_DLA_VAR",
+	"DW_DLA_WEAK",
+	"DW_DLA_ADDR",
+	"DW_DLA_ABBREV_LIST",
+	"DW_DLA_CHAIN",
+	"DW_DLA_CU_CONTEXT",
+	"DW_DLA_FRAME",
+	"DW_DLA_GLOBAL_CONTEXT",
+	"DW_DLA_FILE_ENTRY",
+	"DW_DLA_LINE_CONTEXT",
+	"DW_DLA_LOC_CHAIN",
+	"DW_DLA_HASH_TABLE",
+	"DW_DLA_FUNC_CONTEXT",
+	"DW_DLA_TYPENAME_CONTEXT",
+	"DW_DLA_VAR_CONTEXT",
+	"DW_DLA_WEAK_CONTEXT" "DW_DLA_PUBTYPES_CONTEXT"
+    };
+
+    if (dbg == NULL)
+	return;
+
+    printf("Size of Dwarf_Debug        %4ld bytes\n",
+	   (long) sizeof(*dbg));
+    printf("Size of Dwarf_Alloc_Hdr_s  %4ld bytes\n",
+	   (long) sizeof(struct Dwarf_Alloc_Hdr_s));
+    printf("size of Dwarf_Alloc_Area_s %4ld bytes\n",
+	   (long) sizeof(struct Dwarf_Alloc_Area_s));
+
+    printf("   Alloc Type                   Curr  Structs byt   str\n");
+    printf("   ----------                   ----  ------- per   per\n");
+    for (i = 1; i <= MAX_DW_DLA; i++) {
+	int indx = index_into_allocated[i].ia_al_num;
+
+	alloc_hdr = &dbg->de_alloc_hdr[indx];
+	if (alloc_hdr->ah_bytes_one_struct != 1) {
+	    printf("%2d %-25s   %6d %8d %6d %6d\n",
+		   (int) i,
+		   alloc_type_name[i],
+		   (int) alloc_hdr->ah_chunks_allocated,
+		   (int) alloc_hdr->ah_struct_user_holds,
+		   (int) alloc_hdr->ah_bytes_malloc_per_chunk,
+		   (int) alloc_hdr->ah_structs_per_chunk);
+	}
+    }
+}
+
+
+#ifndef DWARF_SIMPLE_MALLOC
+/*
+    This function is used to recursively
+    free the chunks still allocated, and
+    forward chained through the aa_next
+    pointer.
+*/
+static void
+_dwarf_recursive_free(Dwarf_Alloc_Area alloc_area)
+{
+    if (alloc_area->aa_next != NULL) {
+	_dwarf_recursive_free(alloc_area->aa_next);
+    }
+
+    alloc_area->aa_next = 0;
+    alloc_area->aa_prev = 0;
+    free(alloc_area);
+}
+#endif
+
+/*
+    Used to free all space allocated for this Dwarf_Debug.
+    The caller should assume that the Dwarf_Debug pointer 
+    itself is no longer valid upon return from this function.
+
+    In case of difficulty, this function simply returns quietly.
+*/
+int
+_dwarf_free_all_of_one_debug(Dwarf_Debug dbg)
+{
+    Dwarf_Alloc_Hdr alloc_hdr;
+    Dwarf_Shalf i;
+    Dwarf_CU_Context context = 0;
+    Dwarf_CU_Context nextcontext = 0;
+
+    if (dbg == NULL)
+	return (DW_DLV_ERROR);
+
+    /* To do complete validation that we have no surprising missing or
+       erroneous deallocs it is advisable to do the dwarf_deallocs here 
+       that are not things the user can otherwise request.
+       Housecleaning.  */
+
+    for (context = dbg->de_cu_context_list;
+	 context; context = nextcontext) {
+	Dwarf_Hash_Table hash_table = context->cc_abbrev_hash_table;
+
+	/* A Hash Table is an array with ABBREV_HASH_TABLE_SIZE struct
+	   Dwarf_Hash_Table_s entries in the array. */
+	int hashnum = 0;
+
+	for (; hashnum < ABBREV_HASH_TABLE_SIZE; ++hashnum) {
+	    struct Dwarf_Abbrev_List_s *abbrev = 0;
+	    struct Dwarf_Abbrev_List_s *nextabbrev = 0;
+
+	    abbrev = hash_table[hashnum].at_head;
+	    for (; abbrev; abbrev = nextabbrev) {
+		nextabbrev = abbrev->ab_next;
+		dwarf_dealloc(dbg, abbrev, DW_DLA_ABBREV_LIST);
+	    }
+	}
+	nextcontext = context->cc_next;
+	dwarf_dealloc(dbg, hash_table, DW_DLA_HASH_TABLE);
+	dwarf_dealloc(dbg, context, DW_DLA_CU_CONTEXT);
+    }
+
+    /* Housecleaning done. Now really free all the space. */
+
+#ifdef DWARF_SIMPLE_MALLOC
+    if (dbg->de_simple_malloc_base) {
+	struct simple_malloc_record_s *smp = dbg->de_simple_malloc_base;
+
+	while (smp) {
+	    int i;
+	    struct simple_malloc_record_s *prev_smp = 0;
+
+	    for (i = 0; i < smp->sr_used; ++i) {
+		struct simple_malloc_entry_s *cur;
+
+		cur = &smp->sr_entry[i];
+		if (cur->se_addr != 0) {
+		    free(cur->se_addr);
+		    cur->se_addr = 0;
+		}
+	    }
+	    prev_smp = smp;
+	    smp = smp->sr_next;
+	    free(prev_smp);
+	}
+	dbg->de_simple_malloc_base = 0;
+    }
+#else
+    for (i = 1; i < ALLOC_AREA_REAL_TABLE_MAX; i++) {
+	int indx = i;
+
+	alloc_hdr = &dbg->de_alloc_hdr[indx];
+	if (alloc_hdr->ah_alloc_area_head != NULL) {
+	    _dwarf_recursive_free(alloc_hdr->ah_alloc_area_head);
+	}
+    }
+
+#endif
+
+    memset(dbg, 0, sizeof(*dbg)); /* Prevent accidental use later. */
+    free(dbg);
+    return (DW_DLV_OK);
+}
+
+/* A special case: we have no dbg, no alloc header etc.
+   So create something out of thin air that we can recognize
+   in dwarf_dealloc.
+   Something with the prefix (prefix space hidden from caller).
+
+   Only applies to DW_DLA_ERROR, making up an error record.
+*/
+
+struct Dwarf_Error_s *
+_dwarf_special_no_dbg_error_malloc(void)
+{
+    /* the union unused things are to guarantee proper alignment */
+    union u {
+	Dwarf_Alloc_Area ptr_not_used;
+	struct Dwarf_Error_s base_not_used;
+	char data_space[sizeof(struct Dwarf_Error_s) +
+			(DW_RESERVE * 2)];
+    };
+    char *mem;
+
+    mem = malloc(sizeof(union u));
+
+    if (mem == 0) {
+	return 0;
+
+    }
+    memset(mem, 0, sizeof(union u));
+    mem += DW_RESERVE;
+    return (struct Dwarf_Error_s *) mem;
+}
+
+/* The free side of  _dwarf_special_no_dbg_error_malloc()
+*/
+static void
+_dwarf_free_special_error(Dwarf_Ptr space)
+{
+    char *mem = (char *) space;
+
+    mem -= DW_RESERVE;
+    free(mem);
+}
+
+
+#ifdef DWARF_SIMPLE_MALLOC
+/* here solely for planting a breakpoint. */
+/* ARGSUSED */
+void
+_dwarf_simple_malloc_botch(int err)
+{
+       fprintf(stderr,"simple malloc botch %d\n",err);
+}
+static void
+_dwarf_simple_malloc_add_to_list(Dwarf_Debug dbg,
+				 Dwarf_Ptr addr,
+				 unsigned long size, short alloc_type)
+{
+    struct simple_malloc_record_s *cur;
+    struct simple_malloc_entry_s *newentry;
+
+    if (!dbg->de_simple_malloc_base) {
+	/* First entry to this routine. */
+	dbg->de_simple_malloc_base =
+	    malloc(sizeof(struct simple_malloc_record_s));
+	if (!dbg->de_simple_malloc_base) {
+	    _dwarf_simple_malloc_botch(7);
+	    return;		/* no memory, give up */
+	}
+	memset(dbg->de_simple_malloc_base,
+	       0, sizeof(struct simple_malloc_record_s));
+    }
+    cur = dbg->de_simple_malloc_base;
+
+    if (cur->sr_used >= DSM_BLOCK_COUNT) {
+	/* better not be > than as that means chaos */
+
+	/* Create a new block to link at the head. */
+
+	struct simple_malloc_record_s *newblock =
+	    malloc(sizeof(struct simple_malloc_record_s));
+	if (!newblock) {
+	    _dwarf_simple_malloc_botch(8);
+	    return;		/* Can do nothing, out of memory */
+	}
+	memset(newblock, 0, sizeof(struct simple_malloc_record_s));
+	/* Link the new block at the head of the chain, and make it
+	   'current' */
+	dbg->de_simple_malloc_base = newblock;
+	newblock->sr_next = cur;
+	cur = newblock;
+    }
+    newentry = &cur->sr_entry[cur->sr_used];
+    newentry->se_addr = addr;
+    newentry->se_size = size;
+    newentry->se_type = alloc_type;
+    ++cur->sr_used;
+}
+
+/*
+   DWARF_SIMPLE_MALLOC: testing the hypothesis that the existing
+   malloc scheme here (see _dwarf_get_alloc()) is pointless complexity.
+
+   DWARF_SIMPLE_MALLOC also makes it easy for a malloc-tracing
+   tool to verify libdwarf malloc has no botches (though of course
+   such does not test the complicated standard-libdwarf-alloc code).
+
+   To properly answer the question, the simple-malloc allocate
+   and delete should be something other than a simple list.
+   Perhaps a heap, or perhaps a red-black tree.
+
+*/
+static void
+_dwarf_simple_malloc_delete_from_list(Dwarf_Debug dbg,
+				      Dwarf_Ptr space, short alloc_type)
+{
+    if (space == 0) {
+	_dwarf_simple_malloc_botch(6);
+    }
+    if (dbg->de_simple_malloc_base) {
+	struct simple_malloc_record_s *smp = dbg->de_simple_malloc_base;
+
+	while (smp) {
+	    int i;
+
+	    for (i = 0; i < smp->sr_used; ++i) {
+		struct simple_malloc_entry_s *cur;
+
+		cur = &smp->sr_entry[i];
+		if (cur->se_addr == space) {
+		    if (cur->se_type != alloc_type) {
+			_dwarf_simple_malloc_botch(0);
+		    }
+		    cur->se_addr = 0;
+		    return;
+		}
+	    }
+	    smp = smp->sr_next;
+	}
+    }
+    /* Never found the space */
+    _dwarf_simple_malloc_botch(1);
+    return;
+
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_alloc.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,167 @@
+/*
+
+  Copyright (C) 2000,2005 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+Dwarf_Ptr _dwarf_get_alloc(Dwarf_Debug, Dwarf_Small, Dwarf_Unsigned);
+Dwarf_Debug _dwarf_get_debug(void);
+Dwarf_Debug _dwarf_setup_debug(Dwarf_Debug);
+int _dwarf_free_all_of_one_debug(Dwarf_Debug);
+
+typedef struct Dwarf_Alloc_Area_s *Dwarf_Alloc_Area;
+typedef struct Dwarf_Free_List_s *Dwarf_Free_List;
+
+#define ALLOC_AREA_INDEX_TABLE_MAX 43
+#define ALLOC_AREA_REAL_TABLE_MAX 32
+
+/* 
+    This struct is used to chain all the deallocated
+    structs on the free list of each chain.  The structs
+    are chained internally, by using the memory they
+    contain.
+*/
+struct Dwarf_Free_List_s {
+    Dwarf_Free_List fl_next;
+};
+
+
+/*
+    This struct is used to manage all the chunks malloc'ed
+    for a particular alloc_type.  Many of the fields are
+    initialized by dwarf_init().
+*/
+struct Dwarf_Alloc_Hdr_s {
+
+    /* Count of actual number of structs user app holds pointers to
+       currently. */
+    Dwarf_Sword ah_struct_user_holds;
+
+    /* 
+       Size of each struct that will be allocated for this alloc_type.
+       Initialized by dwarf_init(). */
+    Dwarf_Half ah_bytes_one_struct;
+
+    /* 
+       Number of structs of this alloc_type that will be contained in
+       each chunk that is malloc'ed. Initialized by dwarf_init(). */
+    Dwarf_Word ah_structs_per_chunk;
+
+    /* 
+       Number of bytes malloc'ed per chunk which is basically
+       (ah_bytes_one_struct+_DWARF_RESERVE) * ah_alloc_num. */
+    Dwarf_Word ah_bytes_malloc_per_chunk;
+
+    /* Count of chunks currently allocated for type. */
+    Dwarf_Sword ah_chunks_allocated;
+
+    /* 
+       Points to a chain of Dwarf_Alloc_Area_s structs that represent
+       all the chunks currently allocated for the alloc_type. */
+    Dwarf_Alloc_Area ah_alloc_area_head;
+
+    /* Last Alloc Area that was allocated by malloc. The
+       free-space-search area looks here first and only if it is full
+       goes thru the list pointed to by ah_alloc_area_head. */
+    Dwarf_Alloc_Area ah_last_alloc_area;
+};
+
+
+/*
+    This struct is used to manage each chunk that is
+    malloc'ed for a particular alloc_type.  For each
+    allocation type, the allocation header points to
+    a list of all the chunks malloc'ed for that type.
+*/
+struct Dwarf_Alloc_Area_s {
+
+    /* Points to the free list of structs in the chunk. */
+    Dwarf_Ptr aa_free_list;
+
+    /* 
+       Count of the number of free structs in the chunk. This includes
+       both those on the free list, and in the blob. */
+    Dwarf_Sword aa_free_structs_in_chunk;
+
+    /* 
+       Points to the first byte of the blob from which struct will be
+       allocated.  A struct is put on the free_list only when it
+       dwarf_deallocated.  Initial allocations are from the blob. */
+    Dwarf_Small *aa_blob_start;
+
+    /* Points just past the last byte of the blob. */
+    Dwarf_Small *aa_blob_end;
+
+    /* Points to alloc_hdr this alloc_area is linked to: The owner, in 
+       other words. */
+    Dwarf_Alloc_Hdr aa_alloc_hdr;
+
+    /* 
+       Used for chaining Dwarf_Alloc_Area_s atructs. Alloc areas are
+       doubly linked to enable deletion from the list in constant time. */
+    Dwarf_Alloc_Area aa_next;
+    Dwarf_Alloc_Area aa_prev;
+};
+
+struct Dwarf_Error_s *_dwarf_special_no_dbg_error_malloc(void);
+
+#ifdef DWARF_SIMPLE_MALLOC
+/*
+   DWARF_SIMPLE_MALLOC is for testing the hypothesis that the existing
+   complex malloc scheme in libdwarf is pointless complexity.
+
+   DWARF_SIMPLE_MALLOC also makes it easy for a malloc-tracing
+   tool to verify libdwarf malloc has no botches (though of course
+   such does not test the complicated standard-libdwarf-alloc code).
+
+*/
+
+struct simple_malloc_entry_s {
+    Dwarf_Small   *se_addr;
+    unsigned long  se_size;
+    short          se_type;
+};
+#define DSM_BLOCK_COUNT (1000)
+#define DSM_BLOCK_SIZE (sizeof(struct simple_malloc_entry_s)*DSM_BLOCK_COUNT)
+
+/* we do this so dwarf_dealloc can really free everything */
+struct simple_malloc_record_s {
+	struct simple_malloc_record_s *sr_next;
+	int 			       sr_used;
+	struct simple_malloc_entry_s   sr_entry[DSM_BLOCK_COUNT];
+};
+
+
+
+#endif /* DWARF_SIMPLE_MALLOC */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_arange.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,649 @@
+/*
+
+  Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include "dwarf_arange.h"
+#include "dwarf_global.h"	/* for _dwarf_fixup_* */
+
+
+/*
+    This function returns the count of the number of
+    aranges in the .debug_aranges section.  It sets
+    aranges to point to a block of Dwarf_Arange's 
+    describing the arange's.  It returns DW_DLV_ERROR
+    on error.
+
+    Must be identical in most aspects to
+	dwarf_get_aranges_addr_offsets!
+*/
+int
+dwarf_get_aranges(Dwarf_Debug dbg,
+		  Dwarf_Arange ** aranges,
+		  Dwarf_Signed * returned_count, Dwarf_Error * error)
+{
+    /* Sweeps the .debug_aranges section. */
+    Dwarf_Small *arange_ptr = 0;
+
+    /* 
+       Start of arange header.  Used for rounding offset of arange_ptr
+       to twice the tuple size.  Libdwarf requirement. */
+    Dwarf_Small *header_ptr = 0;
+
+
+    /* Version of .debug_aranges header. */
+    Dwarf_Half version = 0;
+
+    /* Offset of current set of aranges into .debug_info. */
+    Dwarf_Off info_offset = 0;
+
+    /* Size in bytes of addresses in target. */
+    Dwarf_Small address_size = 0;
+
+    /* Size in bytes of segment offsets in target. */
+    Dwarf_Small segment_size = 0;
+
+    Dwarf_Small remainder = 0;
+
+    /* Count of total number of aranges. */
+    Dwarf_Unsigned arange_count = 0;
+
+    /* Start address of arange. */
+    Dwarf_Addr range_address = 0;
+
+    /* Length of arange. */
+    Dwarf_Unsigned range_length = 0;
+
+    Dwarf_Arange arange, *arange_block = 0;
+
+    Dwarf_Unsigned i = 0;
+
+    /* Used to chain Dwarf_Aranges structs. */
+    Dwarf_Chain curr_chain = NULL;
+    Dwarf_Chain prev_chain = NULL;
+    Dwarf_Chain head_chain = NULL;
+
+    int res = 0;
+
+    /* ***** BEGIN CODE ***** */
+
+    if (dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    res =
+	_dwarf_load_section(dbg,
+			    dbg->de_debug_aranges_index,
+			    &dbg->de_debug_aranges, error);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+
+    arange_ptr = dbg->de_debug_aranges;
+    do {
+	/* Length of current set of aranges. */
+	Dwarf_Unsigned length;
+	Dwarf_Small *arange_ptr_past_end = 0;
+
+	int local_length_size;
+
+	 /*REFERENCED*/		/* Not used in this instance of the
+				   macro */
+	int local_extension_size;
+
+	header_ptr = arange_ptr;
+
+	/* READ_AREA_LENGTH updates arange_ptr for consumed bytes */
+	READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
+			 arange_ptr, local_length_size,
+			 local_extension_size);
+	arange_ptr_past_end = arange_ptr + length;
+
+
+	READ_UNALIGNED(dbg, version, Dwarf_Half,
+		       arange_ptr, sizeof(Dwarf_Half));
+	arange_ptr += sizeof(Dwarf_Half);
+	length = length - sizeof(Dwarf_Half);
+	if (version != CURRENT_VERSION_STAMP) {
+	    _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
+	    return (DW_DLV_ERROR);
+	}
+
+	READ_UNALIGNED(dbg, info_offset, Dwarf_Off,
+		       arange_ptr, local_length_size);
+	arange_ptr += local_length_size;
+	length = length - local_length_size;
+	if (info_offset >= dbg->de_debug_info_size) {
+	    FIX_UP_OFFSET_IRIX_BUG(dbg, info_offset,
+				   "arange info offset.a");
+	    if (info_offset >= dbg->de_debug_info_size) {
+		_dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD);
+		return (DW_DLV_ERROR);
+	    }
+	}
+
+	address_size = *(Dwarf_Small *) arange_ptr;
+	if (address_size != dbg->de_pointer_size) {
+	    /* Internal error of some kind */
+	    _dwarf_error(dbg, error, DW_DLE_BADBITC);
+	    return (DW_DLV_ERROR);
+	}
+	arange_ptr = arange_ptr + sizeof(Dwarf_Small);
+	length = length - sizeof(Dwarf_Small);
+
+	segment_size = *(Dwarf_Small *) arange_ptr;
+	arange_ptr = arange_ptr + sizeof(Dwarf_Small);
+	length = length - sizeof(Dwarf_Small);
+	if (segment_size != 0) {
+	    _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD);
+	    return (DW_DLV_ERROR);
+	}
+
+	/* Round arange_ptr offset to next multiple of address_size. */
+	remainder = (Dwarf_Unsigned) (arange_ptr - header_ptr) %
+	    (2 * address_size);
+	if (remainder != 0) {
+	    arange_ptr = arange_ptr + (2 * address_size) - remainder;
+	    length = length - ((2 * address_size) - remainder);
+	}
+
+	do {
+	    READ_UNALIGNED(dbg, range_address, Dwarf_Addr,
+			   arange_ptr, address_size);
+	    arange_ptr += address_size;
+	    length = length - address_size;
+
+	    READ_UNALIGNED(dbg, range_length, Dwarf_Unsigned,
+			   arange_ptr, address_size);
+	    arange_ptr += address_size;
+	    length = length - address_size;
+
+	    if (range_address != 0 || range_length != 0) {
+
+		arange = (Dwarf_Arange)
+		    _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
+		if (arange == NULL) {
+		    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+		    return (DW_DLV_ERROR);
+		}
+
+		arange->ar_address = range_address;
+		arange->ar_length = range_length;
+		arange->ar_info_offset = info_offset;
+		arange->ar_dbg = dbg;
+		arange_count++;
+
+		curr_chain = (Dwarf_Chain)
+		    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+		if (curr_chain == NULL) {
+		    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+		    return (DW_DLV_ERROR);
+		}
+
+		curr_chain->ch_item = arange;
+		if (head_chain == NULL)
+		    head_chain = prev_chain = curr_chain;
+		else {
+		    prev_chain->ch_next = curr_chain;
+		    prev_chain = curr_chain;
+		}
+	    }
+	} while (range_address != 0 || range_length != 0);
+
+	/* A compiler could emit some padding bytes here. dwarf2/3
+	   (dwarf3 draft8 sec 7.20) does not clearly make extra padding 
+	   bytes illegal. */
+	if (arange_ptr_past_end < arange_ptr) {
+	    _dwarf_error(dbg, error, DW_DLE_ARANGE_LENGTH_BAD);
+	    return (DW_DLV_ERROR);
+	}
+	/* For most compilers, arange_ptr == arange_ptr_past_end at
+	   this point. But not if there were padding bytes */
+	arange_ptr = arange_ptr_past_end;
+
+    } while (arange_ptr <
+	     dbg->de_debug_aranges + dbg->de_debug_aranges_size);
+
+    if (arange_ptr !=
+	dbg->de_debug_aranges + dbg->de_debug_aranges_size) {
+	_dwarf_error(dbg, error, DW_DLE_ARANGE_DECODE_ERROR);
+	return (DW_DLV_ERROR);
+    }
+
+    arange_block = (Dwarf_Arange *)
+	_dwarf_get_alloc(dbg, DW_DLA_LIST, arange_count);
+    if (arange_block == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+
+    curr_chain = head_chain;
+    for (i = 0; i < arange_count; i++) {
+	*(arange_block + i) = curr_chain->ch_item;
+	prev_chain = curr_chain;
+	curr_chain = curr_chain->ch_next;
+	dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
+    }
+
+    *aranges = arange_block;
+    *returned_count = (arange_count);
+    return DW_DLV_OK;
+}
+
+/*
+    This function returns DW_DLV_OK if it succeeds
+    and DW_DLV_ERR or DW_DLV_OK otherwise.
+    count is set to the number of addresses in the
+    .debug_aranges section. 
+    For each address, the corresponding element in
+    an array is set to the address itself(aranges) and
+    the section offset (offsets).
+    Must be identical in most aspects to
+	dwarf_get_aranges!
+*/
+int
+_dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg,
+				Dwarf_Addr ** addrs,
+				Dwarf_Off ** offsets,
+				Dwarf_Signed * count,
+				Dwarf_Error * error)
+{
+    /* Sweeps the .debug_aranges section. */
+    Dwarf_Small *arange_ptr = 0;
+    Dwarf_Small *arange_start_ptr = 0;
+
+    /* 
+       Start of arange header.  Used for rounding offset of arange_ptr
+       to twice the tuple size.  Libdwarf requirement. */
+    Dwarf_Small *header_ptr = 0;
+
+    /* Length of current set of aranges. */
+    Dwarf_Unsigned length = 0;
+
+    /* Version of .debug_aranges header. */
+    Dwarf_Half version = 0;
+
+    /* Offset of current set of aranges into .debug_info. */
+    Dwarf_Off info_offset = 0;
+
+    /* Size in bytes of addresses in target. */
+    Dwarf_Small address_size = 0;
+
+    /* Size in bytes of segment offsets in target. */
+    Dwarf_Small segment_size = 0;
+
+    Dwarf_Small remainder = 0;
+
+    /* Count of total number of aranges. */
+    Dwarf_Unsigned arange_count = 0;
+
+    /* Start address of arange. */
+    Dwarf_Addr range_address = 0;
+
+    /* Length of arange. */
+    Dwarf_Unsigned range_length = 0;
+
+    Dwarf_Arange arange = 0;
+
+    Dwarf_Unsigned i = 0;
+
+    /* Used to chain Dwarf_Aranges structs. */
+    Dwarf_Chain curr_chain = NULL;
+    Dwarf_Chain prev_chain = NULL;
+    Dwarf_Chain head_chain = NULL;
+
+    Dwarf_Addr *arange_addrs = 0;
+    Dwarf_Off *arange_offsets = 0;
+
+    int res = 0;
+
+    /* ***** BEGIN CODE ***** */
+
+    if (error != NULL)
+	*error = NULL;
+
+    if (dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    res =
+	_dwarf_load_section(dbg,
+			    dbg->de_debug_aranges_index,
+			    &dbg->de_debug_aranges, error);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+
+    arange_ptr = dbg->de_debug_aranges;
+    do {
+	int local_length_size;
+
+	 /*REFERENCED*/		/* not used in this instance of the
+				   macro */
+	int local_extension_size;
+
+	header_ptr = arange_ptr;
+
+
+	/* READ_AREA_LENGTH updates arange_ptr for consumed bytes */
+	READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
+			 arange_ptr, local_length_size,
+			 local_extension_size);
+
+
+	READ_UNALIGNED(dbg, version, Dwarf_Half,
+		       arange_ptr, sizeof(Dwarf_Half));
+	arange_ptr += sizeof(Dwarf_Half);
+	length = length - sizeof(Dwarf_Half);
+	if (version != CURRENT_VERSION_STAMP) {
+	    _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
+	    return (DW_DLV_ERROR);
+	}
+
+	READ_UNALIGNED(dbg, info_offset, Dwarf_Off,
+		       arange_ptr, local_length_size);
+	arange_ptr += local_length_size;
+	length = length - local_length_size;
+	if (info_offset >= dbg->de_debug_info_size) {
+	    FIX_UP_OFFSET_IRIX_BUG(dbg, info_offset,
+				   "arange info offset.b");
+	    if (info_offset >= dbg->de_debug_info_size) {
+
+		_dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD);
+		return (DW_DLV_ERROR);
+	    }
+	}
+
+	address_size = *(Dwarf_Small *) arange_ptr;
+	arange_ptr = arange_ptr + sizeof(Dwarf_Small);
+	length = length - sizeof(Dwarf_Small);
+
+	segment_size = *(Dwarf_Small *) arange_ptr;
+	arange_ptr = arange_ptr + sizeof(Dwarf_Small);
+	length = length - sizeof(Dwarf_Small);
+	if (segment_size != 0) {
+	    _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD);
+	    return (DW_DLV_ERROR);
+	}
+
+	/* Round arange_ptr offset to next multiple of address_size. */
+	remainder = (Dwarf_Unsigned) (arange_ptr - header_ptr) %
+	    (2 * address_size);
+	if (remainder != 0) {
+	    arange_ptr = arange_ptr + (2 * address_size) - remainder;
+	    length = length - ((2 * address_size) - remainder);
+	}
+
+	do {
+	    arange_start_ptr = arange_ptr;
+	    READ_UNALIGNED(dbg, range_address, Dwarf_Addr,
+			   arange_ptr, dbg->de_pointer_size);
+	    arange_ptr += dbg->de_pointer_size;
+	    length = length - dbg->de_pointer_size;
+
+	    READ_UNALIGNED(dbg, range_length, Dwarf_Unsigned,
+			   arange_ptr, local_length_size);
+	    arange_ptr += local_length_size;
+	    length = length - local_length_size;
+
+	    if (range_address != 0 || range_length != 0) {
+
+		arange = (Dwarf_Arange)
+		    _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
+		if (arange == NULL) {
+		    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+		    return (DW_DLV_ERROR);
+		}
+
+		arange->ar_address = range_address;
+		arange->ar_length = range_length;
+		arange->ar_info_offset =
+		    arange_start_ptr - dbg->de_debug_aranges;
+		arange->ar_dbg = dbg;
+		arange_count++;
+
+		curr_chain = (Dwarf_Chain)
+		    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+		if (curr_chain == NULL) {
+		    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+		    return (DW_DLV_ERROR);
+		}
+
+		curr_chain->ch_item = arange;
+		if (head_chain == NULL)
+		    head_chain = prev_chain = curr_chain;
+		else {
+		    prev_chain->ch_next = curr_chain;
+		    prev_chain = curr_chain;
+		}
+	    }
+	} while (range_address != 0 || range_length != 0);
+
+	if (length != 0) {
+	    _dwarf_error(dbg, error, DW_DLE_ARANGE_LENGTH_BAD);
+	    return (DW_DLV_ERROR);
+	}
+
+    } while (arange_ptr <
+	     dbg->de_debug_aranges + dbg->de_debug_aranges_size);
+
+    if (arange_ptr !=
+	dbg->de_debug_aranges + dbg->de_debug_aranges_size) {
+	_dwarf_error(dbg, error, DW_DLE_ARANGE_DECODE_ERROR);
+	return (DW_DLV_ERROR);
+    }
+
+    arange_addrs = (Dwarf_Addr *)
+	_dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
+    if (arange_addrs == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+    arange_offsets = (Dwarf_Off *)
+	_dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
+    if (arange_offsets == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+
+    curr_chain = head_chain;
+    for (i = 0; i < arange_count; i++) {
+	Dwarf_Arange ar = curr_chain->ch_item;
+
+	arange_addrs[i] = ar->ar_address;
+	arange_offsets[i] = ar->ar_info_offset;
+	prev_chain = curr_chain;
+	curr_chain = curr_chain->ch_next;
+	dwarf_dealloc(dbg, ar, DW_DLA_ARANGE);
+	dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
+    }
+    *count = arange_count;
+    *offsets = arange_offsets;
+    *addrs = arange_addrs;
+    return (DW_DLV_OK);
+}
+
+
+/*
+    This function takes a pointer to a block
+    of Dwarf_Arange's, and a count of the
+    length of the block.  It checks if the
+    given address is within the range of an
+    address range in the block.  If yes, it
+    returns the appropriate Dwarf_Arange.
+    Otherwise, it returns DW_DLV_ERROR.
+*/
+int
+dwarf_get_arange(Dwarf_Arange * aranges,
+		 Dwarf_Unsigned arange_count,
+		 Dwarf_Addr address,
+		 Dwarf_Arange * returned_arange, Dwarf_Error * error)
+{
+    Dwarf_Arange curr_arange;
+    Dwarf_Unsigned i;
+
+    if (aranges == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ARANGES_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    for (i = 0; i < arange_count; i++) {
+	curr_arange = *(aranges + i);
+	if (address >= curr_arange->ar_address &&
+	    address <
+	    curr_arange->ar_address + curr_arange->ar_length) {
+	    *returned_arange = curr_arange;
+	    return (DW_DLV_OK);
+	}
+    }
+
+    return (DW_DLV_NO_ENTRY);
+}
+
+
+/*
+    This function takes an Dwarf_Arange,
+    and returns the offset of the first
+    die in the compilation-unit that the
+    arange belongs to.  Returns DW_DLV_ERROR
+    on error.
+*/
+int
+dwarf_get_cu_die_offset(Dwarf_Arange arange,
+			Dwarf_Off * returned_offset,
+			Dwarf_Error * error)
+{
+    Dwarf_Debug dbg;
+    Dwarf_Off offset;
+
+    if (arange == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+
+    dbg = arange->ar_dbg;
+
+
+    offset = arange->ar_info_offset;
+    if (!dbg->de_debug_info) {
+	int res = _dwarf_load_debug_info(dbg, error);
+
+	if (res != DW_DLV_OK) {
+	    return res;
+	}
+    }
+
+    *returned_offset = offset + _dwarf_length_of_cu_header(dbg, offset);
+    return DW_DLV_OK;
+}
+
+/*
+    This function takes an Dwarf_Arange,
+    and returns the offset of the CU header
+    in the compilation-unit that the
+    arange belongs to.  Returns DW_DLV_ERROR
+    on error.
+*/
+int
+dwarf_get_arange_cu_header_offset(Dwarf_Arange arange,
+				  Dwarf_Off * cu_header_offset_returned,
+				  Dwarf_Error * error)
+{
+    if (arange == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *cu_header_offset_returned = arange->ar_info_offset;
+    return DW_DLV_OK;
+}
+
+
+
+/*
+    This function takes a Dwarf_Arange, and returns
+    true if it is not NULL.  It also stores the start
+    address of the range in *start, the length of the
+    range in *length, and the offset of the first die
+    in the compilation-unit in *cu_die_offset.  It
+    returns false on error.
+*/
+int
+dwarf_get_arange_info(Dwarf_Arange arange,
+		      Dwarf_Addr * start,
+		      Dwarf_Unsigned * length,
+		      Dwarf_Off * cu_die_offset, Dwarf_Error * error)
+{
+    if (arange == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ARANGE_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    if (start != NULL)
+	*start = arange->ar_address;
+    if (length != NULL)
+	*length = arange->ar_length;
+    if (cu_die_offset != NULL) {
+	Dwarf_Debug dbg = arange->ar_dbg;
+	Dwarf_Off offset = arange->ar_info_offset;
+
+	if (!dbg->de_debug_info) {
+	    int res = _dwarf_load_debug_info(dbg, error);
+
+	    if (res != DW_DLV_OK) {
+		return res;
+	    }
+	}
+
+	*cu_die_offset =
+	    offset + _dwarf_length_of_cu_header(dbg, offset);
+    }
+    return (DW_DLV_OK);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_arange.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,63 @@
+/*
+
+  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+/* This structure is used to read an arange into. */
+struct Dwarf_Arange_s {
+
+    /* Starting address of the arange, ie low-pc. */
+    Dwarf_Addr ar_address;
+
+    /* Length of the arange. */
+    Dwarf_Unsigned ar_length;
+
+    /* 
+       Offset into .debug_info of the start of the compilation-unit
+       containing this set of aranges. */
+    Dwarf_Off ar_info_offset;
+
+    /* Corresponding Dwarf_Debug. */
+    Dwarf_Debug ar_dbg;
+};
+
+
+
+int
+  _dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg,
+				  Dwarf_Addr ** addrs,
+				  Dwarf_Off ** offsets,
+				  Dwarf_Signed * count,
+				  Dwarf_Error * error);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_base_types.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,109 @@
+/*
+
+  Copyright (C) 2000,2005 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "libdwarfdefs.h"
+
+#define true                    1
+#define false                   0
+
+/* to identify a cie */
+#define DW_CIE_ID 		~(0x0)
+#define DW_CIE_VERSION		1 /* DWARF2 */
+#define DW_CIE_VERSION3		3 /* DWARF3 */
+#define ABBREV_HASH_TABLE_SIZE	10
+
+
+/* 
+    These are allocation type codes for structs that
+    are internal to the Libdwarf Consumer library.
+*/
+#define DW_DLA_ABBREV_LIST	DW_DLA_ADDR + 1
+#define DW_DLA_CHAIN		DW_DLA_ADDR + 2
+#define DW_DLA_CU_CONTEXT	DW_DLA_ADDR + 3
+#define DW_DLA_FRAME		DW_DLA_ADDR + 4
+#define DW_DLA_GLOBAL_CONTEXT	DW_DLA_ADDR + 5
+#define DW_DLA_FILE_ENTRY	DW_DLA_ADDR + 6
+#define DW_DLA_LINE_CONTEXT	DW_DLA_ADDR + 7
+#define DW_DLA_LOC_CHAIN	DW_DLA_ADDR + 8
+#define DW_DLA_HASH_TABLE	DW_DLA_ADDR + 9
+#define DW_DLA_FUNC_CONTEXT	DW_DLA_ADDR + 10
+#define DW_DLA_TYPENAME_CONTEXT	DW_DLA_ADDR + 11
+#define DW_DLA_VAR_CONTEXT	DW_DLA_ADDR + 12
+#define DW_DLA_WEAK_CONTEXT	DW_DLA_ADDR + 13
+#define DW_DLA_PUBTYPES_CONTEXT	DW_DLA_ADDR + 14 /* DWARF3 */
+
+/* Maximum number of allocation types for allocation routines. */
+#define MAX_DW_DLA		DW_DLA_PUBTYPES_CONTEXT
+
+/*Dwarf_Word  is unsigned word usable for index, count in memory */
+/*Dwarf_Sword is   signed word usable for index, count in memory */
+/* The are 32 or 64 bits depending if 64 bit longs or not, which
+** fits the  ILP32 and LP64 models
+** These work equally well with ILP64.
+*/
+
+typedef unsigned long Dwarf_Word;
+typedef signed long Dwarf_Sword;
+
+typedef signed char Dwarf_Sbyte;
+typedef unsigned char Dwarf_Ubyte;
+typedef signed short Dwarf_Shalf;
+typedef Dwarf_Small *Dwarf_Byte_Ptr;
+
+/* these 2 are fixed sizes which must not vary with the
+** ILP32/LP64 model. Between these two, stay at 32 bit.
+*/
+typedef __uint32_t Dwarf_ufixed;
+typedef __int32_t Dwarf_sfixed;
+
+/*
+        In various places the code mistakenly associates
+        forms 8 bytes long with Dwarf_Signed or Dwarf_Unsigned
+	This is not a very portable assumption.
+        The following should be used instead for 64 bit integers.
+*/
+typedef __uint64_t Dwarf_ufixed64;
+typedef __int64_t Dwarf_sfixed64;
+
+
+typedef struct Dwarf_Abbrev_List_s *Dwarf_Abbrev_List;
+typedef struct Dwarf_File_Entry_s *Dwarf_File_Entry;
+typedef struct Dwarf_CU_Context_s *Dwarf_CU_Context;
+typedef struct Dwarf_Hash_Table_s *Dwarf_Hash_Table;
+
+
+typedef struct Dwarf_Alloc_Hdr_s *Dwarf_Alloc_Hdr;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_die_deliv.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,816 @@
+/*
+
+  Copyright (C) 2000,2001,2002,2003,2004,2005,2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#ifdef HAVE_ELF_H
+#include <elf.h>
+#endif
+#include <stdio.h>
+#include "dwarf_die_deliv.h"
+
+
+/*
+    For a given Dwarf_Debug dbg, this function checks 
+    if a CU that includes the given offset has been read 
+    or not.  If yes, it returns the Dwarf_CU_Context 
+    for the CU.  Otherwise it returns NULL.  Being an 
+    internal routine, it is assumed that a valid dbg 
+    is passed.
+
+    **This is a sequential search.  May be too slow.
+
+    If debug_info and debug_abbrev not loaded, this will
+    wind up returning NULL. So no need to load before calling
+    this.
+*/
+static Dwarf_CU_Context
+_dwarf_find_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset)
+{
+    Dwarf_CU_Context cu_context;
+
+    if (offset >= dbg->de_info_last_offset)
+	return (NULL);
+
+    if (dbg->de_cu_context != NULL &&
+	dbg->de_cu_context->cc_next != NULL &&
+	dbg->de_cu_context->cc_next->cc_debug_info_offset == offset) {
+
+	return (dbg->de_cu_context->cc_next);
+    }
+
+    if (dbg->de_cu_context != NULL &&
+	dbg->de_cu_context->cc_debug_info_offset <= offset) {
+
+	for (cu_context = dbg->de_cu_context;
+	     cu_context != NULL; cu_context = cu_context->cc_next) {
+
+	    if (offset >= cu_context->cc_debug_info_offset &&
+		offset < cu_context->cc_debug_info_offset +
+		cu_context->cc_length + cu_context->cc_length_size
+		+ cu_context->cc_extension_size) {
+
+		return (cu_context);
+	    }
+	}
+    }
+
+    for (cu_context = dbg->de_cu_context_list;
+	 cu_context != NULL; cu_context = cu_context->cc_next) {
+
+	if (offset >= cu_context->cc_debug_info_offset &&
+	    offset < cu_context->cc_debug_info_offset +
+	    cu_context->cc_length + cu_context->cc_length_size
+	    + cu_context->cc_extension_size) {
+
+	    return (cu_context);
+	}
+    }
+
+    return (NULL);
+}
+
+
+/*
+    This routine checks the dwarf_offdie() list of 
+    CU contexts for the right CU context.
+*/
+static Dwarf_CU_Context
+_dwarf_find_offdie_CU_Context(Dwarf_Debug dbg, Dwarf_Off offset)
+{
+    Dwarf_CU_Context cu_context;
+
+    for (cu_context = dbg->de_offdie_cu_context;
+	 cu_context != NULL; cu_context = cu_context->cc_next)
+
+	if (offset >= cu_context->cc_debug_info_offset &&
+	    offset < cu_context->cc_debug_info_offset +
+	    cu_context->cc_length + cu_context->cc_length_size
+	    + cu_context->cc_extension_size)
+
+	    return (cu_context);
+
+    return (NULL);
+}
+
+
+/*
+    This function is used to create a CU Context for
+    a compilation-unit that begins at offset in 
+    .debug_info.  The CU Context is attached to the
+    list of CU Contexts for this dbg.  It is assumed
+    that the CU at offset has not been read before,
+    and so do not call this routine before making
+    sure of this with _dwarf_find_CU_Context().
+    Returns NULL on error.  As always, being an
+    internal routine, assumes a good dbg.
+
+    This function must always set a dwarf error code
+    before returning NULL. Always.
+*/
+static Dwarf_CU_Context
+_dwarf_make_CU_Context(Dwarf_Debug dbg,
+		       Dwarf_Off offset, Dwarf_Error * error)
+{
+    Dwarf_CU_Context cu_context;
+    Dwarf_Unsigned length;
+    Dwarf_Signed abbrev_offset;
+    Dwarf_Byte_Ptr cu_ptr;
+    int local_extension_size = 0;
+    int local_length_size;
+
+    cu_context =
+	(Dwarf_CU_Context) _dwarf_get_alloc(dbg, DW_DLA_CU_CONTEXT, 1);
+    if (cu_context == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (NULL);
+    }
+    cu_context->cc_dbg = dbg;
+
+    cu_ptr = (Dwarf_Byte_Ptr) (dbg->de_debug_info + offset);
+
+    /* READ_AREA_LENGTH updates cu_ptr for consumed bytes */
+    READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
+		     cu_ptr, local_length_size, local_extension_size);
+    cu_context->cc_length_size = local_length_size;
+    cu_context->cc_extension_size = local_extension_size;
+
+
+    cu_context->cc_length = (Dwarf_Word) length;
+
+    READ_UNALIGNED(dbg, cu_context->cc_version_stamp, Dwarf_Half,
+		   cu_ptr, sizeof(Dwarf_Half));
+    cu_ptr += sizeof(Dwarf_Half);
+
+    READ_UNALIGNED(dbg, abbrev_offset, Dwarf_Signed,
+		   cu_ptr, local_length_size);
+    cu_ptr += local_length_size;
+    cu_context->cc_abbrev_offset = (Dwarf_Sword) abbrev_offset;
+
+    cu_context->cc_address_size = *(Dwarf_Small *) cu_ptr;
+
+    if ((length < CU_VERSION_STAMP_SIZE + local_length_size +
+	 CU_ADDRESS_SIZE_SIZE) ||
+	(offset + length + local_length_size +
+	 local_extension_size > dbg->de_debug_info_size)) {
+
+	dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
+	_dwarf_error(dbg, error, DW_DLE_CU_LENGTH_ERROR);
+	return (NULL);
+    }
+
+    if (cu_context->cc_address_size != dbg->de_pointer_size) {
+	dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
+	_dwarf_error(dbg, error, DW_DLE_CU_ADDRESS_SIZE_BAD);
+	return (NULL);
+    }
+
+    if (cu_context->cc_version_stamp != CURRENT_VERSION_STAMP
+        && cu_context->cc_version_stamp != CURRENT_VERSION_STAMP3
+        && cu_context->cc_version_stamp != CURRENT_VERSION_STAMP4) {
+	dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
+	_dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR);
+	return (NULL);
+    }
+
+    if (abbrev_offset >= dbg->de_debug_abbrev_size) {
+	dwarf_dealloc(dbg, cu_context, DW_DLA_CU_CONTEXT);
+	_dwarf_error(dbg, error, DW_DLE_ABBREV_OFFSET_ERROR);
+	return (NULL);
+    }
+
+    cu_context->cc_abbrev_hash_table =
+	(Dwarf_Hash_Table) _dwarf_get_alloc(dbg, DW_DLA_HASH_TABLE, 1);
+    if (cu_context->cc_abbrev_hash_table == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (NULL);
+    }
+
+    cu_context->cc_debug_info_offset = (Dwarf_Word) offset;
+    dbg->de_info_last_offset =
+	(Dwarf_Word) (offset + length +
+		      local_extension_size + local_length_size);
+
+    if (dbg->de_cu_context_list == NULL) {
+	dbg->de_cu_context_list = cu_context;
+	dbg->de_cu_context_list_end = cu_context;
+    } else {
+	dbg->de_cu_context_list_end->cc_next = cu_context;
+	dbg->de_cu_context_list_end = cu_context;
+    }
+
+    return (cu_context);
+}
+
+
+/*
+    Returns offset of next compilation-unit thru next_cu_offset
+	pointer.
+    It basically sequentially moves from one
+    cu to the next.  The current cu is recorded
+    internally by libdwarf.
+*/
+int
+dwarf_next_cu_header(Dwarf_Debug dbg,
+		     Dwarf_Unsigned * cu_header_length,
+		     Dwarf_Half * version_stamp,
+		     Dwarf_Unsigned * abbrev_offset,
+		     Dwarf_Half * address_size,
+		     Dwarf_Unsigned * next_cu_offset,
+		     Dwarf_Error * error)
+{
+    /* Offset for current and new CU. */
+    Dwarf_Unsigned new_offset;
+
+    /* CU Context for current CU. */
+    Dwarf_CU_Context cu_context;
+
+    /* ***** BEGIN CODE ***** */
+
+    if (dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+    /* 
+       Get offset into .debug_info of next CU. If dbg has no context,
+       this has to be the first one. */
+    if (dbg->de_cu_context == NULL) {
+	new_offset = 0;
+	if (!dbg->de_debug_info) {
+	    int res = _dwarf_load_debug_info(dbg, error);
+
+	    if (res != DW_DLV_OK) {
+		return res;
+	    }
+	}
+
+    } else {
+	new_offset = dbg->de_cu_context->cc_debug_info_offset +
+	    dbg->de_cu_context->cc_length +
+	    dbg->de_cu_context->cc_length_size +
+	    dbg->de_cu_context->cc_extension_size;
+    }
+
+    /* 
+       Check that there is room in .debug_info beyond the new offset
+       for at least a new cu header. If not, return 0 to indicate end
+       of debug_info section, and reset de_cu_debug_info_offset to
+       enable looping back through the cu's. */
+    if ((new_offset + _dwarf_length_of_cu_header_simple(dbg)) >=
+	dbg->de_debug_info_size) {
+	dbg->de_cu_context = NULL;
+	return (DW_DLV_NO_ENTRY);
+    }
+
+    /* Check if this CU has been read before. */
+    cu_context = _dwarf_find_CU_Context(dbg, new_offset);
+
+    /* If not, make CU Context for it. */
+    if (cu_context == NULL) {
+	cu_context = _dwarf_make_CU_Context(dbg, new_offset, error);
+	if (cu_context == NULL) {
+	    /* Error if CU Context could not be made. Since
+	       _dwarf_make_CU_Context has already registered an error
+	       we do not do that here: we let the lower error pass
+	       thru. */
+	    return (DW_DLV_ERROR);
+	}
+    }
+
+    dbg->de_cu_context = cu_context;
+
+    if (cu_header_length != NULL)
+	*cu_header_length = cu_context->cc_length;
+
+    if (version_stamp != NULL)
+	*version_stamp = cu_context->cc_version_stamp;
+
+    if (abbrev_offset != NULL)
+	*abbrev_offset = cu_context->cc_abbrev_offset;
+
+    if (address_size != NULL)
+	*address_size = cu_context->cc_address_size;
+
+    new_offset = new_offset + cu_context->cc_length +
+	cu_context->cc_length_size + cu_context->cc_extension_size;
+    *next_cu_offset = new_offset;
+    return (DW_DLV_OK);
+}
+
+
+/* 
+    This function does two slightly different things
+    depending on the input flag want_AT_sibling.  If
+    this flag is true, it checks if the input die has
+    a DW_AT_sibling attribute.  If it does it returns
+    a pointer to the start of the sibling die in the
+    .debug_info section.  Otherwise it behaves the 
+    same as the want_AT_sibling false case.
+
+    If the want_AT_sibling flag is false, it returns
+    a pointer to the immediately adjacent die in the 
+    .debug_info section.
+
+    Die_info_end points to the end of the .debug_info 
+    portion for the cu the die belongs to.  It is used 
+    to check that the search for the next die does not 
+    cross the end of the current cu.  Cu_info_start points 
+    to the start of the .debug_info portion for the 
+    current cu, and is used to add to the offset for 
+    DW_AT_sibling attributes.  Finally, has_die_child 
+    is a pointer to a Dwarf_Bool that is set true if 
+    the present die has children, false otherwise.  
+    However, in case want_AT_child is true and the die 
+    has a DW_AT_sibling attribute *has_die_child is set 
+    false to indicate that the children are being skipped.
+
+    die_info_end  points to the last byte+1 of the cu.
+    
+*/
+static Dwarf_Byte_Ptr
+_dwarf_next_die_info_ptr(Dwarf_Byte_Ptr die_info_ptr,
+			 Dwarf_CU_Context cu_context,
+			 Dwarf_Byte_Ptr die_info_end,
+			 Dwarf_Byte_Ptr cu_info_start,
+			 Dwarf_Bool want_AT_sibling,
+			 Dwarf_Bool * has_die_child)
+{
+    Dwarf_Byte_Ptr info_ptr;
+    Dwarf_Byte_Ptr abbrev_ptr;
+    Dwarf_Word abbrev_code;
+    Dwarf_Abbrev_List abbrev_list;
+    Dwarf_Half attr;
+    Dwarf_Half attr_form;
+    Dwarf_Unsigned offset;
+    Dwarf_Word leb128_length;
+    Dwarf_Unsigned utmp;
+    Dwarf_Debug dbg;
+
+    info_ptr = die_info_ptr;
+    DECODE_LEB128_UWORD(info_ptr, utmp);
+    abbrev_code = (Dwarf_Word) utmp;
+    if (abbrev_code == 0) {
+	return NULL;
+    }
+
+    abbrev_list = _dwarf_get_abbrev_for_code(cu_context, abbrev_code);
+    if (abbrev_list == NULL) {
+	return (NULL);
+    }
+    dbg = cu_context->cc_dbg;
+
+    *has_die_child = abbrev_list->ab_has_child;
+
+    abbrev_ptr = abbrev_list->ab_abbrev_ptr;
+    do {
+	Dwarf_Unsigned utmp2;
+
+	DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
+	attr = (Dwarf_Half) utmp2;
+	DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
+	attr_form = (Dwarf_Half) utmp2;
+	if (attr_form == DW_FORM_indirect) {
+	    Dwarf_Unsigned utmp6;
+
+	    /* READ_UNALIGNED does update info_ptr */
+	    DECODE_LEB128_UWORD(info_ptr, utmp6);
+	    attr_form = (Dwarf_Half) utmp6;
+
+	}
+
+	if (want_AT_sibling && attr == DW_AT_sibling) {
+	    switch (attr_form) {
+	    case DW_FORM_ref1:
+		offset = *(Dwarf_Small *) info_ptr;
+		break;
+	    case DW_FORM_ref2:
+		READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+			       info_ptr, sizeof(Dwarf_Half));
+		break;
+	    case DW_FORM_ref4:
+		READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+			       info_ptr, sizeof(Dwarf_ufixed));
+		break;
+	    case DW_FORM_ref8:
+		READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+			       info_ptr, sizeof(Dwarf_Unsigned));
+		break;
+	    case DW_FORM_ref_udata:
+		offset =
+		    _dwarf_decode_u_leb128(info_ptr, &leb128_length);
+		break;
+	    default:
+		return (NULL);
+	    }
+
+	    /* Reset *has_die_child to indicate children skipped.  */
+	    *has_die_child = false;
+
+	    /* A value beyond die_info_end indicates an error. Exactly
+	       at die_info_end means 1-past-cu-end and simply means we
+	       are at the end, do not return NULL. Higher level code
+	       will detect that we are at the end. */
+	    if (cu_info_start + offset > die_info_end) {
+		/* Error case, bad DWARF. */
+		return (NULL);
+	    }
+	    /* At or before end-of-cu */
+	    return (cu_info_start + offset);
+	}
+
+	if (attr_form != 0) {
+	    info_ptr += _dwarf_get_size_of_val(cu_context->cc_dbg,
+					       attr_form, info_ptr,
+					       cu_context->
+					       cc_length_size);
+	    /* It is ok for info_ptr == die_info_end, as we will test
+	       later before using a too-large info_ptr */
+	    if (info_ptr > die_info_end) {
+		/* More than one-past-end indicates a bug somewhere,
+		   likely bad dwarf generation. */
+		return (NULL);
+	    }
+	}
+    } while (attr != 0 || attr_form != 0);
+
+    return (info_ptr);
+}
+
+
+/*
+    Given a Dwarf_Debug dbg, and a Dwarf_Die die, it returns 
+    a Dwarf_Die for the sibling of die.  In case die is NULL, 
+    it returns (thru ptr) a Dwarf_Die for the first die in the current 
+    cu in dbg.  Returns DW_DLV_ERROR on error.
+
+    It is assumed that every sibling chain including those with 
+    only one element is terminated with a NULL die, except a 
+    chain with only a NULL die.
+
+    The algorithm moves from one die to the adjacent one.  It 
+    returns when the depth of children it sees equals the number 
+    of sibling chain terminations.  A single count, child_depth 
+    is used to track the depth of children and sibling terminations 
+    encountered.  Child_depth is incremented when a die has the 
+    Has-Child flag set unless the child happens to be a NULL die.  
+    Child_depth is decremented when a die has Has-Child false, 
+    and the adjacent die is NULL.  Algorithm returns when 
+    child_depth is 0.
+
+    **NOTE: Do not modify input die, since it is used at the end.
+*/
+int
+dwarf_siblingof(Dwarf_Debug dbg,
+		Dwarf_Die die,
+		Dwarf_Die * caller_ret_die, Dwarf_Error * error)
+{
+    Dwarf_Die ret_die;
+    Dwarf_Byte_Ptr die_info_ptr;
+    Dwarf_Byte_Ptr cu_info_start = 0;
+
+    /* die_info_end points 1-past end of die (once set) */
+    Dwarf_Byte_Ptr die_info_end = 0;
+    Dwarf_Half abbrev_code;
+    Dwarf_Unsigned utmp;
+
+
+    if (dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    if (die == NULL) {
+	/* Find root die of cu */
+	/* die_info_end is untouched here, need not be set in this
+	   branch. */
+	Dwarf_Off off2;
+
+	/* If we've not loaded debug_info, de_cu_context will be NULL,
+	   so no need to laod */
+
+	if (dbg->de_cu_context == NULL) {
+	    _dwarf_error(dbg, error, DW_DLE_DBG_NO_CU_CONTEXT);
+	    return (DW_DLV_ERROR);
+	}
+
+	off2 = dbg->de_cu_context->cc_debug_info_offset;
+	die_info_ptr = dbg->de_debug_info +
+	    off2 + _dwarf_length_of_cu_header(dbg, off2);
+    } else {
+	/* Find sibling die. */
+	Dwarf_Bool has_child = false;
+	Dwarf_Sword child_depth;
+
+	/* We cannot have a legal die unless debug_info was loaded, so
+	   no need to load debug_info here. */
+	CHECK_DIE(die, DW_DLV_ERROR);
+
+	die_info_ptr = die->di_debug_info_ptr;
+	if (*die_info_ptr == 0) {
+	    return (DW_DLV_NO_ENTRY);
+	}
+	cu_info_start = dbg->de_debug_info +
+	    die->di_cu_context->cc_debug_info_offset;
+	die_info_end = cu_info_start + die->di_cu_context->cc_length +
+	    die->di_cu_context->cc_length_size +
+	    die->di_cu_context->cc_extension_size;
+
+	if ((*die_info_ptr) == 0) {
+	    return (DW_DLV_NO_ENTRY);
+	}
+	child_depth = 0;
+	do {
+	    die_info_ptr = _dwarf_next_die_info_ptr(die_info_ptr,
+						    die->di_cu_context,
+						    die_info_end,
+						    cu_info_start, true,
+						    &has_child);
+	    if (die_info_ptr == NULL) {
+		_dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL);
+		return (DW_DLV_ERROR);
+	    }
+
+            /* die_info_end is one past end. Do not read it!  
+               A test for ``!= die_info_end''  would work as well,
+               but perhaps < reads more like the meaning. */
+            if(die_info_ptr < die_info_end) { 
+	        if ((*die_info_ptr) == 0 && has_child) {
+                    die_info_ptr++;
+                    has_child = false;
+	        }
+	    }
+
+	    /* die_info_ptr can be one-past-end. */
+	    if ((die_info_ptr == die_info_end) ||
+		((*die_info_ptr) == 0)) {
+		for (; child_depth > 0 && *die_info_ptr == 0;
+		     child_depth--, die_info_ptr++);
+	    } else {
+		child_depth = has_child ? child_depth + 1 : child_depth;
+	    }
+
+	} while (child_depth != 0);
+    }
+
+    /* die_info_ptr > die_info_end is really a bug (possibly in dwarf
+       generation)(but we are past end, no more DIEs here), whereas
+       die_info_ptr == die_info_end means 'one past end, no more DIEs
+       here'. */
+    if (die != NULL && die_info_ptr >= die_info_end) {
+	return (DW_DLV_NO_ENTRY);
+    }
+
+    if ((*die_info_ptr) == 0) {
+	return (DW_DLV_NO_ENTRY);
+    }
+
+    ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1);
+    if (ret_die == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+
+    ret_die->di_debug_info_ptr = die_info_ptr;
+    ret_die->di_cu_context =
+	die == NULL ? dbg->de_cu_context : die->di_cu_context;
+
+    DECODE_LEB128_UWORD(die_info_ptr, utmp);
+    abbrev_code = (Dwarf_Half) utmp;
+    if (abbrev_code == 0) {
+	/* Zero means a null DIE */
+	dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
+	return (DW_DLV_NO_ENTRY);
+    }
+    ret_die->di_abbrev_list =
+	_dwarf_get_abbrev_for_code(ret_die->di_cu_context, abbrev_code);
+    if (ret_die->di_abbrev_list == NULL || (die == NULL &&
+					    ret_die->di_abbrev_list->
+					    ab_tag !=
+					    DW_TAG_compile_unit)) {
+	dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
+	_dwarf_error(dbg, error, DW_DLE_FIRST_DIE_NOT_CU);
+	return (DW_DLV_ERROR);
+    }
+
+    *caller_ret_die = ret_die;
+    return (DW_DLV_OK);
+}
+
+
+int
+dwarf_child(Dwarf_Die die,
+	    Dwarf_Die * caller_ret_die, Dwarf_Error * error)
+{
+    Dwarf_Byte_Ptr die_info_ptr = 0;
+
+    /* die_info_end points one-past-end of die area. */
+    Dwarf_Byte_Ptr die_info_end = 0;
+    Dwarf_Die ret_die = 0;
+    Dwarf_Bool has_die_child = 0;
+    Dwarf_Debug dbg;
+    Dwarf_Half abbrev_code = 0;
+    Dwarf_Unsigned utmp = 0;
+
+
+    CHECK_DIE(die, DW_DLV_ERROR);
+    dbg = die->di_cu_context->cc_dbg;
+    die_info_ptr = die->di_debug_info_ptr;
+
+    /* NULL die has no child. */
+    if ((*die_info_ptr) == 0)
+	return (DW_DLV_NO_ENTRY);
+
+    die_info_end = dbg->de_debug_info +
+	die->di_cu_context->cc_debug_info_offset +
+	die->di_cu_context->cc_length +
+	die->di_cu_context->cc_length_size +
+	die->di_cu_context->cc_extension_size;
+
+    die_info_ptr =
+	_dwarf_next_die_info_ptr(die_info_ptr, die->di_cu_context,
+				 die_info_end, NULL, false,
+				 &has_die_child);
+    if (die_info_ptr == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_NEXT_DIE_PTR_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    if (!has_die_child)
+	return (DW_DLV_NO_ENTRY);
+
+    ret_die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1);
+    if (ret_die == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+    ret_die->di_debug_info_ptr = die_info_ptr;
+    ret_die->di_cu_context = die->di_cu_context;
+
+    DECODE_LEB128_UWORD(die_info_ptr, utmp);
+    abbrev_code = (Dwarf_Half) utmp;
+    if (abbrev_code == 0) {
+	/* We have arrived at a null DIE, at the end of a CU or the end 
+	   of a list of siblings. */
+	*caller_ret_die = 0;
+	dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
+	return DW_DLV_NO_ENTRY;
+    }
+    ret_die->di_abbrev_list =
+	_dwarf_get_abbrev_for_code(die->di_cu_context, abbrev_code);
+    if (ret_die->di_abbrev_list == NULL) {
+	dwarf_dealloc(dbg, ret_die, DW_DLA_DIE);
+	_dwarf_error(dbg, error, DW_DLE_DIE_BAD);
+	return (DW_DLV_ERROR);
+    }
+
+    *caller_ret_die = ret_die;
+    return (DW_DLV_OK);
+}
+
+/*
+	Given a die offset, this returns
+	a pointer to a DIE thru *new_die.
+	It is up to the caller to do a
+	dwarf_dealloc(dbg,*new_die,DW_DLE_DIE);
+*/
+int
+dwarf_offdie(Dwarf_Debug dbg,
+	     Dwarf_Off offset, Dwarf_Die * new_die, Dwarf_Error * error)
+{
+    Dwarf_CU_Context cu_context;
+    Dwarf_Off new_cu_offset = 0;
+    Dwarf_Die die = 0;
+    Dwarf_Byte_Ptr info_ptr = 0;
+    Dwarf_Half abbrev_code = 0;
+    Dwarf_Unsigned utmp = 0;
+
+    if (dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    cu_context = _dwarf_find_CU_Context(dbg, offset);
+    if (cu_context == NULL)
+	cu_context = _dwarf_find_offdie_CU_Context(dbg, offset);
+
+    if (cu_context == NULL) {
+	int res = _dwarf_load_debug_info(dbg, error);
+
+	if (res != DW_DLV_OK) {
+	    return res;
+	}
+
+	if (dbg->de_offdie_cu_context_end != NULL) {
+	    Dwarf_CU_Context lcu_context =
+		dbg->de_offdie_cu_context_end;
+	    new_cu_offset =
+		lcu_context->cc_debug_info_offset +
+		lcu_context->cc_length +
+		lcu_context->cc_length_size +
+		lcu_context->cc_extension_size;
+	}
+
+
+	do {
+	    if ((new_cu_offset +
+		 _dwarf_length_of_cu_header_simple(dbg)) >=
+		dbg->de_debug_info_size) {
+		_dwarf_error(dbg, error, DW_DLE_OFFSET_BAD);
+		return (DW_DLV_ERROR);
+	    }
+
+	    cu_context =
+		_dwarf_make_CU_Context(dbg, new_cu_offset, error);
+	    if (cu_context == NULL) {
+		/* Error if CU Context could not be made. Since
+		   _dwarf_make_CU_Context has already registered an
+		   error we do not do that here: we let the lower error
+		   pass thru. */
+
+		return (DW_DLV_ERROR);
+	    }
+
+	    if (dbg->de_offdie_cu_context == NULL) {
+		dbg->de_offdie_cu_context = cu_context;
+		dbg->de_offdie_cu_context_end = cu_context;
+	    } else {
+		dbg->de_offdie_cu_context_end->cc_next = cu_context;
+		dbg->de_offdie_cu_context_end = cu_context;
+	    }
+
+	    new_cu_offset = new_cu_offset + cu_context->cc_length +
+		cu_context->cc_length_size;
+
+	} while (offset >= new_cu_offset);
+    }
+
+    die = (Dwarf_Die) _dwarf_get_alloc(dbg, DW_DLA_DIE, 1);
+    if (die == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+    die->di_cu_context = cu_context;
+
+    info_ptr = dbg->de_debug_info + offset;
+    die->di_debug_info_ptr = info_ptr;
+    DECODE_LEB128_UWORD(info_ptr, utmp);
+    abbrev_code = (Dwarf_Half) utmp;
+    if (abbrev_code == 0) {
+	/* we are at a null DIE (or there is a bug). */
+	*new_die = 0;
+	dwarf_dealloc(dbg, die, DW_DLA_DIE);
+	return DW_DLV_NO_ENTRY;
+    }
+
+    die->di_abbrev_list =
+	_dwarf_get_abbrev_for_code(cu_context, abbrev_code);
+    if (die->di_abbrev_list == NULL) {
+	dwarf_dealloc(dbg, die, DW_DLA_DIE);
+	_dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_LIST_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *new_die = die;
+    return (DW_DLV_OK);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_die_deliv.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,56 @@
+/*
+
+  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+
+/*
+    This struct holds information about a abbreviation.
+    It is put in the hash table for abbreviations for
+    a compile-unit.
+*/
+struct Dwarf_Abbrev_List_s {
+
+    Dwarf_Word ab_code;
+    Dwarf_Half ab_tag;
+    Dwarf_Half ab_has_child;
+
+    /* 
+       Points to start of attribute and form pairs in the .debug_abbrev 
+       section for the abbrev. */
+    Dwarf_Byte_Ptr ab_abbrev_ptr;
+
+    struct Dwarf_Abbrev_List_s *ab_next;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_error.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,388 @@
+/*
+
+  Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#ifdef HAVE_ELF_H
+#include <elf.h>
+#endif
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <stdlib.h>
+
+/* Array to hold string representation of errors. Any time a 
+   define is added to the list in libdwarf.h, a string should be 
+   added to this Array
+*/
+
+const char *_dwarf_errmsgs[] = {
+
+    "No error (0)\n",
+    "DW_DLE_VMM 1 dwarf format/library version mismatch",
+    "DW_DLE_MAP 2 memory map failure",
+    "DW_DLE_LEE 3 libelf error",
+    "DW_DLE_NDS 4 no debug section",
+    "DW_DLE_NLS    5  no line section ",
+    "DW_DLE_ID     6  invalid descriptor for query ",
+    "DW_DLE_IOF    7  I/O failure ",
+    "DW_DLE_MAF    8  memory allocation failure ",
+    "DW_DLE_IA     9  invalid argument ",
+    "DW_DLE_MDE    10  mangled debugging entry ",
+    "DW_DLE_MLE    11  mangled line number entry ",
+    "DW_DLE_FNO    12  file not open ",
+    "DW_DLE_FNR    13  file not a regular file ",
+    "DW_DLE_FWA    14  file open with wrong access ",
+    "DW_DLE_NOB    15  not an object file ",
+    "DW_DLE_MOF    16  mangled object file header ",
+    "DW_DLE_EOLL   17  end of location list entries ",
+    "DW_DLE_NOLL   18  no location list section ",
+    "DW_DLE_BADOFF 19  Invalid offset ",
+    "DW_DLE_EOS    20  end of section  ",
+    "DW_DLE_ATRUNC 21  abbreviations section appears truncated",
+    "DW_DLE_BADBITC  22  Address size passed to dwarf bad",
+
+    "DW_DLE_DBG_ALLOC 23 Unable to malloc a Dwarf_Debug structure",
+    "DW_DLE_FSTAT_ERROR 24 The file fd passed to dwarf_init "
+	"cannot be fstat()ed",
+    "DW_DLE_FSTAT_MODE_ERROR 25 The file mode bits do not "
+	"indicate that the file being opened via "
+	"dwarf_init() is a normal file",
+    "DW_DLE_INIT_ACCESS_WRONG 26 A call to dwarf_init had an "
+	"access of other than DW_DLC_READ",
+    "DW_DLE_ELF_BEGIN_ERROR 27 a call to "
+	"elf_begin(... ELF_C_READ_MMAP... ) failed",
+    "DW_DLE_ELF_GETEHDR_ERROR 28 a call to "
+	"elf32_getehdr() or elf64_getehdr() failed",
+    "DW_DLE_ELF_GETSHDR_ERROR 29 a call to "
+	"elf32_getshdr() or elf64_getshdr() failed",
+    "DW_DLE_ELF_STRPTR_ERROR 30 a call to "
+	"elf_strptr() failed trying to get a section name",
+    "DW_DLE_DEBUG_INFO_DUPLICATE 31  Only one .debug_info  "
+	"section is allowed",
+    "DW_DLE_DEBUG_INFO_NULL 32 .debug_info section present but "
+	"elf_getdata() failed or section is zero-length",
+    "DW_DLE_DEBUG_ABBREV_DUPLICATE 33 Only one .debug_abbrev  "
+	"section is allowed",
+    "DW_DLE_DEBUG_ABBREV_NULL 34 .debug_abbrev section present but "
+	"elf_getdata() failed or section is zero-length",
+    "DW_DLE_DEBUG_ARANGES_DUPLICATE 35 Only one .debug_aranges  "
+	"section is allowed",
+    "DW_DLE_DEBUG_ARANGES_NULL 36 .debug_aranges section present but "
+	"elf_getdata() failed or section is zero-length",
+    "DW_DLE_DEBUG_LINE_DUPLICATE 37 Only one .debug_line  "
+	"section is allowed",
+    "DW_DLE_DEBUG_LINE_NULL (38) .debug_line section present but "
+	"elf_getdata() failed or section is zero-length",
+    "DW_DLE_DEBUG_LOC_DUPLICATE (39) Only one .debug_loc  "
+	"section is allowed",
+    "DW_DLE_DEBUG_LOC_NULL (40) .debug_loc section present but "
+	"elf_getdata() failed or section is zero-length",
+    "DW_DLE_DEBUG_MACINFO_DUPLICATE (41) Only one .debug_macinfo  "
+	"section is allowed",
+    "DW_DLE_DEBUG_MACINFO_NULL (42) .debug_macinfo section present but "
+	"elf_getdata() failed or section is zero-length",
+    "DW_DLE_DEBUG_PUBNAMES_DUPLICATE (43) Only one .debug_pubnames  "
+	"section is allowed",
+    "DW_DLE_DEBUG_PUBNAMES_NULL (44) .debug_pubnames section present but "
+	"elf_getdata() failed or section is zero-length",
+    "DW_DLE_DEBUG_STR_DUPLICATE (45)  Only one .debug_str  "
+	"section is allowed",
+    "DW_DLE_DEBUG_STR_NULL (46) .debug_str section present but "
+	"elf_getdata() failed or section is zero-length",
+    "DW_DLE_CU_LENGTH_ERROR (47)",
+    "DW_DLE_VERSION_STAMP_ERROR (48)",
+    "DW_DLE_ABBREV_OFFSET_ERROR (49)",
+    "DW_DLE_ADDRESS_SIZE_ERROR (50)",
+    "DW_DLE_DEBUG_INFO_PTR_NULL (51)",
+    "DW_DLE_DIE_NULL (52)",
+    "DW_DLE_STRING_OFFSET_BAD (53)",
+    "DW_DLE_DEBUG_LINE_LENGTH_BAD (54)",
+    "DW_DLE_LINE_PROLOG_LENGTH_BAD (55)",
+    "DW_DLE_LINE_NUM_OPERANDS_BAD",
+    "DW_DLE_LINE_SET_ADDR_ERROR",
+    "DW_DLE_LINE_EXT_OPCODE_BAD",
+    "DW_DLE_DWARF_LINE_NULL",
+    "DW_DLE_INCL_DIR_NUM_BAD",
+    "DW_DLE_LINE_FILE_NUM_BAD",
+    "DW_DLE_ALLOC_FAIL",
+    "DW_DLE_NO_CALLBACK_FUNC",
+    "DW_DLE_SECT_ALLOC",
+    "DW_DLE_FILE_ENTRY_ALLOC",
+    "DW_DLE_LINE_ALLOC",
+    "DW_DLE_FPGM_ALLOC",
+    "DW_DLE_INCDIR_ALLOC",
+    "DW_DLE_STRING_ALLOC",
+    "DW_DLE_CHUNK_ALLOC",
+    "DW_DLE_BYTEOFF_ERR",
+    "DW_DLE_CIE_ALLOC",
+    "DW_DLE_FDE_ALLOC",
+    "DW_DLE_REGNO_OVFL",
+    "DW_DLE_CIE_OFFS_ALLOC",
+    "DW_DLE_WRONG_ADDRESS",
+    "DW_DLE_EXTRA_NEIGHBORS",
+    "DW_DLE_WRONG_TAG",
+    "DW_DLE_DIE_ALLOC",
+    "DW_DLE_PARENT_EXISTS",
+    "DW_DLE_DBG_NULL",
+    "DW_DLE_DEBUGLINE_ERROR",
+    "DW_DLE_DEBUGFRAME_ERROR",
+    "DW_DLE_DEBUGINFO_ERROR",
+    "DW_DLE_ATTR_ALLOC",
+    "DW_DLE_ABBREV_ALLOC",
+    "DW_DLE_OFFSET_UFLW",
+    "DW_DLE_ELF_SECT_ERR",
+    "DW_DLE_DEBUG_FRAME_LENGTH_BAD",
+    "DW_DLE_FRAME_VERSION_BAD",
+    "DW_DLE_CIE_RET_ADDR_REG_ERROR",
+    "DW_DLE_FDE_NULL",
+    "DW_DLE_FDE_DBG_NULL",
+    "DW_DLE_CIE_NULL",
+    "DW_DLE_CIE_DBG_NULL",
+    "DW_DLE_FRAME_TABLE_COL_BAD",
+    "DW_DLE_PC_NOT_IN_FDE_RANGE",
+    "DW_DLE_CIE_INSTR_EXEC_ERROR",
+    "DW_DLE_FRAME_INSTR_EXEC_ERROR",
+    "DW_DLE_FDE_PTR_NULL",
+    "DW_DLE_RET_OP_LIST_NULL",
+    "DW_DLE_LINE_CONTEXT_NULL",
+    "DW_DLE_DBG_NO_CU_CONTEXT",
+    "DW_DLE_DIE_NO_CU_CONTEXT",
+    "DW_DLE_FIRST_DIE_NOT_CU",
+    "DW_DLE_NEXT_DIE_PTR_NULL",
+    "DW_DLE_DEBUG_FRAME_DUPLICATE  Only one .debug_frame  "
+	"section is allowed",
+    "DW_DLE_DEBUG_FRAME_NULL  .debug_frame section present but "
+	"elf_getdata() failed or section is zero-length",
+    "DW_DLE_ABBREV_DECODE_ERROR",
+    "DW_DLE_DWARF_ABBREV_NULL",
+    "DW_DLE_ATTR_NULL",
+    "DW_DLE_DIE_BAD",
+    "DW_DLE_DIE_ABBREV_BAD",
+    "DW_DLE_ATTR_FORM_BAD",
+    "DW_DLE_ATTR_NO_CU_CONTEXT",
+    "DW_DLE_ATTR_FORM_SIZE_BAD",
+    "DW_DLE_ATTR_DBG_NULL",
+    "DW_DLE_BAD_REF_FORM",
+    "DW_DLE_ATTR_FORM_OFFSET_BAD",
+    "DW_DLE_LINE_OFFSET_BAD",
+    "DW_DLE_DEBUG_STR_OFFSET_BAD",
+    "DW_DLE_STRING_PTR_NULL",
+    "DW_DLE_PUBNAMES_VERSION_ERROR",
+    "DW_DLE_PUBNAMES_LENGTH_BAD",
+    "DW_DLE_GLOBAL_NULL",
+    "DW_DLE_GLOBAL_CONTEXT_NULL",
+    "DW_DLE_DIR_INDEX_BAD",
+    "DW_DLE_LOC_EXPR_BAD",
+    "DW_DLE_DIE_LOC_EXPR_BAD",
+    "DW_DLE_ADDR_ALLOC",
+    "DW_DLE_OFFSET_BAD",
+    "DW_DLE_MAKE_CU_CONTEXT_FAIL",
+    "DW_DLE_REL_ALLOC",
+    "DW_DLE_ARANGE_OFFSET_BAD",
+    "DW_DLE_SEGMENT_SIZE_BAD",
+    "DW_DLE_ARANGE_LENGTH_BAD",
+    "DW_DLE_ARANGE_DECODE_ERROR",
+    "DW_DLE_ARANGES_NULL",
+    "DW_DLE_ARANGE_NULL",
+    "DW_DLE_NO_FILE_NAME",
+    "DW_DLE_NO_COMP_DIR",
+    "DW_DLE_CU_ADDRESS_SIZE_BAD",
+    "DW_DLE_INPUT_ATTR_BAD",
+    "DW_DLE_EXPR_NULL",
+    "DW_DLE_BAD_EXPR_OPCODE",
+    "DW_DLE_EXPR_LENGTH_BAD",
+    "DW_DLE_MULTIPLE_RELOC_IN_EXPR",
+    "DW_DLE_ELF_GETIDENT_ERROR",
+    "DW_DLE_NO_AT_MIPS_FDE",
+    "DW_DLE_NO_CIE_FOR_FDE",
+    "DW_DLE_DIE_ABBREV_LIST_NULL",
+    "DW_DLE_DEBUG_FUNCNAMES_DUPLICATE",
+    "DW_DLE_DEBUG_FUNCNAMES_NULL .debug_funcnames section present but "
+	"elf_getdata() failed or section is zero-length",
+    "DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR",
+    "DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD",
+    "DW_DLE_FUNC_NULL",
+    "DW_DLE_FUNC_CONTEXT_NULL",
+    "DW_DLE_DEBUG_TYPENAMES_DUPLICATE",
+    "DW_DLE_DEBUG_TYPENAMES_NULL .debug_typenames section present but "
+	"elf_getdata() failed or section is zero-length",
+    "DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR",
+    "DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD",
+    "DW_DLE_TYPE_NULL",
+    "DW_DLE_TYPE_CONTEXT_NULL",
+    "DW_DLE_DEBUG_VARNAMES_DUPLICATE",
+    "DW_DLE_DEBUG_VARNAMES_NULL .debug_varnames section present but "
+	"elf_getdata() failed or section is zero-length",
+    "DW_DLE_DEBUG_VARNAMES_VERSION_ERROR",
+    "DW_DLE_DEBUG_VARNAMES_LENGTH_BAD",
+    "DW_DLE_VAR_NULL",
+    "DW_DLE_VAR_CONTEXT_NULL",
+    "DW_DLE_DEBUG_WEAKNAMES_DUPLICATE",
+    "DW_DLE_DEBUG_WEAKNAMES_NULL .debug_weaknames section present but "
+	"elf_getdata() failed or section is zero-length",
+
+    "DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR",
+    "DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD",
+    "DW_DLE_WEAK_NULL",
+    "DW_DLE_WEAK_CONTEXT_NULL (175)",
+    "DW_DLE_LOCDESC_COUNT_WRONG (176)",
+    "DW_DLE_MACINFO_STRING_NULL (177)",
+    "DW_DLE_MACINFO_STRING_EMPTY (178)",
+    "DW_DLE_MACINFO_INTERNAL_ERROR_SPACE (179)",
+    "DW_DLE_MACINFO_MALLOC_FAIL (180)",
+    "DW_DLE_DEBUGMACINFO_ERROR (181)",
+    "DW_DLE_DEBUG_MACRO_LENGTH_BAD (182)",
+    "DW_DLE_DEBUG_MACRO_MAX_BAD (183)",
+    "DW_DLE_DEBUG_MACRO_INTERNAL_ERR (184)",
+    "DW_DLE_DEBUG_MACRO_MALLOC_SPACE (185)",
+    "DW_DLE_DEBUG_MACRO_INCONSISTENT (186)",
+    "DW_DLE_DF_NO_CIE_AUGMENTATION(187)",
+    "DW_DLE_DF_REG_NUM_TOO_HIGH(188)",
+    "DW_DLE_DF_MAKE_INSTR_NO_INIT(189)",
+    "DW_DLE_DF_NEW_LOC_LESS_OLD_LOC(190)",
+    "DW_DLE_DF_POP_EMPTY_STACK(191)",
+    "DW_DLE_DF_ALLOC_FAIL(192)",
+    "DW_DLE_DF_FRAME_DECODING_ERROR(193)",
+    "DW_DLE_DEBUG_LOC_SECTION_SHORT(194)",
+    "DW_DLE_FRAME_AUGMENTATION_UNKNOWN(195)",
+    "DW_DLA_PUBTYPE_CONTEXT(196)",
+    "DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD(197)",
+    "DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR(198)",
+    "DW_DLE_DEBUG_PUBTYPES_DUPLICATE(199)",
+    "DW_DLE_FRAME_CIE_DECODE_ERROR(200)",
+    "DW_DLE_FRAME_REGISTER_UNREPRESENTABLE(201)",
+    "DW_DLE_FRAME_REGISTER_COUNT_MISMATCH(202)",
+    "DW_DLE_LINK_LOOP(203)",
+     
+
+
+};
+
+
+
+
+/* 
+    This function performs error handling as described in the 
+    libdwarf consumer document section 3.  Dbg is the Dwarf_debug
+    structure being processed.  Error is a pointer to the pointer
+    to the error descriptor that will be returned.  Errval is an
+    error code listed in dwarf_error.h.
+*/
+void
+_dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error, Dwarf_Sword errval)
+{
+    Dwarf_Error errptr;
+
+    /* 
+       Allow NULL dbg on entry, since sometimes that can happen and we
+       want to report the upper-level error, not this one. */
+    if (error != NULL) {
+
+	/* 
+	   If dbg is NULL, use the alternate error struct. However,
+	   this will overwrite the earlier error. */
+	if (dbg != NULL) {
+	    errptr =
+		(Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1);
+	    if (errptr == NULL) {
+		fprintf(stderr,
+			"Could not allocate Dwarf_Error structure, "
+			"abort() in libdwarf.\n");
+		abort();
+	    }
+	} else {
+	    /* We have no dbg to work with. dwarf_init failed. We hack
+	       up a special area. */
+	    errptr = _dwarf_special_no_dbg_error_malloc();
+	    if (errptr == NULL) {
+		fprintf(stderr,
+			"Could not allocate Dwarf_Error structure, "
+			"abort() in libdwarf..\n");
+		abort();
+	    }
+	}
+
+	errptr->er_errval = errval;
+	*error = errptr;
+	return;
+    }
+
+    if (dbg != NULL && dbg->de_errhand != NULL) {
+	errptr = (Dwarf_Error) _dwarf_get_alloc(dbg, DW_DLA_ERROR, 1);
+	if (errptr == NULL) {
+	    fprintf(stderr, "Could not allocate Dwarf_Error structure,"
+		    " abort() in libdwarf.\n");
+	    abort();
+	}
+	errptr->er_errval = errval;
+	dbg->de_errhand(errptr, dbg->de_errarg);
+	return;
+    }
+    fprintf(stderr,
+	    "abort() in libdwarf. No error argument, no handler.\n");
+    abort();
+}
+
+
+Dwarf_Unsigned
+dwarf_errno(Dwarf_Error error)
+{
+    if (error == NULL) {
+	return (0);
+    }
+
+    return (error->er_errval);
+}
+
+
+/* 
+*/
+char *
+dwarf_errmsg(Dwarf_Error error)
+{
+    if (error == NULL) {
+	return "Dwarf_Error is NULL";
+    }
+
+    if (error->er_errval > (sizeof(_dwarf_errmsgs) / sizeof(char *))) {
+	return "Dwarf_Error value out of range";
+    }
+
+    return ((char *) _dwarf_errmsgs[error->er_errval]);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_error.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,43 @@
+/*
+
+  Copyright (C) 2000 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+void _dwarf_error(Dwarf_Debug dbg, Dwarf_Error * error,
+		  Dwarf_Sword errval);
+
+struct Dwarf_Error_s {
+    Dwarf_Sword er_errval;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_form.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,810 @@
+/*
+
+  Copyright (C) 2000,2002,2004,2005  Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include "dwarf_die_deliv.h"
+
+int
+dwarf_hasform(Dwarf_Attribute attr,
+	      Dwarf_Half form,
+	      Dwarf_Bool * return_bool, Dwarf_Error * error)
+{
+    Dwarf_CU_Context cu_context;
+
+    if (attr == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    cu_context = attr->ar_cu_context;
+    if (cu_context == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+	return (DW_DLV_ERROR);
+    }
+
+    if (cu_context->cc_dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *return_bool = (attr->ar_attribute_form == form);
+    return DW_DLV_OK;
+}
+
+/* Not often called, we do not worry about efficiency here.
+   The dwarf_whatform() call does the sanity checks for us.
+*/
+int
+dwarf_whatform_direct(Dwarf_Attribute attr,
+		      Dwarf_Half * return_form, Dwarf_Error * error)
+{
+    int res = dwarf_whatform(attr, return_form, error);
+
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+
+    *return_form = attr->ar_attribute_form_direct;
+    return (DW_DLV_OK);
+}
+void *
+dwarf_uncompress_integer_block(
+    Dwarf_Debug      dbg,
+    Dwarf_Bool       unit_is_signed,
+    Dwarf_Small      unit_length_in_bits,
+    void*            input_block,
+    Dwarf_Unsigned   input_length_in_bytes,
+    Dwarf_Unsigned*  output_length_in_units_ptr,
+    Dwarf_Error*     error
+)
+{
+    Dwarf_Unsigned output_length_in_units;
+    void * output_block;
+    int i;
+    char * ptr;
+    int remain;
+    Dwarf_sfixed * array;
+
+    if (dbg == NULL) {
+        _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+        return((void *)DW_DLV_BADADDR);
+    }
+    
+    if (unit_is_signed == false ||
+	unit_length_in_bits != 32 ||
+	input_block == NULL ||
+	input_length_in_bytes == 0 ||
+	output_length_in_units_ptr == NULL) {
+	
+	_dwarf_error(NULL, error, DW_DLE_BADBITC);
+	return ((void *) DW_DLV_BADADDR);
+    }
+
+    /* At this point we assume the format is: signed 32 bit */
+
+    /* first uncompress everything to find the total size. */
+
+    output_length_in_units = 0;
+    remain = input_length_in_bytes;
+    ptr = input_block;
+    while (remain > 0) {
+	Dwarf_Signed num;
+	Dwarf_Word len;
+	num = _dwarf_decode_s_leb128((unsigned char *)ptr, &len);
+	ptr += len;
+	remain -= len;
+	output_length_in_units++;
+    }
+
+    if (remain != 0) {
+	_dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
+	return((void *)DW_DLV_BADADDR);
+    }
+    
+    /* then alloc */
+
+    output_block = (void *)
+        _dwarf_get_alloc(dbg,
+			 DW_DLA_STRING,
+			 output_length_in_units * (unit_length_in_bits / 8));
+    if (output_block == NULL) {
+        _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return((void*)DW_DLV_BADADDR);
+    }
+    
+    /* then uncompress again and copy into new buffer */
+
+    array = (Dwarf_sfixed *) output_block;
+    remain = input_length_in_bytes;
+    ptr = input_block;
+    for (i=0; i<output_length_in_units && remain>0; i++) {
+	Dwarf_Signed num;
+	Dwarf_Word len;
+	num = _dwarf_decode_s_leb128((unsigned char *)ptr, &len);
+	ptr += len;
+	remain -= len;
+	array[i] = num;
+    }
+
+    if (remain != 0) {
+	dwarf_dealloc(dbg, (unsigned char *)output_block, DW_DLA_STRING);
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return((Dwarf_P_Attribute)DW_DLV_BADADDR);
+    }
+
+    *output_length_in_units_ptr = output_length_in_units;
+    return output_block;
+}
+
+void
+dwarf_dealloc_uncompressed_block(Dwarf_Debug dbg, void * space)
+{
+    dwarf_dealloc(dbg, space, DW_DLA_STRING);
+}
+
+
+int
+dwarf_whatform(Dwarf_Attribute attr,
+	       Dwarf_Half * return_form, Dwarf_Error * error)
+{
+    Dwarf_CU_Context cu_context;
+
+    if (attr == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    cu_context = attr->ar_cu_context;
+    if (cu_context == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+	return (DW_DLV_ERROR);
+    }
+
+    if (cu_context->cc_dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *return_form = attr->ar_attribute_form;
+    return (DW_DLV_OK);
+}
+
+
+/*
+    This function is analogous to dwarf_whatform.
+    It returns the attribute in attr instead of
+    the form.
+*/
+int
+dwarf_whatattr(Dwarf_Attribute attr,
+	       Dwarf_Half * return_attr, Dwarf_Error * error)
+{
+    Dwarf_CU_Context cu_context;
+
+    if (attr == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    cu_context = attr->ar_cu_context;
+    if (cu_context == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+	return (DW_DLV_ERROR);
+    }
+
+    if (cu_context->cc_dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *return_attr = (attr->ar_attribute);
+    return DW_DLV_OK;
+}
+
+
+/* 
+    DW_FORM_ref_addr is considered an incorrect form 
+    for this call because this function returns an 
+    offset  within the local CU thru the pointer.
+
+    DW_FORM_ref_addr is a global-offset into the debug_info section.
+    A DW_FORM_ref_addr cannot be returned by this interface:
+    see dwarf_global_formref();
+
+    DW_FORM_ref_addr has a value which was documented in
+    DWARF2 as address-size but which was always an offset
+    so should have always been offset size (wording
+    corrected in DWARF3). 
+    
+*/
+int
+dwarf_formref(Dwarf_Attribute attr,
+	      Dwarf_Off * ret_offset, Dwarf_Error * error)
+{
+    Dwarf_Debug dbg;
+    Dwarf_Unsigned offset;
+    Dwarf_CU_Context cu_context;
+
+
+    if (attr == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    cu_context = attr->ar_cu_context;
+    if (cu_context == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+	return (DW_DLV_ERROR);
+    }
+
+    if (cu_context->cc_dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+    dbg = cu_context->cc_dbg;
+
+    switch (attr->ar_attribute_form) {
+
+    case DW_FORM_ref1:
+	offset = *(Dwarf_Small *) attr->ar_debug_info_ptr;
+	break;
+
+    case DW_FORM_ref2:
+	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+		       attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
+	break;
+
+    case DW_FORM_ref4:
+	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+		       attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
+	break;
+
+    case DW_FORM_ref8:
+	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+		       attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned));
+	break;
+
+    case DW_FORM_ref_udata:
+	offset = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL);
+	break;
+
+    default:
+	_dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM);
+	return (DW_DLV_ERROR);
+    }
+
+    /* Check that offset is within current cu portion of .debug_info. */
+
+    if (offset >= cu_context->cc_length +
+	cu_context->cc_length_size + cu_context->cc_extension_size) {
+	_dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD);
+	return (DW_DLV_ERROR);
+    }
+
+    *ret_offset = (offset);
+    return DW_DLV_OK;
+}
+
+/* 
+    Since this returns section-relative debug_info offsets,
+    this can represent all REFERENCE forms correctly
+    and allows all forms.
+
+    DW_FORM_ref_addr has a value which was documented in
+    DWARF2 as address-size but which was always an offset
+    so should have always been offset size (wording
+    corrected in DWARF3).
+    
+*/
+int
+dwarf_global_formref(Dwarf_Attribute attr,
+		     Dwarf_Off * ret_offset, Dwarf_Error * error)
+{
+    Dwarf_Debug dbg;
+    Dwarf_Unsigned offset;
+    Dwarf_Addr ref_addr;
+    Dwarf_CU_Context cu_context;
+
+    if (attr == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    cu_context = attr->ar_cu_context;
+    if (cu_context == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+	return (DW_DLV_ERROR);
+    }
+
+    if (cu_context->cc_dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+    dbg = cu_context->cc_dbg;
+
+    switch (attr->ar_attribute_form) {
+
+    case DW_FORM_ref1:
+	offset = *(Dwarf_Small *) attr->ar_debug_info_ptr;
+	goto fixoffset;
+
+    case DW_FORM_ref2:
+	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+		       attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
+	goto fixoffset;
+
+    case DW_FORM_ref4:
+	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+		       attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
+	goto fixoffset;
+
+    case DW_FORM_ref8:
+	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+		       attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned));
+	goto fixoffset;
+
+    case DW_FORM_ref_udata:
+	offset = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL);
+
+      fixoffset:		/* we have a local offset, make it
+				   global */
+
+	/* check legality of offset */
+	if (offset >= cu_context->cc_length +
+	    cu_context->cc_length_size +
+	    cu_context->cc_extension_size) {
+	    _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD);
+	    return (DW_DLV_ERROR);
+	}
+
+	/* globalize the offset */
+	offset += cu_context->cc_debug_info_offset;
+	break;
+
+    case DW_FORM_ref_addr:
+	/* This offset is defined to be debug_info global already, so
+	   use this value unaltered. */
+	READ_UNALIGNED(dbg, ref_addr, Dwarf_Addr,
+		       attr->ar_debug_info_ptr,
+		       cu_context->cc_length_size);
+	offset = ref_addr;
+	break;
+    default:
+	_dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM);
+	return (DW_DLV_ERROR);
+    }
+
+    /* Check that offset is within current cu portion of .debug_info. */
+
+    *ret_offset = (offset);
+    return DW_DLV_OK;
+}
+
+
+int
+dwarf_formaddr(Dwarf_Attribute attr,
+	       Dwarf_Addr * return_addr, Dwarf_Error * error)
+{
+    Dwarf_Debug dbg;
+    Dwarf_Addr ret_addr;
+    Dwarf_CU_Context cu_context;
+
+    if (attr == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    cu_context = attr->ar_cu_context;
+    if (cu_context == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+	return (DW_DLV_ERROR);
+    }
+
+    if (cu_context->cc_dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+    dbg = cu_context->cc_dbg;
+
+    if (attr->ar_attribute_form == DW_FORM_addr
+	/* || attr->ar_attribute_form == DW_FORM_ref_addr Allowance of
+	   DW_FORM_ref_addr was a mistake. The value returned in that
+	   case is NOT an address it is a global debug_info offset (ie, 
+	   not CU-relative offset within the CU in debug_info). The
+	   Dwarf document refers to it as an address (misleadingly) in
+	   sec 6.5.4 where it describes the reference form. It is
+	   address-sized so that the linker can easily update it, but
+	   it is a reference inside the debug_info section. No longer
+	   allowed. */
+	) {
+
+	READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
+		       attr->ar_debug_info_ptr, dbg->de_pointer_size);
+	*return_addr = ret_addr;
+	return (DW_DLV_OK);
+    }
+
+    _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
+    return (DW_DLV_ERROR);
+}
+
+
+int
+dwarf_formflag(Dwarf_Attribute attr,
+	       Dwarf_Bool * ret_bool, Dwarf_Error * error)
+{
+    Dwarf_CU_Context cu_context;
+
+    if (attr == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    cu_context = attr->ar_cu_context;
+    if (cu_context == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+	return (DW_DLV_ERROR);
+    }
+
+    if (cu_context->cc_dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    if (attr->ar_attribute_form == DW_FORM_flag) {
+	*ret_bool = (*(Dwarf_Small *) attr->ar_debug_info_ptr != 0);
+	return (DW_DLV_OK);
+    }
+    _dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD);
+    return (DW_DLV_ERROR);
+}
+
+
+int
+dwarf_formudata(Dwarf_Attribute attr,
+		Dwarf_Unsigned * return_uval, Dwarf_Error * error)
+{
+    Dwarf_Unsigned ret_value;
+    Dwarf_Debug dbg;
+    Dwarf_CU_Context cu_context;
+
+    if (attr == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+
+    cu_context = attr->ar_cu_context;
+    if (cu_context == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+	return (DW_DLV_ERROR);
+    }
+
+    dbg = cu_context->cc_dbg;
+    if (dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    switch (attr->ar_attribute_form) {
+
+    case DW_FORM_data1:
+	READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+		       attr->ar_debug_info_ptr, sizeof(Dwarf_Small));
+	*return_uval = ret_value;
+	return DW_DLV_OK;
+
+    /* READ_UNALIGNED does the right thing as it reads
+       the right number bits and generates host order. 
+       So we can just assign to *return_uval. */
+    case DW_FORM_data2:{
+	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+			   attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
+	    *return_uval = ret_value;
+	    return DW_DLV_OK;
+	}
+
+    case DW_FORM_data4:{
+	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+			   attr->ar_debug_info_ptr,
+			   sizeof(Dwarf_ufixed));
+	    *return_uval = ret_value;
+	    return DW_DLV_OK;
+	}
+
+    case DW_FORM_data8:{
+	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+			   attr->ar_debug_info_ptr,
+			   sizeof(Dwarf_Unsigned));
+	    *return_uval = ret_value;
+	    return DW_DLV_OK;
+	}
+
+    case DW_FORM_udata:
+	ret_value =
+	    (_dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL));
+	*return_uval = ret_value;
+	return DW_DLV_OK;
+
+
+	/* see bug 583450. We do not allow reading sdata from a udata
+	   value. Caller can retry, calling sdata */
+
+
+    default:
+	break;
+    }
+    _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
+    return (DW_DLV_ERROR);
+}
+
+
+int
+dwarf_formsdata(Dwarf_Attribute attr,
+		Dwarf_Signed * return_sval, Dwarf_Error * error)
+{
+    Dwarf_Signed ret_value;
+    Dwarf_Debug dbg;
+    Dwarf_CU_Context cu_context;
+
+    if (attr == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    cu_context = attr->ar_cu_context;
+    if (cu_context == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+	return (DW_DLV_ERROR);
+    }
+
+    dbg = cu_context->cc_dbg;
+    if (dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    switch (attr->ar_attribute_form) {
+
+    case DW_FORM_data1:
+	*return_sval = (*(Dwarf_Sbyte *) attr->ar_debug_info_ptr);
+	return DW_DLV_OK;
+
+    /* READ_UNALIGNED does not sign extend. 
+       So we have to use a cast to get the
+       value sign extended in the right way for each case. */
+    case DW_FORM_data2:{
+	    READ_UNALIGNED(dbg, ret_value, Dwarf_Signed,
+			   attr->ar_debug_info_ptr,
+			   sizeof(Dwarf_Shalf));
+	    *return_sval = (Dwarf_Shalf) ret_value;
+	    return DW_DLV_OK;
+
+	}
+
+    case DW_FORM_data4:{
+	    READ_UNALIGNED(dbg, ret_value, Dwarf_Signed,
+			   attr->ar_debug_info_ptr,
+			   sizeof(Dwarf_sfixed));
+	    *return_sval = (Dwarf_sfixed) ret_value;
+	    return DW_DLV_OK;
+	}
+
+    case DW_FORM_data8:{
+	    READ_UNALIGNED(dbg, ret_value, Dwarf_Signed,
+			   attr->ar_debug_info_ptr,
+			   sizeof(Dwarf_Signed));
+	    *return_sval = (Dwarf_Signed) ret_value;
+	    return DW_DLV_OK;
+	}
+
+    case DW_FORM_sdata:
+	ret_value =
+	    (_dwarf_decode_s_leb128(attr->ar_debug_info_ptr, NULL));
+	*return_sval = ret_value;
+	return DW_DLV_OK;
+
+
+	/* see bug 583450. We do not allow reading sdata from a udata
+	   value. Caller can retry, calling sdata */
+
+
+    default:
+	break;
+    }
+    _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
+    return (DW_DLV_ERROR);
+}
+
+
+int
+dwarf_formblock(Dwarf_Attribute attr,
+		Dwarf_Block ** return_block, Dwarf_Error * error)
+{
+    Dwarf_CU_Context cu_context;
+    Dwarf_Debug dbg;
+    Dwarf_Unsigned length;
+    Dwarf_Small *data;
+    Dwarf_Word leb128_length;
+    Dwarf_Block *ret_block;
+
+    if (attr == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    cu_context = attr->ar_cu_context;
+    if (cu_context == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+	return (DW_DLV_ERROR);
+    }
+
+    if (cu_context->cc_dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+    dbg = cu_context->cc_dbg;
+
+    switch (attr->ar_attribute_form) {
+
+    case DW_FORM_block1:
+	length = *(Dwarf_Small *) attr->ar_debug_info_ptr;
+	data = attr->ar_debug_info_ptr + sizeof(Dwarf_Small);
+	break;
+
+    case DW_FORM_block2:
+	READ_UNALIGNED(dbg, length, Dwarf_Unsigned,
+		       attr->ar_debug_info_ptr, sizeof(Dwarf_Half));
+	data = attr->ar_debug_info_ptr + sizeof(Dwarf_Half);
+	break;
+
+    case DW_FORM_block4:
+	READ_UNALIGNED(dbg, length, Dwarf_Unsigned,
+		       attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed));
+	data = attr->ar_debug_info_ptr + sizeof(Dwarf_ufixed);
+	break;
+
+    case DW_FORM_block:
+	length = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr,
+					&leb128_length);
+	data = attr->ar_debug_info_ptr + leb128_length;
+	break;
+
+    default:
+	_dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD);
+	return (DW_DLV_ERROR);
+    }
+
+    /* Check that block lies within current cu in .debug_info. */
+    if (attr->ar_debug_info_ptr + length >=
+	dbg->de_debug_info + cu_context->cc_debug_info_offset +
+	cu_context->cc_length + cu_context->cc_length_size +
+	cu_context->cc_extension_size) {
+	_dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
+	return (DW_DLV_ERROR);
+    }
+
+    ret_block = (Dwarf_Block *) _dwarf_get_alloc(dbg, DW_DLA_BLOCK, 1);
+    if (ret_block == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+
+    ret_block->bl_len = length;
+    ret_block->bl_data = (Dwarf_Ptr) data;
+    ret_block->bl_from_loclist = 0;
+    ret_block->bl_section_offset = data - dbg->de_debug_info;
+
+
+    *return_block = ret_block;
+    return (DW_DLV_OK);
+}
+
+
+/* Contrary to long standing documentation,
+   The string pointer returned thru return_str must
+   never have dwarf_dealloc() applied to it.
+   Documentation fixed July 2005.
+*/
+int
+dwarf_formstring(Dwarf_Attribute attr,
+		 char **return_str, Dwarf_Error * error)
+{
+    Dwarf_CU_Context cu_context;
+    Dwarf_Debug dbg;
+    Dwarf_Unsigned offset;
+    int res;
+
+    if (attr == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    cu_context = attr->ar_cu_context;
+    if (cu_context == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+	return (DW_DLV_ERROR);
+    }
+
+    if (cu_context->cc_dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+    dbg = cu_context->cc_dbg;
+
+    if (attr->ar_attribute_form == DW_FORM_string) {
+
+	void *begin = attr->ar_debug_info_ptr;
+
+	if (0 == dbg->de_assume_string_in_bounds) {
+	    /* Check that string lies within current cu in .debug_info. 
+	     */
+	    void *end = dbg->de_debug_info +
+		cu_context->cc_debug_info_offset +
+		cu_context->cc_length + cu_context->cc_length_size +
+		cu_context->cc_extension_size;
+	    if (0 == _dwarf_string_valid(begin, end)) {
+		_dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD);
+		return (DW_DLV_ERROR);
+	    }
+	}
+	*return_str = (char *) (begin);
+	return DW_DLV_OK;
+    }
+
+    if (attr->ar_attribute_form == DW_FORM_strp) {
+	READ_UNALIGNED(dbg, offset, Dwarf_Unsigned,
+		       attr->ar_debug_info_ptr,
+		       cu_context->cc_length_size);
+
+	res =
+	    _dwarf_load_section(dbg,
+				dbg->de_debug_str_index,
+				&dbg->de_debug_str, error);
+	if (res != DW_DLV_OK) {
+	    return res;
+	}
+
+	*return_str = (char *) (dbg->de_debug_str + offset);
+	return DW_DLV_OK;
+    }
+
+    _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
+    return (DW_DLV_ERROR);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_frame.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,2359 @@
+/*
+
+  Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "dwarf_frame.h"
+#include "dwarf_arange.h"	/* Using Arange as a way to build a
+				   list */
+
+#define FDE_NULL_CHECKS_AND_SET_DBG(fde,dbg )          \
+    do {                                               \
+     if ((fde) == NULL) {                              \
+        _dwarf_error(NULL, error, DW_DLE_FDE_NULL);    \
+        return (DW_DLV_ERROR);                         \
+    }                                                  \
+    (dbg)= (fde)->fd_dbg;                              \
+    if ((dbg) == NULL) {                               \
+        _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);\
+        return (DW_DLV_ERROR);                         \
+    } } while (0)
+
+
+#define MIN(a,b)  (((a) < (b))? a:b)
+
+static void _dwarf_init_regrule_table(struct Dwarf_Reg_Rule_s *t1reg,
+				      int last_reg_num,
+				      int initial_value);
+static int dwarf_initialize_fde_table(Dwarf_Debug dbg,
+				      struct Dwarf_Frame_s *fde_table,
+				      unsigned table_real_data_size,
+				      Dwarf_Error * error);
+static void dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table);
+
+#if 0
+/* Only used for debugging libdwarf. */
+static void dump_frame_rule(char *msg,
+			    struct Dwarf_Reg_Rule_s *reg_rule);
+#endif
+
+
+
+/* 
+    This function is the heart of the debug_frame stuff.  Don't even
+    think of reading this without reading both the Libdwarf and 
+    consumer API carefully first.  This function basically executes     
+    frame instructions contained in a Cie or an Fde, but does in a      
+    number of different ways depending on the information sought.       
+    Start_instr_ptr points to the first byte of the frame instruction    
+    stream, and final_instr_ptr to the to the first byte after the       
+    last.                                                                
+                                                                        
+    The offsets returned in the frame instructions are factored.  That   
+    is they need to be multiplied by either the code_alignment_factor    
+    or the data_alignment_factor, as appropriate to obtain the actual      
+    offset.  This makes it possible to expand an instruction stream      
+    without the corresponding Cie.  However, when an Fde frame instr     
+    sequence is being expanded there must be a valid Cie with a pointer  
+    to an initial table row.                                             
+                                                                         
+
+    If successful, returns DW_DLV_OK
+		And sets returned_count thru the pointer
+		 if make_instr is true.
+		If make_instr is false returned_count 
+		 should NOT be used by the caller (returned_count
+		 is set to 0 thru the pointer by this routine...)
+    If unsuccessful, returns DW_DLV_ERROR
+		and sets returned_error to the error code
+
+    It does not do a whole lot of input validation being a private 
+    function.  Please make sure inputs are valid.
+                                                                        
+    (1) If make_instr is true, it makes a list of pointers to              
+    Dwarf_Frame_Op structures containing the frame instructions          
+    executed.  A pointer to this list is returned in ret_frame_instr.    
+    Make_instr is true only when a list of frame instructions is to be   
+    returned.  In this case since we are not interested in the contents  
+    of the table, the input Cie can be NULL.  This is the only case
+    where the inpute Cie can be NULL.
+
+    (2) If search_pc is true, frame instructions are executed till       
+    either a location is reached that is greater than the search_pc_val
+    provided, or all instructions are executed.  At this point the       
+    last row of the table generated is returned in a structure.          
+    A pointer to this structure is supplied in table.                    
+                                                                    
+    (3) This function is also used to create the initial table row       
+    defined by a Cie.  In this case, the Dwarf_Cie pointer cie, is       
+    NULL.  For an FDE, however, cie points to the associated Cie.        
+
+    make_instr - make list of frame instr? 0/1
+    ret_frame_instr -  Ptr to list of ptrs to frame instrs
+    search_pc  - Search for a pc value?  0/1
+     search_pc_val -  Search for this pc value
+    initial_loc - Initial code location value.
+    start_instr_ptr -   Ptr to start of frame instrs.
+    final_instr_ptr -   Ptr just past frame instrs. 
+    table       -     Ptr to struct with last row. 
+    cie     -   Ptr to Cie used by the Fde.
+
+*/
+
+int
+_dwarf_exec_frame_instr(Dwarf_Bool make_instr,
+			Dwarf_Frame_Op ** ret_frame_instr,
+			Dwarf_Bool search_pc,
+			Dwarf_Addr search_pc_val,
+			Dwarf_Addr initial_loc,
+			Dwarf_Small * start_instr_ptr,
+			Dwarf_Small * final_instr_ptr,
+			Dwarf_Frame table,
+			Dwarf_Cie cie,
+			Dwarf_Debug dbg,
+			Dwarf_Half reg_num_of_cfa,
+			Dwarf_Sword * returned_count,
+			int *returned_error)
+{
+#define ERROR_IF_REG_NUM_TOO_HIGH(macreg,machigh_reg)               \
+     do {                                             \
+       if ((macreg) >= (machigh_reg) || (macreg) < 0) {            \
+	SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH); \
+       }                                              \
+     } /*CONSTCOND */ while(0)
+#define SIMPLE_ERROR_RETURN(code) \
+        free(localregtab); \
+        *returned_error = code; \
+        return DW_DLV_ERROR
+
+    /* Sweeps the frame instructions. */
+    Dwarf_Small *instr_ptr;
+
+    /* Register numbers not limited to just 255, thus not using
+       Dwarf_Small. */
+    typedef int reg_num_type;
+
+    Dwarf_Unsigned factored_N_value;
+    Dwarf_Signed signed_factored_N_value;
+    Dwarf_Addr current_loc = initial_loc;	/* code location/
+						   pc-value
+						   corresponding to the 
+						   frame instructions.
+						   Starts at zero when
+						   the caller has no
+						   value to pass in. */
+
+    /* Must be min de_pointer_size bytes and must be at least sizeof
+       Dwarf_ufixed */
+    Dwarf_Unsigned adv_loc;
+
+    int reg_count = dbg->de_frame_reg_rules_entry_count;
+    struct Dwarf_Reg_Rule_s *localregtab = calloc(reg_count,
+					  sizeof(struct
+						 Dwarf_Reg_Rule_s));
+
+    struct Dwarf_Reg_Rule_s cfa_reg;
+
+
+    /* This is used to end executing frame instructions.  */
+    /* Becomes true when search_pc is true and current_loc */
+    /* is greater than search_pc_val.  */
+    Dwarf_Bool search_over = false;
+
+    /* Used by the DW_FRAME_advance_loc instr */
+    /* to hold the increment in pc value.  */
+    Dwarf_Addr adv_pc;
+
+    /* Contains the length in bytes of */
+    /* an leb128 encoded number.  */
+    Dwarf_Word leb128_length;
+
+    /* Counts the number of frame instructions executed.  */
+    Dwarf_Word instr_count = 0;
+
+    /* 
+       These contain the current fields of the current frame
+       instruction. */
+    Dwarf_Small fp_base_op = 0;
+    Dwarf_Small fp_extended_op;
+    reg_num_type fp_register;
+
+    /* The value in fp_offset may be signed, though we call it
+       unsigned. This works ok for 2-s complement arithmetic. */
+    Dwarf_Unsigned fp_offset;
+    Dwarf_Off fp_instr_offset;
+
+    /* 
+       Stack_table points to the row (Dwarf_Frame ie) being pushed or
+       popped by a remember or restore instruction. Top_stack points to 
+       the top of the stack of rows. */
+    Dwarf_Frame stack_table;
+    Dwarf_Frame top_stack = NULL;
+
+    /* 
+       These are used only when make_instr is true. Curr_instr is a
+       pointer to the current frame instruction executed.
+       Curr_instr_ptr, head_instr_list, and curr_instr_list are used to 
+       form a chain of Dwarf_Frame_Op structs. Dealloc_instr_ptr is
+       used to deallocate the structs used to form the chain.
+       Head_instr_block points to a contiguous list of pointers to the
+       Dwarf_Frame_Op structs executed. */
+    Dwarf_Frame_Op *curr_instr;
+    Dwarf_Chain curr_instr_item, dealloc_instr_item;
+    Dwarf_Chain head_instr_chain = NULL;
+    Dwarf_Chain tail_instr_chain = NULL;
+    Dwarf_Frame_Op *head_instr_block;
+
+    /* 
+       These are the alignment_factors taken from the Cie provided.
+       When no input Cie is provided they are set to 1, because only
+       factored offsets are required. */
+    Dwarf_Sword code_alignment_factor = 1;
+    Dwarf_Sword data_alignment_factor = 1;
+
+    /* 
+       This flag indicates when an actual alignment factor is needed.
+       So if a frame instruction that computes an offset using an
+       alignment factor is encountered when this flag is set, an error
+       is returned because the Cie did not have a valid augmentation. */
+    Dwarf_Bool need_augmentation = false;
+
+    Dwarf_Word i;
+
+    /* Initialize first row from associated Cie. Using temp regs
+       explicity */
+
+
+    if (localregtab == 0) {
+	SIMPLE_ERROR_RETURN(DW_DLE_ALLOC_FAIL);
+    }
+    {
+	struct Dwarf_Reg_Rule_s *t1reg = localregtab;
+	struct Dwarf_Reg_Rule_s *t1end = t1reg + reg_count;
+
+	if (cie != NULL && cie->ci_initial_table != NULL) {
+	    struct Dwarf_Reg_Rule_s *t2reg =
+		cie->ci_initial_table->fr_reg;
+
+	    if (reg_count != cie->ci_initial_table->fr_reg_count) {
+		/* Should never happen, it makes no sense to have the
+		   table sizes change. There is no real allowance for
+		   the set of registers to change dynamically in a
+		   single Dwarf_Debug (except the size can be set near
+		   initial Dwarf_Debug creation time). */
+		SIMPLE_ERROR_RETURN
+		    (DW_DLE_FRAME_REGISTER_COUNT_MISMATCH);
+	    }
+
+	    for (; t1reg < t1end; t1reg++, t2reg++) {
+		*t1reg = *t2reg;
+	    }
+	    cfa_reg = cie->ci_initial_table->fr_cfa_rule;
+	} else {
+	    _dwarf_init_regrule_table(t1reg,
+				      reg_count,
+				      dbg->de_frame_rule_initial_value);
+	    _dwarf_init_regrule_table(&cfa_reg, 1,
+				      dbg->de_frame_rule_initial_value);
+	}
+    }
+
+    /* 
+       The idea here is that the code_alignment_factor and
+       data_alignment_factor which are needed for certain instructions
+       are valid only when the Cie has a proper augmentation string. So 
+       if the augmentation is not right, only Frame instruction can be
+       read. */
+    if (cie != NULL && cie->ci_augmentation != NULL) {
+	code_alignment_factor = cie->ci_code_alignment_factor;
+	data_alignment_factor = cie->ci_data_alignment_factor;
+    } else {
+	need_augmentation = !make_instr;
+    }
+
+    instr_ptr = start_instr_ptr;
+    while ((instr_ptr < final_instr_ptr) && (!search_over)) {
+        Dwarf_Small instr = 0;
+        Dwarf_Small opcode = 0;
+        reg_num_type reg_no = 0;
+
+
+	fp_instr_offset = instr_ptr - start_instr_ptr;
+	instr = *(Dwarf_Small *) instr_ptr;
+	instr_ptr += sizeof(Dwarf_Small);
+
+	fp_base_op = (instr & 0xc0) >> 6;
+	if ((instr & 0xc0) == 0x00) {
+	    opcode = instr;	/* is really extended op */
+	    fp_extended_op = (instr & (~(0xc0))) & 0xff;
+	} else {
+	    opcode = instr & 0xc0;	/* is base op */
+	    fp_extended_op = 0;
+	}
+
+	fp_register = 0;
+	fp_offset = 0;
+	switch (opcode) {
+	case DW_CFA_advance_loc:
+	    {
+		/* base op */
+		fp_offset = adv_pc = instr & DW_FRAME_INSTR_OFFSET_MASK;
+
+		if (need_augmentation) {
+		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+		}
+		adv_pc = adv_pc * code_alignment_factor;
+
+		search_over = search_pc &&
+		    (current_loc + adv_pc > search_pc_val);
+		/* If gone past pc needed, retain old pc.  */
+		if (!search_over)
+		    current_loc = current_loc + adv_pc;
+		break;
+	    }
+
+	case DW_CFA_offset:
+	    {			/* base op */
+		reg_no =
+		    (reg_num_type) (instr & DW_FRAME_INSTR_OFFSET_MASK);
+		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+
+		factored_N_value =
+		    _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
+		instr_ptr = instr_ptr + leb128_length;
+
+		fp_register = reg_no;
+		fp_offset = factored_N_value;
+
+		if (need_augmentation) {
+		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+		}
+
+		localregtab[reg_no].ru_is_off = 1;
+		localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
+		localregtab[reg_no].ru_register = reg_num_of_cfa;
+		localregtab[reg_no].ru_offset_or_block_len =
+		    factored_N_value * data_alignment_factor;
+
+		break;
+	    }
+
+	case DW_CFA_restore:
+	    {			/* base op */
+		reg_no = (instr & DW_FRAME_INSTR_OFFSET_MASK);
+		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+
+		fp_register = reg_no;
+
+		if (cie != NULL && cie->ci_initial_table != NULL)
+		    localregtab[reg_no] = 
+                       cie->ci_initial_table->fr_reg[reg_no];
+		else if (!make_instr) {
+		    SIMPLE_ERROR_RETURN(DW_DLE_DF_MAKE_INSTR_NO_INIT);
+		}
+
+		break;
+	    }
+	case DW_CFA_set_loc:
+	    {
+		Dwarf_Addr new_loc = 0;
+
+		READ_UNALIGNED(dbg, new_loc, Dwarf_Addr,
+			       instr_ptr, dbg->de_pointer_size);
+		instr_ptr += dbg->de_pointer_size;
+		if (new_loc != 0 && current_loc != 0) {
+		    /* Pre-relocation or before current_loc is set the
+		       test comparing new_loc and current_loc makes no
+		       sense. Testing for non-zero (above) is a way
+		       (fallible) to check that current_loc, new_loc
+		       are already relocated.  */
+		    if (new_loc <= current_loc) {
+			/* Within a frame, address must increase.
+			   Seemingly it has not. Seems to be an error. */
+
+			SIMPLE_ERROR_RETURN
+			    (DW_DLE_DF_NEW_LOC_LESS_OLD_LOC);
+		    }
+		}
+
+		search_over = search_pc && (new_loc > search_pc_val);
+
+		/* If gone past pc needed, retain old pc.  */
+		if (!search_over)
+		    current_loc = new_loc;
+		fp_offset = new_loc;
+		break;
+	    }
+
+	case DW_CFA_advance_loc1:
+	    {
+		fp_offset = adv_loc = *(Dwarf_Small *) instr_ptr;
+		instr_ptr += sizeof(Dwarf_Small);
+
+		if (need_augmentation) {
+		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+		}
+		adv_loc *= code_alignment_factor;
+
+		search_over = search_pc &&
+		    (current_loc + adv_loc > search_pc_val);
+
+		/* If gone past pc needed, retain old pc.  */
+		if (!search_over)
+		    current_loc = current_loc + adv_loc;
+		break;
+	    }
+
+	case DW_CFA_advance_loc2:
+	    {
+		READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned,
+			       instr_ptr, sizeof(Dwarf_Half));
+		instr_ptr += sizeof(Dwarf_Half);
+		fp_offset = adv_loc;
+
+		if (need_augmentation) {
+		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+		}
+		adv_loc *= code_alignment_factor;
+
+		search_over = search_pc &&
+		    (current_loc + adv_loc > search_pc_val);
+
+		/* If gone past pc needed, retain old pc.  */
+		if (!search_over)
+		    current_loc = current_loc + adv_loc;
+		break;
+	    }
+
+	case DW_CFA_advance_loc4:
+	    {
+		READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned,
+			       instr_ptr, sizeof(Dwarf_ufixed));
+		instr_ptr += sizeof(Dwarf_ufixed);
+		fp_offset = adv_loc;
+
+		if (need_augmentation) {
+		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+		}
+		adv_loc *= code_alignment_factor;
+
+		search_over = search_pc &&
+		    (current_loc + adv_loc > search_pc_val);
+
+		/* If gone past pc needed, retain old pc.  */
+		if (!search_over)
+		    current_loc = current_loc + adv_loc;
+		break;
+	    }
+
+	case DW_CFA_offset_extended:
+	    {
+		Dwarf_Unsigned lreg;
+
+		DECODE_LEB128_UWORD(instr_ptr, lreg);
+		reg_no = (reg_num_type) lreg;
+		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);;
+		factored_N_value =
+		    _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
+		instr_ptr += leb128_length;
+
+		if (need_augmentation) {
+		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+		}
+		localregtab[reg_no].ru_is_off = 1;
+		localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
+		localregtab[reg_no].ru_register = reg_num_of_cfa;
+		localregtab[reg_no].ru_offset_or_block_len = factored_N_value *
+		    data_alignment_factor;
+
+		fp_register = reg_no;
+		fp_offset = factored_N_value;
+		break;
+	    }
+
+	case DW_CFA_restore_extended:
+	    {
+		Dwarf_Unsigned lreg;
+
+		DECODE_LEB128_UWORD(instr_ptr, lreg);
+		reg_no = (reg_num_type) lreg;
+
+		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+
+		if (cie != NULL && cie->ci_initial_table != NULL) {
+		    localregtab[reg_no] = cie->ci_initial_table->fr_reg[reg_no];
+		} else {
+		    if (!make_instr) {
+			SIMPLE_ERROR_RETURN
+			    (DW_DLE_DF_MAKE_INSTR_NO_INIT);
+		    }
+		}
+
+		fp_register = reg_no;
+		break;
+	    }
+
+	case DW_CFA_undefined:
+	    {
+		Dwarf_Unsigned lreg;
+
+		DECODE_LEB128_UWORD(instr_ptr, lreg);
+		reg_no = (reg_num_type) lreg;
+		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+
+		localregtab[reg_no].ru_is_off = 0;
+		localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
+		localregtab[reg_no].ru_register = DW_FRAME_UNDEFINED_VAL;
+		localregtab[reg_no].ru_offset_or_block_len = 0;
+
+		fp_register = reg_no;
+		break;
+	    }
+
+	case DW_CFA_same_value:
+	    {
+		Dwarf_Unsigned lreg;
+
+		DECODE_LEB128_UWORD(instr_ptr, lreg);
+		reg_no = (reg_num_type) lreg;
+		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+
+		localregtab[reg_no].ru_is_off = 0;
+		localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
+		localregtab[reg_no].ru_register = DW_FRAME_SAME_VAL;
+		localregtab[reg_no].ru_offset_or_block_len = 0;
+		fp_register = reg_no;
+		break;
+	    }
+
+	case DW_CFA_register:
+	    {
+		Dwarf_Unsigned lreg;
+		reg_num_type reg_noA = 0;
+		reg_num_type reg_noB = 0;
+
+		DECODE_LEB128_UWORD(instr_ptr, lreg);
+		reg_noA = (reg_num_type) lreg;
+
+		ERROR_IF_REG_NUM_TOO_HIGH(reg_noA, reg_count);
+
+		DECODE_LEB128_UWORD(instr_ptr, lreg);
+		reg_noB = (reg_num_type) lreg;
+
+		if (reg_noB > reg_count) {
+		    SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH);
+		}
+
+
+		localregtab[reg_noA].ru_is_off = 0;
+		localregtab[reg_noA].ru_value_type = DW_EXPR_OFFSET;
+		localregtab[reg_noA].ru_register = reg_noB;
+		localregtab[reg_noA].ru_offset_or_block_len = 0;
+
+		fp_register = reg_noA;
+		fp_offset = reg_noB;
+		break;
+	    }
+
+	case DW_CFA_remember_state:
+	    {
+		stack_table = (Dwarf_Frame)
+		    _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
+		if (stack_table == NULL) {
+		    SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
+		}
+
+		for (i = 0; i < reg_count; i++)
+		    stack_table->fr_reg[i] = localregtab[i];
+
+		if (top_stack != NULL)
+		    stack_table->fr_next = top_stack;
+		top_stack = stack_table;
+
+		break;
+	    }
+
+	case DW_CFA_restore_state:
+	    {
+		if (top_stack == NULL) {
+		    SIMPLE_ERROR_RETURN(DW_DLE_DF_POP_EMPTY_STACK);
+		}
+		stack_table = top_stack;
+		top_stack = stack_table->fr_next;
+
+		for (i = 0; i < reg_count; i++)
+		    localregtab[i] = stack_table->fr_reg[i];
+
+		dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
+		break;
+	    }
+
+	case DW_CFA_def_cfa:
+	    {
+		Dwarf_Unsigned lreg;
+
+		DECODE_LEB128_UWORD(instr_ptr, lreg);
+		reg_no = (reg_num_type) lreg;
+
+		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+
+		factored_N_value =
+		    _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
+		instr_ptr += leb128_length;
+
+		if (need_augmentation) {
+		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+		}
+		cfa_reg.ru_is_off = 1;
+		cfa_reg.ru_value_type = DW_EXPR_OFFSET;
+		cfa_reg.ru_register = reg_no;
+		cfa_reg.ru_offset_or_block_len = factored_N_value;
+
+		fp_register = reg_no;
+		fp_offset = factored_N_value;
+		break;
+	    }
+
+	case DW_CFA_def_cfa_register:
+	    {
+		Dwarf_Unsigned lreg;
+
+		DECODE_LEB128_UWORD(instr_ptr, lreg);
+		reg_no = (reg_num_type) lreg;
+		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+
+		cfa_reg.ru_register = reg_no;
+		/* Do NOT set ru_offset_or_block_len or ru_is_off here. 
+		   See dwarf2/3 spec.  */
+		fp_register = reg_no;
+		break;
+	    }
+
+	case DW_CFA_def_cfa_offset:
+	    {
+		factored_N_value =
+		    _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
+		instr_ptr += leb128_length;
+
+		if (need_augmentation) {
+		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+		}
+		/* Do set ru_is_off here, as here factored_N_value
+		   counts.  */
+		cfa_reg.ru_is_off = 1;
+		cfa_reg.ru_value_type = DW_EXPR_OFFSET;
+		cfa_reg.ru_offset_or_block_len = factored_N_value;
+
+		fp_offset = factored_N_value;
+		break;
+	    }
+	case DW_CFA_nop:
+	    {
+		break;
+	    }
+	    /* DWARF3 ops begin here. */
+	case DW_CFA_def_cfa_expression:
+	    {
+		/* A single DW_FORM_block representing a dwarf
+		   expression. The form block establishes the way to
+		   compute the CFA. */
+		Dwarf_Unsigned block_len = 0;
+
+		DECODE_LEB128_UWORD(instr_ptr, block_len);
+		cfa_reg.ru_is_off = 0;	/* arbitrary */
+		cfa_reg.ru_value_type = DW_EXPR_EXPRESSION;
+		cfa_reg.ru_offset_or_block_len = block_len;
+		cfa_reg.ru_block = instr_ptr;
+		fp_offset = (Dwarf_Unsigned) instr_ptr;
+
+	    }
+	    break;
+	case DW_CFA_expression:
+	    {
+		/* An unsigned leb128 value is the first operand (a
+		   register number). The second operand is single
+		   DW_FORM_block representing a dwarf expression. The
+		   evaluator pushes the CFA on the evaluation stack
+		   then evaluates the expression to compute the value
+		   of the register contents. */
+		Dwarf_Unsigned lreg = 0;
+		Dwarf_Unsigned block_len = 0;
+
+		DECODE_LEB128_UWORD(instr_ptr, lreg);
+		reg_no = (reg_num_type) lreg;
+		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+		DECODE_LEB128_UWORD(instr_ptr, block_len);
+		localregtab[lreg].ru_is_off = 0;	/* arbitrary */
+		localregtab[lreg].ru_value_type = DW_EXPR_EXPRESSION;
+		localregtab[lreg].ru_offset_or_block_len = block_len;
+		localregtab[lreg].ru_block = instr_ptr;
+		fp_offset = (Dwarf_Unsigned) instr_ptr;
+		fp_register = reg_no;
+
+	    }
+	    break;
+	case DW_CFA_cfa_offset_extended_sf:
+	    {
+		/* The first operand is an unsigned leb128 register
+		   number. The second is a signed factored offset.
+		   Identical to DW_CFA_offset_extended except the
+		   secondoperand is signed */
+		Dwarf_Unsigned lreg;
+
+		DECODE_LEB128_UWORD(instr_ptr, lreg);
+		reg_no = (reg_num_type) lreg;
+		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+		signed_factored_N_value =
+		    _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
+		instr_ptr += leb128_length;
+
+		if (need_augmentation) {
+		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+		}
+		localregtab[reg_no].ru_is_off = 1;
+		localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
+		localregtab[reg_no].ru_register = reg_num_of_cfa;
+		localregtab[reg_no].ru_offset_or_block_len =
+		    signed_factored_N_value * data_alignment_factor;
+
+		fp_register = reg_no;
+		fp_offset = signed_factored_N_value;
+	    }
+	    break;
+	case DW_CFA_def_cfa_sf:
+	    {
+		/* The first operand is an unsigned leb128 register
+		   number. The second is a signed leb128 factored
+		   offset. Identical to DW_CFA_def_cfa except that the
+		   second operand is signed and factored. */
+		Dwarf_Unsigned lreg;
+
+		DECODE_LEB128_UWORD(instr_ptr, lreg);
+		reg_no = (reg_num_type) lreg;
+		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+
+		signed_factored_N_value =
+		    _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
+		instr_ptr += leb128_length;
+
+		if (need_augmentation) {
+		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+		}
+		cfa_reg.ru_is_off = 1;
+		cfa_reg.ru_value_type = DW_EXPR_OFFSET;
+		cfa_reg.ru_register = reg_no;
+		cfa_reg.ru_offset_or_block_len =
+		    signed_factored_N_value * data_alignment_factor;
+
+		fp_register = reg_no;
+		fp_offset = signed_factored_N_value;
+	    }
+	    break;
+	case DW_CFA_def_cfa_offset_sf:
+	    {
+		/* The operand is a signed leb128 operand representing
+		   a factored offset.  Identical to
+		   DW_CFA_def_cfa_offset excep the operand is signed
+		   and factored. */
+
+		signed_factored_N_value =
+		    _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
+		instr_ptr += leb128_length;
+
+		if (need_augmentation) {
+		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+		}
+		/* Do set ru_is_off here, as here factored_N_value
+		   counts.  */
+		cfa_reg.ru_is_off = 1;
+		cfa_reg.ru_value_type = DW_EXPR_OFFSET;
+		cfa_reg.ru_offset_or_block_len =
+		    signed_factored_N_value * data_alignment_factor;
+
+		fp_offset = signed_factored_N_value;
+	    }
+	    break;
+	case DW_CFA_val_offset:
+	    {
+		/* The first operand is an unsigned leb128 register
+		   number. The second is a factored unsigned offset.
+		   Makes the register be a val_offset(N) rule with N =
+		   factored_offset*data_alignment_factor. */
+
+		Dwarf_Unsigned lreg;
+
+		DECODE_LEB128_UWORD(instr_ptr, lreg);
+		reg_no = (reg_num_type) lreg;
+
+		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+
+		factored_N_value =
+		    _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
+		instr_ptr += leb128_length;
+
+		if (need_augmentation) {
+		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+		}
+		/* Do set ru_is_off here, as here factored_N_value
+		   counts.  */
+		localregtab[reg_no].ru_is_off = 1;
+		localregtab[reg_no].ru_register = reg_num_of_cfa;
+		localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET;
+		localregtab[reg_no].ru_offset_or_block_len =
+		    factored_N_value * data_alignment_factor;
+
+		fp_offset = factored_N_value;
+		break;
+	    }
+	case DW_CFA_val_offset_sf:
+	    {
+		/* The first operand is an unsigned leb128 register
+		   number. The second is a factored signed offset.
+		   Makes the register be a val_offset(N) rule with N =
+		   factored_offset*data_alignment_factor. */
+		Dwarf_Unsigned lreg;
+
+		DECODE_LEB128_UWORD(instr_ptr, lreg);
+		reg_no = (reg_num_type) lreg;
+
+		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+		signed_factored_N_value =
+		    _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
+		instr_ptr += leb128_length;
+
+		if (need_augmentation) {
+		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
+		}
+		/* Do set ru_is_off here, as here factored_N_value
+		   counts.  */
+		localregtab[reg_no].ru_is_off = 1;
+		localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET;
+		localregtab[reg_no].ru_offset_or_block_len =
+		    signed_factored_N_value * data_alignment_factor;
+
+		fp_offset = signed_factored_N_value;
+
+	    }
+	    break;
+	case DW_CFA_val_expression:
+	    {
+		/* The first operand is an unsigned leb128 register
+		   number. The second is a DW_FORM_block representing a 
+		   DWARF expression. The rule for the register number
+		   becomes a val_expression(E) rule. */
+		Dwarf_Unsigned lreg = 0;
+		Dwarf_Unsigned block_len = 0;
+
+		DECODE_LEB128_UWORD(instr_ptr, lreg);
+		reg_no = (reg_num_type) lreg;
+		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
+		DECODE_LEB128_UWORD(instr_ptr, block_len);
+		localregtab[lreg].ru_is_off = 0;	/* arbitrary */
+		localregtab[lreg].ru_value_type = DW_EXPR_VAL_EXPRESSION;
+		localregtab[lreg].ru_offset_or_block_len = block_len;
+		localregtab[lreg].ru_block = instr_ptr;
+		fp_offset = (Dwarf_Unsigned) instr_ptr;
+
+                instr_ptr += block_len;
+		fp_register = reg_no;
+
+	    }
+	    break;
+
+	    /* END DWARF3 new ops. */
+
+
+#ifdef DW_CFA_GNU_window_save
+	case DW_CFA_GNU_window_save:
+	    {
+		/* no information: this just tells unwinder to restore
+		   the window registers from the previous frame's
+		   window save area */
+		break;
+	    }
+#endif
+#ifdef  DW_CFA_GNU_args_size
+	    /* single uleb128 is the current arg area size in bytes. No 
+	       register exists yet to save this in */
+	case DW_CFA_GNU_args_size:
+	    {
+		Dwarf_Unsigned lreg;
+
+		DECODE_LEB128_UWORD(instr_ptr, lreg);
+		reg_no = (reg_num_type) lreg;
+
+		break;
+	    }
+#endif
+	default:
+	    /* ERROR, we have an opcode we know nothing about. Memory
+	       leak here, but an error like this is not supposed to
+	       happen so we ignore the leak. These used to be ignored,
+	       now we notice and report. */
+	    SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR);
+
+	}
+
+	if (make_instr) {
+	    instr_count++;
+
+	    curr_instr = (Dwarf_Frame_Op *)
+		_dwarf_get_alloc(dbg, DW_DLA_FRAME_OP, 1);
+	    if (curr_instr == NULL) {
+		SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
+	    }
+
+	    curr_instr->fp_base_op = fp_base_op;
+	    curr_instr->fp_extended_op = fp_extended_op;
+	    curr_instr->fp_register = fp_register;
+	    curr_instr->fp_offset = fp_offset;
+	    curr_instr->fp_instr_offset = fp_instr_offset;
+
+	    curr_instr_item = (Dwarf_Chain)
+		_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+	    if (curr_instr_item == NULL) {
+		SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
+	    }
+
+	    curr_instr_item->ch_item = curr_instr;
+	    if (head_instr_chain == NULL)
+		head_instr_chain = tail_instr_chain = curr_instr_item;
+	    else {
+		tail_instr_chain->ch_next = curr_instr_item;
+		tail_instr_chain = curr_instr_item;
+	    }
+	}
+    }
+
+    /* 
+       If frame instruction decoding was right we would stop exactly at 
+       final_instr_ptr. */
+    if (instr_ptr > final_instr_ptr) {
+	SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR);
+    }
+
+    /* Create the last row generated.  */
+    if (table != NULL) {
+
+	struct Dwarf_Reg_Rule_s *t2reg = table->fr_reg;
+	struct Dwarf_Reg_Rule_s *t3reg = localregtab;
+	struct Dwarf_Reg_Rule_s *t3end = t3reg + reg_count;
+
+	table->fr_loc = current_loc;
+	for (; t3reg < t3end; t3reg++, t2reg++) {
+	    *t2reg = *t3reg;
+	}
+
+	/* CONSTCOND */
+	if (reg_num_of_cfa < reg_count) {
+	    t2reg = table->fr_reg + reg_num_of_cfa;
+	    /* Update both the old DW_FRAME_CFA_COL row and the new
+	       fr_cfa_rule with the cfa_reg, this is the old-style
+	       update. */
+	    *t2reg = cfa_reg;
+	}
+	table->fr_cfa_rule = cfa_reg;
+    }
+
+    /* Dealloc anything remaining on stack. */
+    for (; top_stack != NULL;) {
+	stack_table = top_stack;
+	top_stack = top_stack->fr_next;
+	dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
+    }
+
+    if (make_instr) {
+	/* Allocate list of pointers to Dwarf_Frame_Op's.  */
+	head_instr_block = (Dwarf_Frame_Op *)
+	    _dwarf_get_alloc(dbg, DW_DLA_FRAME_BLOCK, instr_count);
+	if (head_instr_block == NULL) {
+	    SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
+	}
+
+	/* 
+	   Store pointers to Dwarf_Frame_Op's in this list and
+	   deallocate the structs that chain the Dwarf_Frame_Op's. */
+	curr_instr_item = head_instr_chain;
+	for (i = 0; i < instr_count; i++) {
+	    *(head_instr_block + i) =
+		*(Dwarf_Frame_Op *) curr_instr_item->ch_item;
+	    dealloc_instr_item = curr_instr_item;
+	    curr_instr_item = curr_instr_item->ch_next;
+	    dwarf_dealloc(dbg, dealloc_instr_item->ch_item,
+			  DW_DLA_FRAME_OP);
+	    dwarf_dealloc(dbg, dealloc_instr_item, DW_DLA_CHAIN);
+	}
+	*ret_frame_instr = head_instr_block;
+
+	*returned_count = (Dwarf_Sword) instr_count;
+    } else {
+	*returned_count = 0;
+    }
+    free(localregtab);
+    return DW_DLV_OK;
+#undef ERROR_IF_REG_NUM_TOO_HIGH
+#undef SIMPLE_ERROR_RETURN
+}
+
+/*  Depending on version, either read the return address register
+    as a ubyte or as an leb number.
+    The form of this value changed for DWARF3.
+*/
+Dwarf_Unsigned
+_dwarf_get_return_address_reg(Dwarf_Small * frame_ptr,
+			      int version, unsigned long *size)
+{
+    Dwarf_Unsigned uvalue = 0;
+    Dwarf_Word leb128_length = 0;
+
+    if (version == 1) {
+	*size = 1;
+	uvalue = *(unsigned char *) frame_ptr;
+	return uvalue;
+    }
+    uvalue = _dwarf_decode_u_leb128(frame_ptr, &leb128_length);
+    *size = leb128_length;
+    return uvalue;
+}
+
+
+/* Trivial consumer function. 
+*/
+int
+dwarf_get_cie_of_fde(Dwarf_Fde fde,
+		     Dwarf_Cie * cie_returned, Dwarf_Error * error)
+{
+    if (fde == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_FDE_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *cie_returned = fde->fd_cie;
+    return DW_DLV_OK;
+
+}
+
+/*
+  For g++ .eh_frame fde and cie.
+  the cie id is different as the
+  definition of the cie_id in an fde
+	is the distance back from the address of the
+	value to the cie.
+  Or 0 if this is a true cie.
+  Non standard dwarf, designed this way to be
+  convenient at run time for an allocated 
+  (mapped into memory as part of the running image) section.
+*/
+int
+dwarf_get_fde_list_eh(Dwarf_Debug dbg,
+		      Dwarf_Cie ** cie_data,
+		      Dwarf_Signed * cie_element_count,
+		      Dwarf_Fde ** fde_data,
+		      Dwarf_Signed * fde_element_count,
+		      Dwarf_Error * error)
+{
+    int res;
+
+    res =
+	_dwarf_load_section(dbg,
+			    dbg->de_debug_frame_eh_gnu_index,
+			    &dbg->de_debug_frame_eh_gnu, error);
+
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+
+    res =
+	_dwarf_get_fde_list_internal(dbg,
+				     cie_data,
+				     cie_element_count,
+				     fde_data,
+				     fde_element_count,
+				     dbg->de_debug_frame_eh_gnu,
+				     dbg->de_debug_frame_eh_gnu_index,
+				     dbg->de_debug_frame_size_eh_gnu,
+				     /* cie_id_value */ 0,
+				     /* use_gnu_cie_calc= */ 1,
+				     error);
+    return res;
+}
+
+
+
+/*
+  For standard dwarf .debug_frame
+  cie_id is -1  in a cie, and
+  is the section offset in the .debug_frame section
+  of the cie otherwise.  Standard dwarf
+*/
+int
+dwarf_get_fde_list(Dwarf_Debug dbg,
+		   Dwarf_Cie ** cie_data,
+		   Dwarf_Signed * cie_element_count,
+		   Dwarf_Fde ** fde_data,
+		   Dwarf_Signed * fde_element_count,
+		   Dwarf_Error * error)
+{
+    int res;
+
+    res =
+	_dwarf_load_section(dbg,
+			    dbg->de_debug_frame_index,
+			    &dbg->de_debug_frame, error);
+
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+
+    res =
+	_dwarf_get_fde_list_internal(dbg, cie_data,
+				     cie_element_count,
+				     fde_data,
+				     fde_element_count,
+				     dbg->de_debug_frame,
+				     dbg->de_debug_frame_index,
+				     dbg->de_debug_frame_size,
+				     DW_CIE_ID,
+				     /* use_gnu_cie_calc= */ 0,
+				     error);
+
+    return res;
+}
+
+
+/*
+   Only works on dwarf sections, not eh_frame
+   Given a Dwarf_Die, see if it has a
+   DW_AT_MIPS_fde attribute and if so use that
+   to get an fde offset.
+   Then create a Dwarf_Fde to return thru the ret_fde pointer.
+   Also creates a cie (pointed at from the Dwarf_Fde).
+*/
+int
+dwarf_get_fde_for_die(Dwarf_Debug dbg,
+		      Dwarf_Die die,
+		      Dwarf_Fde * ret_fde, Dwarf_Error * error)
+{
+    Dwarf_Attribute attr;
+    Dwarf_Unsigned fde_offset = 0;
+    Dwarf_Signed signdval = 0;
+    Dwarf_Fde new_fde = 0;
+    unsigned char *fde_ptr = 0;
+    unsigned char *cie_ptr = 0;
+    Dwarf_Unsigned cie_id = 0;
+
+    /* Fields for the current Cie being read. */
+    int res;
+    int resattr;
+    int sdatares;
+
+    struct cie_fde_prefix_s prefix;
+    struct cie_fde_prefix_s prefix_c;
+
+    if (die == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DIE_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    resattr = dwarf_attr(die, DW_AT_MIPS_fde, &attr, error);
+    if (resattr != DW_DLV_OK) {
+	return resattr;
+    }
+
+    /* why is this formsdata? FIX */
+    sdatares = dwarf_formsdata(attr, &signdval, error);
+    if (sdatares != DW_DLV_OK) {
+	return sdatares;
+    }
+
+    res =
+	_dwarf_load_section(dbg,
+			    dbg->de_debug_frame_index,
+			    &dbg->de_debug_frame, error);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+
+    fde_offset = signdval;
+    fde_ptr = (dbg->de_debug_frame + fde_offset);
+
+
+    /* First read in the 'common prefix' to figure out what * we are to 
+       do with this entry. */
+    memset(&prefix_c, 0, sizeof(prefix_c));
+    memset(&prefix, 0, sizeof(prefix));
+    res = dwarf_read_cie_fde_prefix(dbg, fde_ptr,
+				    dbg->de_debug_frame,
+				    dbg->de_debug_frame_index,
+				    dbg->de_debug_frame_size, &prefix,
+				    error);
+    if (res == DW_DLV_ERROR) {
+	return res;
+    }
+    if (res == DW_DLV_NO_ENTRY)
+	return res;
+    fde_ptr = prefix.cf_addr_after_prefix;
+    cie_id = prefix.cf_cie_id;
+    /* Pass NULL, not section pointer, for 3rd argument. de_debug_frame 
+       has no eh_frame relevance. */
+    res = dwarf_create_fde_from_after_start(dbg, &prefix,
+					    (Dwarf_Small *) NULL,
+					    fde_ptr,
+					    /* use_gnu_cie_calc= */ 0,
+					    /* Dwarf_Cie = */ 0,
+					    &new_fde, error);
+
+    if (res == DW_DLV_ERROR) {
+	return res;
+    } else if (res == DW_DLV_NO_ENTRY) {
+	return res;
+    }
+    /* DW_DLV_OK */
+
+    /* now read the cie corresponding to the fde */
+    cie_ptr = new_fde->fd_section_ptr + cie_id;
+    res = dwarf_read_cie_fde_prefix(dbg, cie_ptr,
+				    dbg->de_debug_frame,
+				    dbg->de_debug_frame_index,
+				    dbg->de_debug_frame_size,
+				    &prefix_c, error);
+    if (res == DW_DLV_ERROR) {
+	return res;
+    }
+    if (res == DW_DLV_NO_ENTRY)
+	return res;
+
+    cie_ptr = prefix_c.cf_addr_after_prefix;
+    cie_id = prefix_c.cf_cie_id;
+
+
+    if (cie_id == DW_CIE_ID) {
+	int res2 = 0;
+	Dwarf_Cie new_cie = 0;
+
+	/* Pass NULL, not section pointer, for 3rd argument.
+	   de_debug_frame has no eh_frame relevance. */
+	res2 = dwarf_create_cie_from_after_start(dbg,
+						 &prefix_c,
+						 (Dwarf_Small *) NULL,
+						 cie_ptr,
+						 /* cie_count= */ 0,
+						 /* use_gnu_cie_calc= */
+						 0, &new_cie, error);
+	if (res2 == DW_DLV_ERROR) {
+	    dwarf_dealloc(dbg, new_fde, DW_DLA_FDE);
+	    return res;
+	} else if (res2 == DW_DLV_NO_ENTRY) {
+	    dwarf_dealloc(dbg, new_fde, DW_DLA_FDE);
+	    return res;
+	}
+
+
+	new_fde->fd_cie = new_cie;
+
+    } else {
+	_dwarf_error(dbg, error, DW_DLE_NO_CIE_FOR_FDE);
+	return (DW_DLV_ERROR);
+    }
+
+    *ret_fde = new_fde;
+    return DW_DLV_OK;
+}
+
+/* A dwarf consumer operation, see the consumer library documentation.
+*/
+int
+dwarf_get_fde_range(Dwarf_Fde fde,
+		    Dwarf_Addr * low_pc,
+		    Dwarf_Unsigned * func_length,
+		    Dwarf_Ptr * fde_bytes,
+		    Dwarf_Unsigned * fde_byte_length,
+		    Dwarf_Off * cie_offset,
+		    Dwarf_Signed * cie_index,
+		    Dwarf_Off * fde_offset, Dwarf_Error * error)
+{
+    Dwarf_Debug dbg;
+
+    if (fde == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_FDE_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    dbg = fde->fd_dbg;
+    if (dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+
+    /* We have always already done the section load here, so no need to 
+       load the section. We did the section load in order to create the 
+       Dwarf_Fde pointer passed in here. */
+
+
+    if (low_pc != NULL)
+	*low_pc = fde->fd_initial_location;
+    if (func_length != NULL)
+	*func_length = fde->fd_address_range;
+    if (fde_bytes != NULL)
+	*fde_bytes = fde->fd_fde_start;
+    if (fde_byte_length != NULL)
+	*fde_byte_length = fde->fd_length;
+    if (cie_offset != NULL)
+	*cie_offset = fde->fd_cie_offset;
+    if (cie_index != NULL)
+	*cie_index = fde->fd_cie_index;
+    if (fde_offset != NULL)
+	*fde_offset = fde->fd_fde_start - fde->fd_section_ptr;
+
+    return DW_DLV_OK;
+}
+
+/* IRIX specific function.   The exception tables
+   have C++ destructor information and are
+   at present undocumented.  */
+int
+dwarf_get_fde_exception_info(Dwarf_Fde fde,
+			     Dwarf_Signed *
+			     offset_into_exception_tables,
+			     Dwarf_Error * error)
+{
+    Dwarf_Debug dbg;
+
+    dbg = fde->fd_dbg;
+    if (dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+    *offset_into_exception_tables =
+	fde->fd_offset_into_exception_tables;
+    return DW_DLV_OK;
+}
+
+
+/* A consumer code function.
+   Given a CIE pointer, return the normal CIE data thru
+   pointers.
+   Special augmentation data is not returned here.
+*/
+int
+dwarf_get_cie_info(Dwarf_Cie cie,
+		   Dwarf_Unsigned * bytes_in_cie,
+		   Dwarf_Small * ptr_to_version,
+		   char **augmenter,
+		   Dwarf_Unsigned * code_alignment_factor,
+		   Dwarf_Signed * data_alignment_factor,
+		   Dwarf_Half * return_address_register,
+		   Dwarf_Ptr * initial_instructions,
+		   Dwarf_Unsigned * initial_instructions_length,
+		   Dwarf_Error * error)
+{
+    Dwarf_Debug dbg;
+
+    if (cie == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_CIE_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    dbg = cie->ci_dbg;
+    if (dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_CIE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    if (ptr_to_version != NULL)
+	*ptr_to_version = cie->ci_cie_version_number;
+    if (augmenter != NULL)
+	*augmenter = cie->ci_augmentation;
+    if (code_alignment_factor != NULL)
+	*code_alignment_factor = cie->ci_code_alignment_factor;
+    if (data_alignment_factor != NULL)
+	*data_alignment_factor = cie->ci_data_alignment_factor;
+    if (return_address_register != NULL)
+	*return_address_register = cie->ci_return_address_register;
+    if (initial_instructions != NULL)
+	*initial_instructions = cie->ci_cie_instr_start;
+    if (initial_instructions_length != NULL) {
+	*initial_instructions_length = cie->ci_length +
+	    cie->ci_length_size +
+	    cie->ci_extension_size -
+	    (cie->ci_cie_instr_start - cie->ci_cie_start);
+
+    }
+    *bytes_in_cie = (cie->ci_length);
+    return (DW_DLV_OK);
+}
+
+/* Return the register rules for all registers at a given pc. 
+*/
+static int
+_dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde,
+				 Dwarf_Addr pc_requested,
+				 Dwarf_Frame table,
+				 Dwarf_Half cfa_reg_col_num,
+				 Dwarf_Error * error)
+{
+    Dwarf_Debug dbg = 0;
+    Dwarf_Cie cie = 0;
+    int dw_err = 0;
+    Dwarf_Sword icount = 0;
+    int res = 0;
+
+    if (fde == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_FDE_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    dbg = fde->fd_dbg;
+    if (dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    if (pc_requested < fde->fd_initial_location ||
+	pc_requested >=
+	fde->fd_initial_location + fde->fd_address_range) {
+	_dwarf_error(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
+	return (DW_DLV_ERROR);
+    }
+
+    cie = fde->fd_cie;
+    if (cie->ci_initial_table == NULL) {
+	cie->ci_initial_table = _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
+
+	if (cie->ci_initial_table == NULL) {
+	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	    return (DW_DLV_ERROR);
+	}
+	_dwarf_init_regrule_table(cie->ci_initial_table->fr_reg,
+				  dbg->de_frame_reg_rules_entry_count,
+				  dbg->de_frame_rule_initial_value);
+	_dwarf_init_regrule_table(&cie->ci_initial_table->fr_cfa_rule,
+				  1, dbg->de_frame_rule_initial_value);
+	res = _dwarf_exec_frame_instr( /* make_instr= */ false,
+				      /* ret_frame_instr= */ NULL,
+				      /* search_pc */ false,
+				      /* search_pc_val */ 0,
+				      /* location */ 0,
+				      cie->ci_cie_instr_start,
+				      cie->ci_cie_instr_start +
+				      (cie->ci_length +
+				       cie->ci_length_size +
+				       cie->ci_extension_size -
+				       (cie->ci_cie_instr_start -
+					cie->ci_cie_start)),
+				      cie->ci_initial_table, cie, dbg,
+				      cfa_reg_col_num, &icount,
+				      &dw_err);
+	if (res == DW_DLV_ERROR) {
+	    _dwarf_error(dbg, error, dw_err);
+	    return (res);
+	} else if (res == DW_DLV_NO_ENTRY) {
+	    return res;
+	}
+    }
+
+    {
+	Dwarf_Small *instr_end = fde->fd_fde_instr_start +
+	    fde->fd_length +
+	    fde->fd_length_size +
+	    fde->fd_extension_size - (fde->fd_fde_instr_start -
+				      fde->fd_fde_start);
+
+	res = _dwarf_exec_frame_instr( /* make_instr= */ false,
+				      /* ret_frame_instr= */ NULL,
+				      /* search_pc */ true,
+				      /* search_pc_val */ pc_requested,
+				      fde->fd_initial_location,
+				      fde->fd_fde_instr_start,
+				      instr_end,
+				      table,
+				      cie, dbg,
+				      cfa_reg_col_num, &icount,
+				      &dw_err);
+    }
+    if (res == DW_DLV_ERROR) {
+	_dwarf_error(dbg, error, dw_err);
+	return (res);
+    } else if (res == DW_DLV_NO_ENTRY) {
+	return res;
+    }
+
+    return DW_DLV_OK;
+}
+
+/* A consumer call for efficiently getting the register info
+   for all registers in one call.
+
+   The output table rules array is size DW_REG_TABLE_SIZE.
+   The frame info  rules array in fde_table is of size
+   DW_REG_TABLE_SIZE too.
+
+   This interface  really only works well with MIPS/IRIX
+   where DW_FRAME_CFA_COL is zero (in that case it's safe).
+
+   It is also restricted to the case  where
+   DW_REG_TABLE_SIZE == DW_FRAME_LAST_REG_NUM  ==
+   dbg->de_frame_reg_rules_entry_count (true for MIPS/IRIX).
+   If this condition is not met calling this routine can result in
+   incorrect output or in memory corruption.
+
+*/
+int
+dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde,
+				Dwarf_Addr pc_requested,
+				Dwarf_Regtable * reg_table,
+				Dwarf_Addr * row_pc,
+				Dwarf_Error * error)
+{
+
+    /* Table size: DW_REG_TABLE_SIZE */
+    struct Dwarf_Frame_s fde_table;
+    Dwarf_Sword i = 0;
+    struct Dwarf_Reg_Rule_s *rule = NULL;
+    struct Dwarf_Regtable_Entry_s *out_rule = NULL;
+    int res = 0;
+    Dwarf_Debug dbg = 0;
+
+    /* For this interface the size is fixed at compile time. */
+    int output_table_real_data_size = DW_REG_TABLE_SIZE;
+
+    FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
+
+    res = dwarf_initialize_fde_table(dbg, &fde_table,
+				     output_table_real_data_size,
+				     error);
+    if (res != DW_DLV_OK)
+	return res;
+
+
+
+    /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks 
+     */
+    res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested,
+					   &fde_table,
+					   DW_FRAME_CFA_COL, error);
+    if (res != DW_DLV_OK) {
+	dwarf_free_fde_table(&fde_table);
+	return res;
+    }
+
+    out_rule = &reg_table->rules[0];
+    rule = &fde_table.fr_reg[0];
+    for (i = 0; i < output_table_real_data_size;
+	 i++, ++out_rule, ++rule) {
+	out_rule->dw_offset_relevant = rule->ru_is_off;
+	out_rule->dw_value_type = rule->ru_value_type;
+	out_rule->dw_regnum = rule->ru_register;
+	out_rule->dw_offset = rule->ru_offset_or_block_len;
+    }
+    for (; i < DW_REG_TABLE_SIZE; ++i, ++out_rule) {
+	out_rule->dw_offset_relevant = 0;
+	out_rule->dw_value_type = DW_EXPR_OFFSET;
+	out_rule->dw_regnum = DW_FRAME_UNDEFINED_VAL;
+	out_rule->dw_offset = 0;
+    }
+
+    /* The test is just in case it's not inside the table. For non-MIPS 
+       it could be outside the table and that is just fine, it was
+       really a mistake to put it in the table in 1993.  */
+    /* CONSTCOND */
+    if (DW_FRAME_CFA_COL < DW_REG_TABLE_SIZE) {
+	out_rule = &reg_table->rules[DW_FRAME_CFA_COL];
+	out_rule->dw_offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
+	out_rule->dw_value_type = fde_table.fr_cfa_rule.ru_value_type;
+	out_rule->dw_regnum = fde_table.fr_cfa_rule.ru_register;
+	out_rule->dw_offset =
+	    fde_table.fr_cfa_rule.ru_offset_or_block_len;
+    }
+
+    if (row_pc != NULL)
+	*row_pc = fde_table.fr_loc;
+    dwarf_free_fde_table(&fde_table);
+    return DW_DLV_OK;
+}
+
+/* A consumer call for efficiently getting the register info
+   for all registers in one call.
+
+   The output table rules array is size output_table_real_data_size.
+   (normally  DW_REG_TABLE_SIZE).
+   The frame info  rules array in fde_table is normally of size
+   DW_FRAME_LAST_REG_NUM.
+*/
+int
+dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde,
+				 Dwarf_Addr pc_requested,
+				 Dwarf_Regtable3 * reg_table,
+				 Dwarf_Addr * row_pc,
+				 Dwarf_Error * error)
+{
+
+    struct Dwarf_Frame_s fde_table;
+    Dwarf_Sword i = 0;
+    int res = 0;
+    struct Dwarf_Reg_Rule_s *rule = NULL;
+    struct Dwarf_Regtable_Entry3_s *out_rule = NULL;
+    Dwarf_Debug dbg = 0;
+    int output_table_real_data_size = reg_table->rt3_reg_table_size;
+
+    FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
+
+    output_table_real_data_size =
+	MIN(output_table_real_data_size,
+	    dbg->de_frame_reg_rules_entry_count);
+
+    res = dwarf_initialize_fde_table(dbg, &fde_table,
+				     output_table_real_data_size,
+				     error);
+
+    /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks 
+     */
+    res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested,
+					   &fde_table,
+					   DW_FRAME_CFA_COL3, error);
+    if (res != DW_DLV_OK) {
+	dwarf_free_fde_table(&fde_table);
+	return res;
+    }
+
+    out_rule = &reg_table->rt3_rules[0];
+    rule = &fde_table.fr_reg[0];
+    for (i = 0; i < output_table_real_data_size;
+	 i++, ++out_rule, ++rule) {
+	out_rule->dw_offset_relevant = rule->ru_is_off;
+	out_rule->dw_value_type = rule->ru_value_type;
+	out_rule->dw_regnum = rule->ru_register;
+	out_rule->dw_offset_or_block_len = rule->ru_offset_or_block_len;
+	out_rule->dw_block_ptr = rule->ru_block;
+    }
+    for (; i < reg_table->rt3_reg_table_size; i++, ++out_rule) {
+	out_rule->dw_offset_relevant = 0;
+	out_rule->dw_value_type = DW_EXPR_OFFSET;
+	out_rule->dw_regnum = DW_FRAME_UNDEFINED_VAL;
+	out_rule->dw_offset_or_block_len = 0;
+	out_rule->dw_block_ptr = 0;
+    }
+    reg_table->rt3_cfa_rule.dw_offset_relevant =
+	fde_table.fr_cfa_rule.ru_is_off;
+    reg_table->rt3_cfa_rule.dw_value_type =
+	fde_table.fr_cfa_rule.ru_value_type;
+    reg_table->rt3_cfa_rule.dw_regnum =
+	fde_table.fr_cfa_rule.ru_register;
+    reg_table->rt3_cfa_rule.dw_offset_or_block_len =
+	fde_table.fr_cfa_rule.ru_offset_or_block_len;
+    reg_table->rt3_cfa_rule.dw_block_ptr =
+	fde_table.fr_cfa_rule.ru_block;
+
+    if (row_pc != NULL)
+	*row_pc = fde_table.fr_loc;
+
+    dwarf_free_fde_table(&fde_table);
+    return DW_DLV_OK;
+}
+
+
+/* Gets the register info for a single register at a given PC value
+   for the FDE specified.
+
+*/
+int
+dwarf_get_fde_info_for_reg(Dwarf_Fde fde,
+			   Dwarf_Half table_column,
+			   Dwarf_Addr pc_requested,
+			   Dwarf_Signed * offset_relevant,
+			   Dwarf_Signed * register_num,
+			   Dwarf_Signed * offset,
+			   Dwarf_Addr * row_pc, Dwarf_Error * error)
+{
+    struct Dwarf_Frame_s fde_table;
+    int res;
+    Dwarf_Debug dbg = 0;
+    int output_table_real_data_size = 0;
+
+    FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
+    output_table_real_data_size = dbg->de_frame_reg_rules_entry_count;
+
+    res = dwarf_initialize_fde_table(dbg, &fde_table,
+				     output_table_real_data_size,
+				     error);
+    if (res != DW_DLV_OK)
+	return res;
+
+
+    if (table_column >= output_table_real_data_size) {
+	dwarf_free_fde_table(&fde_table);
+	_dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
+	return (DW_DLV_ERROR);
+    }
+
+    /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks 
+     */
+    res =
+	_dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
+					 DW_FRAME_CFA_COL, error);
+    if (res != DW_DLV_OK) {
+	dwarf_free_fde_table(&fde_table);
+	return res;
+    }
+
+    if (fde_table.fr_reg[table_column].ru_value_type != DW_EXPR_OFFSET) {
+	dwarf_free_fde_table(&fde_table);
+	_dwarf_error(NULL, error,
+		     DW_DLE_FRAME_REGISTER_UNREPRESENTABLE);
+	return (DW_DLV_ERROR);
+    }
+
+    if (register_num != NULL)
+	*register_num = fde_table.fr_reg[table_column].ru_register;
+    if (offset != NULL)
+	*offset = fde_table.fr_reg[table_column].ru_offset_or_block_len;
+    if (row_pc != NULL)
+	*row_pc = fde_table.fr_loc;
+
+    *offset_relevant = (fde_table.fr_reg[table_column].ru_is_off);
+    dwarf_free_fde_table(&fde_table);
+    return DW_DLV_OK;
+}
+
+/* In this interface, table_column of DW_FRAME_CFA_COL
+   is not meaningful.
+   Use  dwarf_get_fde_info_for_cfa_reg3() to get the CFA.
+*/
+int
+dwarf_get_fde_info_for_reg3(Dwarf_Fde fde,
+			    Dwarf_Half table_column,
+			    Dwarf_Addr pc_requested,
+			    Dwarf_Small * value_type,
+			    Dwarf_Signed * offset_relevant,
+			    Dwarf_Signed * register_num,
+			    Dwarf_Signed * offset_or_block_len,
+			    Dwarf_Ptr * block_ptr,
+			    Dwarf_Addr * row_pc_out,
+			    Dwarf_Error * error)
+{
+    struct Dwarf_Frame_s fde_table;
+    int res = 0;
+
+    Dwarf_Debug dbg = 0;
+    int table_real_data_size = 0;
+
+    FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
+    table_real_data_size = dbg->de_frame_reg_rules_entry_count;
+    res = dwarf_initialize_fde_table(dbg, &fde_table,
+				     table_real_data_size, error);
+    if (res != DW_DLV_OK)
+	return res;
+    if (table_column >= table_real_data_size) {
+	dwarf_free_fde_table(&fde_table);
+	_dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
+	return (DW_DLV_ERROR);
+    }
+
+    /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks 
+     */
+    res =
+	_dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
+					 DW_FRAME_CFA_COL3, error);
+    if (res != DW_DLV_OK) {
+	dwarf_free_fde_table(&fde_table);
+	return res;
+    }
+
+    if (register_num != NULL)
+	*register_num = fde_table.fr_reg[table_column].ru_register;
+    if (offset_or_block_len != NULL)
+	*offset_or_block_len =
+	    fde_table.fr_reg[table_column].ru_offset_or_block_len;
+    if (row_pc_out != NULL)
+	*row_pc_out = fde_table.fr_loc;
+    if (block_ptr)
+	*block_ptr = fde_table.fr_reg[table_column].ru_block;
+
+    /* Without value_type the data cannot be understood, so we insist
+       on it being present, we don't test it. */
+    *value_type = fde_table.fr_reg[table_column].ru_value_type;
+    *offset_relevant = (fde_table.fr_reg[table_column].ru_is_off);
+    dwarf_free_fde_table(&fde_table);
+    return DW_DLV_OK;
+
+}
+
+/* For latest DWARF, this is the preferred interface.
+   It more portably deals with the  CFA by not
+   making the CFA a column number, which means
+   DW_FRAME_CFA_COL becomes an index like DW_CFA_SAME_VALUE,
+   a special value, not something one uses as an index.  */
+int
+dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde,
+				Dwarf_Addr pc_requested,
+				Dwarf_Small * value_type,
+				Dwarf_Signed * offset_relevant,
+				Dwarf_Signed * register_num,
+				Dwarf_Signed * offset_or_block_len,
+				Dwarf_Ptr * block_ptr,
+				Dwarf_Addr * row_pc_out,
+				Dwarf_Error * error)
+{
+    struct Dwarf_Frame_s fde_table;
+    int res;
+    Dwarf_Debug dbg = 0;
+
+    int table_real_data_size = 0;
+
+    FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
+
+    table_real_data_size = dbg->de_frame_reg_rules_entry_count;
+    res = dwarf_initialize_fde_table(dbg, &fde_table,
+				     table_real_data_size, error);
+    if (res != DW_DLV_OK)
+	return res;
+    res =
+	_dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
+					 DW_FRAME_CFA_COL3, error);
+    if (res != DW_DLV_OK) {
+	dwarf_free_fde_table(&fde_table);
+	return res;
+    }
+
+    if (register_num != NULL)
+	*register_num = fde_table.fr_cfa_rule.ru_register;
+    if (offset_or_block_len != NULL)
+	*offset_or_block_len =
+	    fde_table.fr_cfa_rule.ru_offset_or_block_len;
+    if (row_pc_out != NULL)
+	*row_pc_out = fde_table.fr_loc;
+    if (block_ptr)
+	*block_ptr = fde_table.fr_cfa_rule.ru_block;
+
+    /* Without value_type the data cannot be understood, so we insist
+       on it being present, we don't test it. */
+    *value_type = fde_table.fr_cfa_rule.ru_value_type;
+    *offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
+    dwarf_free_fde_table(&fde_table);
+    return DW_DLV_OK;
+}
+
+
+
+/*
+	Return pointer to the instructions in the dwarf
+	fde.
+*/
+int
+dwarf_get_fde_instr_bytes(Dwarf_Fde inFde, Dwarf_Ptr * outinstraddr,
+			  Dwarf_Unsigned * outaddrlen,
+			  Dwarf_Error * error)
+{
+    Dwarf_Unsigned len = 0;
+    unsigned char *instrs = 0;
+    Dwarf_Debug dbg = 0;
+
+    if (inFde == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_FDE_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    dbg = inFde->fd_dbg;
+    if (dbg == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_FDE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    instrs = inFde->fd_fde_instr_start;
+
+    len = (inFde->fd_fde_start + inFde->fd_length +
+	   inFde->fd_length_size + inFde->fd_extension_size) - instrs;
+
+    *outinstraddr = instrs;
+    *outaddrlen = len;
+    return DW_DLV_OK;
+}
+
+/* Allows getting an fde from its table via an index.  
+   With more error checking than simply indexing oneself.
+*/
+int
+dwarf_get_fde_n(Dwarf_Fde * fde_data,
+		Dwarf_Unsigned fde_index,
+		Dwarf_Fde * returned_fde, Dwarf_Error * error)
+{
+    Dwarf_Debug dbg = 0;
+
+    if (fde_data == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_FDE_PTR_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    FDE_NULL_CHECKS_AND_SET_DBG(*fde_data, dbg);
+
+    if (fde_index >= dbg->de_fde_count) {
+	return (DW_DLV_NO_ENTRY);
+    }
+    *returned_fde = (*(fde_data + fde_index));
+    return DW_DLV_OK;
+}
+
+
+/* 
+    Lopc and hipc are extensions to the interface to 
+    return the range of addresses that are described
+    by the returned fde.
+*/
+int
+dwarf_get_fde_at_pc(Dwarf_Fde * fde_data,
+		    Dwarf_Addr pc_of_interest,
+		    Dwarf_Fde * returned_fde,
+		    Dwarf_Addr * lopc,
+		    Dwarf_Addr * hipc, Dwarf_Error * error)
+{
+    Dwarf_Debug dbg = NULL;
+    Dwarf_Fde fde = NULL;
+    Dwarf_Fde entryfde = NULL;
+
+    if (fde_data == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_FDE_PTR_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    /* Assumes fde_data table has at least one entry. */
+    entryfde = *fde_data;
+    FDE_NULL_CHECKS_AND_SET_DBG(entryfde, dbg);
+
+    if (dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+    {
+	/* The fde's are sorted by their addresses. Binary search to
+	   find correct fde. */
+	Dwarf_Signed low = 0;
+	Dwarf_Signed high = dbg->de_fde_count - 1L;
+	Dwarf_Signed middle = 0;
+	Dwarf_Fde cur_fde;
+
+	while (low <= high) {
+	    middle = (low + high) / 2;
+	    cur_fde = fde_data[middle];
+	    if (pc_of_interest < cur_fde->fd_initial_location) {
+		high = middle - 1;
+	    } else if (pc_of_interest >=
+		       (cur_fde->fd_initial_location +
+			cur_fde->fd_address_range)) {
+		low = middle + 1;
+	    } else {
+		fde = fde_data[middle];
+		break;
+	    }
+	}
+    }
+
+    if (fde) {
+	if (lopc != NULL)
+	    *lopc = fde->fd_initial_location;
+	if (hipc != NULL)
+	    *hipc =
+		fde->fd_initial_location + fde->fd_address_range - 1;
+	*returned_fde = fde;
+	return (DW_DLV_OK);
+    }
+
+    return (DW_DLV_NO_ENTRY);
+}
+
+
+/* Expands a single frame instruction block
+   into a n array of Dwarf_Frame_Op-s.
+*/
+int
+dwarf_expand_frame_instructions(Dwarf_Debug dbg,
+				Dwarf_Ptr instruction,
+				Dwarf_Unsigned i_length,
+				Dwarf_Frame_Op ** returned_op_list,
+				Dwarf_Signed * returned_op_count,
+				Dwarf_Error * error)
+{
+    Dwarf_Sword instr_count;
+    int res;
+    int dw_err;
+
+    if (dbg == 0) {
+	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    if (returned_op_list == 0 || returned_op_count == 0) {
+	_dwarf_error(dbg, error, DW_DLE_RET_OP_LIST_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    /* The cast to Dwarf_Ptr may get a compiler warning, but it is safe 
+       as it is just an i_length offset from 'instruction' itself. A
+       caller has made a big mistake if the result is not a valid
+       pointer. */
+    res = _dwarf_exec_frame_instr( /* make_instr= */ true,
+				  returned_op_list,
+				  /* search_pc */ false,
+				  /* search_pc_val */ 0,
+				  /* location */ 0,
+				  instruction,
+				  (Dwarf_Ptr) ((Dwarf_Unsigned)
+					       instruction + i_length),
+				  /* Dwarf_Frame */ NULL,
+				  /* cie_ptr */ NULL,
+				  dbg,
+				  DW_FRAME_CFA_COL, &instr_count,
+				  &dw_err);
+    if (res != DW_DLV_OK) {
+	if (res == DW_DLV_ERROR) {
+	    _dwarf_error(dbg, error, dw_err);
+	}
+	return (res);
+    }
+
+    *returned_op_count = instr_count;
+    return DW_DLV_OK;
+}
+
+
+/* Used by dwarfdump -v to print offsets, for debugging
+   dwarf info.
+   The dwarf_ version is preferred over the obsolete _dwarf version.
+   _dwarf version kept for compatibility.
+*/
+/* ARGSUSED 4 */
+int
+_dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde,
+			  Dwarf_Off * fde_off, Dwarf_Off * cie_off,
+			  Dwarf_Error * err) 
+{
+  return _dwarf_fde_section_offset(dbg,in_fde,fde_off,
+     cie_off,err);
+}
+/* ARGSUSED 4 */
+int
+dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde,
+			  Dwarf_Off * fde_off, Dwarf_Off * cie_off,
+			  Dwarf_Error * err)
+{
+    char *start = 0;
+    char *loc = 0;
+
+
+
+    start = (char *) in_fde->fd_section_ptr;
+    loc = (char *) in_fde->fd_fde_start;
+
+    *fde_off = (loc - start);
+    *cie_off = in_fde->fd_cie_offset;
+    return DW_DLV_OK;
+}
+
+/* Used by dwarfdump -v to print offsets, for debugging
+   dwarf info.
+   The dwarf_ version is preferred over the obsolete _dwarf version.
+   _dwarf version kept for compatibility.
+*/
+/* ARGSUSED 4 */
+int
+_dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie,
+			  Dwarf_Off * cie_off, Dwarf_Error * err)
+{
+    return dwarf_cie_section_offset(dbg,in_cie,cie_off,err);
+}
+/* ARGSUSED 4 */
+int
+dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie,
+			  Dwarf_Off * cie_off, Dwarf_Error * err)
+{
+    char *start = 0;
+    char *loc = 0;
+
+    start = (char *) in_cie->ci_section_ptr;
+    loc = (char *) in_cie->ci_cie_start;
+
+    *cie_off = (loc - start);
+    return DW_DLV_OK;
+}
+
+/* Returns  a pointer to target-specific augmentation data thru augdata
+   and returns the length of the data thru augdata_len.
+
+   It's up to the consumer code to know how to interpret the bytes
+   of target-specific data (endian issues apply too, these
+   are just raw bytes pointed to).
+   See  Linux Standard Base Core Specification version 3.0 for
+   the details on .eh_frame info.
+
+   Returns DW_DLV_ERROR if fde is NULL or some other serious
+   error.
+   Returns DW_DLV_NO_ENTRY if there is no target-specific
+   augmentation data. 
+
+   The bytes pointed to are in the Dwarf_Cie, and as long as that
+   is valid the bytes are there. No 'dealloc' call is needed
+   for the bytes.
+*/
+int
+dwarf_get_cie_augmentation_data(Dwarf_Cie cie,
+				Dwarf_Small ** augdata,
+				Dwarf_Unsigned * augdata_len,
+				Dwarf_Error * error)
+{
+    if (cie == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_CIE_NULL);
+	return (DW_DLV_ERROR);
+    }
+    if (cie->ci_gnu_eh_augmentation_len == 0) {
+	return DW_DLV_NO_ENTRY;
+    }
+    *augdata = (Dwarf_Small *) (cie->ci_gnu_eh_augmentation_bytes);
+    *augdata_len = cie->ci_gnu_eh_augmentation_len;
+    return DW_DLV_OK;
+}
+
+
+/* Returns  a pointer to target-specific augmentation data thru augdata
+   and returns the length of the data thru augdata_len.
+
+   It's up to the consumer code to know how to interpret the bytes
+   of target-specific data (endian issues apply too, these
+   are just raw bytes pointed to).
+   See  Linux Standard Base Core Specification version 3.0 for
+   the details on .eh_frame info.
+
+   Returns DW_DLV_ERROR if fde is NULL or some other serious
+   error.
+   Returns DW_DLV_NO_ENTRY if there is no target-specific
+   augmentation data. 
+
+   The bytes pointed to are in the Dwarf_Fde, and as long as that
+   is valid the bytes are there. No 'dealloc' call is needed
+   for the bytes.
+
+*/
+int
+dwarf_get_fde_augmentation_data(Dwarf_Fde fde,
+				Dwarf_Small * *augdata,
+				Dwarf_Unsigned * augdata_len,
+				Dwarf_Error * error)
+{
+    Dwarf_Cie cie = 0;
+
+    if (fde == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_FDE_NULL);
+	return (DW_DLV_ERROR);
+    }
+    cie = fde->fd_cie;
+    if (cie == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_CIE_NULL);
+	return (DW_DLV_ERROR);
+    }
+    if (cie->ci_gnu_eh_augmentation_len == 0) {
+	return DW_DLV_NO_ENTRY;
+    }
+    *augdata = (Dwarf_Small *) fde->fd_gnu_eh_augmentation_bytes;
+    *augdata_len = fde->fd_gnu_eh_augmentation_len;
+    return DW_DLV_OK;
+}
+
+
+/* Initialize with same_value , a value which makes sense
+   for IRIX/MIPS.
+   The correct value to use is ABI dependent.
+   For register-windows machines most
+   or all registers should get DW_FRAME_UNDEFINED_VAL as the
+   correct initial value.
+   Some think DW_FRAME_UNDEFINED_VAL is always the
+   right value.   
+
+   For some ABIs a setting which varies by register
+   would be more appropriate.
+
+   FIXME. */
+
+static void
+_dwarf_init_regrule_table(struct Dwarf_Reg_Rule_s *t1reg,
+			  int last_reg_num, int initial_value)
+{
+    struct Dwarf_Reg_Rule_s *t1end = t1reg + last_reg_num;
+
+    for (; t1reg < t1end; t1reg++) {
+	t1reg->ru_is_off = 0;
+	t1reg->ru_value_type = DW_EXPR_OFFSET;
+	t1reg->ru_register = initial_value;
+	t1reg->ru_offset_or_block_len = 0;
+	t1reg->ru_block = 0;
+    }
+}
+
+#if 0
+/* Used solely for debugging libdwarf. */
+static void
+dump_frame_rule(char *msg, struct Dwarf_Reg_Rule_s *reg_rule)
+{
+    printf
+	("%s type %s (0x%x), is_off %d reg %d offset 0x%llx blockp 0x%llx \n",
+	 msg,
+	 (reg_rule->ru_value_type ==
+	  DW_EXPR_OFFSET) ? "DW_EXPR_OFFSET" : (reg_rule->
+						ru_value_type ==
+						DW_EXPR_VAL_OFFSET) ?
+	 "DW_EXPR_VAL_OFFSET" : (reg_rule->ru_value_type ==
+				 DW_EXPR_VAL_EXPRESSION) ?
+	 "DW_EXPR_VAL_EXPRESSION" : (reg_rule->ru_value_type ==
+				     DW_EXPR_EXPRESSION) ?
+	 "DW_EXPR_EXPRESSION" : "Unknown",
+	 (unsigned) reg_rule->ru_value_type, (int) reg_rule->ru_is_off,
+	 (int) reg_rule->ru_register,
+	 (unsigned long long) reg_rule->ru_offset_or_block_len,
+	 (unsigned long long) reg_rule->ru_block);
+    return;
+}
+#endif
+
+/* This allows consumers to set the 'initial value' so that
+   an ISA/ABI specific default can be used, dynamically,
+   at run time.  Useful for dwarfdump and non-MIPS architectures.. 
+   The value  defaults to one of
+	DW_FRAME_SAME_VALUE or DW_FRAME_UNKNOWN_VALUE
+   but dwarfdump can dump multiple ISA/ABI objects so
+   we may want to get this set to what the ABI says is correct.
+
+   Returns the value that was present before we changed it here.
+*/
+
+Dwarf_Half
+dwarf_set_frame_rule_inital_value(Dwarf_Debug dbg, Dwarf_Half value)
+{
+    Dwarf_Half orig = dbg->de_frame_rule_initial_value;
+
+    dbg->de_frame_rule_initial_value = value;
+    return orig;
+}
+
+/* This allows consumers to set the array size of the  reg rules
+   table so that
+   an ISA/ABI specific value can be used, dynamically,
+   at run time.  Useful for non-MIPS archtectures.
+   The value  defaults  to DW_FRAME_LAST_REG_NUM.
+   but dwarfdump can dump multiple ISA/ABI objects so
+   consumers want to get this set to what the ABI says is correct.
+
+   Returns the value that was present before we changed it here.
+*/
+
+Dwarf_Half
+dwarf_set_frame_rule_table_size(Dwarf_Debug dbg, Dwarf_Half value)
+{
+    Dwarf_Half orig = dbg->de_frame_reg_rules_entry_count;
+
+    dbg->de_frame_reg_rules_entry_count = value;
+    return orig;
+}
+
+
+static int
+dwarf_initialize_fde_table(Dwarf_Debug dbg,
+			   struct Dwarf_Frame_s *fde_table,
+			   unsigned table_real_data_size,
+			   Dwarf_Error * error)
+{
+    unsigned entry_size = sizeof(struct Dwarf_Frame_s);
+
+    fde_table->fr_loc = 0;
+    fde_table->fr_reg_count = table_real_data_size;
+    fde_table->fr_next = 0;
+
+    fde_table->fr_reg = (struct Dwarf_Reg_Rule_s *)
+	calloc(entry_size, table_real_data_size);
+    if (fde_table->fr_reg == 0) {
+	_dwarf_error(dbg, error, DW_DLE_DF_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+    return DW_DLV_OK;
+
+}
+static void
+dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table)
+{
+    free(fde_table->fr_reg);
+    fde_table->fr_reg_count = 0;
+    fde_table->fr_reg = 0;
+}
+
+
+/* Return DW_DLV_OK if we succeed. else return DW_DLV_ERROR.
+*/
+int
+_dwarf_frame_constructor(Dwarf_Debug dbg, void *frame)
+{
+    struct Dwarf_Frame_s *fp = frame;
+
+    if (!dbg) {
+	return DW_DLV_ERROR;
+    }
+
+    fp->fr_reg = calloc(dbg->de_frame_reg_rules_entry_count,
+			sizeof(struct Dwarf_Reg_Rule_s));
+    if (!fp->fr_reg) {
+	return DW_DLV_ERROR;
+    }
+    fp->fr_reg_count = dbg->de_frame_reg_rules_entry_count;
+    return DW_DLV_OK;
+}
+
+void
+_dwarf_frame_destructor(void *frame)
+{
+    struct Dwarf_Frame_s *fp = frame;
+
+    if (fp->fr_reg)
+	free(fp->fr_reg);
+    fp->fr_reg = 0;
+    fp->fr_reg_count = 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_frame.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,400 @@
+/*
+
+  Copyright (C) 2000, 2004, 2006 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+/* The dwarf 2.0 standard dictates that only the following
+ * fields can be read when an unexpected augmentation string
+ * (in the cie) is encountered: CIE length, CIE_id, version and
+ * augmentation; FDE: length, CIE pointer, initial location and
+ * address range. Unfortunately, with the above restrictions, it
+ * is impossible to read the instruction table from a CIE or a FDE
+ * when a new augmentation string is encountered.
+ * To fix this problem, the following layout is used, if the
+ * augmentation string starts with the string "z".
+ *   CIE                        FDE
+ *   length                     length
+ *   CIE_id                     CIE_pointer
+ *   version                    initial_location
+ *   augmentation               address_range
+ *                              length_of_augmented_fields (*NEW*)
+ *   code_alignment_factor      Any new fields as necessary
+ *   data_alignment_factor      instruction_table
+ *   return_address
+ *   length_of_augmented fields
+ *   Any new fields as necessary
+ *   initial_instructions
+ *
+ * The type of all the old data items are the same as what is
+ * described in dwarf 2.0 standard. The length_of_augmented_fields
+ * is an LEB128 data item that denotes the size (in bytes) of
+ * the augmented fields (not including the size of
+ * "length_of_augmented_fields" itself).
+ 
+ * Handling of cie augmentation strings is necessarly a heuristic.
+ * See dwarf_frame.c for the currently known augmentation strings.
+
+
+   ---START SGI-ONLY COMMENT:
+ * SGI-IRIX versions of cie or fde  were intended to use "z1", "z2" as the
+ * augmenter strings if required for new augmentation.
+ * However, that never happened (as of March 2005).
+ *
+ * The fde's augmented by the string "z" have a new field 
+ * (signed constant, 4 byte field)
+ * called offset_into_exception_tables, following the 
+ * length_of_augmented field.   This field contains an offset 
+ * into the "_MIPS_eh_region", which describes
+ * the IRIX CC exception handling tables.
+   ---END SGI-ONLY COMMENT
+ 
+
+ * GNU .eh_frame has an augmentation string of z[RLP]* (gcc 3.4)
+ * The similarity to IRIX 'z' (and proposed but never
+ * implemented IRIX z1, z2 etc) was confusing things.
+ * If the section is .eh_frame then 'z' means GNU exception
+ * information 'Augmentation Data' not IRIX 'z'.
+ * See The Linux Standard Base Core Specification version 3.0
+ */
+
+#define DW_DEBUG_FRAME_VERSION                 	1 /* DWARF2 */
+#define DW_DEBUG_FRAME_VERSION3                	3 /* DWARF3 */
+#define DW_DEBUG_FRAME_AUGMENTER_STRING     	"mti v1"
+
+/* The value of the offset field for Cie's. */
+#define DW_CIE_OFFSET		~(0x0)
+
+/* The augmentation string may be NULL.	*/
+#define DW_EMPTY_STRING		""
+
+#define DW_FRAME_INSTR_OPCODE_SHIFT		6
+#define DW_FRAME_INSTR_OFFSET_MASK		0x3f
+
+/* 
+    This struct denotes the rule for a register in a row of
+    the frame table.  In other words, it is one element of 
+    the table.
+*/
+struct Dwarf_Reg_Rule_s {
+
+    /* 
+       Is a flag indicating whether the rule includes the offset
+       field, ie whether the ru_offset field is valid or not. 
+       Applies only if DW_EXPR_OFFSET or DW_EXPR_VAL_OFFSET.
+       It is important, since reg+offset (offset of 0) is different from
+       just 'register' since the former means 'read memory at address
+       given by the sum of register contents plus offset to get the
+       value'. whereas the latter means 'the value is in the register'.
+
+       The 'register' numbers are either real registers (ie, table
+       columns defined as real registers) or defined entries that are
+       not really hardware registers, such as DW_FRAME_SAME_VAL or
+       DW_FRAME_CFA_COL.
+
+     */
+    Dwarf_Sbyte ru_is_off; 
+
+    /* DW_EXPR_OFFSET (0, DWARF2)  
+       DW_EXPR_VAL_OFFSET 1 (dwarf2/3)
+       DW_EXPR_EXPRESSION 2  (dwarf2/3)
+	DW_EXPR_VAL_EXPRESSION 3 (dwarf2/3) 
+       See dwarf_frame.h. */
+    Dwarf_Sbyte ru_value_type;
+
+    /* Register involved in this rule. */
+    Dwarf_Half ru_register;
+
+    /* Offset to add to register, if indicated by ru_is_offset
+       and if DW_EXPR_OFFSET or DW_EXPR_VAL_OFFSET. 
+       If DW_EXPR_EXPRESSION or DW_EXPR_VAL_EXPRESSION
+       this is DW_FORM_block block-length, not offset. */
+    Dwarf_Unsigned ru_offset_or_block_len;
+    
+    /* For DW_EXPR_EXPRESSION DW_EXPR_VAL_EXPRESSION these is set,
+       else 0. */
+    Dwarf_Small *ru_block;
+};
+
+typedef struct Dwarf_Frame_s *Dwarf_Frame;
+
+/* 
+    This structure represents a row of the frame table. 
+    Fr_loc is the pc value for this row, and Fr_reg
+    contains the rule for each column.
+
+    Entry DW_FRAME_CFA_COL of fr_reg was the tradional MIPS
+    way of setting CFA.  cfa_rule is the new one.
+*/
+struct Dwarf_Frame_s {
+
+    /* Pc value corresponding to this row of the frame table. */
+    Dwarf_Addr fr_loc;
+
+    /* Rules for all the registers in this row. */
+    struct Dwarf_Reg_Rule_s fr_cfa_rule;
+
+	/* fr_reg_count is the the number of
+	entries of the fr_reg array. */
+    unsigned long            fr_reg_count;
+    struct Dwarf_Reg_Rule_s *fr_reg;
+
+    Dwarf_Frame fr_next;
+};
+
+typedef struct Dwarf_Frame_Op_List_s *Dwarf_Frame_Op_List;
+
+/* This is used to chain together Dwarf_Frame_Op structures. */
+struct Dwarf_Frame_Op_List_s {
+    Dwarf_Frame_Op *fl_frame_instr;
+    Dwarf_Frame_Op_List fl_next;
+};
+
+/* See dwarf_frame.c for the heuristics used to set the
+   Dwarf_Cie ci_augmentation_type.  
+
+   This succinctly helps interpret the size and meaning of .debug_frame
+   and (for gcc) .eh_frame.
+
+   In the case of gcc .eh_frame (gcc 3.3, 3.4)
+   z may be followed by one or more of
+   L R P.  
+
+*/
+enum Dwarf_augmentation_type {
+        aug_empty_string, /* Default empty augmentation string.  */
+        aug_irix_exception_table,  /* IRIX  plain  "z",
+                   for exception handling, IRIX CC compiler.
+		   Proposed z1 z2 ... never implemented.  */
+        aug_gcc_eh_z,       /* gcc z augmentation,  (including
+			L R P variations). gcc 3.3 3.4 exception
+			handling in eh_frame.  */
+        aug_irix_mti_v1,  /* IRIX "mti v1" augmentation string. Probably
+                             never in any released SGI-IRIX compiler. */
+        aug_eh,           /* For gcc .eh_frame, "eh" is the string.,
+				gcc 1,2, egcs. Older values.  */
+        aug_unknown,      /* Unknown augmentation, we cannot do much. */
+        aug_past_last
+};
+
+
+/* 
+    This structure contains all the pertinent info for a Cie. Most 
+    of the fields are taken straight from the definition of a Cie.  
+    Ci_cie_start points to the address (in .debug_frame) where this 
+    Cie begins.  Ci_cie_instr_start points to the first byte of the 
+    frame instructions for this Cie.  Ci_dbg points to the associated 
+    Dwarf_Debug structure.  Ci_initial_table is a pointer to the table 
+    row generated by the instructions for this Cie.
+*/
+struct Dwarf_Cie_s {
+    Dwarf_Word ci_length;
+    char *ci_augmentation;
+    Dwarf_Small ci_code_alignment_factor;
+    Dwarf_Sbyte ci_data_alignment_factor;
+    Dwarf_Small ci_return_address_register;
+    Dwarf_Small *ci_cie_start;
+    Dwarf_Small *ci_cie_instr_start;
+    Dwarf_Debug ci_dbg;
+    Dwarf_Frame ci_initial_table;
+    Dwarf_Cie ci_next;
+    Dwarf_Small ci_length_size;
+    Dwarf_Small ci_extension_size;
+    Dwarf_Half ci_cie_version_number;
+    enum Dwarf_augmentation_type ci_augmentation_type;	 
+
+    /* The following 2 for GNU .eh_frame exception handling
+       Augmentation Data. Set if ci_augmentation_type
+       is aug_gcc_eh_z. Zero if unused. */
+    Dwarf_Unsigned ci_gnu_eh_augmentation_len;
+    Dwarf_Ptr      ci_gnu_eh_augmentation_bytes;
+
+    /* These are extracted from the gnu eh_frame
+       augmentation if the
+       augmentation begins with 'z'. See Linux LSB documents.
+       Otherwize these are zero. */
+    unsigned char    ci_gnu_personality_handler_encoding;
+    unsigned char    ci_gnu_lsda_encoding;
+    unsigned char    ci_gnu_fde_begin_encoding;
+
+    /* If 'P' augmentation present, is handler addr. Else
+	is zero. */
+    Dwarf_Addr     ci_gnu_personality_handler_addr;
+
+
+    /* In creating list of cie's (which will become an array)
+       record the position so fde can get it on fde creation. */
+    Dwarf_Unsigned ci_index;
+    Dwarf_Small *  ci_section_ptr;
+};
+
+/*
+	This structure contains all the pertinent info for a Fde.
+	Most of the fields are taken straight from the definition.
+	fd_cie_index is the index of the Cie associated with this
+	Fde in the list of Cie's for this debug_frame.  Fd_cie
+	points to the corresponsing Dwarf_Cie structure.  Fd_fde_start
+	points to the start address of the Fde.  Fd_fde_instr_start
+	points to the start of the instructions for this Fde.  Fd_dbg
+	points to the associated Dwarf_Debug structure.
+*/
+struct Dwarf_Fde_s {
+    Dwarf_Unsigned fd_length;
+    Dwarf_Addr fd_cie_offset;
+    Dwarf_Unsigned fd_cie_index;
+    Dwarf_Cie fd_cie;
+    Dwarf_Addr fd_initial_location;
+    Dwarf_Small *fd_initial_loc_pos;
+    Dwarf_Addr fd_address_range;
+    Dwarf_Small *fd_fde_start;
+    Dwarf_Small *fd_fde_instr_start;
+    Dwarf_Debug fd_dbg;
+
+	/* fd_offset_into_exception_tables is SGI/IRIX exception table
+	   offset. Unused and zero if not IRIX .debug_frame. */
+    Dwarf_Signed fd_offset_into_exception_tables;
+
+    Dwarf_Fde fd_next;
+    Dwarf_Small fd_length_size;
+    Dwarf_Small fd_extension_size;
+    /* The following 2 for GNU .eh_frame exception handling
+       Augmentation Data. Set if CIE ci_augmentation_type
+       is aug_gcc_eh_z. Zero if unused. */
+    Dwarf_Unsigned fd_gnu_eh_augmentation_len;
+    Dwarf_Ptr fd_gnu_eh_augmentation_bytes;
+    Dwarf_Addr fd_gnu_eh_lsda; /* If 'L' augmentation letter
+         present:  is address of the 
+         Language Specific Data Area (LSDA). If not 'L" is zero. */
+
+    /* The following 3 are about the Elf section the FDEs come from. */
+    Dwarf_Small * fd_section_ptr;
+    Dwarf_Unsigned fd_section_length;
+    Dwarf_Unsigned fd_section_index; 
+
+};
+
+
+int
+  _dwarf_frame_address_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrlist,
+			       Dwarf_Off ** offsetlist,
+			       Dwarf_Signed * returncount,
+			       Dwarf_Error * err);
+
+int
+_dwarf_get_fde_list_internal(Dwarf_Debug dbg,
+                              Dwarf_Cie ** cie_data,
+                              Dwarf_Signed * cie_element_count,
+                              Dwarf_Fde ** fde_data,
+                              Dwarf_Signed * fde_element_count,
+                              Dwarf_Small * section_ptr,
+                              Dwarf_Unsigned section_index,
+                              Dwarf_Unsigned section_length,
+                              Dwarf_Unsigned cie_id_value,
+                              int use_gnu_cie_calc,  /* If non-zero,
+                                this is gcc eh_frame. */
+                              Dwarf_Error * error);
+
+enum Dwarf_augmentation_type
+_dwarf_get_augmentation_type(Dwarf_Debug dbg,
+        Dwarf_Small *augmentation_string,
+        int is_gcc_eh_frame);
+
+Dwarf_Unsigned _dwarf_get_return_address_reg(Dwarf_Small *frame_ptr,
+                        int version,
+                        unsigned long *size);
+
+/* Temporary recording of crucial cie/fde prefix data.
+ * Vastly simplifies some argument lists.
+ */
+struct cie_fde_prefix_s {
+   Dwarf_Small *  cf_start_addr;
+   Dwarf_Small *  cf_addr_after_prefix;
+   Dwarf_Unsigned cf_length;
+   int            cf_local_length_size;
+   int            cf_local_extension_size;
+   Dwarf_Unsigned cf_cie_id;
+   Dwarf_Small *  cf_cie_id_addr; /* used for eh_frame calculations. */
+
+   /* Simplifies passing around these values to create fde having
+      these here. */
+   Dwarf_Small *  cf_section_ptr;
+   Dwarf_Unsigned cf_section_index; 
+   Dwarf_Unsigned cf_section_length; 
+};
+
+int
+_dwarf_exec_frame_instr(Dwarf_Bool make_instr,
+                        Dwarf_Frame_Op ** ret_frame_instr,
+                        Dwarf_Bool search_pc,
+                        Dwarf_Addr search_pc_val,
+                        Dwarf_Addr initial_loc,
+                        Dwarf_Small * start_instr_ptr,
+                        Dwarf_Small * final_instr_ptr,
+                        Dwarf_Frame table,
+                        Dwarf_Cie cie,
+                        Dwarf_Debug dbg,
+			Dwarf_Half reg_num_of_cfa,
+                        Dwarf_Sword * returned_count,
+                        int *returned_error);
+
+
+int dwarf_read_cie_fde_prefix(Dwarf_Debug dbg,
+        Dwarf_Small *frame_ptr_in,
+        Dwarf_Small *section_ptr_in,
+        Dwarf_Unsigned section_index_in,
+	Dwarf_Unsigned section_length_in,
+        struct cie_fde_prefix_s *prefix_out,
+        Dwarf_Error *error);
+
+int dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
+        struct cie_fde_prefix_s *  prefix,
+        Dwarf_Small *section_pointer,
+        Dwarf_Small *frame_ptr,
+        int use_gnu_cie_calc,
+        Dwarf_Cie  cie_ptr_in,
+        Dwarf_Fde *fde_ptr_out,
+        Dwarf_Error *error);
+
+int dwarf_create_cie_from_after_start(Dwarf_Debug dbg,
+        struct cie_fde_prefix_s *prefix,
+        Dwarf_Small* section_pointer,
+        Dwarf_Small* frame_ptr,
+        Dwarf_Unsigned cie_count,
+        int use_gnu_cie_calc,
+        Dwarf_Cie *cie_ptr_out,
+        Dwarf_Error *error);
+
+
+int _dwarf_frame_constructor(Dwarf_Debug dbg,void * );
+void _dwarf_frame_destructor (void *);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_frame2.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1447 @@
+/*
+
+  Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+/*
+	This  implements _dwarf_get_fde_list_internal()
+        and related helper functions for reading cie/fde data.
+*/
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "dwarf_frame.h"
+#include "dwarf_arange.h"	/* using Arange as a way to build a
+				   list */
+
+
+static int dwarf_find_existing_cie_ptr(Dwarf_Small * cie_ptr,
+				       Dwarf_Cie cur_cie_ptr,
+				       Dwarf_Cie * cie_ptr_to_use_out,
+				       Dwarf_Cie head_cie_ptr);
+static void dealloc_fde_cie_list_internal(Dwarf_Fde head_fde_ptr,
+					  Dwarf_Cie head_cie_ptr);
+static int dwarf_create_cie_from_start(Dwarf_Debug dbg,
+				       Dwarf_Small * cie_ptr_val,
+				       Dwarf_Small * section_ptr,
+				       Dwarf_Unsigned section_index,
+				       Dwarf_Unsigned section_length,
+				       Dwarf_Small * frame_ptr_end,
+				       Dwarf_Unsigned cie_id_value,
+				       Dwarf_Unsigned cie_count,
+				       int use_gnu_cie_calc,
+				       Dwarf_Cie * cie_ptr_to_use_out,
+				       Dwarf_Error * error);
+
+static Dwarf_Small *get_cieptr_given_offset(Dwarf_Unsigned cie_id_value,
+					    int use_gnu_cie_calc,
+					    Dwarf_Small * section_ptr,
+					    Dwarf_Small * cie_id_addr);
+static int get_gcc_eh_augmentation(Dwarf_Debug dbg,
+				   Dwarf_Small * frame_ptr,
+				   unsigned long
+				   *size_of_augmentation_data,
+				   enum Dwarf_augmentation_type augtype,
+				   Dwarf_Small * section_pointer,
+				   Dwarf_Small * fde_eh_encoding_out,
+				   char *augmentation);
+
+static int
+  gnu_aug_encodings(Dwarf_Debug dbg, char *augmentation,
+		    Dwarf_Small * aug_data, Dwarf_Unsigned aug_data_len,
+		    unsigned char *pers_hand_enc_out,
+		    unsigned char *lsda_enc_out,
+		    unsigned char *fde_begin_enc_out,
+		    Dwarf_Addr * gnu_pers_addr_out);
+
+
+static int read_encoded_ptr(Dwarf_Debug dbg,
+			    Dwarf_Small * section_pointer,
+			    Dwarf_Small * input_field,
+			    int gnu_encoding,
+			    Dwarf_Unsigned * addr,
+			    Dwarf_Small ** input_field_out);
+
+
+
+static int qsort_compare(const void *elem1, const void *elem2);
+
+
+/* Adds 'newone' to the end of the list starting at 'head'
+   and makes the new one 'cur'rent. */
+static void
+chain_up_fde(Dwarf_Fde newone, Dwarf_Fde * head, Dwarf_Fde * cur)
+{
+    if (*head == NULL)
+	*head = newone;
+    else {
+	(*cur)->fd_next = newone;
+    }
+    *cur = newone;
+
+}
+
+/* Adds 'newone' to the end of the list starting at 'head'
+   and makes the new one 'cur'rent. */
+static void
+chain_up_cie(Dwarf_Cie newone, Dwarf_Cie * head, Dwarf_Cie * cur)
+{
+    if (*head == NULL) {
+	*head = newone;
+    } else {
+	(*cur)->ci_next = newone;
+    }
+    *cur = newone;
+}
+
+#if 0
+/* For debugging only. */
+static void
+print_prefix(struct cie_fde_prefix_s *prefix, int line)
+{
+    printf("prefix-print, prefix at 0x%lx, line %d\n",
+	   (long) prefix, line);
+    printf("  start addr 0x%lx after prefix 0x%lx\n",
+	   (long) prefix->cf_start_addr,
+	   (long) prefix->cf_addr_after_prefix);
+    printf("  length 0x%llx, len size %d ext size %d\n", (long long)
+	   (unsigned long long) prefix->cf_length,
+	   prefix->cf_local_length_size,
+	   prefix->cf_local_extension_size);
+    printf("  cie_id 0x%llx cie_id  cie_id_addr 0x%lx\n",
+	   (unsigned long long) prefix->cf_cie_id,
+	   (long) prefix->cf_cie_id_addr);
+    printf
+	("  sec ptr 0x%lx sec index %lld sec len 0x%llx sec past end 0x%lx\n",
+	 (long) prefix->cf_section_ptr,
+	 (long long) prefix->cf_section_index,
+	 (unsigned long long) prefix->cf_section_length,
+	 (long) prefix->cf_section_ptr + prefix->cf_section_length);
+}
+#endif
+
+
+
+/* Internal function called from various places to create
+   lists of CIEs and FDEs.  Not directly called
+   by consumer code */
+int
+_dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data,
+			     Dwarf_Signed * cie_element_count,
+			     Dwarf_Fde ** fde_data,
+			     Dwarf_Signed * fde_element_count,
+			     Dwarf_Small * section_ptr,
+			     Dwarf_Unsigned section_index,
+			     Dwarf_Unsigned section_length,
+			     Dwarf_Unsigned cie_id_value,
+			     int use_gnu_cie_calc, Dwarf_Error * error)
+{
+    /* Scans the debug_frame section. */
+    Dwarf_Small *frame_ptr = section_ptr;
+    Dwarf_Small *frame_ptr_end = section_ptr + section_length;
+
+
+
+    /* 
+       New_cie points to the Cie being read, and head_cie_ptr and
+       cur_cie_ptr are used for chaining them up in sequence. 
+       In case cie's are reused aggressively we need tail_cie_ptr
+       to add to the chain.  If we re-use an early cie
+       later on, that does not mean we chain a new cie to the early one,
+       we always chain it to the tail.  */
+    Dwarf_Cie head_cie_ptr = NULL;
+    Dwarf_Cie cur_cie_ptr = NULL;
+    Dwarf_Cie tail_cie_ptr = NULL;
+    Dwarf_Word cie_count = 0;
+
+    /* 
+       Points to a list of contiguous pointers to Dwarf_Cie structures. 
+     */
+    Dwarf_Cie *cie_list_ptr = 0;
+
+
+    /* 
+       New_fde points to the Fde being created, and head_fde_ptr and
+       cur_fde_ptr are used to chain them up. */
+    Dwarf_Fde head_fde_ptr = NULL;
+    Dwarf_Fde cur_fde_ptr = NULL;
+    Dwarf_Word fde_count = 0;
+
+    /* 
+       Points to a list of contiguous pointers to Dwarf_Fde structures. 
+     */
+    Dwarf_Fde *fde_list_ptr = NULL;
+
+    Dwarf_Word i = 0;
+    int res = 0;
+
+    if (frame_ptr == 0) {
+	return DW_DLV_NO_ENTRY;
+    }
+
+    /* We create the fde and cie arrays. Processing each CIE as we come 
+       to it or as an FDE refers to it.  We cannot process 'late' CIEs
+       late as GNU .eh_frame complexities mean we need the whole CIE
+       before we can process the FDE correctly. */
+    while (frame_ptr < frame_ptr_end) {
+
+	struct cie_fde_prefix_s prefix;
+
+	/* First read in the 'common prefix' to figure out what we are
+	   to do with this entry. */
+	memset(&prefix, 0, sizeof(prefix));
+	res = dwarf_read_cie_fde_prefix(dbg,
+					frame_ptr, section_ptr,
+					section_index,
+					section_length, &prefix, error);
+	if (res == DW_DLV_ERROR) {
+	    dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
+	    return res;
+	}
+	if (res == DW_DLV_NO_ENTRY)
+	    break;
+	frame_ptr = prefix.cf_addr_after_prefix;
+	if (frame_ptr >= frame_ptr_end) {
+	    dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
+	    _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
+	    return DW_DLV_ERROR;
+
+	}
+
+	if (prefix.cf_cie_id == cie_id_value) {
+	    /* This is a CIE.  */
+	    Dwarf_Cie cie_ptr_to_use = 0;
+
+	    int res = dwarf_find_existing_cie_ptr(prefix.cf_start_addr,
+						  cur_cie_ptr,
+						  &cie_ptr_to_use,
+						  head_cie_ptr);
+
+	    if (res == DW_DLV_OK) {
+		cur_cie_ptr = cie_ptr_to_use;
+		/* Ok. Seen already. */
+	    } else if (res == DW_DLV_NO_ENTRY) {
+		/* CIE before its FDE in this case. */
+		res = dwarf_create_cie_from_after_start(dbg,
+							&prefix,
+							section_ptr,
+							frame_ptr,
+							cie_count,
+							use_gnu_cie_calc,
+							&cie_ptr_to_use,
+							error);
+		/* ASSERT: res==DW_DLV_NO_ENTRY impossible. */
+		if (res == DW_DLV_ERROR) {
+		    dealloc_fde_cie_list_internal(head_fde_ptr,
+						  head_cie_ptr);
+		    return res;
+		}
+		/* ASSERT res != DW_DLV_NO_ENTRY */
+		cie_count++;
+		chain_up_cie(cie_ptr_to_use, &head_cie_ptr,
+			     &tail_cie_ptr);
+                cur_cie_ptr = tail_cie_ptr;
+	    } else {		/* res == DW_DLV_ERROR */
+
+		dealloc_fde_cie_list_internal(head_fde_ptr,
+					      head_cie_ptr);
+		return res;
+	    }
+	    frame_ptr = cie_ptr_to_use->ci_cie_start +
+		cie_ptr_to_use->ci_length +
+		cie_ptr_to_use->ci_length_size +
+		cie_ptr_to_use->ci_extension_size;
+	    continue;
+	} else {
+	    /* this is an FDE, Frame Description Entry, see the Dwarf
+	       Spec, section 6.4.1 */
+	    int res = 0;
+	    Dwarf_Cie cie_ptr_to_use = 0;
+	    Dwarf_Fde fde_ptr_to_use = 0;
+
+	    /* Do not call this twice on one prefix, as
+	       prefix.cf_cie_id_addr is altered as a side effect. */
+	    Dwarf_Small *cieptr_val =
+		get_cieptr_given_offset(prefix.cf_cie_id,
+					use_gnu_cie_calc,
+					section_ptr,
+					prefix.cf_cie_id_addr);
+
+	    res = dwarf_find_existing_cie_ptr(cieptr_val,
+					      cur_cie_ptr,
+					      &cie_ptr_to_use,
+					      head_cie_ptr);
+	    if (res == DW_DLV_OK) {
+		cur_cie_ptr = cie_ptr_to_use;
+		/* Ok. Seen CIE already. */
+	    } else if (res == DW_DLV_NO_ENTRY) {
+		res = dwarf_create_cie_from_start(dbg,
+						  cieptr_val,
+						  section_ptr,
+						  section_index,
+						  section_length,
+						  frame_ptr_end,
+						  cie_id_value,
+						  cie_count,
+						  use_gnu_cie_calc,
+						  &cie_ptr_to_use,
+						  error);
+		if (res == DW_DLV_ERROR) {
+		    dealloc_fde_cie_list_internal(head_fde_ptr,
+						  head_cie_ptr);
+		    return res;
+		} else if (res == DW_DLV_NO_ENTRY) {
+		    return res;
+		}
+		++cie_count;
+		chain_up_cie(cie_ptr_to_use, &head_cie_ptr,
+			     &tail_cie_ptr);
+                cur_cie_ptr = tail_cie_ptr;
+
+	    } else {
+		/* DW_DLV_ERROR */
+		return res;
+	    }
+
+	    res = dwarf_create_fde_from_after_start(dbg,
+						    &prefix,
+						    section_ptr,
+						    frame_ptr,
+						    use_gnu_cie_calc,
+						    cie_ptr_to_use,
+						    &fde_ptr_to_use,
+						    error);
+	    if (res == DW_DLV_ERROR) {
+		return res;
+	    }
+	    chain_up_fde(fde_ptr_to_use, &head_fde_ptr, &cur_fde_ptr);
+	    fde_count++;
+	    /* ASSERT: DW_DLV_OK. */
+	    frame_ptr = fde_ptr_to_use->fd_fde_start +
+		fde_ptr_to_use->fd_length +
+		fde_ptr_to_use->fd_length_size +
+		fde_ptr_to_use->fd_extension_size;
+	    continue;
+
+	}
+
+    }
+
+    /* Now build list of CIEs from the list. */
+    if (cie_count > 0) {
+	cie_list_ptr = (Dwarf_Cie *)
+	    _dwarf_get_alloc(dbg, DW_DLA_LIST, cie_count);
+    } else {
+	dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
+	return (DW_DLV_NO_ENTRY);
+    }
+    if (cie_list_ptr == NULL) {
+	dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+    cur_cie_ptr = head_cie_ptr;
+    for (i = 0; i < cie_count; i++) {
+	*(cie_list_ptr + i) = cur_cie_ptr;
+	cur_cie_ptr = cur_cie_ptr->ci_next;
+    }
+
+
+
+    /* Now build array of FDEs from the list. */
+    if (fde_count > 0) {
+	fde_list_ptr = (Dwarf_Fde *)
+	    _dwarf_get_alloc(dbg, DW_DLA_LIST, fde_count);
+    } else {
+	dwarf_fde_cie_list_dealloc(dbg, cie_list_ptr, cie_count,
+				   /* fde_data */ 0,
+				   /* fde_element_count */ 0);
+	dealloc_fde_cie_list_internal(head_fde_ptr,	/* head cie_ptr 
+							 */
+				      0);
+	return (DW_DLV_NO_ENTRY);
+    }
+    if (fde_list_ptr == NULL) {
+	dwarf_fde_cie_list_dealloc(dbg, cie_list_ptr, cie_count,
+				   /* fde_data */ 0,
+				   /* fde_element_count */ 0);
+	dealloc_fde_cie_list_internal(head_fde_ptr,	/* head cie_ptr 
+							 */
+				      0);
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+    cur_fde_ptr = head_fde_ptr;
+    for (i = 0; i < fde_count; i++) {
+	*(fde_list_ptr + i) = cur_fde_ptr;
+	cur_fde_ptr = cur_fde_ptr->fd_next;
+    }
+
+
+    /* Return arguments. */
+    *cie_data = cie_list_ptr;
+    *cie_element_count = cie_count;
+    dbg->de_cie_data = cie_list_ptr;
+    dbg->de_cie_count = cie_count;
+
+    *fde_data = fde_list_ptr;
+    *fde_element_count = fde_count;
+    dbg->de_fde_data = fde_list_ptr;
+    dbg->de_fde_count = fde_count;
+
+    /* Sort the list by the address so that dwarf_get_fde_at_pc() can
+       binary search this list. */
+    qsort((void *) fde_list_ptr, fde_count, sizeof(Dwarf_Ptr),
+	  qsort_compare);
+
+    return (DW_DLV_OK);
+}
+
+/* Internal function, not called by consumer code.
+   'prefix' has accumulated the info up thru the cie-id
+   and now we consume the rest and build a Dwarf_Cie_s structure.
+*/
+int
+dwarf_create_cie_from_after_start(Dwarf_Debug dbg,
+				  struct cie_fde_prefix_s *prefix,
+				  Dwarf_Small * section_pointer,
+				  Dwarf_Small * frame_ptr,
+				  Dwarf_Unsigned cie_count,
+				  int use_gnu_cie_calc,
+				  Dwarf_Cie * cie_ptr_out,
+				  Dwarf_Error * error)
+{
+    Dwarf_Cie new_cie = 0;
+
+    /* egcs-1.1.2 .eh_frame uses 0 as the distinguishing id. sgi uses
+       -1 (in .debug_frame). .eh_frame not quite identical to
+       .debug_frame */
+    Dwarf_Small eh_fde_encoding = 0;
+    Dwarf_Small *augmentation = 0;
+    Dwarf_Sword data_alignment_factor = -1;
+    Dwarf_Word code_alignment_factor = 4;
+    Dwarf_Unsigned return_address_register = 31;
+    int local_length_size = 0;
+    Dwarf_Word leb128_length = 0;
+    Dwarf_Unsigned cie_aug_data_len = 0;
+    Dwarf_Small *cie_aug_data = 0;
+    Dwarf_Addr gnu_personality_handler_addr = 0;
+    unsigned char gnu_personality_handler_encoding = 0;
+    unsigned char gnu_lsda_encoding = 0;
+    unsigned char gnu_fde_begin_encoding = 0;
+
+
+    enum Dwarf_augmentation_type augt = aug_unknown;
+
+
+    /* this is a CIE, Common Information Entry: See the dwarf spec,
+       section 6.4.1 */
+    Dwarf_Small version = *(Dwarf_Small *) frame_ptr;
+
+    frame_ptr++;
+    if (version != DW_CIE_VERSION && version != DW_CIE_VERSION3) {
+	_dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD);
+	return (DW_DLV_ERROR);
+    }
+
+    augmentation = frame_ptr;
+    frame_ptr = frame_ptr + strlen((char *) frame_ptr) + 1;
+    augt = _dwarf_get_augmentation_type(dbg,
+					augmentation, use_gnu_cie_calc);
+    if (augt == aug_eh) {
+	/* REFERENCED *//* Not used in this instance */
+	Dwarf_Unsigned exception_table_addr;
+
+	/* this is per egcs-1.1.2 as on RH 6.0 */
+	READ_UNALIGNED(dbg, exception_table_addr,
+		       Dwarf_Unsigned, frame_ptr, local_length_size);
+	frame_ptr += local_length_size;
+    }
+    {
+	Dwarf_Unsigned lreg = 0;
+	unsigned long size = 0;
+
+	DECODE_LEB128_UWORD(frame_ptr, lreg);
+	code_alignment_factor = (Dwarf_Word) lreg;
+
+	data_alignment_factor =
+	    (Dwarf_Sword) _dwarf_decode_s_leb128(frame_ptr,
+						 &leb128_length);
+
+	frame_ptr = frame_ptr + leb128_length;
+
+	return_address_register =
+	    _dwarf_get_return_address_reg(frame_ptr, version, &size);
+	if (return_address_register > DW_FRAME_LAST_REG_NUM) {
+	    _dwarf_error(dbg, error, DW_DLE_CIE_RET_ADDR_REG_ERROR);
+	    return (DW_DLV_ERROR);
+	}
+	frame_ptr += size;
+    }
+    switch (augt) {
+    case aug_empty_string:
+	break;
+    case aug_irix_mti_v1:
+	break;
+    case aug_irix_exception_table:{
+	    Dwarf_Unsigned lreg = 0;
+	    Dwarf_Word length_of_augmented_fields;
+
+	    /* Decode the length of augmented fields. */
+	    DECODE_LEB128_UWORD(frame_ptr, lreg);
+	    length_of_augmented_fields = (Dwarf_Word) lreg;
+
+
+	    /* set the frame_ptr to point at the instruction start. */
+	    frame_ptr += length_of_augmented_fields;
+	}
+	break;
+
+    case aug_eh:{
+
+	    int err = 0;
+	    unsigned long increment = 0;
+
+	    if (!use_gnu_cie_calc) {
+		/* This should be impossible. */
+		_dwarf_error(dbg, error,
+			     DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
+		return DW_DLV_ERROR;
+	    }
+
+	    err = get_gcc_eh_augmentation(dbg, frame_ptr, &increment,
+					  augt,
+					  prefix->cf_section_ptr,
+					  &eh_fde_encoding,
+					  (char *) augmentation);
+	    if (err == DW_DLV_ERROR) {
+		_dwarf_error(dbg, error,
+			     DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
+		return DW_DLV_ERROR;
+	    }
+	    frame_ptr += increment;
+	    break;
+	}
+    case aug_gcc_eh_z:{
+	    /* Here we have Augmentation Data Length (uleb128) followed 
+	       by Augmentation Data bytes. */
+	    int res;
+	    Dwarf_Unsigned adlen = 0;
+
+	    DECODE_LEB128_UWORD(frame_ptr, adlen);
+	    cie_aug_data_len = adlen;
+	    cie_aug_data = frame_ptr;
+	    res = gnu_aug_encodings(dbg,
+				    (char *) augmentation,
+				    cie_aug_data,
+				    cie_aug_data_len,
+				    &gnu_personality_handler_encoding,
+				    &gnu_lsda_encoding,
+				    &gnu_fde_begin_encoding,
+				    &gnu_personality_handler_addr);
+	    if (res != DW_DLV_OK) {
+		_dwarf_error(dbg, error,
+			     DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
+		return res;
+	    }
+
+
+	    frame_ptr += adlen;
+	    break;
+	}
+    default:{
+	    /* We do not understand the augmentation string. No
+	       assumption can be made about any fields other than what
+	       we have already read. */
+	    frame_ptr = prefix->cf_start_addr +
+		prefix->cf_length + prefix->cf_local_length_size
+		+ prefix->cf_local_extension_size;
+	    /* FIX -- What are the values of data_alignment_factor,
+	       code_alignement_factor, return_address_register and
+	       instruction start? They were clearly uninitalized in the 
+	       previous version and I am leaving them the same way. */
+	    break;
+	}
+    }				/* End switch on augmentation type. */
+
+    new_cie = (Dwarf_Cie) _dwarf_get_alloc(dbg, DW_DLA_CIE, 1);
+    if (new_cie == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+
+    new_cie->ci_cie_version_number = version;
+    new_cie->ci_initial_table = NULL;
+    new_cie->ci_length = (Dwarf_Word) prefix->cf_length;
+    new_cie->ci_length_size = prefix->cf_local_length_size;
+    new_cie->ci_extension_size = prefix->cf_local_extension_size;
+    new_cie->ci_augmentation = (char *) augmentation;
+
+    new_cie->ci_data_alignment_factor =
+	(Dwarf_Sbyte) data_alignment_factor;
+    new_cie->ci_code_alignment_factor =
+	(Dwarf_Small) code_alignment_factor;
+    new_cie->ci_return_address_register = return_address_register;
+    new_cie->ci_cie_start = prefix->cf_start_addr;
+    new_cie->ci_cie_instr_start = frame_ptr;
+    new_cie->ci_dbg = dbg;
+    new_cie->ci_augmentation_type = augt;
+    new_cie->ci_gnu_eh_augmentation_len = cie_aug_data_len;
+    new_cie->ci_gnu_eh_augmentation_bytes = cie_aug_data;
+    new_cie->ci_gnu_personality_handler_encoding =
+	gnu_personality_handler_encoding;
+    new_cie->ci_gnu_personality_handler_addr =
+	gnu_personality_handler_addr;
+    new_cie->ci_gnu_lsda_encoding = gnu_lsda_encoding;
+    new_cie->ci_gnu_fde_begin_encoding = gnu_fde_begin_encoding;
+
+    new_cie->ci_index = cie_count;
+    new_cie->ci_section_ptr = prefix->cf_section_ptr;
+
+    *cie_ptr_out = new_cie;
+    return DW_DLV_OK;
+
+}
+
+
+/* Internal function, not called by consumer code.
+   'prefix' has accumulated the info up thru the cie-id
+   and now we consume the rest and build a Dwarf_Fde_s structure.
+*/
+
+int
+dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
+				  struct cie_fde_prefix_s *prefix,
+				  Dwarf_Small * section_pointer,
+				  Dwarf_Small * frame_ptr,
+				  int use_gnu_cie_calc,
+				  Dwarf_Cie cie_ptr_in,
+				  Dwarf_Fde * fde_ptr_out,
+				  Dwarf_Error * error)
+{
+    Dwarf_Fde new_fde = 0;
+    Dwarf_Cie cieptr = cie_ptr_in;
+    Dwarf_Small *saved_frame_ptr = 0;
+
+    Dwarf_Small *initloc = frame_ptr;
+    Dwarf_Signed offset_into_exception_tables
+	/* must be min dwarf_sfixed in size */
+	= (Dwarf_Signed) DW_DLX_NO_EH_OFFSET;
+    Dwarf_Small *fde_aug_data = 0;
+    Dwarf_Unsigned fde_aug_data_len = 0;
+    Dwarf_Addr cie_base_offset = prefix->cf_cie_id;
+    Dwarf_Addr initial_location = 0;	/* must be min de_pointer_size
+					   bytes in size */
+    Dwarf_Addr address_range = 0;	/* must be min de_pointer_size
+					   bytes in size */
+
+    enum Dwarf_augmentation_type augt = cieptr->ci_augmentation_type;
+
+    if (augt == aug_gcc_eh_z) {
+	/* If z augmentation this is eh_frame, and initial_location and 
+	   address_range in the FDE are read according to the CIE
+	   augmentation string instructions.  */
+
+	{
+	    Dwarf_Small *fp_updated = 0;
+	    int res = res = read_encoded_ptr(dbg,
+					     section_pointer,
+					     frame_ptr,
+					     cieptr->
+					     ci_gnu_fde_begin_encoding,
+					     &initial_location,
+					     &fp_updated);
+
+	    if (res != DW_DLV_OK) {
+		_dwarf_error(dbg, error,
+			     DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
+		return DW_DLV_ERROR;
+	    }
+	    frame_ptr = fp_updated;
+	    /* For the address-range it makes no sense to be
+	       pc-relative, so we turn it off with a section_pointer of 
+	       NULL. Masking off DW_EH_PE_pcrel from the
+	       ci_gnu_fde_begin_encoding in this call would also work
+	       to turn off DW_EH_PE_pcrel. */
+	    res = read_encoded_ptr(dbg, (Dwarf_Small *) NULL,
+				   frame_ptr,
+				   cieptr->ci_gnu_fde_begin_encoding,
+				   &address_range, &fp_updated);
+	    if (res != DW_DLV_OK) {
+		_dwarf_error(dbg, error,
+			     DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
+		return DW_DLV_ERROR;
+	    }
+	    frame_ptr = fp_updated;
+	}
+	{
+	    Dwarf_Unsigned adlen = 0;
+
+	    DECODE_LEB128_UWORD(frame_ptr, adlen);
+	    fde_aug_data_len = adlen;
+	    fde_aug_data = frame_ptr;
+	    frame_ptr += adlen;
+	}
+
+    } else {
+	READ_UNALIGNED(dbg, initial_location, Dwarf_Addr,
+		       frame_ptr, dbg->de_pointer_size);
+	frame_ptr += dbg->de_pointer_size;
+
+	READ_UNALIGNED(dbg, address_range, Dwarf_Addr,
+		       frame_ptr, dbg->de_pointer_size);
+	frame_ptr += dbg->de_pointer_size;
+    }
+
+
+
+
+
+    switch (augt) {
+    case aug_irix_mti_v1:
+    case aug_empty_string:
+	break;
+    case aug_irix_exception_table:{
+	    Dwarf_Unsigned lreg = 0;
+	    Dwarf_Word length_of_augmented_fields = 0;
+
+	    DECODE_LEB128_UWORD(frame_ptr, lreg);
+	    length_of_augmented_fields = (Dwarf_Word) lreg;
+
+	    saved_frame_ptr = frame_ptr;
+	    /* The first word is an offset into exception tables.
+	       Defined as a 32bit offset even for CC -64. */
+	    READ_UNALIGNED(dbg, offset_into_exception_tables,
+			   Dwarf_Addr, frame_ptr, sizeof(Dwarf_sfixed));
+	    SIGN_EXTEND(offset_into_exception_tables,
+			sizeof(Dwarf_sfixed));
+	    frame_ptr = saved_frame_ptr + length_of_augmented_fields;
+	}
+	break;
+    case aug_eh:{
+	    Dwarf_Unsigned eh_table_value = 0;
+
+	    if (!use_gnu_cie_calc) {
+		/* This should be impossible. */
+		_dwarf_error(dbg, error,
+			     DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
+		return DW_DLV_ERROR;
+	    }
+
+	    /* gnu eh fde case. we do not need to do anything */
+	     /*REFERENCED*/	/* Not used in this instance of the
+				   macro */
+		READ_UNALIGNED(dbg, eh_table_value,
+			       Dwarf_Unsigned, frame_ptr,
+			       dbg->de_pointer_size);
+	    frame_ptr += dbg->de_pointer_size;
+	}
+	break;
+
+    case aug_gcc_eh_z:{
+	    /* The Augmentation Data Length is here, followed by the
+	       Augmentation Data bytes themselves. */
+	}
+	break;
+    case aug_past_last:
+	break;
+    case aug_unknown:
+	_dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
+	return DW_DLV_ERROR;
+    }				/* End switch on augmentation type */
+    new_fde = (Dwarf_Fde) _dwarf_get_alloc(dbg, DW_DLA_FDE, 1);
+    if (new_fde == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+
+    new_fde->fd_length = prefix->cf_length;
+    new_fde->fd_length_size = prefix->cf_local_length_size;
+    new_fde->fd_extension_size = prefix->cf_local_extension_size;
+    new_fde->fd_cie_offset = cie_base_offset;
+    new_fde->fd_cie_index = cieptr->ci_index;
+    new_fde->fd_cie = cieptr;
+    new_fde->fd_initial_location = initial_location;
+    new_fde->fd_initial_loc_pos = initloc;
+    new_fde->fd_address_range = address_range;
+    new_fde->fd_fde_start = prefix->cf_start_addr;
+    new_fde->fd_fde_instr_start = frame_ptr;
+    new_fde->fd_dbg = dbg;
+    new_fde->fd_offset_into_exception_tables =
+	offset_into_exception_tables;
+
+    new_fde->fd_section_ptr = prefix->cf_section_ptr;
+    new_fde->fd_section_index = prefix->cf_section_index;
+    new_fde->fd_section_length = prefix->cf_section_length;
+
+    new_fde->fd_gnu_eh_augmentation_bytes = fde_aug_data;
+    new_fde->fd_gnu_eh_augmentation_len = fde_aug_data_len;
+
+    *fde_ptr_out = new_fde;
+    return DW_DLV_OK;
+}
+
+/* called by qsort to compare FDE entries.
+   Consumer code expects the array of FDE pointers to be in address order.
+*/
+static int
+qsort_compare(const void *elem1, const void *elem2)
+{
+    Dwarf_Fde fde1 = *(Dwarf_Fde *) elem1;
+    Dwarf_Fde fde2 = *(Dwarf_Fde *) elem2;
+    Dwarf_Addr addr1 = fde1->fd_initial_location;
+    Dwarf_Addr addr2 = fde2->fd_initial_location;
+
+    if (addr1 < addr2) {
+	return -1;
+    } else if (addr1 > addr2) {
+	return 1;
+    }
+    return 0;
+}
+
+
+/* Read in the common cie/fde prefix, including reading
+ * the cie-value which shows which this is: cie or fde.
+ * */
+int
+dwarf_read_cie_fde_prefix(Dwarf_Debug dbg,
+			  Dwarf_Small * frame_ptr_in,
+			  Dwarf_Small * section_ptr_in,
+			  Dwarf_Unsigned section_index_in,
+			  Dwarf_Unsigned section_length_in,
+			  struct cie_fde_prefix_s *data_out,
+			  Dwarf_Error * error)
+{
+    Dwarf_Unsigned length = 0;
+    int local_length_size = 0;
+    int local_extension_size = 0;
+    Dwarf_Small *frame_ptr = frame_ptr_in;
+    Dwarf_Small *cie_ptr_addr = 0;
+    Dwarf_Unsigned cie_id = 0;
+
+    /* READ_AREA_LENGTH updates frame_ptr for consumed bytes */
+    READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
+		     frame_ptr, local_length_size,
+		     local_extension_size);
+
+    if (length % local_length_size != 0) {
+	_dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
+	return (DW_DLV_ERROR);
+    }
+
+    if (length == 0) {
+	/* nul bytes at end of section, seen at end of egcs eh_frame
+	   sections (in a.out). Take this as meaning no more CIE/FDE
+	   data. We should be very close to end of section. */
+	return DW_DLV_NO_ENTRY;
+    }
+
+    cie_ptr_addr = frame_ptr;
+    READ_UNALIGNED(dbg, cie_id, Dwarf_Unsigned,
+		   frame_ptr, local_length_size);
+    SIGN_EXTEND(cie_id, local_length_size);
+    frame_ptr += local_length_size;
+
+    data_out->cf_start_addr = frame_ptr_in;
+    data_out->cf_addr_after_prefix = frame_ptr;
+
+    data_out->cf_length = length;
+    data_out->cf_local_length_size = local_length_size;
+    data_out->cf_local_extension_size = local_extension_size;
+    data_out->cf_cie_id = cie_id;
+    data_out->cf_cie_id_addr = cie_ptr_addr;
+    data_out->cf_section_ptr = section_ptr_in;
+    data_out->cf_section_index = section_index_in;
+    data_out->cf_section_length = section_length_in;
+    return DW_DLV_OK;
+}
+
+/* On various errors previously-allocated CIEs and FDEs
+   must be cleaned up.
+   This helps avoid leaks in case of errors.
+*/
+static void
+dealloc_fde_cie_list_internal(Dwarf_Fde head_fde_ptr,
+			      Dwarf_Cie head_cie_ptr)
+{
+    Dwarf_Fde curfde = 0;
+    Dwarf_Cie curcie = 0;
+    Dwarf_Fde nextfde = 0;
+    Dwarf_Cie nextcie = 0;
+
+    for (curfde = head_fde_ptr; curfde; curfde = nextfde) {
+	nextfde = curfde->fd_next;
+	dwarf_dealloc(curfde->fd_dbg, curfde, DW_DLA_FDE);
+    }
+    for (curcie = head_cie_ptr; curcie; curcie = nextcie) {
+	Dwarf_Frame frame = curcie->ci_initial_table;
+
+	nextcie = curcie->ci_next;
+	if (frame)
+	    dwarf_dealloc(curcie->ci_dbg, frame, DW_DLA_FRAME);
+	dwarf_dealloc(curcie->ci_dbg, curcie, DW_DLA_CIE);
+    }
+}
+
+/* Find the cie whose id value is given: the id
+ * value is, per DWARF2/3, an offset in the section. 
+ * For .debug_frame, zero is a legal offset. For
+ * GNU .eh_frame it is not a legal offset.
+ * 'cie_ptr' is a pointer into our section, not an offset. */
+static int
+dwarf_find_existing_cie_ptr(Dwarf_Small * cie_ptr,
+			    Dwarf_Cie cur_cie_ptr,
+			    Dwarf_Cie * cie_ptr_to_use_out,
+			    Dwarf_Cie head_cie_ptr)
+{
+    Dwarf_Cie next = 0;
+
+    if (cur_cie_ptr && cie_ptr == cur_cie_ptr->ci_cie_start) {
+	/* Usually, we use the same cie again and again. */
+	*cie_ptr_to_use_out = cur_cie_ptr;
+	return DW_DLV_OK;
+    }
+    for (next = head_cie_ptr; next; next = next->ci_next) {
+	if (cie_ptr == next->ci_cie_start) {
+	    *cie_ptr_to_use_out = next;
+	    return DW_DLV_OK;
+	}
+    }
+    return DW_DLV_NO_ENTRY;
+}
+
+
+/* We have a valid cie_ptr_val that has not been
+ * turned into an internal Cie yet. Do so now.
+ * Returns DW_DLV_OK or DW_DLV_ERROR, never
+ * DW_DLV_NO_ENTRY.
+
+ 'section_ptr'    - Points to first byte of section data.
+ 'section_length' - Length of the section, in bytes.
+ 'frame_ptr_end'  - Points 1-past last byte of section data.
+ * */
+static int
+dwarf_create_cie_from_start(Dwarf_Debug dbg,
+			    Dwarf_Small * cie_ptr_val,
+			    Dwarf_Small * section_ptr,
+			    Dwarf_Unsigned section_index,
+			    Dwarf_Unsigned section_length,
+			    Dwarf_Small * frame_ptr_end,
+			    Dwarf_Unsigned cie_id_value,
+			    Dwarf_Unsigned cie_count,
+			    int use_gnu_cie_calc,
+			    Dwarf_Cie * cie_ptr_to_use_out,
+			    Dwarf_Error * error)
+{
+    struct cie_fde_prefix_s prefix;
+    int res = 0;
+    Dwarf_Small *frame_ptr = cie_ptr_val;
+
+    if (frame_ptr < section_ptr || frame_ptr > frame_ptr_end) {
+	_dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
+	return DW_DLV_ERROR;
+    }
+    /* First read in the 'common prefix' to figure out what * we are to 
+       do with this entry. IF it's not a cie * we are in big trouble. */
+    memset(&prefix, 0, sizeof(prefix));
+    res = dwarf_read_cie_fde_prefix(dbg, frame_ptr, section_ptr,
+				    section_index, section_length,
+				    &prefix, error);
+    if (res == DW_DLV_ERROR) {
+	return res;
+    }
+    if (res == DW_DLV_NO_ENTRY) {
+	/* error. */
+	_dwarf_error(dbg, error, DW_DLE_FRAME_CIE_DECODE_ERROR);
+	return DW_DLV_ERROR;
+
+    }
+
+    if (prefix.cf_cie_id != cie_id_value) {
+	_dwarf_error(dbg, error, DW_DLE_FRAME_CIE_DECODE_ERROR);
+	return DW_DLV_ERROR;
+    }
+    frame_ptr = prefix.cf_addr_after_prefix;
+    res = dwarf_create_cie_from_after_start(dbg,
+					    &prefix,
+					    section_ptr,
+					    frame_ptr,
+					    cie_count,
+					    use_gnu_cie_calc,
+					    cie_ptr_to_use_out, error);
+
+    return res;
+
+}
+
+
+/* This is for gnu eh frames, the 'z' case.
+   We find the letter involved
+   Return the augmentation character and, if applicable,
+   the personality routine address.
+
+   personality_routine_out - 
+	if 'P' is augchar, is personality handler addr. 
+        Otherwise is not set.
+   aug_data  - if 'P' points  to data space of the
+   aug_data_len - length of areas aug_data points to.
+   
+*/
+#if 0
+/* For debugging only. */
+void
+dump_bytes(Dwarf_Small * start, long len)
+{
+    Dwarf_Small *end = start + len;
+    Dwarf_Small *cur = start;
+
+    for (; cur < end; cur++) {
+	printf(" byte %d, data %02x\n", (int) (cur - start), *cur);
+    }
+
+}
+#endif
+static int
+gnu_aug_encodings(Dwarf_Debug dbg, char *augmentation,
+		  Dwarf_Small * aug_data, Dwarf_Unsigned aug_data_len,
+		  unsigned char *pers_hand_enc_out,
+		  unsigned char *lsda_enc_out,
+		  unsigned char *fde_begin_enc_out,
+		  Dwarf_Addr * gnu_pers_addr_out)
+{
+    char *nc = 0;
+    Dwarf_Small *cur_aug_p = aug_data;
+    Dwarf_Small *end_aug_p = aug_data + aug_data_len;
+
+    for (nc = augmentation; *nc; ++nc) {
+	char c = *nc;
+
+	switch (c) {
+	case 'z':
+            /* Means that the augmentation data is present. */
+	    continue;
+
+	case 'S':
+            /* Indicates this is a signal stack frame.  Debuggers have to do 
+               special handling.  We don't need to do more than print this flag at 
+               the right time, though (see dwarfdump where it prints the augmentation
+               string). 
+               A signal stack frame (in some OS's) can only be
+               unwound (backtraced) by knowing it is a signal stack frame 
+               (perhaps by noticing the name of the function for the stack frame
+               if the name can be found somehow) and figuring
+               out (or knowing) how the kernel and libc pushed a structure
+               onto the stack and loading registers from that structure.
+               Totally different from normal stack unwinding.
+               This flag gives an unwinder a big leg up by decoupling the
+               'hint: this is a stack frame' from knowledge like
+               the function name (the name might be unavailable at unwind time).
+            */
+            break;
+            
+	case 'L':
+	    if (cur_aug_p > end_aug_p) {
+		return DW_DLV_ERROR;
+	    }
+	    *lsda_enc_out = *(unsigned char *) cur_aug_p;
+	    ++cur_aug_p;
+	    break;
+	case 'R':
+            /* Followed by a one byte argument giving the
+               pointer encoding for the address pointers in the fde. */
+	    if (cur_aug_p >= end_aug_p) {
+		return DW_DLV_ERROR;
+	    }
+	    *fde_begin_enc_out = *(unsigned char *) cur_aug_p;
+	    ++cur_aug_p;
+	    break;
+	case 'P':{
+		int res = 0;
+		Dwarf_Small *updated_aug_p = 0;
+		unsigned char encoding = 0;
+
+		if (cur_aug_p >= end_aug_p) {
+		    return DW_DLV_ERROR;
+		}
+		encoding = *(unsigned char *) cur_aug_p;
+		*pers_hand_enc_out = encoding;
+		++cur_aug_p;
+		if (cur_aug_p > end_aug_p) {
+		    return DW_DLV_ERROR;
+		}
+		/* DW_EH_PE_pcrel makes no sense here, so we turn it
+		   off via a section pointer of NULL. */
+		res = read_encoded_ptr(dbg,
+				       (Dwarf_Small *) NULL,
+				       cur_aug_p,
+				       encoding,
+				       gnu_pers_addr_out,
+				       &updated_aug_p);
+		if (res != DW_DLV_OK) {
+		    return res;
+		}
+		cur_aug_p = updated_aug_p;
+		if (cur_aug_p > end_aug_p) {
+		    return DW_DLV_ERROR;
+		}
+	    }
+	    break;
+	default:
+	    return DW_DLV_ERROR;
+
+	}
+    }
+
+    return DW_DLV_OK;
+}
+
+/* Given augmentation character (the encoding) giving the
+address format, read the address from input_field
+and return an incremented value 1 past the input bytes of the
+address.
+Push the address read back thru the *addr pointer.
+See LSB (Linux Standar Base)  exception handling documents. 
+*/
+static int
+read_encoded_ptr(Dwarf_Debug dbg,
+		 Dwarf_Small * section_pointer,
+		 Dwarf_Small * input_field,
+		 int gnu_encoding,
+		 Dwarf_Unsigned * addr,
+		 Dwarf_Small ** input_field_updated)
+{
+    Dwarf_Word length = 0;
+    int value_type = gnu_encoding & 0xf;
+    Dwarf_Small *input_field_original = input_field;
+
+    if (gnu_encoding == 0xff) {
+	/* There is no data here. */
+
+	*addr = 0;
+	*input_field_updated = input_field;
+	/* Should we return DW_DLV_NO_ENTRY? */
+	return DW_DLV_OK;
+    }
+    switch (value_type) {
+    case DW_EH_PE_absptr:{
+	    /* value_type is zero. Treat as pointer size of the object. 
+	     */
+	    Dwarf_Unsigned ret_value = 0;
+
+	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+			   input_field, dbg->de_pointer_size);
+	    *addr = ret_value;
+	    *input_field_updated = input_field + dbg->de_pointer_size;
+	}
+	break;
+    case DW_EH_PE_uleb128:{
+	    Dwarf_Unsigned val = _dwarf_decode_u_leb128(input_field,
+							&length);
+
+	    *addr = val;
+	    *input_field_updated = input_field + length;
+	}
+	break;
+    case DW_EH_PE_udata2:{
+	    Dwarf_Unsigned ret_value = 0;
+
+	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+			   input_field, 2);
+	    *addr = ret_value;
+	    *input_field_updated = input_field + 2;
+	}
+	break;
+
+    case DW_EH_PE_udata4:{
+
+	    Dwarf_Unsigned ret_value = 0;
+
+	    /* ASSERT: sizeof(Dwarf_ufixed) == 4 */
+	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+			   input_field, sizeof(Dwarf_ufixed));
+	    *addr = ret_value;
+	    *input_field_updated = input_field + sizeof(Dwarf_ufixed);
+	}
+	break;
+
+    case DW_EH_PE_udata8:{
+	    Dwarf_Unsigned ret_value = 0;
+
+	    /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */
+	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+			   input_field, sizeof(Dwarf_Unsigned));
+	    *addr = ret_value;
+	    *input_field_updated = input_field + sizeof(Dwarf_Unsigned);
+	}
+	break;
+
+    case DW_EH_PE_sleb128:{
+	    Dwarf_Signed val = _dwarf_decode_s_leb128(input_field,
+						      &length);
+
+	    *addr = (Dwarf_Unsigned) val;
+	    *input_field_updated = input_field + length;
+	}
+	break;
+    case DW_EH_PE_sdata2:{
+	    Dwarf_Unsigned val = 0;
+
+	    READ_UNALIGNED(dbg, val, Dwarf_Unsigned, input_field, 2);
+	    SIGN_EXTEND(val, 2);
+	    *addr = (Dwarf_Unsigned) val;
+	    *input_field_updated = input_field + 2;
+	}
+	break;
+
+    case DW_EH_PE_sdata4:{
+	    Dwarf_Unsigned val = 0;
+
+	    /* ASSERT: sizeof(Dwarf_ufixed) == 4 */
+	    READ_UNALIGNED(dbg, val,
+			   Dwarf_Unsigned, input_field,
+			   sizeof(Dwarf_ufixed));
+	    SIGN_EXTEND(val, sizeof(Dwarf_ufixed));
+	    *addr = (Dwarf_Unsigned) val;
+	    *input_field_updated = input_field + sizeof(Dwarf_ufixed);
+	}
+	break;
+    case DW_EH_PE_sdata8:{
+	    Dwarf_Unsigned val = 0;
+
+	    /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */
+	    READ_UNALIGNED(dbg, val,
+			   Dwarf_Unsigned, input_field,
+			   sizeof(Dwarf_Unsigned));
+	    *addr = (Dwarf_Unsigned) val;
+	    *input_field_updated = input_field + sizeof(Dwarf_Unsigned);
+	}
+	break;
+    default:
+	return DW_DLV_ERROR;
+
+    };
+    /* The ELF ABI for gnu does not document the meaning of
+       DW_EH_PE_pcrel, which is awkward.  It apparently means the value 
+       we got above is pc-relative (meaning section-relative), so we
+       adjust the value. Section_pointer may be null if it is known
+       DW_EH_PE_pcrel cannot apply, such as for .debug_frame or for an
+       address-range value. */
+    if (section_pointer && ((gnu_encoding & 0x70) == DW_EH_PE_pcrel)) {
+	/* Address (*addr) above is pc relative with respect to a
+	   section. Add to the offset the base address (from elf) of
+	   section and the distance of the field we are reading from
+	   the section-beginning to get the actual address. */
+	/* ASSERT: input_field_original >= section_pointer */
+	Dwarf_Unsigned distance =
+	    input_field_original - section_pointer;
+	*addr += dbg->de_debug_frame_eh_addr + distance;
+    }
+
+    return DW_DLV_OK;
+}
+
+
+
+
+/* 
+	All augmentation string checking done here now.
+
+	For .eh_frame, gcc from 3.3 uses the z style, earlier used
+ 	only "eh" as augmentation.  We don't yet handle 
+        decoding .eh_frame with the z style extensions like L P. 
+
+	These are nasty heuristics, but then that's life
+        as augmentations are implementation specific.
+*/
+/* ARGSUSED */
+enum Dwarf_augmentation_type
+_dwarf_get_augmentation_type(Dwarf_Debug dbg,
+			     Dwarf_Small * augmentation_string,
+			     int is_gcc_eh_frame)
+{
+    enum Dwarf_augmentation_type t = aug_unknown;
+    char *ag_string = (char *) augmentation_string;
+
+    if (ag_string[0] == 0) {
+	/* Empty string. We'll just guess that we know what this means: 
+	   standard dwarf2/3 with no implementation-defined fields.  */
+	t = aug_empty_string;
+    } else if (strcmp(ag_string, DW_DEBUG_FRAME_AUGMENTER_STRING) == 0) {
+	/* The string is "mti v1". Used internally at SGI, probably
+	   never shipped. Replaced by "z". Treat like 'nothing
+	   special'.  */
+	t = aug_irix_mti_v1;
+    } else if (ag_string[0] == 'z') {
+	/* If it's IRIX cc, z means aug_irix_exception_table. z1 z2
+	   were designed as for IRIX CC, but never implemented */
+	/* If it's gcc, z may be any of several things. "z" or z
+	   followed optionally followed by one or more of L R P, each
+	   of which means a value may be present. Should be in eh_frame 
+	   only, I think. */
+	if (is_gcc_eh_frame) {
+	    t = aug_gcc_eh_z;
+	} else if (ag_string[1] == 0) {
+	    /* This is the normal IRIX C++ case, where there is an
+	       offset into a table in each fde. The table being for
+	       IRIX CC exception handling.  */
+	    /* DW_CIE_AUGMENTER_STRING_V0 "z" */
+	    t = aug_irix_exception_table;
+	}			/* Else unknown. */
+    } else if (strncmp(ag_string, "eh", 2) == 0) {
+	/* gcc .eh_frame augmentation for egcs and gcc 2.x, at least
+	   for x86. */
+	t = aug_eh;
+    }
+    return t;
+}
+
+/* Using augmentation, and version 
+   read in the augmentation data for GNU eh. 
+
+   Return DW_DLV_OK if we succeeded,
+   DW_DLV_ERR if we fail.
+
+   On success, update  'size_of_augmentation_data' with
+   the length of the fields that are part of augmentation (so the
+   caller can increment frame_ptr appropriately).
+
+   'frame_ptr' points within section.
+   'section_pointer' points to section base address in memory.
+*/
+/* ARGSUSED */
+static int
+get_gcc_eh_augmentation(Dwarf_Debug dbg, Dwarf_Small * frame_ptr,
+			unsigned long *size_of_augmentation_data,
+			enum Dwarf_augmentation_type augtype,
+			Dwarf_Small * section_pointer,
+			Dwarf_Small * fde_eh_encoding_out,
+			char *augmentation)
+{
+    char *suffix = 0;
+    unsigned long augdata_size = 0;
+
+    if (augtype == aug_gcc_eh_z) {
+	/* Has leading 'z'. */
+	Dwarf_Word leb128_length = 0;
+
+	/* Dwarf_Unsigned eh_value = */
+	_dwarf_decode_u_leb128(frame_ptr, &leb128_length);
+	augdata_size += leb128_length;
+	frame_ptr += leb128_length;
+	suffix = augmentation + 1;
+    } else {
+	/* Prefix is 'eh'.  As in gcc 3.2. No suffix present
+	   apparently. */
+	suffix = augmentation + 2;
+    }
+    for (; *suffix; ++suffix) {
+	/* We have no idea what this is as yet. Some extensions beyond
+	   dwarf exist which we do not yet handle. */
+	return DW_DLV_ERROR;
+
+    }
+
+    *size_of_augmentation_data = augdata_size;
+    return DW_DLV_OK;
+}
+
+
+/* Make the 'cie_id_addr' consistent across .debug_frame and .eh_frame.
+   Calculate a pointer into section bytes given a cie_id, which is
+   trivial for .debug_frame, but a bit more work for .eh_frame.  
+*/
+static Dwarf_Small *
+get_cieptr_given_offset(Dwarf_Unsigned cie_id_value,
+			int use_gnu_cie_calc,
+			Dwarf_Small * section_ptr,
+			Dwarf_Small * cie_id_addr)
+{
+    Dwarf_Small *cieptr = 0;
+
+    if (use_gnu_cie_calc) {
+	/* cie_id value is offset, in section, of the cie_id itself, to 
+	   use vm ptr of the value, less the value, to get to the cie
+	   itself. In addition, munge *cie_id_addr to look *as if* it
+	   was from real dwarf. */
+	cieptr = (Dwarf_Small *) ((Dwarf_Unsigned) cie_id_addr) -
+	    ((Dwarf_Unsigned) cie_id_value);
+    } else {
+	/* Traditional dwarf section offset is in cie_id */
+	cieptr = (section_ptr + cie_id_value);
+    }
+    return cieptr;
+}
+
+/* To properly release all spaced used.
+   Earlier approaches (before July 15, 2005)
+   letting client do the dealloc directly left
+   some data allocated.
+   This is directly called by consumer code.
+*/
+void
+dwarf_fde_cie_list_dealloc(Dwarf_Debug dbg,
+			   Dwarf_Cie * cie_data,
+			   Dwarf_Signed cie_element_count,
+			   Dwarf_Fde * fde_data,
+			   Dwarf_Signed fde_element_count)
+{
+    Dwarf_Signed i = 0;
+
+    for (i = 0; i < cie_element_count; ++i) {
+	Dwarf_Frame frame = cie_data[i]->ci_initial_table;
+
+	if (frame)
+	    dwarf_dealloc(dbg, frame, DW_DLA_FRAME);
+	dwarf_dealloc(dbg, cie_data[i], DW_DLA_CIE);
+    }
+    for (i = 0; i < fde_element_count; ++i) {
+	dwarf_dealloc(dbg, fde_data[i], DW_DLA_FDE);
+    }
+    if (cie_data)
+	dwarf_dealloc(dbg, cie_data, DW_DLA_LIST);
+    if (fde_data)
+	dwarf_dealloc(dbg, fde_data, DW_DLA_LIST);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_frame3.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,293 @@
+/*
+
+  Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "dwarf_frame.h"
+#include "dwarf_arange.h"	/* using Arange as a way to build a
+				   list */
+
+/*
+	Used by rqs (an IRIX application).  
+        Not needed except for that one application.
+        Should be moved to its own source file since
+        it is so rarely needed.
+	Returns DW_DLV_OK if returns the arrays.
+	Returns DW_DLV_NO_ENTRY if no section. ?? (How do I tell?)
+	Returns DW_DLV_ERROR if there is an error.
+
+        Uses DW_FRAME_CFA_COL because IRIX is only DWARF2
+        and that is what IRIX compilers and compatible
+	compilers support on IRIX.
+*/
+int
+_dwarf_frame_address_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrlist,
+			     Dwarf_Off ** offsetlist,
+			     Dwarf_Signed * returncount,
+			     Dwarf_Error * err)
+{
+    int retval = DW_DLV_OK;
+    int res;
+    Dwarf_Cie *cie_data;
+    Dwarf_Signed cie_count;
+    Dwarf_Fde *fde_data;
+    Dwarf_Signed fde_count;
+    Dwarf_Signed i;
+    Dwarf_Frame_Op *frame_inst;
+    Dwarf_Fde fdep;
+    Dwarf_Cie ciep;
+    Dwarf_Chain curr_chain = 0;
+    Dwarf_Chain head_chain = 0;
+    Dwarf_Chain prev_chain = 0;
+    Dwarf_Arange arange;
+    Dwarf_Unsigned arange_count = 0;
+    Dwarf_Addr *arange_addrs = 0;
+    Dwarf_Off *arange_offsets = 0;
+
+    res = dwarf_get_fde_list(dbg, &cie_data, &cie_count,
+			     &fde_data, &fde_count, err);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+
+    res =
+	_dwarf_load_section(dbg,
+			    dbg->de_debug_frame_index,
+			    &dbg->de_debug_frame, err);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+
+    for (i = 0; i < cie_count; i++) {
+	Dwarf_Off instoff = 0;
+	Dwarf_Signed initial_instructions_length = 0;
+	Dwarf_Small *instr_end = 0;
+	Dwarf_Sword icount = 0;
+	int j;
+	int dw_err;
+
+	ciep = cie_data[i];
+	instoff = ciep->ci_cie_instr_start - dbg->de_debug_frame;
+	initial_instructions_length = ciep->ci_length +
+	    ciep->ci_length_size + ciep->ci_extension_size -
+	    (ciep->ci_cie_instr_start - ciep->ci_cie_start);
+	instr_end = ciep->ci_cie_instr_start +
+	    initial_instructions_length;
+	res = _dwarf_exec_frame_instr( /* make_instr */ true,
+				      &frame_inst,
+				      /* search_pc= */ false,
+				      /* search_pc_val= */ 0,
+				      /* location */ 0,
+				      ciep->ci_cie_instr_start,
+				      instr_end,
+				      /* Dwarf_frame= */ 0,
+				      /* cie= */ 0,
+				      dbg,
+				      DW_FRAME_CFA_COL,
+				      &icount, &dw_err);
+	if (res == DW_DLV_ERROR) {
+	    _dwarf_error(dbg, err, dw_err);
+	    return (res);
+	} else if (res == DW_DLV_NO_ENTRY) {
+	    continue;
+	}
+
+	for (j = 0; j < icount; ++j) {
+	    Dwarf_Frame_Op *finst = frame_inst + j;
+
+	    if (finst->fp_base_op == 0 && finst->fp_extended_op == 1) {
+		/* is DW_CFA_set_loc */
+		Dwarf_Addr add = (Dwarf_Addr) finst->fp_offset;
+		Dwarf_Off off = finst->fp_instr_offset + instoff;
+
+		arange = (Dwarf_Arange)
+		    _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
+		if (arange == NULL) {
+		    _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+		    return (DW_DLV_ERROR);
+		}
+		arange->ar_address = add;
+		arange->ar_info_offset = off;
+		arange_count++;
+		curr_chain = (Dwarf_Chain)
+		    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+		if (curr_chain == NULL) {
+		    _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+		    return (DW_DLV_ERROR);
+		}
+		curr_chain->ch_item = arange;
+		if (head_chain == NULL)
+		    head_chain = prev_chain = curr_chain;
+		else {
+		    prev_chain->ch_next = curr_chain;
+		    prev_chain = curr_chain;
+		}
+	    }
+	}
+	dwarf_dealloc(dbg, frame_inst, DW_DLA_FRAME_BLOCK);
+
+    }
+    for (i = 0; i < fde_count; i++) {
+	Dwarf_Small *instr_end = 0;
+	Dwarf_Sword icount = 0;
+	Dwarf_Signed instructions_length = 0;
+	Dwarf_Off instoff = 0;
+	Dwarf_Off off = 0;
+	Dwarf_Addr addr = 0;
+	int j;
+	int dw_err;
+
+	fdep = fde_data[i];
+	off = fdep->fd_initial_loc_pos - dbg->de_debug_frame;
+	addr = fdep->fd_initial_location;
+	arange = (Dwarf_Arange)
+	    _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
+	if (arange == NULL) {
+	    _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+	    return (DW_DLV_ERROR);
+	}
+	arange->ar_address = addr;
+	arange->ar_info_offset = off;
+	arange_count++;
+	curr_chain = (Dwarf_Chain)
+	    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+	if (curr_chain == NULL) {
+	    _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+	    return (DW_DLV_ERROR);
+	}
+	curr_chain->ch_item = arange;
+	if (head_chain == NULL)
+	    head_chain = prev_chain = curr_chain;
+	else {
+	    prev_chain->ch_next = curr_chain;
+	    prev_chain = curr_chain;
+	}
+
+
+	instoff = fdep->fd_fde_instr_start - dbg->de_debug_frame;
+	instructions_length = fdep->fd_length +
+	    fdep->fd_length_size + fdep->fd_extension_size -
+	    (fdep->fd_fde_instr_start - fdep->fd_fde_start);
+	instr_end = fdep->fd_fde_instr_start + instructions_length;
+	res = _dwarf_exec_frame_instr( /* make_instr */ true,
+				      &frame_inst,
+				      /* search_pc= */ false,
+				      /* search_pc_val= */ 0,
+				      /* location */ 0,
+				      fdep->fd_fde_instr_start,
+				      instr_end,
+				      /* Dwarf_frame= */ 0,
+				      /* cie= */ 0,
+				      dbg,
+				      DW_FRAME_CFA_COL,
+				      &icount, &dw_err);
+	if (res == DW_DLV_ERROR) {
+	    _dwarf_error(dbg, err, dw_err);
+	    return (res);
+	} else if (res == DW_DLV_NO_ENTRY) {
+	    continue;
+	}
+
+	for (j = 0; j < icount; ++j) {
+	    Dwarf_Frame_Op *finst2 = frame_inst + j;
+
+	    if (finst2->fp_base_op == 0 && finst2->fp_extended_op == 1) {
+		/* is DW_CFA_set_loc */
+		Dwarf_Addr add = (Dwarf_Addr) finst2->fp_offset;
+		Dwarf_Off off = finst2->fp_instr_offset + instoff;
+
+		arange = (Dwarf_Arange)
+		    _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1);
+		if (arange == NULL) {
+		    _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+		    return (DW_DLV_ERROR);
+		}
+		arange->ar_address = add;
+		arange->ar_info_offset = off;
+		arange_count++;
+		curr_chain = (Dwarf_Chain)
+		    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+		if (curr_chain == NULL) {
+		    _dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+		    return (DW_DLV_ERROR);
+		}
+		curr_chain->ch_item = arange;
+		if (head_chain == NULL)
+		    head_chain = prev_chain = curr_chain;
+		else {
+		    prev_chain->ch_next = curr_chain;
+		    prev_chain = curr_chain;
+		}
+
+	    }
+	}
+	dwarf_dealloc(dbg, frame_inst, DW_DLA_FRAME_BLOCK);
+
+    }
+    dwarf_dealloc(dbg, fde_data, DW_DLA_LIST);
+    dwarf_dealloc(dbg, cie_data, DW_DLA_LIST);
+    arange_addrs = (Dwarf_Addr *)
+	_dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
+    if (arange_addrs == NULL) {
+	_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+    arange_offsets = (Dwarf_Off *)
+	_dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count);
+    if (arange_offsets == NULL) {
+	_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+
+    curr_chain = head_chain;
+    for (i = 0; i < arange_count; i++) {
+	Dwarf_Arange ar = curr_chain->ch_item;
+
+	arange_addrs[i] = ar->ar_address;
+	arange_offsets[i] = ar->ar_info_offset;
+	prev_chain = curr_chain;
+	curr_chain = curr_chain->ch_next;
+	dwarf_dealloc(dbg, ar, DW_DLA_ARANGE);
+	dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
+    }
+    *returncount = arange_count;
+    *offsetlist = arange_offsets;
+    *addrlist = arange_addrs;
+    return retval;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_funcs.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,140 @@
+/*
+
+  Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include "dwarf_funcs.h"
+#include "dwarf_global.h"
+
+int
+dwarf_get_funcs(Dwarf_Debug dbg,
+		Dwarf_Func ** funcs,
+		Dwarf_Signed * ret_func_count, Dwarf_Error * error)
+{
+    int res;
+
+    res =
+	_dwarf_load_section(dbg,
+			    dbg->de_debug_funcnames_index,
+			    &dbg->de_debug_funcnames, error);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+
+    return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_funcnames, dbg->de_debug_funcnames_size, (Dwarf_Global **) funcs,	/* type 
+																	   punning, 
+																	   Dwarf_Type 
+																	   is 
+																	   never 
+																	   a 
+																	   completed 
+																	   type 
+																	 */
+						  ret_func_count,
+						  error,
+						  DW_DLA_FUNC_CONTEXT,
+						  DW_DLA_FUNC,
+						  DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD,
+						  DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR);
+
+}
+
+/* Deallocating fully requires deallocating the list
+   and all entries.  But some internal data is
+   not exposed, so we need a function with internal knowledge.
+*/
+
+void
+dwarf_funcs_dealloc(Dwarf_Debug dbg, Dwarf_Func * dwgl,
+		    Dwarf_Signed count)
+{
+    _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl,
+				    count,
+				    DW_DLA_FUNC_CONTEXT,
+				    DW_DLA_FUNC, DW_DLA_LIST);
+    return;
+}
+
+
+
+int
+dwarf_funcname(Dwarf_Func func_in, char **ret_name, Dwarf_Error * error)
+{
+    Dwarf_Global func = (Dwarf_Global) func_in;
+
+    if (func == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_FUNC_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *ret_name = (char *) (func->gl_name);
+    return DW_DLV_OK;
+}
+
+int
+dwarf_func_die_offset(Dwarf_Func func_in,
+		      Dwarf_Off * return_offset, Dwarf_Error * error)
+{
+    Dwarf_Global func = (Dwarf_Global) func_in;
+
+    return dwarf_global_die_offset(func, return_offset, error);
+}
+
+
+int
+dwarf_func_cu_offset(Dwarf_Func func_in,
+		     Dwarf_Off * return_offset, Dwarf_Error * error)
+{
+    Dwarf_Global func = (Dwarf_Global) func_in;
+
+    return dwarf_global_cu_offset(func, return_offset, error);
+}
+
+
+int
+dwarf_func_name_offsets(Dwarf_Func func_in,
+			char **ret_func_name,
+			Dwarf_Off * die_offset,
+			Dwarf_Off * cu_die_offset, Dwarf_Error * error)
+{
+    Dwarf_Global func = (Dwarf_Global) func_in;
+
+    return dwarf_global_name_offsets(func,
+				     ret_func_name,
+				     die_offset, cu_die_offset, error);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_funcs.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,42 @@
+/*
+
+  Copyright (C) 2000, 2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+
+typedef struct Dwarf_Func_Context_s *Dwarf_Func_Context;
+
+
+/* struct  never completed: see dwarf_global.h */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_global.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,594 @@
+/*
+
+  Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include "dwarf_global.h"
+
+
+#ifdef __sgi			/* __sgi should only be defined for
+				   IRIX/MIPS. */
+/* The 'fixup' here intended for IRIX targets only.
+   With a  2+GB Elf64 IRIX executable (under 4GB in size),  
+   some DIE offsets wrongly
+   got the 32bit upper bit sign extended.  For the cu-header
+   offset in the .debug_pubnames section  and in the
+   .debug_aranges section.
+   the 'varp' here is a pointer to an offset into .debug_info.
+   We fix up the offset here if it seems advisable..
+   
+   As of June 2005 we have identified a series of mistakes
+   in ldx64 that can cause this (64 bit values getting passed
+   thru 32-bit signed knothole).  
+*/
+void
+_dwarf_fix_up_offset_irix(Dwarf_Debug dbg,
+			  Dwarf_Unsigned * varp, char *caller_site_name)
+{
+
+    Dwarf_Unsigned var = *varp;
+
+#define UPPER33 0xffffffff80000000LL
+#define LOWER32         0xffffffffLL
+    /* Restrict the hack to the known case. Upper 32 bits erroneously
+       sign extended from lower 32 upper bit. */
+    if ((var & UPPER33) == UPPER33) {
+	var &= LOWER32;
+	/* Apply the fix. Dreadful hack. */
+	*varp = var;
+    }
+#undef UPPER33
+#undef LOWER32
+    return;
+}
+#endif
+
+
+int
+dwarf_get_globals(Dwarf_Debug dbg,
+		  Dwarf_Global ** globals,
+		  Dwarf_Signed * return_count, Dwarf_Error * error)
+{
+    int res;
+
+    res =
+	_dwarf_load_section(dbg,
+			    dbg->de_debug_pubnames_index,
+			    &dbg->de_debug_pubnames, error);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+
+
+
+    return _dwarf_internal_get_pubnames_like_data(dbg,
+						  dbg->
+						  de_debug_pubnames,
+						  dbg->
+						  de_debug_pubnames_size,
+						  globals, return_count,
+						  error,
+						  DW_DLA_GLOBAL_CONTEXT,
+						  DW_DLA_GLOBAL,
+						  DW_DLE_PUBNAMES_LENGTH_BAD,
+						  DW_DLE_PUBNAMES_VERSION_ERROR);
+
+}
+
+/* Deallocating fully requires deallocating the list
+   and all entries.  But some internal data is
+   not exposed, so we need a function with internal knowledge.
+*/
+
+void
+dwarf_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl,
+		      Dwarf_Signed count)
+{
+    _dwarf_internal_globals_dealloc(dbg, dwgl,
+				    count,
+				    DW_DLA_GLOBAL_CONTEXT,
+				    DW_DLA_GLOBAL, DW_DLA_LIST);
+    return;
+}
+
+void
+_dwarf_internal_globals_dealloc(Dwarf_Debug dbg, Dwarf_Global * dwgl,
+				Dwarf_Signed count,
+				int context_code,
+				int global_code, int list_code)
+{
+    Dwarf_Signed i;
+    struct Dwarf_Global_Context_s *gcp = 0;
+    struct Dwarf_Global_Context_s *lastgcp = 0;
+
+    for (i = 0; i < count; i++) {
+	Dwarf_Global dgb = dwgl[i];
+
+	gcp = dgb->gl_context;
+
+	if (lastgcp != gcp) {
+	    lastgcp = gcp;
+	    dwarf_dealloc(dbg, gcp, context_code);
+	}
+	dwarf_dealloc(dbg, dgb, global_code);
+    }
+    dwarf_dealloc(dbg, dwgl, list_code);
+    return;
+}
+
+
+/* Sweeps the complete  section. 
+*/
+int
+_dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg,
+				       Dwarf_Small * section_data_ptr,
+				       Dwarf_Unsigned section_length,
+				       Dwarf_Global ** globals,
+				       Dwarf_Signed * return_count,
+				       Dwarf_Error * error,
+				       int context_code,
+				       int global_code,
+				       int length_err_num,
+				       int version_err_num)
+{
+
+
+    Dwarf_Small *pubnames_like_ptr = 0;
+
+
+
+    /* 
+       Points to the context for the current set of global names, and
+       contains information to identify the compilation-unit that the
+       set refers to. */
+    Dwarf_Global_Context pubnames_context = 0;
+
+    Dwarf_Half version = 0;
+
+    /* 
+       Offset from the start of compilation-unit for the current
+       global. */
+    Dwarf_Off die_offset_in_cu = 0;
+
+    Dwarf_Unsigned global_count = 0;
+
+    /* Points to the current global read. */
+    Dwarf_Global global = 0;
+
+    /* 
+       Used to chain the Dwarf_Global_s structs for creating contiguous 
+       list of pointers to the structs. */
+    Dwarf_Chain curr_chain = 0;
+    Dwarf_Chain prev_chain = 0;
+    Dwarf_Chain head_chain = 0;
+
+    /* Points to contiguous block of Dwarf_Global's to be returned. */
+    Dwarf_Global *ret_globals = 0;
+
+    /* Temporary counter. */
+    Dwarf_Unsigned i = 0;
+
+
+
+
+    if (dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+    /* We will eventually need the .debug_info data. Load it now. */
+    if (!dbg->de_debug_info) {
+	int res = _dwarf_load_debug_info(dbg, error);
+
+	if (res != DW_DLV_OK) {
+	    return res;
+	}
+    }
+
+    if (section_data_ptr == NULL) {
+	return (DW_DLV_NO_ENTRY);
+    }
+
+    pubnames_like_ptr = section_data_ptr;
+    do {
+	Dwarf_Unsigned length = 0;
+	int local_extension_size = 0;
+	int local_length_size = 0;
+
+	/* Some compilers emit padding at the end of each cu's area.
+	   pubnames_ptr_past_end_cu records the true area end for this
+	   cu's data.  Essentially the length in the header and the 0
+	   terminator of the data are redundant information. The
+	   dwarf2/3 spec does not mention what to do if the length is
+	   past the 0 terminator. So we take any bytes left after the 0 
+	   as padding and ignore them. */
+	Dwarf_Small *pubnames_ptr_past_end_cu = 0;
+
+
+	pubnames_context = (Dwarf_Global_Context)
+	    _dwarf_get_alloc(dbg, context_code, 1);
+	if (pubnames_context == NULL) {
+	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	    return (DW_DLV_ERROR);
+	}
+	/* READ_AREA_LENGTH updates pubnames_like_ptr for consumed
+	   bytes */
+	READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
+			 pubnames_like_ptr, local_length_size,
+			 local_extension_size);
+	pubnames_context->pu_length_size = local_length_size;
+	pubnames_context->pu_extension_size = local_extension_size;
+	pubnames_context->pu_dbg = dbg;
+
+	pubnames_ptr_past_end_cu = pubnames_like_ptr + length;
+
+	READ_UNALIGNED(dbg, version, Dwarf_Half,
+		       pubnames_like_ptr, sizeof(Dwarf_Half));
+	pubnames_like_ptr += sizeof(Dwarf_Half);
+	if (version != CURRENT_VERSION_STAMP) {
+	    _dwarf_error(dbg, error, version_err_num);
+	    return (DW_DLV_ERROR);
+	}
+
+	/* offset of CU header in debug section */
+	READ_UNALIGNED(dbg, pubnames_context->pu_offset_of_cu_header,
+		       Dwarf_Off, pubnames_like_ptr,
+		       pubnames_context->pu_length_size);
+	pubnames_like_ptr += pubnames_context->pu_length_size;
+
+	FIX_UP_OFFSET_IRIX_BUG(dbg,
+			       pubnames_context->pu_offset_of_cu_header,
+			       "pubnames cu header offset");
+
+
+	READ_UNALIGNED(dbg, pubnames_context->pu_info_length,
+		       Dwarf_Unsigned, pubnames_like_ptr,
+		       pubnames_context->pu_length_size);
+	pubnames_like_ptr += pubnames_context->pu_length_size;
+
+	if (pubnames_like_ptr > (section_data_ptr + section_length)) {
+	    _dwarf_error(dbg, error, length_err_num);
+	    return (DW_DLV_ERROR);
+	}
+
+	/* read initial offset (of DIE within CU) of a pubname, final
+	   entry is not a pair, just a zero offset */
+	READ_UNALIGNED(dbg, die_offset_in_cu, Dwarf_Off,
+		       pubnames_like_ptr,
+		       pubnames_context->pu_length_size);
+	pubnames_like_ptr += pubnames_context->pu_length_size;
+	FIX_UP_OFFSET_IRIX_BUG(dbg,
+			       die_offset_in_cu, "offset of die in cu");
+
+	/* loop thru pairs. DIE off with CU followed by string */
+	while (die_offset_in_cu != 0) {
+
+	    /* Already read offset, pubnames_like_ptr now points to the 
+	       string */
+	    global =
+		(Dwarf_Global) _dwarf_get_alloc(dbg, global_code, 1);
+	    if (global == NULL) {
+		_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+		return (DW_DLV_ERROR);
+	    }
+	    global_count++;
+
+	    global->gl_context = pubnames_context;
+
+	    global->gl_named_die_offset_within_cu = die_offset_in_cu;
+
+	    global->gl_name = pubnames_like_ptr;
+
+	    pubnames_like_ptr = pubnames_like_ptr +
+		strlen((char *) pubnames_like_ptr) + 1;
+
+
+	    /* finish off current entry chain */
+	    curr_chain =
+		(Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+	    if (curr_chain == NULL) {
+		_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+		return (DW_DLV_ERROR);
+	    }
+
+	    /* Put current global on singly_linked list. */
+	    curr_chain->ch_item = (Dwarf_Global) global;
+
+	    if (head_chain == NULL)
+		head_chain = prev_chain = curr_chain;
+	    else {
+		prev_chain->ch_next = curr_chain;
+		prev_chain = curr_chain;
+	    }
+
+	    /* read offset for the *next* entry */
+	    READ_UNALIGNED(dbg, die_offset_in_cu, Dwarf_Off,
+			   pubnames_like_ptr,
+			   pubnames_context->pu_length_size);
+
+	    pubnames_like_ptr += pubnames_context->pu_length_size;
+	    FIX_UP_OFFSET_IRIX_BUG(dbg,
+				   die_offset_in_cu,
+				   "offset of next die in cu");
+
+	    if (pubnames_like_ptr > (section_data_ptr + section_length)) {
+		_dwarf_error(dbg, error, length_err_num);
+		return (DW_DLV_ERROR);
+	    }
+	}
+	/* ASSERT: die_offset_in_cu == 0 */
+	if (pubnames_like_ptr > pubnames_ptr_past_end_cu) {
+	    /* This is some kind of error. This simply cannot happen.
+	       The encoding is wrong or the length in the header for
+	       this cu's contribution is wrong. */
+	    _dwarf_error(dbg, error, length_err_num);
+	    return (DW_DLV_ERROR);
+
+	}
+	/* If there is some kind of padding at the end of the section,
+	   as emitted by some compilers, skip over that padding and
+	   simply ignore the bytes thus passed-over.  With most
+	   compilers, pubnames_like_ptr == pubnames_ptr_past_end_cu at
+	   this point */
+	pubnames_like_ptr = pubnames_ptr_past_end_cu;
+
+    } while (pubnames_like_ptr < (section_data_ptr + section_length));
+
+    /* Points to contiguous block of Dwarf_Global's. */
+    ret_globals = (Dwarf_Global *)
+	_dwarf_get_alloc(dbg, DW_DLA_LIST, global_count);
+    if (ret_globals == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+
+    /* 
+       Store pointers to Dwarf_Global_s structs in contiguous block,
+       and deallocate the chain. */
+    curr_chain = head_chain;
+    for (i = 0; i < global_count; i++) {
+	*(ret_globals + i) = curr_chain->ch_item;
+	prev_chain = curr_chain;
+	curr_chain = curr_chain->ch_next;
+	dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
+    }
+
+    *globals = ret_globals;
+    *return_count = (Dwarf_Signed) global_count;
+    return DW_DLV_OK;
+}
+
+
+/*
+	Given a pubnames entry (or other like section entry)
+	return thru the ret_name pointer
+	a pointer to the string which is the entry name.
+	
+*/
+int
+dwarf_globname(Dwarf_Global glob, char **ret_name, Dwarf_Error * error)
+{
+    if (glob == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *ret_name = (char *) (glob->gl_name);
+    return DW_DLV_OK;
+}
+
+
+/*
+	Given a pubnames entry (or other like section entry)
+	return thru the ret_off pointer the
+	global offset of the DIE for this entry.
+	The global offset is the offset within the .debug_info
+	section as a whole.
+*/
+int
+dwarf_global_die_offset(Dwarf_Global global,
+			Dwarf_Off * ret_off, Dwarf_Error * error)
+{
+    if (global == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    if (global->gl_context == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *ret_off = (global->gl_named_die_offset_within_cu +
+		global->gl_context->pu_offset_of_cu_header);
+    return DW_DLV_OK;
+}
+
+/*
+	Given a pubnames entry (or other like section entry)
+	return thru the ret_off pointer the
+	offset of the compilation unit header of the
+        compilation unit the global is part of.
+
+	In early versions of this, the value returned was
+        the offset of the compilation unit die, and
+	other cu-local die offsets were faked so adding this to 
+        such a cu-local offset got a true section offset.
+        Now things do as they say (adding *cu_header_offset to
+        a cu-local offset gets the section offset).
+
+*/
+int
+dwarf_global_cu_offset(Dwarf_Global global,
+		       Dwarf_Off * cu_header_offset,
+		       Dwarf_Error * error)
+{
+    Dwarf_Global_Context con = 0;
+
+    if (global == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    con = global->gl_context;
+
+    if (con == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    /* In early libdwarf, this incorrectly returned the offset of the
+       CU DIE. Now correctly returns the header offset. */
+    *cu_header_offset = con->pu_offset_of_cu_header;
+
+    return DW_DLV_OK;
+}
+
+/*
+  Give back the pubnames entry (or any other like section)
+  name, symbol DIE offset, and the cu-DIE offset.
+
+  Various errors are possible.
+
+  The string pointer returned thru ret_name is not
+  dwarf_get_alloc()ed, so no dwarf_dealloc() 
+  DW_DLA_STRING should be applied to it.
+
+*/
+int
+dwarf_global_name_offsets(Dwarf_Global global,
+			  char **ret_name,
+			  Dwarf_Off * die_offset,
+			  Dwarf_Off * cu_die_offset,
+			  Dwarf_Error * error)
+{
+    Dwarf_Global_Context con = 0;
+    Dwarf_Debug dbg = 0;
+    Dwarf_Off off = 0;
+
+    if (global == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_GLOBAL_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    con = global->gl_context;
+
+    if (con == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_GLOBAL_CONTEXT_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    off = con->pu_offset_of_cu_header;
+    /* The offset had better not be too close to the end. If it is,
+       _dwarf_length_of_cu_header() will step off the end and therefore 
+       must not be used. 10 is a meaningless heuristic, but no CU
+       header is that small so it is safe. An erroneous offset is due
+       to a bug in the tool chain. A bug like this has been seen on
+       IRIX with MIPSpro 7.3.1.3 and an executable > 2GB in size and
+       with 2 million pubnames entries. */
+#define MIN_CU_HDR_SIZE 10
+    dbg = con->pu_dbg;
+    if (dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+    if (dbg->de_debug_info_size &&
+	((off + MIN_CU_HDR_SIZE) >= dbg->de_debug_info_size)) {
+	_dwarf_error(NULL, error, DW_DLE_OFFSET_BAD);
+	return (DW_DLV_ERROR);
+    }
+#undef MIN_CU_HDR_SIZE
+    if (die_offset != NULL) {
+	*die_offset = global->gl_named_die_offset_within_cu + off;
+    }
+
+    *ret_name = (char *) global->gl_name;
+
+    if (cu_die_offset != NULL) {
+	int res = _dwarf_load_debug_info(dbg, error);
+
+	if (res != DW_DLV_OK) {
+	    return res;
+	}
+	/* The offset had better not be too close to the end. If it is, 
+	   _dwarf_length_of_cu_header() will step off the end and
+	   therefore must not be used. 10 is a meaningless heuristic,
+	   but no CU header is that small so it is safe. */
+	if ((off + 10) >= dbg->de_debug_info_size) {
+	    _dwarf_error(NULL, error, DW_DLE_OFFSET_BAD);
+	    return (DW_DLV_ERROR);
+	}
+	*cu_die_offset = off + _dwarf_length_of_cu_header(dbg, off);
+    }
+
+
+    return DW_DLV_OK;
+}
+
+/*
+	We have the offset to a CU header.
+	Return thru outFileOffset the offset of the CU DIE.
+	
+	New June, 2001.
+	Used by SGI debuggers.
+	No error is possible.
+*/
+
+/* ARGSUSED */
+int
+dwarf_get_cu_die_offset_given_cu_header_offset(Dwarf_Debug dbg,
+					       Dwarf_Off
+					       in_cu_header_offset,
+					       Dwarf_Off *
+					       out_cu_die_offset,
+					       Dwarf_Error * err)
+{
+    Dwarf_Off len =
+	_dwarf_length_of_cu_header(dbg, in_cu_header_offset);
+
+    Dwarf_Off newoff = in_cu_header_offset + len;
+
+    *out_cu_die_offset = newoff;
+    return DW_DLV_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_global.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,124 @@
+/*
+
+  Copyright (C) 2000,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+
+typedef struct Dwarf_Global_Context_s *Dwarf_Global_Context;
+
+/* 
+    This struct contains header information for a set of pubnames.
+    Essentially, they contain the context for a set of pubnames 
+    belonging to a compilation-unit.
+
+    This is also used for the sgi-specific
+    weaknames, typenames, varnames, funcnames data:
+    the structs for those are incomplete and
+    instances of this are used instead.
+
+    Also used for DWARF3 .debug_pubtypes.
+
+*/
+struct Dwarf_Global_Context_s {
+
+    /* Length in .debug_pubnames (etc) of a set of names for a
+       compilation-unit. Dwarf_Word pu_length; The value is not made
+       available outside libdwarf and not used inside, so no need to
+       record it. */
+
+    /* For this context, size of a length. 4 or 8 */
+    unsigned char pu_length_size;
+
+    /* For this CU, size of the extension 0 except for dwarf2 extension 
+       64bit, in which case is 4. */
+    unsigned char pu_extension_size;
+
+    /* 
+       Offset into .debug_info of the compilation-unit header (not DIE) 
+       for this set of pubnames. */
+    Dwarf_Off pu_offset_of_cu_header;
+
+    /* Size of compilation-unit that these pubnames are in. */
+    Dwarf_Unsigned pu_info_length;
+
+    Dwarf_Debug pu_dbg;
+};
+
+
+/* This struct contains information for a single pubname. */
+struct Dwarf_Global_s {
+
+    /* 
+       Offset from the start of the corresponding compilation-unit of
+       the DIE for the given pubname CU. */
+    Dwarf_Off gl_named_die_offset_within_cu;
+
+    /* Points to the given pubname. */
+    Dwarf_Small *gl_name;
+
+    /* Context for this pubname. */
+    Dwarf_Global_Context gl_context;
+};
+
+int _dwarf_internal_get_pubnames_like_data(Dwarf_Debug dbg,
+					   Dwarf_Small *
+					   section_data_ptr,
+					   Dwarf_Unsigned
+					   section_length,
+					   Dwarf_Global ** globals,
+					   Dwarf_Signed * return_count,
+					   Dwarf_Error * error,
+					   int context_code,
+					   int global_code,
+					   int length_err_num,
+					   int version_err_num);
+
+void
+_dwarf_internal_globals_dealloc( Dwarf_Debug dbg, Dwarf_Global *dwgl,
+        Dwarf_Signed count,
+        int context_code,
+        int global_code,
+        int list_code);
+
+
+#ifdef __sgi  /* __sgi should only be defined for IRIX/MIPS. */
+void _dwarf_fix_up_offset_irix(Dwarf_Debug dbg,
+        Dwarf_Unsigned *varp,
+        char *caller_site_name);
+#define FIX_UP_OFFSET_IRIX_BUG(ldbg,var,name) _dwarf_fix_up_offset_irix(ldbg,&var,name)
+#else
+#define FIX_UP_OFFSET_IRIX_BUG(ldbg,var,name)
+#endif
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_incl.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,65 @@
+/*
+
+  Copyright (C) 2000, 2002, 2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#ifndef DWARF_INCL_H
+#define DWARF_INCL_H
+#if (!defined(HAVE_RAW_LIBELF_OK) && defined(HAVE_LIBELF_OFF64_OK) )
+/* At a certain point libelf.h requires _GNU_SOURCE.
+   here we assume the criteria in configure determine that
+   usefully.
+*/
+#define _GNU_SOURCE 1
+#endif
+
+
+#include "libdwarfdefs.h"
+#include <string.h>
+
+#ifdef HAVE_ELF_H
+#include <elf.h>
+#endif
+
+#include <limits.h>
+#include <libdwarf.h>
+#include <dwarf.h>
+
+#include "dwarf_base_types.h"
+#include "dwarf_alloc.h"
+#include "dwarf_opaque.h"
+#include "dwarf_error.h"
+#include "dwarf_util.h"
+#endif /* DWARF_INCL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_init_finish.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,822 @@
+/*
+
+  Copyright (C) 2000,2002,2003,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+#if (!defined(HAVE_RAW_LIBELF_OK) && defined(HAVE_LIBELF_OFF64_OK) )
+#endif
+
+#include "config.h"
+#include "dwarf_incl.h"
+#ifdef HAVE_ELF_H
+#include <elf.h>
+#endif
+#ifdef __SGI_FAST_LIBELF
+#include <libelf_sgi.h>
+#else
+#ifdef HAVE_LIBELF_H
+#include <libelf.h>
+#else
+#ifdef HAVE_LIBELF_LIBELF_H
+#include <libelf/libelf.h>
+#endif
+#endif
+#endif /* !defined(__SGI_FAST_LIBELF) */
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "dwarf_incl.h"
+#include "malloc_check.h"
+
+#define DWARF_DBG_ERROR(dbg,errval,retval) \
+     _dwarf_error(dbg, error, errval); return(retval);
+
+#define FALSE	0
+#define TRUE	1
+
+#ifdef __SGI_FAST_LIBELF
+#else
+#ifdef HAVE_ELF64_GETEHDR
+extern Elf64_Ehdr *elf64_getehdr(Elf *);
+#endif
+#ifdef HAVE_ELF64_GETSHDR
+extern Elf64_Shdr *elf64_getshdr(Elf_Scn *);
+#endif
+#endif /* !defined(__SGI_FAST_LIBELF) */
+
+
+/* This static is copied to the dbg on dbg init
+   so that the static need not be referenced at
+   run time, preserving better locality of
+   reference.
+   Value is 0 means do the string check.
+   Value non-zero means do not do the check.
+*/
+static Dwarf_Small _dwarf_assume_string_bad;
+
+
+int
+dwarf_set_stringcheck(int newval)
+{
+    int oldval = _dwarf_assume_string_bad;
+
+    _dwarf_assume_string_bad = newval;
+    return oldval;
+}
+
+#ifdef __SGI_FAST_LIBELF
+/*
+	This function translates an elf_sgi error code into a libdwarf
+	code.
+ */
+static int
+_dwarf_error_code_from_elf_sgi_error_code(enum elf_sgi_error_type val)
+{
+    switch (val) {
+    case ELF_SGI_ERROR_OK:
+	return DW_DLE_NE;
+    case ELF_SGI_ERROR_BAD_ALLOC:
+	return DW_DLE_MAF;
+    case ELF_SGI_ERROR_FORMAT:
+	return DW_DLE_MDE;
+    case ELF_SGI_ERROR_ERRNO:
+	return DW_DLE_IOF;
+    case ELF_SGI_ERROR_TOO_BIG:
+	return DW_DLE_MOF;
+    default:
+	return DW_DLE_LEE;
+    }
+}
+#endif
+
+/*
+    Given an Elf ptr, set up dbg with pointers
+    to all the Dwarf data sections.
+    Return NULL on error.
+
+    This function is also responsible for determining
+    whether the given object contains Dwarf information
+    or not.  The test currently used is that it contains
+    either a .debug_info or a .debug_frame section.  If 
+    not, it returns DW_DLV_NO_ENTRY causing dwarf_init() also to 
+    return DW_DLV_NO_ENTRY.  Earlier, we had thought of using only 
+    the presence/absence of .debug_info to test, but we 
+    added .debug_frame since there could be stripped objects 
+    that have only a .debug_frame section for exception 
+    processing.
+    DW_DLV_NO_ENTRY or DW_DLV_OK or DW_DLV_ERROR
+*/
+static int
+_dwarf_setup(Dwarf_Debug dbg, dwarf_elf_handle elf, Dwarf_Error * error)
+{
+#ifdef __SGI_FAST_LIBELF
+    Elf64_Ehdr ehdr;
+    Elf64_Shdr shdr;
+    enum elf_sgi_error_type sres;
+    unsigned char const *ehdr_ident = 0;
+#else
+    Elf32_Ehdr *ehdr32 = 0;
+
+#ifdef HAVE_ELF64_GETEHDR
+    Elf64_Ehdr *ehdr64 = 0;
+#endif
+    Elf32_Shdr *shdr32 = 0;
+
+#ifdef HAVE_ELF64_GETSHDR
+    Elf64_Shdr *shdr64 = 0;
+#endif
+    Elf_Scn *scn = 0;
+    char *ehdr_ident = 0;
+#endif /* !defined(__SGI_FAST_LIBELF) */
+    Dwarf_Half machine = 0;
+    char *scn_name = 0;
+    int is_64bit = 0;
+    int foundDwarf = 0;
+
+    Dwarf_Unsigned section_size = 0;
+    Dwarf_Unsigned section_count = 0;
+    Dwarf_Half section_index = 0;
+    Dwarf_Addr section_addr = 0;
+
+    foundDwarf = FALSE;
+    dbg->de_elf = elf;
+
+    dbg->de_assume_string_in_bounds = _dwarf_assume_string_bad;
+
+#ifdef __SGI_FAST_LIBELF
+    sres = elf_sgi_ehdr(elf, &ehdr);
+    if (sres != ELF_SGI_ERROR_OK) {
+	DWARF_DBG_ERROR(dbg,
+			_dwarf_error_code_from_elf_sgi_error_code(sres),
+			DW_DLV_ERROR);
+    }
+    ehdr_ident = ehdr.e_ident;
+    section_count = ehdr.e_shnum;
+    machine = ehdr.e_machine;
+#else
+    if ((ehdr_ident = elf_getident(elf, NULL)) == NULL) {
+	DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETIDENT_ERROR, DW_DLV_ERROR);
+    }
+#endif
+
+    is_64bit = (ehdr_ident[EI_CLASS] == ELFCLASS64);
+
+
+    dbg->de_same_endian = 1;
+    dbg->de_copy_word = memcpy;
+#ifdef WORDS_BIGENDIAN
+    dbg->de_big_endian_object = 1;
+    if (ehdr_ident[EI_DATA] == ELFDATA2LSB) {
+	dbg->de_same_endian = 0;
+	dbg->de_big_endian_object = 0;
+	dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
+    }
+#else /* little endian */
+    dbg->de_big_endian_object = 0;
+    if (ehdr_ident[EI_DATA] == ELFDATA2MSB) {
+	dbg->de_same_endian = 0;
+	dbg->de_big_endian_object = 1;
+	dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
+    }
+#endif /* !WORDS_BIGENDIAN */
+
+    /* The following de_length_size is Not Too Significant. Only used
+       one calculation, and an approximate one at that. */
+    dbg->de_length_size = is_64bit ? 8 : 4;
+    dbg->de_pointer_size = is_64bit ? 8 : 4;
+
+
+#ifdef __SGI_FAST_LIBELF
+    /* We've already loaded the ELF header, so there's nothing to do
+       here */
+#else
+#ifdef HAVE_ELF64_GETEHDR
+    if (is_64bit) {
+	ehdr64 = elf64_getehdr(elf);
+	if (ehdr64 == NULL) {
+	    DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETEHDR_ERROR,
+			    DW_DLV_ERROR);
+	}
+	section_count = ehdr64->e_shnum;
+	machine = ehdr64->e_machine;
+    } else
+#endif
+    {
+	ehdr32 = elf32_getehdr(elf);
+	if (ehdr32 == NULL) {
+	    DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETEHDR_ERROR,
+			    DW_DLV_ERROR);
+	}
+	section_count = ehdr32->e_shnum;
+	machine = ehdr32->e_machine;
+    }
+#endif /* !defined(__SGI_FAST_LIBELF) */
+
+    if (is_64bit && machine != EM_MIPS) {
+	/* MIPS/IRIX makes pointer size and length size 8 for -64.
+	   Other platforms make length 4 always. */
+	/* 4 here supports 32bit-offset dwarf2, as emitted by cygnus
+	   tools, and the dwarfv2.1 64bit extension setting. */
+	dbg->de_length_size = 4;
+    }
+
+    /* We start at index 1 to skip the initial empty section. */
+    for (section_index = 1; section_index < section_count;
+	 ++section_index) {
+
+#ifdef __SGI_FAST_LIBELF
+	sres = elf_sgi_shdr(elf, section_index, &shdr);
+	if (sres != ELF_SGI_ERROR_OK) {
+	    DWARF_DBG_ERROR(dbg,
+			    _dwarf_error_code_from_elf_sgi_error_code
+			    (sres), DW_DLV_ERROR);
+	}
+
+	section_size = shdr.sh_size;
+	section_addr = shdr.sh_addr;
+
+	sres =
+	    elf_sgi_string(elf, ehdr.e_shstrndx, shdr.sh_name,
+			   (char const **) &scn_name);
+	if (sres != ELF_SGI_ERROR_OK) {
+	    DWARF_DBG_ERROR(dbg,
+			    _dwarf_error_code_from_elf_sgi_error_code
+			    (sres), DW_DLV_ERROR);
+	}
+#else /* !defined(__SGI_FAST_LIBELF) */
+	scn = elf_getscn(elf, section_index);
+	if (scn == NULL) {
+	    DWARF_DBG_ERROR(dbg, DW_DLE_MDE, DW_DLV_ERROR);
+	}
+#ifdef HAVE_ELF64_GETSHDR
+	if (is_64bit) {
+	    shdr64 = elf64_getshdr(scn);
+	    if (shdr64 == NULL) {
+		DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETSHDR_ERROR,
+				DW_DLV_ERROR);
+	    }
+
+	    section_size = shdr64->sh_size;
+	    section_addr = shdr64->sh_addr;
+
+	    if ((scn_name = elf_strptr(elf, ehdr64->e_shstrndx,
+				       shdr64->sh_name))
+		== NULL) {
+		DWARF_DBG_ERROR(dbg, DW_DLE_ELF_STRPTR_ERROR,
+				DW_DLV_ERROR);
+	    }
+	} else
+#endif /* HAVE_ELF64_GETSHDR */
+	{
+	    if ((shdr32 = elf32_getshdr(scn)) == NULL) {
+		DWARF_DBG_ERROR(dbg, DW_DLE_ELF_GETSHDR_ERROR, 0);
+	    }
+
+	    section_size = shdr32->sh_size;
+	    section_addr = shdr32->sh_addr;
+
+	    if ((scn_name = elf_strptr(elf, ehdr32->e_shstrndx,
+				       shdr32->sh_name)) == NULL) {
+		DWARF_DBG_ERROR(dbg, DW_DLE_ELF_STRPTR_ERROR,
+				DW_DLV_ERROR);
+	    }
+	}
+#endif /* !defined(__SGI_FAST_LIBELF) */
+
+	if (strncmp(scn_name, ".debug_", 7)
+	    && strcmp(scn_name, ".eh_frame")
+	    )
+	    continue;
+
+	else if (strcmp(scn_name, ".debug_info") == 0) {
+	    if (dbg->de_debug_info != NULL) {
+		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_INFO_DUPLICATE,
+				DW_DLV_ERROR);
+	    }
+	    if (section_size == 0) {
+		/* Know no reason to allow empty debug_info section */
+		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_INFO_NULL,
+				DW_DLV_ERROR);
+	    }
+	    foundDwarf = TRUE;
+	    dbg->de_debug_info_index = section_index;
+	    dbg->de_debug_info_size = section_size;
+	}
+
+	else if (strcmp(scn_name, ".debug_abbrev") == 0) {
+	    if (dbg->de_debug_abbrev != NULL) {
+		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_ABBREV_DUPLICATE,
+				DW_DLV_ERROR);
+	    }
+	    if (section_size == 0) {
+		/* Know no reason to allow empty debug_abbrev section */
+		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_ABBREV_NULL,
+				DW_DLV_ERROR);
+	    }
+	    dbg->de_debug_abbrev_index = section_index;
+	    dbg->de_debug_abbrev_size = section_size;
+	}
+
+	else if (strcmp(scn_name, ".debug_aranges") == 0) {
+	    if (dbg->de_debug_aranges_index != 0) {
+		DWARF_DBG_ERROR(dbg,
+				DW_DLE_DEBUG_ARANGES_DUPLICATE,
+				DW_DLV_ERROR);
+	    }
+	    if (section_size == 0) {
+		/* a zero size section is just empty. Ok, no error */
+		continue;
+	    }
+	    dbg->de_debug_aranges_index = section_index;
+	    dbg->de_debug_aranges_size = section_size;
+	}
+
+	else if (strcmp(scn_name, ".debug_line") == 0) {
+	    if (dbg->de_debug_line_index != 0) {
+		DWARF_DBG_ERROR(dbg,
+				DW_DLE_DEBUG_LINE_DUPLICATE,
+				DW_DLV_ERROR);
+	    }
+	    if (section_size == 0) {
+		/* a zero size section is just empty. Ok, no error */
+		continue;
+	    }
+	    dbg->de_debug_line_index = section_index;
+	    dbg->de_debug_line_size = section_size;
+	}
+
+	else if (strcmp(scn_name, ".debug_frame") == 0) {
+	    if (dbg->de_debug_frame_index != 0) {
+		DWARF_DBG_ERROR(dbg,
+				DW_DLE_DEBUG_FRAME_DUPLICATE,
+				DW_DLV_ERROR);
+	    }
+	    if (section_size == 0) {
+		/* a zero size section is just empty. Ok, no error */
+		continue;
+	    }
+	    dbg->de_debug_frame_index = section_index;
+	    dbg->de_debug_frame_size = section_size;
+	    foundDwarf = TRUE;
+	} else if (strcmp(scn_name, ".eh_frame") == 0) {
+	    /* gnu egcs-1.1.2 data */
+	    if (dbg->de_debug_frame_eh_gnu_index != 0) {
+		DWARF_DBG_ERROR(dbg,
+				DW_DLE_DEBUG_FRAME_DUPLICATE,
+				DW_DLV_ERROR);
+	    }
+	    if (section_size == 0) {
+		/* a zero size section is just empty. Ok, no error */
+		continue;
+	    }
+	    dbg->de_debug_frame_eh_gnu_index = section_index;
+	    dbg->de_debug_frame_size_eh_gnu = section_size;
+	    dbg->de_debug_frame_eh_addr = section_addr;
+	    foundDwarf = TRUE;
+	}
+
+	else if (strcmp(scn_name, ".debug_loc") == 0) {
+	    if (dbg->de_debug_loc_index != 0) {
+		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_LOC_DUPLICATE,
+				DW_DLV_ERROR);
+	    }
+	    if (section_size == 0) {
+		/* a zero size section is just empty. Ok, no error */
+		continue;
+	    }
+	    dbg->de_debug_loc_index = section_index;
+	    dbg->de_debug_loc_size = section_size;
+	}
+
+
+	else if (strcmp(scn_name, ".debug_pubnames") == 0) {
+	    if (dbg->de_debug_pubnames_index != 0) {
+		DWARF_DBG_ERROR(dbg, DW_DLE_DEBUG_PUBNAMES_DUPLICATE,
+				DW_DLV_ERROR);
+	    }
+	    if (section_size == 0) {
+		/* a zero size section is just empty. Ok, no error */
+		continue;
+	    }
+	    dbg->de_debug_pubnames_index = section_index;
+	    dbg->de_debug_pubnames_size = section_size;
+	}
+
+	else if (strcmp(scn_name, ".debug_str") == 0) {
+	    if (dbg->de_debug_str_index != 0) {
+		DWARF_DBG_ERROR(dbg,
+				DW_DLE_DEBUG_STR_DUPLICATE,
+				DW_DLV_ERROR);
+	    }
+	    if (section_size == 0) {
+		/* a zero size section is just empty. Ok, no error */
+		continue;
+	    }
+	    dbg->de_debug_str_index = section_index;
+	    dbg->de_debug_str_size = section_size;
+	}
+
+	else if (strcmp(scn_name, ".debug_funcnames") == 0) {
+	    if (dbg->de_debug_funcnames_index != 0) {
+		DWARF_DBG_ERROR(dbg,
+				DW_DLE_DEBUG_FUNCNAMES_DUPLICATE,
+				DW_DLV_ERROR);
+	    }
+	    if (section_size == 0) {
+		/* a zero size section is just empty. Ok, no error */
+		continue;
+	    }
+	    dbg->de_debug_funcnames_index = section_index;
+	    dbg->de_debug_funcnames_size = section_size;
+	}
+
+	else if (strcmp(scn_name, ".debug_typenames") == 0) {
+	    /* SGI IRIX-only, created years before DWARF3. Content
+	       essentially identical to .debug_pubtypes.  */
+	    if (dbg->de_debug_typenames_index != 0) {
+		DWARF_DBG_ERROR(dbg,
+				DW_DLE_DEBUG_TYPENAMES_DUPLICATE,
+				DW_DLV_ERROR);
+	    }
+	    if (section_size == 0) {
+		/* a zero size section is just empty. Ok, no error */
+		continue;
+	    }
+	    dbg->de_debug_typenames_index = section_index;
+	    dbg->de_debug_typenames_size = section_size;
+	} else if (strcmp(scn_name, ".debug_pubtypes") == 0) {
+	    /* Section new in DWARF3.  */
+	    if (dbg->de_debug_pubtypes_index != 0) {
+		DWARF_DBG_ERROR(dbg,
+				DW_DLE_DEBUG_PUBTYPES_DUPLICATE,
+				DW_DLV_ERROR);
+	    }
+	    if (section_size == 0) {
+		/* a zero size section is just empty. Ok, no error */
+		continue;
+	    }
+	    dbg->de_debug_pubtypes_index = section_index;
+	    dbg->de_debug_pubtypes_size = section_size;
+	}
+
+	else if (strcmp(scn_name, ".debug_varnames") == 0) {
+	    if (dbg->de_debug_varnames_index != 0) {
+		DWARF_DBG_ERROR(dbg,
+				DW_DLE_DEBUG_VARNAMES_DUPLICATE,
+				DW_DLV_ERROR);
+	    }
+	    if (section_size == 0) {
+		/* a zero size section is just empty. Ok, no error */
+		continue;
+	    }
+	    dbg->de_debug_varnames_index = section_index;
+	    dbg->de_debug_varnames_size = section_size;
+	}
+
+	else if (strcmp(scn_name, ".debug_weaknames") == 0) {
+	    if (dbg->de_debug_weaknames_index != 0) {
+		DWARF_DBG_ERROR(dbg,
+				DW_DLE_DEBUG_WEAKNAMES_DUPLICATE,
+				DW_DLV_ERROR);
+	    }
+	    if (section_size == 0) {
+		/* a zero size section is just empty. Ok, no error */
+		continue;
+	    }
+	    dbg->de_debug_weaknames_index = section_index;
+	    dbg->de_debug_weaknames_size = section_size;
+	} else if (strcmp(scn_name, ".debug_macinfo") == 0) {
+	    if (dbg->de_debug_macinfo_index != 0) {
+		DWARF_DBG_ERROR(dbg,
+				DW_DLE_DEBUG_MACINFO_DUPLICATE,
+				DW_DLV_ERROR);
+	    }
+	    if (section_size == 0) {
+		/* a zero size section is just empty. Ok, no error */
+		continue;
+	    }
+	    dbg->de_debug_macinfo_index = section_index;
+	    dbg->de_debug_macinfo_size = section_size;
+	}
+    }
+    if (foundDwarf) {
+	return DW_DLV_OK;
+    }
+
+    return (DW_DLV_NO_ENTRY);
+}
+
+
+/*
+    The basic dwarf initializer function for consumers.
+    Return NULL on error.
+*/
+int
+dwarf_init(int fd,
+	   Dwarf_Unsigned access,
+	   Dwarf_Handler errhand,
+	   Dwarf_Ptr errarg, Dwarf_Debug * ret_dbg, Dwarf_Error * error)
+{
+    Dwarf_Debug dbg;
+    struct stat fstat_buf;
+    dwarf_elf_handle elf;
+    int res;
+
+#ifdef __SGI_FAST_LIBELF
+    enum elf_sgi_error_type sres;
+#else
+    Elf_Cmd what_kind_of_elf_read;
+#endif
+
+    dbg = _dwarf_get_debug();
+    if (dbg == NULL) {
+	DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR);
+    }
+    dbg->de_errhand = errhand;
+    dbg->de_errarg = errarg;
+    dbg->de_frame_rule_initial_value = DW_FRAME_REG_INITIAL_VALUE;
+    dbg->de_frame_reg_rules_entry_count = DW_FRAME_LAST_REG_NUM;
+
+
+    if (fstat(fd, &fstat_buf) != 0) {
+	DWARF_DBG_ERROR(dbg, DW_DLE_FSTAT_ERROR, DW_DLV_ERROR);
+    }
+    if (!S_ISREG(fstat_buf.st_mode)) {
+	DWARF_DBG_ERROR(dbg, DW_DLE_FSTAT_MODE_ERROR, DW_DLV_ERROR);
+    }
+
+    if (access != DW_DLC_READ) {
+	DWARF_DBG_ERROR(dbg, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR);
+    }
+    dbg->de_access = access;
+
+#ifdef __SGI_FAST_LIBELF
+    elf = elf_sgi_new();
+    if (elf == NULL) {
+	DWARF_DBG_ERROR(dbg, DW_DLE_MAF, DW_DLV_ERROR);
+    }
+
+    sres = elf_sgi_begin_fd(elf, fd, 0);
+    if (sres != ELF_SGI_ERROR_OK) {
+	elf_sgi_free(elf);
+	DWARF_DBG_ERROR(dbg,
+			_dwarf_error_code_from_elf_sgi_error_code(sres),
+			DW_DLV_ERROR);
+    }
+#else /* ! __SGI_FAST_LIBELF */
+    elf_version(EV_CURRENT);
+    /* changed to mmap request per bug 281217. 6/95 */
+#ifdef HAVE_ELF_C_READ_MMAP
+    /* ELF_C_READ_MMAP is an SGI IRIX specific enum value from IRIX
+       libelf.h meaning read but use mmap */
+    what_kind_of_elf_read = ELF_C_READ_MMAP;
+#else /* !HAVE_ELF_C_READ_MMAP */
+    /* ELF_C_READ is a portable value */
+    what_kind_of_elf_read = ELF_C_READ;
+#endif /* HAVE_ELF_C_READ_MMAP */
+
+    if ((elf = elf_begin(fd, what_kind_of_elf_read, 0)) == NULL) {
+	DWARF_DBG_ERROR(dbg, DW_DLE_ELF_BEGIN_ERROR, DW_DLV_ERROR);
+    }
+#endif /* !defined(__SGI_FAST_LIBELF) */
+
+    dbg->de_elf_must_close = 1;
+    if ((res = _dwarf_setup(dbg, elf, error)) != DW_DLV_OK) {
+#ifdef __SGI_FAST_LIBELF
+	elf_sgi_free(elf);
+#else
+	elf_end(elf);
+#endif
+	free(dbg);
+	return (res);
+    }
+
+    /* call cannot fail: no malloc or free involved */
+    _dwarf_setup_debug(dbg);
+
+    *ret_dbg = dbg;
+    return (DW_DLV_OK);
+}
+
+
+/*
+    The alternate dwarf setup call for consumers
+*/
+int
+dwarf_elf_init(dwarf_elf_handle elf_file_pointer,
+	       Dwarf_Unsigned access,
+	       Dwarf_Handler errhand,
+	       Dwarf_Ptr errarg,
+	       Dwarf_Debug * ret_dbg, Dwarf_Error * error)
+{
+    Dwarf_Debug dbg;
+    int res;
+
+    dbg = _dwarf_get_debug();
+    if (dbg == NULL) {
+	DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR);
+    }
+    dbg->de_errhand = errhand;
+    dbg->de_errarg = errarg;
+    dbg->de_frame_rule_initial_value = DW_FRAME_REG_INITIAL_VALUE;
+    dbg->de_frame_reg_rules_entry_count = DW_FRAME_LAST_REG_NUM;
+
+    if (access != DW_DLC_READ) {
+	DWARF_DBG_ERROR(dbg, DW_DLE_INIT_ACCESS_WRONG, DW_DLV_ERROR);
+    }
+    dbg->de_access = access;
+
+    dbg->de_elf_must_close = 0;
+    if ((res = _dwarf_setup(dbg, elf_file_pointer, error)) != DW_DLV_OK) {
+	free(dbg);
+	return (res);
+    }
+
+    /* this call cannot fail: allocates nothing, releases nothing */
+    _dwarf_setup_debug(dbg);
+
+    *ret_dbg = dbg;
+    return (DW_DLV_OK);
+}
+
+
+/*
+	Frees all memory that was not previously freed
+	by dwarf_dealloc.
+	Aside from certain categories.
+*/
+int
+dwarf_finish(Dwarf_Debug dbg, Dwarf_Error * error)
+{
+    int res = DW_DLV_OK;
+
+    if (dbg->de_elf_must_close) {
+	/* Must do this *before* _dwarf_free_all_of_one_debug() as that 
+	   zeroes out dbg contents */
+#ifdef __SGI_FAST_LIBELF
+	elf_sgi_free(dbg->de_elf);
+#else
+	elf_end(dbg->de_elf);
+#endif
+    }
+
+    res = _dwarf_free_all_of_one_debug(dbg);
+    if (res == DW_DLV_ERROR) {
+	DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR);
+    }
+    dwarf_malloc_check_complete("After Final free");
+
+    return res;
+
+
+}
+
+
+/*
+    This function returns the Elf * pointer
+    associated with a Dwarf_Debug.
+*/
+int
+dwarf_get_elf(Dwarf_Debug dbg, dwarf_elf_handle * elf,
+	      Dwarf_Error * error)
+{
+    if (dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *elf = dbg->de_elf;
+    return (DW_DLV_OK);
+}
+
+
+/*
+	Load the ELF section with the specified index and set the
+	pointer pointed to by section_data to the memory where it
+	was loaded.
+ */
+int
+_dwarf_load_section(Dwarf_Debug dbg,
+		    Dwarf_Half section_index,
+		    Dwarf_Small ** section_data, Dwarf_Error * error)
+{
+    if (section_index == 0) {
+	return DW_DLV_NO_ENTRY;
+    }
+
+    /* check to see if the section is already loaded */
+    if (*section_data != NULL) {
+	return DW_DLV_OK;
+    }
+
+    {
+#ifdef __SGI_FAST_LIBELF
+	enum elf_sgi_error_type sres;
+
+	sres = elf_sgi_section(dbg->de_elf,
+			       section_index, (void **) section_data);
+	if (sres != ELF_SGI_ERROR_OK) {
+	    DWARF_DBG_ERROR(dbg,
+			    _dwarf_error_code_from_elf_sgi_error_code
+			    (sres), DW_DLV_ERROR);
+	}
+#else
+	Elf_Scn *scn;
+	Elf_Data *data;
+
+	scn = elf_getscn(dbg->de_elf, section_index);
+	if (scn == NULL) {
+	    _dwarf_error(dbg, error, DW_DLE_MDE);
+	    return DW_DLV_ERROR;
+	}
+
+	/* 
+	   When using libelf as a producer, section data may be stored
+	   in multiple buffers. In libdwarf however, we only use libelf
+	   as a consumer (there is a dwarf producer API, but it doesn't
+	   use libelf). Because of this, this single call to elf_getdata
+	   will retrieve the entire section in a single contiguous
+	   buffer. */
+	data = elf_getdata(scn, NULL);
+	if (data == NULL) {
+	    _dwarf_error(dbg, error, DW_DLE_MDE);
+	    return DW_DLV_ERROR;
+	}
+
+	*section_data = data->d_buf;
+#endif /* !defined(__SGI_FAST_LIBELF) */
+    }
+
+    return DW_DLV_OK;
+}
+
+/* This is a hack so clients can verify offsets.
+   Added April 2005 so that debugger can detect broken offsets
+   (which happened in an IRIX  -64 executable larger than 2GB
+    using MIPSpro 7.3.1.3 compilers. A couple .debug_pubnames
+    offsets were wrong.).
+*/
+int
+dwarf_get_section_max_offsets(Dwarf_Debug dbg,
+			      Dwarf_Unsigned * debug_info_size,
+			      Dwarf_Unsigned * debug_abbrev_size,
+			      Dwarf_Unsigned * debug_line_size,
+			      Dwarf_Unsigned * debug_loc_size,
+			      Dwarf_Unsigned * debug_aranges_size,
+			      Dwarf_Unsigned * debug_macinfo_size,
+			      Dwarf_Unsigned * debug_pubnames_size,
+			      Dwarf_Unsigned * debug_str_size,
+			      Dwarf_Unsigned * debug_frame_size,
+			      Dwarf_Unsigned * debug_ranges_size,
+			      Dwarf_Unsigned * debug_typenames_size)
+{
+    *debug_info_size = dbg->de_debug_info_size;
+    *debug_abbrev_size = dbg->de_debug_abbrev_size;
+    *debug_line_size = dbg->de_debug_line_size;
+    *debug_loc_size = dbg->de_debug_loc_size;
+    *debug_aranges_size = dbg->de_debug_aranges_size;
+    *debug_macinfo_size = dbg->de_debug_macinfo_size;
+    *debug_pubnames_size = dbg->de_debug_pubnames_size;
+    *debug_str_size = dbg->de_debug_str_size;
+    *debug_frame_size = dbg->de_debug_frame_size;
+    *debug_ranges_size = 0;	/* Not yet supported. */
+    *debug_typenames_size = dbg->de_debug_typenames_size;
+
+
+    return DW_DLV_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_leb.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,149 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+
+
+/*
+    decode ULEB
+*/
+Dwarf_Unsigned
+_dwarf_decode_u_leb128(Dwarf_Small * leb128, Dwarf_Word * leb128_length)
+{
+    unsigned char byte;
+    Dwarf_Word word_number;
+    Dwarf_Unsigned number;
+    Dwarf_Sword shift;
+    Dwarf_Sword byte_length;
+
+    /* The following unrolls-the-loop for the first few bytes and
+       unpacks into 32 bits to make this as fast as possible.
+       word_number is assumed big enough that the shift has a defined
+       result. */
+    if ((*leb128 & 0x80) == 0) {
+	if (leb128_length != NULL)
+	    *leb128_length = 1;
+	return (*leb128);
+    } else if ((*(leb128 + 1) & 0x80) == 0) {
+	if (leb128_length != NULL)
+	    *leb128_length = 2;
+
+	word_number = *leb128 & 0x7f;
+	word_number |= (*(leb128 + 1) & 0x7f) << 7;
+	return (word_number);
+    } else if ((*(leb128 + 2) & 0x80) == 0) {
+	if (leb128_length != NULL)
+	    *leb128_length = 3;
+
+	word_number = *leb128 & 0x7f;
+	word_number |= (*(leb128 + 1) & 0x7f) << 7;
+	word_number |= (*(leb128 + 2) & 0x7f) << 14;
+	return (word_number);
+    } else if ((*(leb128 + 3) & 0x80) == 0) {
+	if (leb128_length != NULL)
+	    *leb128_length = 4;
+
+	word_number = *leb128 & 0x7f;
+	word_number |= (*(leb128 + 1) & 0x7f) << 7;
+	word_number |= (*(leb128 + 2) & 0x7f) << 14;
+	word_number |= (*(leb128 + 3) & 0x7f) << 21;
+	return (word_number);
+    }
+
+    /* The rest handles long numbers Because the 'number' may be larger 
+       than the default int/unsigned, we must cast the 'byte' before
+       the shift for the shift to have a defined result. */
+    number = 0;
+    shift = 0;
+    byte_length = 1;
+    byte = *(leb128);
+    for (;;) {
+	number |= ((Dwarf_Unsigned) (byte & 0x7f)) << shift;
+
+	if ((byte & 0x80) == 0) {
+	    if (leb128_length != NULL)
+		*leb128_length = byte_length;
+	    return (number);
+	}
+	shift += 7;
+
+	byte_length++;
+	++leb128;
+	byte = *leb128;
+    }
+}
+
+#define BITSINBYTE 8
+
+/*
+    decode SLEB
+*/
+Dwarf_Signed
+_dwarf_decode_s_leb128(Dwarf_Small * leb128, Dwarf_Word * leb128_length)
+{
+    Dwarf_Signed number = 0;
+    Dwarf_Bool sign = 0;
+    Dwarf_Sword shift = 0;
+    unsigned char byte = *leb128;
+    Dwarf_Sword byte_length = 1;
+
+    /* byte_length being the number of bytes of data absorbed so far in 
+       turning the leb into a Dwarf_Signed. */
+
+    for (;;) {
+	sign = byte & 0x40;
+	number |= ((Dwarf_Signed) ((byte & 0x7f))) << shift;
+	shift += 7;
+
+	if ((byte & 0x80) == 0) {
+	    break;
+	}
+	++leb128;
+	byte = *leb128;
+	byte_length++;
+    }
+
+    if ((shift < sizeof(Dwarf_Signed) * BITSINBYTE) && sign) {
+	number |= -((Dwarf_Signed) 1 << shift);
+    }
+
+    if (leb128_length != NULL)
+	*leb128_length = byte_length;
+    return (number);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_line.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1827 @@
+/*
+
+  Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "dwarf_line.h"
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+
+
+/* 
+    Although source files is supposed to return the
+    source files in the compilation-unit, it does
+    not look for any in the statement program.  In
+    other words, it ignores those defined using the
+    extended opcode DW_LNE_define_file.
+*/
+int
+dwarf_srcfiles(Dwarf_Die die,
+	       char ***srcfiles,
+	       Dwarf_Signed * srcfilecount, Dwarf_Error * error)
+{
+    /* 
+       This pointer is used to scan the portion of the .debug_line
+       section for the current cu. */
+    Dwarf_Small *line_ptr;
+
+
+    /* 
+       Pointer to a DW_AT_stmt_list attribute in case it exists in the
+       die. */
+    Dwarf_Attribute stmt_list_attr;
+
+    /* Pointer to DW_AT_comp_dir attribute in die. */
+    Dwarf_Attribute comp_dir_attr;
+
+    /* Pointer to name of compilation directory. */
+    Dwarf_Small *comp_dir = 0;
+
+    /* Offset into .debug_line specified by a DW_AT_stmt_list
+       attribute. */
+    Dwarf_Unsigned line_offset = 0;
+
+
+
+    /* 
+       This points to a block of char *'s, each of which points to a
+       file name. */
+    char **ret_files = 0;
+
+    /* The Dwarf_Debug this die belongs to. */
+    Dwarf_Debug dbg = 0;
+
+    /* Used to chain the file names. */
+    Dwarf_Chain curr_chain = NULL;
+    Dwarf_Chain prev_chain = NULL;
+    Dwarf_Chain head_chain = NULL;
+    int resattr = 0;
+    int lres = 0;
+    struct Line_Table_Prefix_s line_prefix;
+    int i = 0;
+    int res = 0;
+
+
+    /* ***** BEGIN CODE ***** */
+
+    /* Reset error. */
+    if (error != NULL)
+	*error = NULL;
+
+    CHECK_DIE(die, DW_DLV_ERROR);
+    dbg = die->di_cu_context->cc_dbg;
+
+    resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
+    if (resattr != DW_DLV_OK) {
+	return resattr;
+    }
+
+    if (dbg->de_debug_line_index == 0) {
+	_dwarf_error(dbg, error, DW_DLE_DEBUG_LINE_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    res =
+	_dwarf_load_section(dbg,
+			    dbg->de_debug_line_index,
+			    &dbg->de_debug_line, error);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+
+    lres = dwarf_formudata(stmt_list_attr, &line_offset, error);
+    if (lres != DW_DLV_OK) {
+	return lres;
+    }
+    if (line_offset >= dbg->de_debug_line_size) {
+	_dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
+	return (DW_DLV_ERROR);
+    }
+    line_ptr = dbg->de_debug_line + line_offset;
+    dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
+
+    /* 
+       If die has DW_AT_comp_dir attribute, get the string that names
+       the compilation directory. */
+    resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
+    if (resattr == DW_DLV_ERROR) {
+	return resattr;
+    }
+    if (resattr == DW_DLV_OK) {
+	int cres;
+	char *cdir;
+
+	cres = dwarf_formstring(comp_dir_attr, &cdir, error);
+	if (cres == DW_DLV_ERROR) {
+	    return cres;
+	} else if (cres == DW_DLV_OK) {
+	    comp_dir = (Dwarf_Small *) cdir;
+	}
+    }
+    if (resattr == DW_DLV_OK) {
+	dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
+    }
+    dwarf_init_line_table_prefix(&line_prefix);
+    {
+	Dwarf_Small *line_ptr_out = 0;
+	int dres = dwarf_read_line_table_prefix(dbg,
+						line_ptr,
+						dbg->de_debug_line_size,
+						&line_ptr_out,
+						&line_prefix, error);
+
+	if (dres == DW_DLV_ERROR) {
+	    dwarf_free_line_table_prefix(&line_prefix);
+	    return dres;
+	}
+	if (dres == DW_DLV_NO_ENTRY) {
+	    dwarf_free_line_table_prefix(&line_prefix);
+	    return dres;
+	}
+
+	line_ptr = line_ptr_out;
+    }
+
+    for (i = 0; i < line_prefix.pf_files_count; ++i) {
+	struct Line_Table_File_Entry_s *fe =
+	    line_prefix.pf_line_table_file_entries + i;
+	char *file_name = (char *) fe->lte_filename;
+	char *dir_name = 0;
+	char *full_name = 0;
+	Dwarf_Unsigned dir_index = fe->lte_directory_index;
+
+	if (dir_index == 0) {
+	    dir_name = (char *) comp_dir;
+	} else {
+	    dir_name =
+		(char *) line_prefix.pf_include_directories[fe->
+							    lte_directory_index
+							    - 1];
+	}
+
+	/* dir_name can be NULL if there is no DW_AT_comp_dir */
+	if ((*file_name) == '/' || dir_name == 0) {
+	    /* This is safe because dwarf_dealloc is careful to not
+	       dealloc strings which are part of the raw .debug_* data. 
+	     */
+	    full_name = file_name;
+	} else {
+	    full_name = (char *) _dwarf_get_alloc(dbg, DW_DLA_STRING,
+						  strlen(dir_name) + 1 +
+						  strlen(file_name) +
+						  1);
+	    if (full_name == NULL) {
+		dwarf_free_line_table_prefix(&line_prefix);
+		_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+		return (DW_DLV_ERROR);
+	    }
+
+	    /* This is not careful to avoid // in the output, Nothing
+	       forces a 'canonical' name format here. Unclear if this
+	       needs to be fixed. */
+	    strcpy(full_name, dir_name);
+	    strcat(full_name, "/");
+	    strcat(full_name, file_name);
+	}
+	curr_chain =
+	    (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+	if (curr_chain == NULL) {
+	    dwarf_free_line_table_prefix(&line_prefix);
+	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	    return (DW_DLV_ERROR);
+	}
+	curr_chain->ch_item = full_name;
+	if (head_chain == NULL)
+	    head_chain = prev_chain = curr_chain;
+	else {
+	    prev_chain->ch_next = curr_chain;
+	    prev_chain = curr_chain;
+	}
+
+
+    }
+
+    curr_chain = (Dwarf_Chain) _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+    if (curr_chain == NULL) {
+	dwarf_free_line_table_prefix(&line_prefix);
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+
+
+
+
+    if (line_prefix.pf_files_count == 0) {
+	*srcfiles = NULL;
+	*srcfilecount = 0;
+	dwarf_free_line_table_prefix(&line_prefix);
+	return (DW_DLV_NO_ENTRY);
+    }
+
+    ret_files = (char **)
+	_dwarf_get_alloc(dbg, DW_DLA_LIST, line_prefix.pf_files_count);
+    if (ret_files == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	dwarf_free_line_table_prefix(&line_prefix);
+	return (DW_DLV_ERROR);
+    }
+
+    curr_chain = head_chain;
+    for (i = 0; i < line_prefix.pf_files_count; i++) {
+	*(ret_files + i) = curr_chain->ch_item;
+	prev_chain = curr_chain;
+	curr_chain = curr_chain->ch_next;
+	dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN);
+    }
+
+    *srcfiles = ret_files;
+    *srcfilecount = line_prefix.pf_files_count;
+    dwarf_free_line_table_prefix(&line_prefix);
+    return (DW_DLV_OK);
+}
+
+
+/*
+	return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR
+*/
+int
+_dwarf_internal_srclines(Dwarf_Die die,
+			 Dwarf_Line ** linebuf,
+			 Dwarf_Signed * count,
+			 Dwarf_Bool doaddrs,
+			 Dwarf_Bool dolines, Dwarf_Error * error)
+{
+    /* 
+       This pointer is used to scan the portion of the .debug_line
+       section for the current cu. */
+    Dwarf_Small *line_ptr = 0;
+
+    /* 
+       This points to the last byte of the .debug_line portion for the
+       current cu. */
+    Dwarf_Small *line_ptr_end = 0;
+
+
+    /* 
+       Pointer to a DW_AT_stmt_list attribute in case it exists in the
+       die. */
+    Dwarf_Attribute stmt_list_attr = 0;
+
+    /* Pointer to DW_AT_comp_dir attribute in die. */
+    Dwarf_Attribute comp_dir_attr = 0;
+
+    /* Pointer to name of compilation directory. */
+    Dwarf_Small *comp_dir = NULL;
+
+    /* 
+       Offset into .debug_line specified by a DW_AT_stmt_list
+       attribute. */
+    Dwarf_Unsigned line_offset = 0;
+
+    Dwarf_File_Entry file_entries = 0;
+
+    /* These are the state machine state variables. */
+    Dwarf_Addr address = 0;
+    Dwarf_Word file = 1;
+    Dwarf_Word line = 1;
+    Dwarf_Word column = 0;
+
+    /* phony init. See below for true initialization. */
+    Dwarf_Bool is_stmt = false;
+
+    Dwarf_Bool basic_block = false;
+    Dwarf_Bool prologue_end = false;
+    Dwarf_Bool epilogue_begin = false;
+    Dwarf_Small isa = 0;
+    Dwarf_Bool end_sequence = false;
+
+    /* 
+       These pointers are used to build the list of files names by this 
+       cu.  cur_file_entry points to the file name being added, and
+       prev_file_entry to the previous one. */
+    Dwarf_File_Entry cur_file_entry, prev_file_entry;
+
+    Dwarf_Sword i = 0;
+    Dwarf_Sword file_entry_count = 0;
+
+    /* 
+       This is the current opcode read from the statement program. */
+    Dwarf_Small opcode = 0;
+
+    /* 
+       Pointer to a Dwarf_Line_Context_s structure that contains the
+       context such as file names and include directories for the set
+       of lines being generated. */
+    Dwarf_Line_Context line_context = 0;
+
+    /* 
+       This is a pointer to the current line being added to the line
+       matrix. */
+    Dwarf_Line curr_line = 0;
+
+    /* 
+       These variables are used to decode leb128 numbers. Leb128_num
+       holds the decoded number, and leb128_length is its length in
+       bytes. */
+    Dwarf_Word leb128_num = 0;
+    Dwarf_Word leb128_length = 0;
+    Dwarf_Sword advance_line = 0;
+
+    /* 
+       This is the operand of the latest fixed_advance_pc extended
+       opcode. */
+    Dwarf_Half fixed_advance_pc = 0;
+
+    /* 
+       Counts the number of lines in the line matrix. */
+    Dwarf_Sword line_count = 0;
+
+    /* This is the length of an extended opcode instr.  */
+    Dwarf_Word instr_length = 0;
+    Dwarf_Small ext_opcode = 0;
+    struct Line_Table_Prefix_s prefix;
+
+    /* 
+       Used to chain together pointers to line table entries that are
+       later used to create a block of Dwarf_Line entries. */
+    Dwarf_Chain chain_line = NULL;
+    Dwarf_Chain head_chain = NULL;
+    Dwarf_Chain curr_chain = NULL;
+
+    /* 
+       This points to a block of Dwarf_Lines, a pointer to which is
+       returned in linebuf. */
+    Dwarf_Line *block_line = 0;
+
+    /* The Dwarf_Debug this die belongs to. */
+    Dwarf_Debug dbg = 0;
+    int resattr = 0;
+    int lres = 0;
+
+    int res = 0;
+
+    /* ***** BEGIN CODE ***** */
+
+    if (error != NULL)
+	*error = NULL;
+
+    CHECK_DIE(die, DW_DLV_ERROR);
+    dbg = die->di_cu_context->cc_dbg;
+
+    res =
+	_dwarf_load_section(dbg,
+			    dbg->de_debug_line_index,
+			    &dbg->de_debug_line, error);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+
+    resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
+    if (resattr != DW_DLV_OK) {
+	return resattr;
+    }
+
+
+
+    lres = dwarf_formudata(stmt_list_attr, &line_offset, error);
+    if (lres != DW_DLV_OK) {
+	return lres;
+    }
+
+    if (line_offset >= dbg->de_debug_line_size) {
+	_dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
+	return (DW_DLV_ERROR);
+    }
+    line_ptr = dbg->de_debug_line + line_offset;
+    dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
+
+    /* 
+       If die has DW_AT_comp_dir attribute, get the string that names
+       the compilation directory. */
+    resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
+    if (resattr == DW_DLV_ERROR) {
+	return resattr;
+    }
+    if (resattr == DW_DLV_OK) {
+	int cres;
+	char *cdir;
+
+	cres = dwarf_formstring(comp_dir_attr, &cdir, error);
+	if (cres == DW_DLV_ERROR) {
+	    return cres;
+	} else if (cres == DW_DLV_OK) {
+	    comp_dir = (Dwarf_Small *) cdir;
+	}
+    }
+    if (resattr == DW_DLV_OK) {
+	dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
+    }
+    dwarf_init_line_table_prefix(&prefix);
+
+    {
+	Dwarf_Small *newlinep = 0;
+	int res = dwarf_read_line_table_prefix(dbg,
+					       line_ptr,
+					       dbg->de_debug_line_size,
+					       &newlinep,
+					       &prefix,
+					       error);
+
+	if (res == DW_DLV_ERROR) {
+	    dwarf_free_line_table_prefix(&prefix);
+	    return res;
+	}
+	if (res == DW_DLV_NO_ENTRY) {
+	    dwarf_free_line_table_prefix(&prefix);
+	    return res;
+	}
+	line_ptr_end = prefix.pf_line_ptr_end;
+	line_ptr = newlinep;
+    }
+
+
+    /* Set up context structure for this set of lines. */
+    line_context = (Dwarf_Line_Context)
+	_dwarf_get_alloc(dbg, DW_DLA_LINE_CONTEXT, 1);
+    if (line_context == NULL) {
+	dwarf_free_line_table_prefix(&prefix);
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+
+    /* Fill out a Dwarf_File_Entry list as we use that to implement the 
+       define_file operation. */
+    file_entries = prev_file_entry = NULL;
+    for (i = 0; i < prefix.pf_files_count; ++i) {
+	struct Line_Table_File_Entry_s *pfxfile =
+	    prefix.pf_line_table_file_entries + i;
+
+	cur_file_entry = (Dwarf_File_Entry)
+	    _dwarf_get_alloc(dbg, DW_DLA_FILE_ENTRY, 1);
+	if (cur_file_entry == NULL) {
+	    dwarf_free_line_table_prefix(&prefix);
+	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	    return (DW_DLV_ERROR);
+	}
+
+	cur_file_entry->fi_file_name = pfxfile->lte_filename;
+	cur_file_entry->fi_dir_index = pfxfile->lte_directory_index;
+	cur_file_entry->fi_time_last_mod =
+	    pfxfile->lte_last_modification_time;
+
+	cur_file_entry->fi_file_length = pfxfile->lte_length_of_file;
+
+	if (file_entries == NULL)
+	    file_entries = cur_file_entry;
+	else
+	    prev_file_entry->fi_next = cur_file_entry;
+	prev_file_entry = cur_file_entry;
+
+	file_entry_count++;
+    }
+
+
+    /* Initialize the one state machine variable that depends on the
+       prefix.  */
+    is_stmt = prefix.pf_default_is_stmt;
+
+
+    /* Start of statement program.  */
+    while (line_ptr < line_ptr_end) {
+	int type;
+
+	opcode = *(Dwarf_Small *) line_ptr;
+	line_ptr++;
+
+
+	/* 'type' is the output */
+	WHAT_IS_OPCODE(type, opcode, prefix.pf_opcode_base,
+		       prefix.pf_opcode_length_table, line_ptr,
+		       prefix.pf_std_op_count);
+
+	if (type == LOP_DISCARD) {
+	    int oc;
+	    int opcnt = prefix.pf_opcode_length_table[opcode];
+
+	    for (oc = 0; oc < opcnt; oc++) {
+		/* 
+		 ** Read and discard operands we don't 
+		 ** understand.                        
+		 ** arbitrary choice of unsigned read. 
+		 ** signed read would work as well.    
+		 */
+		Dwarf_Unsigned utmp2;
+
+		DECODE_LEB128_UWORD(line_ptr, utmp2);
+	    }
+	} else if (type == LOP_SPECIAL) {
+	    /* This op code is a special op in the object, no matter
+	       that it might fall into the standard op range in this
+	       compile. That is, these are special opcodes between
+	       opcode_base and MAX_LINE_OP_CODE.  (including
+	       opcode_base and MAX_LINE_OP_CODE) */
+
+	    opcode = opcode - prefix.pf_opcode_base;
+	    address = address + prefix.pf_minimum_instruction_length *
+		(opcode / prefix.pf_line_range);
+	    line =
+		line + prefix.pf_line_base +
+		opcode % prefix.pf_line_range;
+
+	    if (dolines) {
+		curr_line =
+		    (Dwarf_Line) _dwarf_get_alloc(dbg, DW_DLA_LINE, 1);
+		if (curr_line == NULL) {
+		    dwarf_free_line_table_prefix(&prefix);
+		    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+		    return (DW_DLV_ERROR);
+		}
+
+		curr_line->li_address = address;
+		curr_line->li_addr_line.li_l_data.li_file =
+		    (Dwarf_Sword) file;
+		curr_line->li_addr_line.li_l_data.li_line =
+		    (Dwarf_Sword) line;
+		curr_line->li_addr_line.li_l_data.li_column =
+		    (Dwarf_Half) column;
+		curr_line->li_addr_line.li_l_data.li_is_stmt = is_stmt;
+		curr_line->li_addr_line.li_l_data.li_basic_block =
+		    basic_block;
+		curr_line->li_addr_line.li_l_data.li_end_sequence =
+		    curr_line->li_addr_line.li_l_data.
+		    li_epilogue_begin = epilogue_begin;
+		curr_line->li_addr_line.li_l_data.li_prologue_end =
+		    prologue_end;
+		curr_line->li_addr_line.li_l_data.li_isa = isa;
+		curr_line->li_context = line_context;
+		line_count++;
+
+		chain_line = (Dwarf_Chain)
+		    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+		if (chain_line == NULL) {
+		    dwarf_free_line_table_prefix(&prefix);
+		    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+		    return (DW_DLV_ERROR);
+		}
+		chain_line->ch_item = curr_line;
+
+		if (head_chain == NULL)
+		    head_chain = curr_chain = chain_line;
+		else {
+		    curr_chain->ch_next = chain_line;
+		    curr_chain = chain_line;
+		}
+	    }
+
+	    basic_block = false;
+	} else if (type == LOP_STANDARD) {
+	    switch (opcode) {
+
+	    case DW_LNS_copy:{
+		    if (dolines) {
+
+			curr_line =
+			    (Dwarf_Line) _dwarf_get_alloc(dbg,
+							  DW_DLA_LINE,
+							  1);
+			if (curr_line == NULL) {
+			    dwarf_free_line_table_prefix(&prefix);
+			    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+			    return (DW_DLV_ERROR);
+			}
+
+			curr_line->li_address = address;
+			curr_line->li_addr_line.li_l_data.li_file =
+			    (Dwarf_Sword) file;
+			curr_line->li_addr_line.li_l_data.li_line =
+			    (Dwarf_Sword) line;
+			curr_line->li_addr_line.li_l_data.li_column =
+			    (Dwarf_Half) column;
+			curr_line->li_addr_line.li_l_data.li_is_stmt =
+			    is_stmt;
+			curr_line->li_addr_line.li_l_data.
+			    li_basic_block = basic_block;
+			curr_line->li_addr_line.li_l_data.
+			    li_end_sequence = end_sequence;
+			curr_line->li_context = line_context;
+			curr_line->li_addr_line.li_l_data.
+			    li_epilogue_begin = epilogue_begin;
+			curr_line->li_addr_line.li_l_data.
+			    li_prologue_end = prologue_end;
+			curr_line->li_addr_line.li_l_data.li_isa = isa;
+			line_count++;
+
+			chain_line = (Dwarf_Chain)
+			    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+			if (chain_line == NULL) {
+			    dwarf_free_line_table_prefix(&prefix);
+			    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+			    return (DW_DLV_ERROR);
+			}
+			chain_line->ch_item = curr_line;
+			if (head_chain == NULL)
+			    head_chain = curr_chain = chain_line;
+			else {
+			    curr_chain->ch_next = chain_line;
+			    curr_chain = chain_line;
+			}
+		    }
+
+		    basic_block = false;
+		    prologue_end = false;
+		    epilogue_begin = false;
+		    break;
+		}
+
+	    case DW_LNS_advance_pc:{
+		    Dwarf_Unsigned utmp2;
+
+		    DECODE_LEB128_UWORD(line_ptr, utmp2);
+		    leb128_num = (Dwarf_Word) utmp2;
+		    address =
+			address +
+			prefix.pf_minimum_instruction_length *
+			leb128_num;
+		    break;
+		}
+
+	    case DW_LNS_advance_line:{
+		    Dwarf_Signed stmp;
+
+		    DECODE_LEB128_SWORD(line_ptr, stmp);
+		    advance_line = (Dwarf_Sword) stmp;
+		    line = line + advance_line;
+		    break;
+		}
+
+	    case DW_LNS_set_file:{
+		    Dwarf_Unsigned utmp2;
+
+		    DECODE_LEB128_UWORD(line_ptr, utmp2);
+		    file = (Dwarf_Word) utmp2;
+		    break;
+		}
+
+	    case DW_LNS_set_column:{
+		    Dwarf_Unsigned utmp2;
+
+		    DECODE_LEB128_UWORD(line_ptr, utmp2);
+		    column = (Dwarf_Word) utmp2;
+		    break;
+		}
+
+	    case DW_LNS_negate_stmt:{
+
+		    is_stmt = !is_stmt;
+		    break;
+		}
+
+	    case DW_LNS_set_basic_block:{
+
+		    basic_block = true;
+		    break;
+		}
+
+	    case DW_LNS_const_add_pc:{
+		    opcode = MAX_LINE_OP_CODE - prefix.pf_opcode_base;
+		    address =
+			address +
+			prefix.pf_minimum_instruction_length * (opcode /
+								prefix.
+								pf_line_range);
+
+		    break;
+		}
+
+	    case DW_LNS_fixed_advance_pc:{
+
+		    READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half,
+				   line_ptr, sizeof(Dwarf_Half));
+		    line_ptr += sizeof(Dwarf_Half);
+		    address = address + fixed_advance_pc;
+		    break;
+		}
+
+		/* New in DWARF3 */
+	    case DW_LNS_set_prologue_end:{
+
+		    prologue_end = true;
+		    break;
+
+
+		}
+		/* New in DWARF3 */
+	    case DW_LNS_set_epilogue_begin:{
+		    epilogue_begin = true;
+		    break;
+		}
+
+		/* New in DWARF3 */
+	    case DW_LNS_set_isa:{
+		    Dwarf_Unsigned utmp2;
+
+		    DECODE_LEB128_UWORD(line_ptr, utmp2);
+		    isa = utmp2;
+		    if (isa != utmp2) {
+			/* The value of the isa did not fit in our
+			   local so we record it wrong. declare an
+			   error. */
+			dwarf_free_line_table_prefix(&prefix);
+
+			_dwarf_error(dbg, error,
+				     DW_DLE_LINE_NUM_OPERANDS_BAD);
+			return (DW_DLV_ERROR);
+		    }
+		    break;
+		}
+	    }
+
+	} else if (type == LOP_EXTENDED) {
+	    Dwarf_Unsigned utmp3;
+
+	    DECODE_LEB128_UWORD(line_ptr, utmp3);
+	    instr_length = (Dwarf_Word) utmp3;
+	    /* Dwarf_Small is a ubyte and the extended opcode is a
+	       ubyte, though not stated as clearly in the 2.0.0 spec as 
+	       one might hope. */
+	    ext_opcode = *(Dwarf_Small *) line_ptr;
+	    line_ptr++;
+	    switch (ext_opcode) {
+
+	    case DW_LNE_end_sequence:{
+		    end_sequence = true;
+
+		    if (dolines) {
+			curr_line = (Dwarf_Line)
+			    _dwarf_get_alloc(dbg, DW_DLA_LINE, 1);
+			if (curr_line == NULL) {
+			    dwarf_free_line_table_prefix(&prefix);
+			    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+			    return (DW_DLV_ERROR);
+			}
+
+			curr_line->li_address = address;
+			curr_line->li_addr_line.li_l_data.li_file =
+			    (Dwarf_Sword) file;
+			curr_line->li_addr_line.li_l_data.li_line =
+			    (Dwarf_Sword) line;
+			curr_line->li_addr_line.li_l_data.li_column =
+			    (Dwarf_Half) column;
+			curr_line->li_addr_line.li_l_data.li_is_stmt =
+			    prefix.pf_default_is_stmt;
+			curr_line->li_addr_line.li_l_data.
+			    li_basic_block = basic_block;
+			curr_line->li_addr_line.li_l_data.
+			    li_end_sequence = end_sequence;
+			curr_line->li_context = line_context;
+			curr_line->li_addr_line.li_l_data.
+			    li_epilogue_begin = epilogue_begin;
+			curr_line->li_addr_line.li_l_data.
+			    li_prologue_end = prologue_end;
+			curr_line->li_addr_line.li_l_data.li_isa = isa;
+			line_count++;
+
+			chain_line = (Dwarf_Chain)
+			    _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+			if (chain_line == NULL) {
+			    dwarf_free_line_table_prefix(&prefix);
+			    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+			    return (DW_DLV_ERROR);
+			}
+			chain_line->ch_item = curr_line;
+
+			if (head_chain == NULL)
+			    head_chain = curr_chain = chain_line;
+			else {
+			    curr_chain->ch_next = chain_line;
+			    curr_chain = chain_line;
+			}
+		    }
+
+		    address = 0;
+		    file = 1;
+		    line = 1;
+		    column = 0;
+		    is_stmt = prefix.pf_default_is_stmt;
+		    basic_block = false;
+		    end_sequence = false;
+		    prologue_end = false;
+		    epilogue_begin = false;
+
+
+		    break;
+		}
+
+	    case DW_LNE_set_address:{
+		    if (instr_length - 1 == dbg->de_pointer_size) {
+			READ_UNALIGNED(dbg, address, Dwarf_Addr,
+				       line_ptr, dbg->de_pointer_size);
+			if (doaddrs) {
+			    curr_line =
+				(Dwarf_Line) _dwarf_get_alloc(dbg,
+							      DW_DLA_LINE,
+							      1);
+			    if (curr_line == NULL) {
+				dwarf_free_line_table_prefix(&prefix);
+				_dwarf_error(dbg, error,
+					     DW_DLE_ALLOC_FAIL);
+				return (DW_DLV_ERROR);
+			    }
+
+			    curr_line->li_address = address;
+			    curr_line->li_addr_line.li_offset =
+				line_ptr - dbg->de_debug_line;
+
+			    line_count++;
+
+			    chain_line = (Dwarf_Chain)
+				_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+			    if (chain_line == NULL) {
+				dwarf_free_line_table_prefix(&prefix);
+				_dwarf_error(dbg, error,
+					     DW_DLE_ALLOC_FAIL);
+				return (DW_DLV_ERROR);
+			    }
+			    chain_line->ch_item = curr_line;
+
+			    if (head_chain == NULL)
+				head_chain = curr_chain = chain_line;
+			    else {
+				curr_chain->ch_next = chain_line;
+				curr_chain = chain_line;
+			    }
+			}
+
+			line_ptr += dbg->de_pointer_size;
+		    } else {
+			dwarf_free_line_table_prefix(&prefix);
+			_dwarf_error(dbg, error,
+				     DW_DLE_LINE_SET_ADDR_ERROR);
+			return (DW_DLV_ERROR);
+		    }
+
+		    break;
+		}
+
+	    case DW_LNE_define_file:{
+
+		    if (dolines) {
+			cur_file_entry = (Dwarf_File_Entry)
+			    _dwarf_get_alloc(dbg, DW_DLA_FILE_ENTRY, 1);
+			if (cur_file_entry == NULL) {
+			    dwarf_free_line_table_prefix(&prefix);
+			    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+			    return (DW_DLV_ERROR);
+			}
+
+			cur_file_entry->fi_file_name =
+			    (Dwarf_Small *) line_ptr;
+			line_ptr =
+			    line_ptr + strlen((char *) line_ptr) + 1;
+
+			cur_file_entry->fi_dir_index = (Dwarf_Sword)
+			    _dwarf_decode_u_leb128(line_ptr,
+						   &leb128_length);
+			line_ptr = line_ptr + leb128_length;
+
+			cur_file_entry->fi_time_last_mod =
+			    _dwarf_decode_u_leb128(line_ptr,
+						   &leb128_length);
+			line_ptr = line_ptr + leb128_length;
+
+			cur_file_entry->fi_file_length =
+			    _dwarf_decode_u_leb128(line_ptr,
+						   &leb128_length);
+			line_ptr = line_ptr + leb128_length;
+
+			if (file_entries == NULL)
+			    file_entries = cur_file_entry;
+			else
+			    prev_file_entry->fi_next = cur_file_entry;
+			prev_file_entry = cur_file_entry;
+
+			file_entry_count++;
+		    }
+		    break;
+		}
+
+	    default:{
+		    dwarf_free_line_table_prefix(&prefix);
+		    _dwarf_error(dbg, error,
+				 DW_DLE_LINE_EXT_OPCODE_BAD);
+		    return (DW_DLV_ERROR);
+		}
+	    }
+
+	}
+    }
+
+    block_line = (Dwarf_Line *)
+	_dwarf_get_alloc(dbg, DW_DLA_LIST, line_count);
+    if (block_line == NULL) {
+	dwarf_free_line_table_prefix(&prefix);
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+
+    curr_chain = head_chain;
+    for (i = 0; i < line_count; i++) {
+	*(block_line + i) = curr_chain->ch_item;
+	head_chain = curr_chain;
+	curr_chain = curr_chain->ch_next;
+	dwarf_dealloc(dbg, head_chain, DW_DLA_CHAIN);
+    }
+
+    line_context->lc_file_entries = file_entries;
+    line_context->lc_file_entry_count = file_entry_count;
+    line_context->lc_include_directories_count =
+	prefix.pf_include_directories_count;
+    if (prefix.pf_include_directories_count > 0) {
+	/* This gets a pointer to the *first* include dir. The others
+	   follow directly with the standard DWARF2/3 NUL byte
+	   following the last. */
+	line_context->lc_include_directories =
+	    prefix.pf_include_directories[0];
+    }
+
+    line_context->lc_line_count = line_count;
+    line_context->lc_compilation_directory = comp_dir;
+    line_context->lc_version_number = prefix.pf_version;
+    line_context->lc_dbg = dbg;
+    *count = line_count;
+
+    *linebuf = block_line;
+    dwarf_free_line_table_prefix(&prefix);
+    return (DW_DLV_OK);
+}
+
+int
+dwarf_srclines(Dwarf_Die die,
+	       Dwarf_Line ** linebuf,
+	       Dwarf_Signed * linecount, Dwarf_Error * error)
+{
+    Dwarf_Signed count;
+    int res;
+
+    res = _dwarf_internal_srclines(die, linebuf, &count,	/* addrlist= 
+								 */ false,
+				   /* linelist= */ true, error);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+    *linecount = count;
+    return res;
+}
+
+
+
+/* Every line table entry (except DW_DLE_end_sequence,
+   which is returned using dwarf_lineendsequence())
+   potentially has the begin-statement
+   flag marked 'on'.   This returns thru *return_bool,
+   the begin-statement flag.
+*/
+
+int
+dwarf_linebeginstatement(Dwarf_Line line,
+			 Dwarf_Bool * return_bool, Dwarf_Error * error)
+{
+    if (line == NULL || return_bool == 0) {
+	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *return_bool = (line->li_addr_line.li_l_data.li_is_stmt);
+    return DW_DLV_OK;
+}
+
+/* At the end of any contiguous line-table there may be
+   a DW_LNE_end_sequence operator.
+   This returns non-zero thru *return_bool
+   if and only if this 'line' entry was a DW_LNE_end_sequence.
+
+   Within a compilation unit or function there may be multiple
+   line tables, each ending with a DW_LNE_end_sequence.
+   Each table describes a contiguous region.
+   Because compilers may split function code up in arbitrary ways
+   compilers may need to emit multiple contigous regions (ie
+   line tables) for a single function.
+   See the DWARF3 spec section 6.2.
+*/
+int
+dwarf_lineendsequence(Dwarf_Line line,
+		      Dwarf_Bool * return_bool, Dwarf_Error * error)
+{
+    if (line == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *return_bool = (line->li_addr_line.li_l_data.li_end_sequence);
+    return DW_DLV_OK;
+}
+
+
+/* Each 'line' entry has a line-number.
+   If the entry is a DW_LNE_end_sequence the line-number is
+   meaningless (see dwarf_lineendsequence(), just above).
+*/
+int
+dwarf_lineno(Dwarf_Line line,
+	     Dwarf_Unsigned * ret_lineno, Dwarf_Error * error)
+{
+    if (line == NULL || ret_lineno == 0) {
+	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *ret_lineno = (line->li_addr_line.li_l_data.li_line);
+    return DW_DLV_OK;
+}
+
+/* Each 'line' entry has a file-number, and index into the file table.
+   If the entry is a DW_LNE_end_sequence the index is
+   meaningless (see dwarf_lineendsequence(), just above).
+   The file number returned is an index into the file table
+   produced by dwarf_srcfiles(), but care is required: the
+   li_file begins with 1 for real files, so that the li_file returned here
+   is 1 greater than its index into the dwarf_srcfiles() output array.
+   And entries from DW_LNE_define_file don't appear in
+   the dwarf_srcfiles() output so file indexes from here may exceed
+   the size of the dwarf_srcfiles() output array size.
+*/
+int
+dwarf_line_srcfileno(Dwarf_Line line,
+		     Dwarf_Unsigned * ret_fileno, Dwarf_Error * error)
+{
+    if (line == NULL || ret_fileno == 0) {
+	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
+	return (DW_DLV_ERROR);
+    }
+    /* li_file must be <= line->li_context->lc_file_entry_count else it 
+       is trash. li_file 0 means not attributable to any source file
+       per dwarf2/3 spec. */
+
+    *ret_fileno = (line->li_addr_line.li_l_data.li_file);
+    return DW_DLV_OK;
+}
+
+
+/* Each 'line' entry has a line-address.
+   If the entry is a DW_LNE_end_sequence the adddress
+   is one-beyond the last address this contigous region
+   covers, so the address is not inside the region, 
+   but is just outside it.
+*/
+int
+dwarf_lineaddr(Dwarf_Line line,
+	       Dwarf_Addr * ret_lineaddr, Dwarf_Error * error)
+{
+    if (line == NULL || ret_lineaddr == 0) {
+	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *ret_lineaddr = (line->li_address);
+    return DW_DLV_OK;
+}
+
+
+/* Each 'line' entry has a column-within-line (offset
+   within the line) where the
+   source text begins.
+   If the entry is a DW_LNE_end_sequence the line-number is
+   meaningless (see dwarf_lineendsequence(), just above).
+   Lines of text begin at column 1.  The value 0
+   means the line begins at the left edge of the line.
+   (See the DWARF3 spec, section 6.2.2).
+*/
+int
+dwarf_lineoff(Dwarf_Line line,
+	      Dwarf_Signed * ret_lineoff, Dwarf_Error * error)
+{
+    if (line == NULL || ret_lineoff == 0) {
+	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *ret_lineoff =
+	(line->li_addr_line.li_l_data.li_column ==
+	 0 ? -1 : line->li_addr_line.li_l_data.li_column);
+    return DW_DLV_OK;
+}
+
+
+int
+dwarf_linesrc(Dwarf_Line line, char **ret_linesrc, Dwarf_Error * error)
+{
+    Dwarf_Signed i;
+    Dwarf_File_Entry file_entry;
+    Dwarf_Small *name_buffer;
+    Dwarf_Small *include_directories;
+    Dwarf_Debug dbg;
+    unsigned int comp_dir_len;
+
+    if (line == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    if (line->li_context == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_LINE_CONTEXT_NULL);
+	return (DW_DLV_ERROR);
+    }
+    dbg = line->li_context->lc_dbg;
+
+    if (line->li_addr_line.li_l_data.li_file >
+	line->li_context->lc_file_entry_count) {
+	_dwarf_error(dbg, error, DW_DLE_LINE_FILE_NUM_BAD);
+	return (DW_DLV_ERROR);
+    }
+
+    if (line->li_addr_line.li_l_data.li_file == 0) {
+	/* No file name known: see dwarf2/3 spec. */
+	_dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME);
+	return (DW_DLV_ERROR);
+    }
+    file_entry = line->li_context->lc_file_entries;
+    /* ASSERT: li_file > 0, dwarf correctness issue, see line table
+       definition of dwarf2/3 spec. */
+    /* Example: if li_file is 2 and lc_file_entry_count is 3,
+       file_entry is file 3 (1 based), aka 2( 0 based) file_entry->next 
+       is file 2 (1 based), aka 1( 0 based) file_entry->next->next is
+       file 1 (1 based), aka 0( 0 based) file_entry->next->next->next
+       is NULL.
+
+       and this loop finds the file_entry we need (2 (1 based) in this
+       case). Because lc_file_entries are in reverse order and
+       effectively zero based as a count whereas li_file is 1 based. */
+    for (i = line->li_addr_line.li_l_data.li_file - 1; i > 0; i--)
+	file_entry = file_entry->fi_next;
+
+    if (file_entry->fi_file_name == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_NO_FILE_NAME);
+	return (DW_DLV_ERROR);
+    }
+
+    if (*(char *) file_entry->fi_file_name == '/') {
+	*ret_linesrc = ((char *) file_entry->fi_file_name);
+	return DW_DLV_OK;
+    }
+
+    if (file_entry->fi_dir_index == 0) {
+
+	/* dir_index of 0 means that the compilation was in the
+	   'current directory of compilation' */
+	if (line->li_context->lc_compilation_directory == NULL) {
+	    /* we don't actually *have* a current directory of
+	       compilation: DW_AT_comp_dir was not present Rather than
+	       emitting DW_DLE_NO_COMP_DIR lets just make an empty name 
+	       here. In other words, do the best we can with what we do 
+	       have instead of reporting an error. _dwarf_error(dbg,
+	       error, DW_DLE_NO_COMP_DIR); return(DW_DLV_ERROR); */
+	    comp_dir_len = 0;
+	} else {
+	    comp_dir_len = strlen((char *)
+				  (line->li_context->
+				   lc_compilation_directory));
+	}
+
+	name_buffer =
+	    _dwarf_get_alloc(line->li_context->lc_dbg, DW_DLA_STRING,
+			     comp_dir_len + 1 +
+			     strlen((char *) file_entry->fi_file_name) +
+			     1);
+	if (name_buffer == NULL) {
+	    _dwarf_error(line->li_context->lc_dbg, error,
+			 DW_DLE_ALLOC_FAIL);
+	    return (DW_DLV_ERROR);
+	}
+
+	if (comp_dir_len > 0) {
+	    /* if comp_dir_len is 0 we do not want to put a / in front
+	       of the fi_file_name as we just don't know anything. */
+	    strcpy((char *) name_buffer,
+		   (char *) (line->li_context->
+			     lc_compilation_directory));
+	    strcat((char *) name_buffer, "/");
+	}
+	strcat((char *) name_buffer, (char *) file_entry->fi_file_name);
+	*ret_linesrc = ((char *) name_buffer);
+	return DW_DLV_OK;
+    }
+
+    if (file_entry->fi_dir_index >
+	line->li_context->lc_include_directories_count) {
+	_dwarf_error(dbg, error, DW_DLE_INCL_DIR_NUM_BAD);
+	return (DW_DLV_ERROR);
+    }
+
+    include_directories = line->li_context->lc_include_directories;
+    for (i = file_entry->fi_dir_index - 1; i > 0; i--)
+	include_directories += strlen((char *) include_directories) + 1;
+
+    if (line->li_context->lc_compilation_directory) {
+	comp_dir_len = strlen((char *)
+			      (line->li_context->
+			       lc_compilation_directory));
+    } else {
+	/* No DW_AT_comp_dir present. Do the best we can without it. */
+	comp_dir_len = 0;
+    }
+
+    name_buffer = _dwarf_get_alloc(dbg, DW_DLA_STRING,
+				   (*include_directories == '/' ?
+				    0 : comp_dir_len + 1) +
+				   strlen((char *) include_directories)
+				   + 1 +
+				   strlen((char *) file_entry->
+					  fi_file_name) + 1);
+    if (name_buffer == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+
+    if (*include_directories != '/') {
+	if (comp_dir_len > 0) {
+	    strcpy((char *) name_buffer,
+		   (char *) line->li_context->lc_compilation_directory);
+	    /* Who provides the / needed after the compilation
+	       directory? */
+	    if (name_buffer[comp_dir_len - 1] != '/') {
+		/* Here we provide the / separator */
+		name_buffer[comp_dir_len] = '/';	/* overwrite
+							   previous nul 
+							   terminator
+							   with needed
+							   / */
+		name_buffer[comp_dir_len + 1] = 0;
+	    }
+	}
+    } else {
+	strcpy((char *) name_buffer, "");
+    }
+    strcat((char *) name_buffer, (char *) include_directories);
+    strcat((char *) name_buffer, "/");
+    strcat((char *) name_buffer, (char *) file_entry->fi_file_name);
+    *ret_linesrc = ((char *) name_buffer);
+    return DW_DLV_OK;
+}
+
+/* Every line table entry potentially has the basic-block-start
+   flag marked 'on'.   This returns thru *return_bool,
+   the basic-block-start flag.
+*/
+int
+dwarf_lineblock(Dwarf_Line line,
+		Dwarf_Bool * return_bool, Dwarf_Error * error)
+{
+    if (line == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DWARF_LINE_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *return_bool = (line->li_addr_line.li_l_data.li_basic_block);
+    return DW_DLV_OK;
+}
+
+
+#if 0				/* Ignore this.  This needs major
+				   re-work. */
+/* 
+    This routine works by looking for exact matches between 
+    the current line address and pc, and crossovers from
+    from less than pc value to greater than.  At each line
+    that satisfies the above, it records a pointer to the
+    line, and the difference between the address and pc.
+    It then scans these pointers and picks out those with
+    the smallest difference between pc and address.         
+*/
+int
+dwarf_pclines(Dwarf_Debug dbg,
+	      Dwarf_Addr pc,
+	      Dwarf_Line ** linebuf,
+	      Dwarf_Signed slide,
+	      Dwarf_Signed * linecount, Dwarf_Error * error)
+{
+    /* 
+       Scans the line matrix for the current cu to which a pointer
+       exists in dbg. */
+    Dwarf_Line line;
+    Dwarf_Line prev_line;
+
+    /* 
+       These flags are for efficiency reasons. Check_line is true
+       initially, but set false when the address of the current line is 
+       greater than pc.  It is set true only when the address of the
+       current line falls below pc.  This assumes that addresses within 
+       the same segment increase, and we are only interested in the
+       switch from a less than pc address to a greater than. First_line 
+       is set true initially, but set false after the first line is
+       scanned.  This is to prevent looking at the address of previous
+       line when slide is DW_DLS_BACKWARD, and the first line is being
+       scanned. */
+    Dwarf_Bool check_line, first_line;
+
+    /* 
+       Diff tracks the smallest difference a line address and the input 
+       pc value. */
+    Dwarf_Signed diff, i;
+
+    /* 
+       For the slide = DW_DLS_BACKWARD case, pc_less is the value of
+       the address of the line immediately preceding the first line
+       that has value greater than pc. For the slide = DW_DLS_FORWARD
+       case, pc_more is the values of address for the first line that
+       is greater than pc. Diff is the difference between either of the 
+       these values and pc. */
+    Dwarf_Addr pc_less, pc_more;
+
+    /* 
+       Pc_line_buf points to a chain of pointers to lines of which
+       those with a diff equal to the smallest difference will be
+       returned. */
+    Dwarf_Line *pc_line_buf, *pc_line;
+
+    /* 
+       Chain_count counts the number of lines in the above chain for
+       which the diff is equal to the smallest difference This is the
+       number returned by this routine. */
+    Dwarf_Signed chain_count;
+
+    chain_head = NULL;
+
+    check_line = true;
+    first_line = true;
+    diff = MAX_LINE_DIFF;
+
+    for (i = 0; i < dbg->de_cu_line_count; i++) {
+
+	line = *(dbg->de_cu_line_ptr + i);
+	prev_line = first_line ? NULL : *(dbg->de_cu_line_ptr + i - 1);
+
+	if (line->li_address == pc) {
+	    chain_ptr = (struct chain *)
+		_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+	    if (chain_ptr == NULL) {
+		_dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
+		return (DW_DLV_ERROR);
+	    }
+
+	    chain_ptr->line = line;
+	    chain_ptr->diff = diff = 0;
+	    chain_ptr->next = chain_head;
+	    chain_head = chain_ptr;
+	} else
+	    /* 
+	       Look for crossover from less than pc address to greater
+	       than. */
+	if (check_line && line->li_address > pc &&
+		(first_line ? 0 : prev_line->li_address) < pc)
+
+	    if (slide == DW_DLS_BACKWARD && !first_line) {
+		pc_less = prev_line->li_address;
+		if (pc - pc_less <= diff) {
+		    chain_ptr = (struct chain *)
+			_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+		    if (chain_ptr == NULL) {
+			_dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
+			return (DW_DLV_ERROR);
+		    }
+
+		    chain_ptr->line = prev_line;
+		    chain_ptr->diff = diff = pc - pc_less;
+		    chain_ptr->next = chain_head;
+		    chain_head = chain_ptr;
+		}
+		check_line = false;
+	    } else if (slide == DW_DLS_FORWARD) {
+		pc_more = line->li_address;
+		if (pc_more - pc <= diff) {
+		    chain_ptr = (struct chain *)
+			_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
+		    if (chain_ptr == NULL) {
+			_dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL);
+			return (DW_DLV_ERROR);
+		    }
+
+		    chain_ptr->line = line;
+		    chain_ptr->diff = diff = pc_more - pc;
+		    chain_ptr->next = chain_head;
+		    chain_head = chain_ptr;
+		}
+		check_line = false;
+	    } else
+		/* Check addresses only when they go */
+		/* below pc.  */
+	    if (line->li_address < pc)
+		check_line = true;
+
+	first_line = false;
+    }
+
+    chain_count = 0;
+    for (chain_ptr = chain_head; chain_ptr != NULL;
+	 chain_ptr = chain_ptr->next)
+	if (chain_ptr->diff == diff)
+	    chain_count++;
+
+    pc_line_buf = pc_line = (Dwarf_Line)
+	_dwarf_get_alloc(dbg, DW_DLA_LIST, chain_count);
+    for (chain_ptr = chain_head; chain_ptr != NULL;
+	 chain_ptr = chain_ptr->next)
+	if (chain_ptr->diff == diff) {
+	    *pc_line = chain_ptr->line;
+	    pc_line++;
+	}
+
+    for (chain_ptr = chain_head; chain_ptr != NULL;) {
+	chain_head = chain_ptr;
+	chain_ptr = chain_ptr->next;
+	dwarf_dealloc(dbg, chain_head, DW_DLA_CHAIN);
+    }
+
+    *linebuf = pc_line_buf;
+    return (chain_count);
+}
+#endif
+
+
+
+/*
+   It's impossible for callers of dwarf_srclines() to get to and
+   free all the resources (in particular, the li_context and its
+   lc_file_entries). 
+   So this function, new July 2005, does it.  
+*/
+
+void
+dwarf_srclines_dealloc(Dwarf_Debug dbg, Dwarf_Line * linebuf,
+		       Dwarf_Signed count)
+{
+
+    Dwarf_Signed i = 0;
+    struct Dwarf_Line_Context_s *context = 0;
+
+    if (count > 0) {
+	/* All these entries share a single context */
+	context = linebuf[0]->li_context;
+    }
+    for (i = 0; i < count; ++i) {
+	dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE);
+    }
+    dwarf_dealloc(dbg, linebuf, DW_DLA_LIST);
+
+    if (context) {
+	Dwarf_File_Entry fe = context->lc_file_entries;
+
+	while (fe) {
+	    Dwarf_File_Entry fenext = fe->fi_next;
+
+	    dwarf_dealloc(dbg, fe, DW_DLA_FILE_ENTRY);
+	    fe = fenext;
+	}
+	dwarf_dealloc(dbg, context, DW_DLA_LINE_CONTEXT);
+    }
+
+    return;
+}
+
+/* Operand counts per standard operand.
+   The initial zero is for DW_LNS_copy. 
+   This is an economical way to verify we understand the table
+   of standard-opcode-lengths in the line table prologue.  */
+#define STANDARD_OPERAND_COUNT_DWARF2 9
+#define STANDARD_OPERAND_COUNT_DWARF3 12
+static unsigned char
+  dwarf_standard_opcode_operand_count[STANDARD_OPERAND_COUNT_DWARF3] = {
+    /* DWARF2 */
+    0,
+    1, 1, 1, 1,
+    0, 0, 0,
+    1,
+    /* Following are new for DWARF3. */
+    0, 0, 1
+};
+
+/* Common line table prefix reading code. 
+   Returns DW_DLV_OK, DW_DLV_ERROR.
+   DW_DLV_NO_ENTRY cannot be returned, but callers should
+   assume it is possible.
+
+   The prefix_out area must be initialized properly before calling this.
+
+   Has the side effect of allocating arrays which
+   must be freed (see the Line_Table_Prefix_s struct which
+   holds the pointers to space we allocate here).
+*/
+int
+dwarf_read_line_table_prefix(Dwarf_Debug dbg,
+			     Dwarf_Small * data_start,
+			     Dwarf_Unsigned data_length,
+			     Dwarf_Small ** updated_data_start_out,
+			     struct Line_Table_Prefix_s *prefix_out,
+			     Dwarf_Error * err)
+{
+    Dwarf_Small *line_ptr = data_start;
+    Dwarf_Unsigned total_length = 0;
+    int local_length_size = 0;
+    int local_extension_size = 0;
+    Dwarf_Unsigned prologue_length = 0;
+    Dwarf_Half version = 0;
+    Dwarf_Unsigned directories_count = 0;
+    Dwarf_Unsigned directories_malloc = 0;
+    Dwarf_Unsigned files_count = 0;
+    Dwarf_Unsigned files_malloc = 0;
+    Dwarf_Small *line_ptr_end = 0;
+
+    prefix_out->pf_line_ptr_start = line_ptr;
+    /* READ_AREA_LENGTH updates line_ptr for consumed bytes */
+    READ_AREA_LENGTH(dbg, total_length, Dwarf_Unsigned,
+		     line_ptr, local_length_size, local_extension_size);
+
+
+    line_ptr_end = line_ptr + total_length;
+    prefix_out->pf_line_ptr_end = line_ptr_end;
+    prefix_out->pf_length_field_length = local_length_size +
+	local_extension_size;
+    /* ASSERT: prefix_out->pf_length_field_length == line_ptr
+       -prefix_out->pf_line_ptr_start; */
+    if (line_ptr_end > dbg->de_debug_line + dbg->de_debug_line_size) {
+	_dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
+	return (DW_DLV_ERROR);
+    }
+    if (line_ptr_end > data_start + data_length) {
+	_dwarf_error(dbg, err, DW_DLE_DEBUG_LINE_LENGTH_BAD);
+	return (DW_DLV_ERROR);
+    }
+    prefix_out->pf_total_length = total_length;
+
+    READ_UNALIGNED(dbg, version, Dwarf_Half,
+		   line_ptr, sizeof(Dwarf_Half));
+    prefix_out->pf_version = version;
+    line_ptr += sizeof(Dwarf_Half);
+    if (version != CURRENT_VERSION_STAMP &&
+	version != CURRENT_VERSION_STAMP3) {
+	_dwarf_error(dbg, err, DW_DLE_VERSION_STAMP_ERROR);
+	return (DW_DLV_ERROR);
+    }
+
+    READ_UNALIGNED(dbg, prologue_length, Dwarf_Unsigned,
+		   line_ptr, local_length_size);
+    prefix_out->pf_prologue_length = prologue_length;
+    line_ptr += local_length_size;
+    prefix_out->pf_line_prologue_start = line_ptr;
+
+
+    prefix_out->pf_minimum_instruction_length =
+	*(unsigned char *) line_ptr;
+    line_ptr = line_ptr + sizeof(Dwarf_Small);
+
+    prefix_out->pf_default_is_stmt = *(unsigned char *) line_ptr;
+    line_ptr = line_ptr + sizeof(Dwarf_Small);
+
+    prefix_out->pf_line_base = *(signed char *) line_ptr;
+    line_ptr = line_ptr + sizeof(Dwarf_Sbyte);
+
+    prefix_out->pf_line_range = *(unsigned char *) line_ptr;
+    line_ptr = line_ptr + sizeof(Dwarf_Small);
+
+    prefix_out->pf_opcode_base = *(unsigned char *) line_ptr;
+    line_ptr = line_ptr + sizeof(Dwarf_Small);
+
+    /* Set up the array of standard opcode lengths. */
+    /* We think this works ok even for cross-endian processing of
+       objects.  It might be wrong, we might need to specially process
+       the array of ubyte into host order.  */
+    prefix_out->pf_opcode_length_table = line_ptr;
+
+    /* pf_opcode_base is one greater than the size of the array. */
+    line_ptr += prefix_out->pf_opcode_base - 1;
+
+    {
+	/* Determine (as best we can) whether the
+	   pf_opcode_length_table holds 9 or 12 standard-conforming
+	   entries.  gcc4 upped to DWARF3's 12 without updating the
+	   version number.  */
+	int operand_ck_fail = true;
+
+	if (prefix_out->pf_opcode_base >= STANDARD_OPERAND_COUNT_DWARF3) {
+	    int mismatch = memcmp(dwarf_standard_opcode_operand_count,
+				  prefix_out->pf_opcode_length_table,
+				  STANDARD_OPERAND_COUNT_DWARF3);
+
+	    if (!mismatch) {
+		operand_ck_fail = false;
+		prefix_out->pf_std_op_count =
+		    STANDARD_OPERAND_COUNT_DWARF3;
+	    }
+
+	}
+	if (operand_ck_fail) {
+	    if (prefix_out->pf_opcode_base >=
+		STANDARD_OPERAND_COUNT_DWARF2) {
+
+		int mismatch =
+		    memcmp(dwarf_standard_opcode_operand_count,
+			   prefix_out->pf_opcode_length_table,
+			   STANDARD_OPERAND_COUNT_DWARF2);
+
+		if (!mismatch) {
+		    operand_ck_fail = false;
+		    prefix_out->pf_std_op_count =
+			STANDARD_OPERAND_COUNT_DWARF2;
+		}
+	    }
+	}
+	if (operand_ck_fail) {
+	    _dwarf_error(dbg, err, DW_DLE_LINE_NUM_OPERANDS_BAD);
+	    return (DW_DLV_ERROR);
+	}
+    }
+    /* At this point we no longer need to check operand counts. */
+
+
+    directories_count = 0;
+    directories_malloc = 5;
+    prefix_out->pf_include_directories = malloc(sizeof(Dwarf_Small *) *
+						directories_malloc);
+    if (prefix_out->pf_include_directories == NULL) {
+	_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+    memset(prefix_out->pf_include_directories, 0,
+	   sizeof(Dwarf_Small *) * directories_malloc);
+
+    while ((*(char *) line_ptr) != '\0') {
+	if (directories_count >= directories_malloc) {
+	    Dwarf_Unsigned expand = 2 * directories_malloc;
+	    Dwarf_Unsigned bytesalloc = sizeof(Dwarf_Small *) * expand;
+	    Dwarf_Small **newdirs =
+		realloc(prefix_out->pf_include_directories,
+			bytesalloc);
+
+	    if (!newdirs) {
+		_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+		return (DW_DLV_ERROR);
+	    }
+	    /* Doubled size, zero out second half. */
+	    memset(newdirs + directories_malloc, 0,
+		   sizeof(Dwarf_Small *) * directories_malloc);
+	    directories_malloc = expand;
+	    prefix_out->pf_include_directories = newdirs;
+	}
+	prefix_out->pf_include_directories[directories_count] =
+	    line_ptr;
+	line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
+	directories_count++;
+    }
+    prefix_out->pf_include_directories_count = directories_count;
+    line_ptr++;
+
+    files_count = 0;
+    files_malloc = 5;
+    prefix_out->pf_line_table_file_entries =
+	malloc(sizeof(struct Line_Table_File_Entry_s) * files_malloc);
+    if (prefix_out->pf_line_table_file_entries == NULL) {
+	_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+    memset(prefix_out->pf_line_table_file_entries, 0,
+	   sizeof(struct Line_Table_File_Entry_s) * files_malloc);
+
+    while (*(char *) line_ptr != '\0') {
+	Dwarf_Unsigned utmp;
+	Dwarf_Unsigned dir_index = 0;
+	Dwarf_Unsigned lastmod = 0;
+	Dwarf_Unsigned file_length = 0;
+	struct Line_Table_File_Entry_s *curline;
+	Dwarf_Word leb128_length = 0;
+
+
+	if (files_count >= files_malloc) {
+	    Dwarf_Unsigned expand = 2 * files_malloc;
+	    struct Line_Table_File_Entry_s *newfiles =
+		realloc(prefix_out->pf_line_table_file_entries,
+			sizeof(struct Line_Table_File_Entry_s) *
+			expand);
+	    if (!newfiles) {
+		_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+		return (DW_DLV_ERROR);
+	    }
+	    memset(newfiles + files_malloc, 0,
+		   sizeof(struct Line_Table_File_Entry_s) *
+		   files_malloc);
+	    files_malloc = expand;
+	    prefix_out->pf_line_table_file_entries = newfiles;
+	}
+	curline = prefix_out->pf_line_table_file_entries + files_count;
+
+	curline->lte_filename = line_ptr;
+	line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
+
+	DECODE_LEB128_UWORD(line_ptr, utmp);
+	dir_index = (Dwarf_Sword) utmp;
+	if (dir_index > directories_count) {
+	    _dwarf_error(dbg, err, DW_DLE_DIR_INDEX_BAD);
+	    return (DW_DLV_ERROR);
+	}
+	curline->lte_directory_index = dir_index;
+
+	lastmod = _dwarf_decode_u_leb128(line_ptr, &leb128_length);
+	line_ptr = line_ptr + leb128_length;
+	curline->lte_last_modification_time = lastmod;
+
+	/* Skip over file length. */
+	file_length = _dwarf_decode_u_leb128(line_ptr, &leb128_length);
+	line_ptr = line_ptr + leb128_length;
+	curline->lte_length_of_file = file_length;
+
+	++files_count;
+
+    }
+    prefix_out->pf_files_count = files_count;
+    /* Skip trailing nul byte */
+    ++line_ptr;
+
+
+    if (line_ptr != (prefix_out->pf_line_prologue_start +
+		     prefix_out->pf_prologue_length)) {
+	_dwarf_error(dbg, err, DW_DLE_LINE_PROLOG_LENGTH_BAD);
+	return (DW_DLV_ERROR);
+    }
+
+
+    *updated_data_start_out = line_ptr;
+    return DW_DLV_OK;
+}
+
+
+/* Initialize the Line_Table_Prefix_s struct. 
+   memset is not guaranteed a portable initializer, but works
+   fine for current architectures.   AFAIK.
+*/
+void
+dwarf_init_line_table_prefix(struct Line_Table_Prefix_s *pf)
+{
+    memset(pf, 0, sizeof(*pf));
+}
+
+/* Free any malloc'd area.  of the Line_Table_Prefix_s struct. */
+void
+dwarf_free_line_table_prefix(struct Line_Table_Prefix_s *pf)
+{
+    if (pf->pf_include_directories) {
+	free(pf->pf_include_directories);
+	pf->pf_include_directories = 0;
+    }
+    if (pf->pf_line_table_file_entries) {
+	free(pf->pf_line_table_file_entries);
+	pf->pf_line_table_file_entries = 0;
+    }
+    return;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_line.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,320 @@
+/*
+
+  Copyright (C) 2000, 2004, 2006 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#define DW_EXTENDED_OPCODE	0
+
+/*
+    This is used as the starting value for an algorithm
+    to get the minimum difference between 2 values.
+    UINT_MAX is used as our approximation to infinity.
+*/
+#define MAX_LINE_DIFF       UINT_MAX
+
+
+/*
+    This structure is used to build a list of all the
+    files that are used in the current compilation unit.
+    All of the fields execpt fi_next have meanings that
+    are obvious from section 6.2.4 of the Libdwarf Doc.
+*/
+struct Dwarf_File_Entry_s {
+    /* Points to string naming the file. */
+    Dwarf_Small *fi_file_name;
+
+    /* 
+       Index into the list of directories of the directory in which
+       this file exits. */
+    Dwarf_Sword fi_dir_index;
+
+    /* Time of last modification of the file. */
+    Dwarf_Unsigned fi_time_last_mod;
+
+    /* Length in bytes of the file. */
+    Dwarf_Unsigned fi_file_length;
+
+    /* Pointer for chaining file entries. */
+    Dwarf_File_Entry fi_next;
+};
+
+
+typedef struct Dwarf_Line_Context_s *Dwarf_Line_Context;
+
+/* 
+    This structure provides the context in which the fields of 
+    a Dwarf_Line structure are interpreted.  They come from the 
+    statement program prologue.  **Updated by dwarf_srclines in 
+    dwarf_line.c.
+*/
+struct Dwarf_Line_Context_s {
+    /* 
+       Points to a chain of entries providing info about source files
+       for the current set of Dwarf_Line structures. File number
+       'li_file 1' is last on the list, the first list entry is the
+       file numbered lc_file_entry_count. The numbering of the file
+       names matches the dwarf2/3 line table specification file table
+       and DW_LNE_define_file numbering rules.  */
+    Dwarf_File_Entry lc_file_entries;
+    /* 
+       Count of number of source files for this set of Dwarf_Line
+       structures. */
+    Dwarf_Sword lc_file_entry_count;
+    /* 
+       Points to the portion of .debug_line section that contains a
+       list of strings naming the included directories. */
+    Dwarf_Small *lc_include_directories;
+
+    /* Count of the number of included directories. */
+    Dwarf_Sword lc_include_directories_count;
+
+    /* Count of the number of lines for this cu. */
+    Dwarf_Sword lc_line_count;
+
+    /* Points to name of compilation directory. */
+    Dwarf_Small *lc_compilation_directory;
+
+    Dwarf_Debug lc_dbg;
+
+    Dwarf_Half lc_version_number;	/* DWARF2/3 version number, 2
+					   for DWARF2, 3 for DWARF3. */
+};
+
+
+/*
+    This structure defines a row of the line table.
+    All of the fields except li_offset have the exact 
+    same meaning that is defined in Section 6.2.2 
+    of the Libdwarf Document. 
+
+    li_offset is used by _dwarf_addr_finder() which is called
+    by rqs(1), an sgi utility for 'moving' shared libraries
+    as if the static linker (ld) had linked the shared library
+    at the newly-specified address.  Most libdwarf-using 
+    apps will ignore li_offset and _dwarf_addr_finder().
+    
+*/
+struct Dwarf_Line_s {
+    Dwarf_Addr li_address;	/* pc value of machine instr */
+    union addr_or_line_s {
+	struct li_inner_s {
+	    Dwarf_Sword li_file;	/* int identifying src file */
+	    /* li_file is a number 1-N, indexing into a conceptual
+	       source file table as described in dwarf2/3 spec line
+	       table doc. (see Dwarf_File_Entry lc_file_entries; and
+	       Dwarf_Sword lc_file_entry_count;) */
+
+	    Dwarf_Sword li_line;	/* source file line number. */
+	    Dwarf_Half li_column;	/* source file column number */
+	    Dwarf_Small li_isa;
+
+	    /* To save space, use bit flags. */
+	    /* indicate start of stmt */
+	    unsigned char li_is_stmt:1;
+
+	    /* indicate start basic block */
+	    unsigned char li_basic_block:1;
+
+	    /* first post sequence instr */
+	    unsigned char li_end_sequence:1;
+
+	    unsigned char li_prologue_end:1;
+	    unsigned char li_epilogue_begin:1;
+	} li_l_data;
+	Dwarf_Off li_offset;	/* for rqs */
+    } li_addr_line;
+    Dwarf_Line_Context li_context;	/* assoc Dwarf_Line_Context_s */
+};
+
+
+int _dwarf_line_address_offsets(Dwarf_Debug dbg,
+				Dwarf_Die die,
+				Dwarf_Addr ** addrs,
+				Dwarf_Off ** offs,
+				Dwarf_Unsigned * returncount,
+				Dwarf_Error * err);
+int _dwarf_internal_srclines(Dwarf_Die die,
+			     Dwarf_Line ** linebuf,
+			     Dwarf_Signed * count,
+			     Dwarf_Bool doaddrs,
+			     Dwarf_Bool dolines, Dwarf_Error * error);
+
+
+
+/* The LOP, WHAT_IS_OPCODE stuff is here so it can
+   be reused in 3 places.  Seemed hard to keep
+   the 3 places the same without an inline func or
+   a macro.
+
+   Handling the line section where the header and the
+   file being processed do not match (unusual, but
+   planned for in the  design of .debug_line)
+   is too tricky to recode this several times and keep
+   it right.
+
+   As it is the code starting up line-reading is duplicated
+   and that is just wrong to do. FIXME!
+*/
+#define LOP_EXTENDED 1
+#define LOP_DISCARD  2
+#define LOP_STANDARD 3
+#define LOP_SPECIAL  4
+
+#define WHAT_IS_OPCODE(type,opcode,base,opcode_length,line_ptr,highest_std) \
+        if( (opcode) < (base) ) {                          \
+           /* we know we must treat as a standard op       \
+                or a special case.                         \
+           */                                              \
+           if((opcode) == DW_EXTENDED_OPCODE) {            \
+                type = LOP_EXTENDED;                       \
+           } else  if( ((highest_std)+1) >=  (base)) {     \
+                /* == Standard case: compile of            \
+                   dwarf_line.c and object                 \
+                   have same standard op codes set.        \
+                                                           \
+                   >  Special case: compile of dwarf_line.c\
+                   has things in standard op codes list    \
+                   in dwarf.h header not                   \
+                   in the object: handle this as a standard\
+                   op code in switch below.                \
+                   The header special ops overlap the      \
+                   object standard ops.                    \
+                   The new standard op codes will not      \
+                   appear in the object.                   \
+                */                                         \
+                type = LOP_STANDARD;                       \
+           } else  {                                       \
+                /* These are standard opcodes in the object\
+                ** that were not defined  in the header    \
+                ** at the time dwarf_line.c                \
+                ** was compiled. Provides the ability of   \
+                ** out-of-date dwarf reader to read newer  \
+                ** line table data transparently.          \
+                */                                         \
+                type = LOP_DISCARD;                         \
+           }                                                \
+                                                            \
+        } else {                                            \
+	   /* Is  a special op code.                        \
+	   */                                               \
+           type =  LOP_SPECIAL;                             \
+        }
+
+/* The following is from  the dwarf definition of 'ubyte'
+   and is specifically  mentioned in section  6.2.5.1, page 54
+   of the Rev 2.0.0 dwarf specification.
+*/
+
+#define MAX_LINE_OP_CODE  255
+
+
+/* The following structs (Line_Table_File_Entry_s,Line_Table_Prefix_s)
+   and functions allow refactoring common code into a single
+   reader routine.
+*/
+/* There can be zero of more of these needed for 1 line prologue. */
+struct Line_Table_File_Entry_s {
+    Dwarf_Small *lte_filename;
+    Dwarf_Unsigned lte_directory_index;
+    Dwarf_Unsigned lte_last_modification_time;
+    Dwarf_Unsigned lte_length_of_file;
+};
+
+/* Data  picked up from the line table prologue for a single
+CU. */
+struct Line_Table_Prefix_s {
+
+    /* pf_total_length is the value of the length field for the line
+       table of this CU. So it does not count the length of itself (the 
+       length value) for consistency with the say lenghts recorded in
+       DWARF2/3. */
+    Dwarf_Unsigned pf_total_length;
+
+    /* Length of the initial length field itself. */
+    Dwarf_Half pf_length_field_length;
+
+    /* The version is 2 for DWARF2, 3 for DWARF3 */
+    Dwarf_Half pf_version;
+
+    Dwarf_Unsigned pf_prologue_length;
+    Dwarf_Small pf_minimum_instruction_length;
+
+    /* Start and end of this CU line area. pf_line_ptr_start +
+       pf_total_length + pf_length_field_length == pf_line_ptr_end.
+       Meaning pf_line_ptr_start is before the length info. */
+    Dwarf_Small *pf_line_ptr_start;
+    Dwarf_Small *pf_line_ptr_end;
+
+    /* Used to check that decoding of the line prologue is done right. */
+    Dwarf_Small *pf_line_prologue_start;
+
+    Dwarf_Small pf_default_is_stmt;
+    Dwarf_Sbyte pf_line_base;
+    Dwarf_Small pf_line_range;
+
+    /* Highest std opcode (+1).  */
+    Dwarf_Small pf_opcode_base;
+
+    /* pf_opcode_base -1 entries (each a count, normally the value of
+       each entry is 0 or 1). */
+    Dwarf_Small *pf_opcode_length_table;
+
+    Dwarf_Unsigned pf_include_directories_count;
+    /* Array of pointers to dir strings. pf_include_directories_count
+       entriesin the array. */
+    Dwarf_Small **pf_include_directories;
+
+    /* Count of entries in line_table_file_entries array. */
+    Dwarf_Unsigned pf_files_count;
+    struct Line_Table_File_Entry_s *pf_line_table_file_entries;
+
+    /* The number to treat as standard ops. This is a special
+       accomodation of gcc using the new standard opcodes but not
+       updating the version number. It's legal dwarf2, but much better
+       for the user to understand as dwarf3 when 'it looks ok'. */
+    Dwarf_Bool pf_std_op_count;
+
+};
+
+void dwarf_init_line_table_prefix(struct Line_Table_Prefix_s *pf);
+void dwarf_free_line_table_prefix(struct Line_Table_Prefix_s *pf);
+
+int
+  dwarf_read_line_table_prefix(Dwarf_Debug dbg,
+			       Dwarf_Small * data_start,
+			       Dwarf_Unsigned data_length,
+			       Dwarf_Small ** updated_data_start_out,
+			       struct Line_Table_Prefix_s *prefix_out,
+			       Dwarf_Error * err);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_line2.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,114 @@
+/*
+
+  Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+/* This source file used for SGI-IRIX rqs processing.
+   Unused otherwise.
+*/
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include "dwarf_line.h"
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+
+
+
+/*
+	Return DW_DLV_OK or, if error,
+	DW_DLV_ERROR.
+
+	Thru pointers, return 2 arrays and a count
+	for rqs.
+*/
+int
+_dwarf_line_address_offsets(Dwarf_Debug dbg,
+			    Dwarf_Die die,
+			    Dwarf_Addr ** addrs,
+			    Dwarf_Off ** offs,
+			    Dwarf_Unsigned * returncount,
+			    Dwarf_Error * err)
+{
+    Dwarf_Addr *laddrs;
+    Dwarf_Off *loffsets;
+    Dwarf_Signed lcount;
+    Dwarf_Signed i;
+    int res;
+    Dwarf_Line *linebuf;
+
+    res = _dwarf_internal_srclines(die, &linebuf, &lcount,	/* addrlist= 
+								 */ true,
+				   /* linelist= */ false, err);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+    laddrs = (Dwarf_Addr *)
+	_dwarf_get_alloc(dbg, DW_DLA_ADDR, lcount);
+    if (laddrs == NULL) {
+	dwarf_srclines_dealloc(dbg, linebuf, lcount);
+	_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+    loffsets = (Dwarf_Off *)
+	_dwarf_get_alloc(dbg, DW_DLA_ADDR, lcount);
+    if (loffsets == NULL) {
+	dwarf_srclines_dealloc(dbg, linebuf, lcount);
+	/* We already allocated what laddrs points at, so we'e better
+	   deallocate that space since we are not going to return the
+	   pointer to the caller. */
+	dwarf_dealloc(dbg, laddrs, DW_DLA_ADDR);
+	_dwarf_error(dbg, err, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+
+    for (i = 0; i < lcount; i++) {
+	laddrs[i] = linebuf[i]->li_address;
+	loffsets[i] = linebuf[i]->li_addr_line.li_offset;
+    }
+    dwarf_srclines_dealloc(dbg, linebuf, lcount);
+    *returncount = lcount;
+    *offs = loffsets;
+    *addrs = laddrs;
+    return DW_DLV_OK;
+}
+
+/*
+   It's impossible for callers of dwarf_srclines() to get to and
+   free all the resources (in particular, the li_context and its
+   lc_file_entries). 
+   So this function, new July 2005, does it.  
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_loc.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1018 @@
+/*
+
+  Copyright (C) 2000,2003,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include "dwarf_loc.h"
+
+
+/*
+    Given a Dwarf_Block that represents a location expression,
+    this function returns a pointer to a Dwarf_Locdesc struct 
+    that has its ld_cents field set to the number of location 
+    operators in the block, and its ld_s field pointing to a 
+    contiguous block of Dwarf_Loc structs.  However, the 
+    ld_lopc and ld_hipc values are uninitialized.  Returns 
+    NULL on error.  This function assumes that the length of 
+    the block is greater than 0.  Zero length location expressions 
+    to represent variables that have been optimized away are 
+    handled in the calling function.
+*/
+static Dwarf_Locdesc *
+_dwarf_get_locdesc(Dwarf_Debug dbg,
+		   Dwarf_Block * loc_block,
+		   Dwarf_Addr lowpc,
+		   Dwarf_Addr highpc, Dwarf_Error * error)
+{
+    /* Size of the block containing the location expression. */
+    Dwarf_Unsigned loc_len = 0;
+
+    /* Sweeps the block containing the location expression. */
+    Dwarf_Small *loc_ptr = 0;
+
+    /* Current location operator. */
+    Dwarf_Small atom = 0;
+
+    /* Offset of current operator from start of block. */
+    Dwarf_Unsigned offset = 0;
+
+    /* Operands of current location operator. */
+    Dwarf_Unsigned operand1, operand2;
+
+    /* Used to chain the Dwarf_Loc_Chain_s structs. */
+    Dwarf_Loc_Chain curr_loc = NULL;
+    Dwarf_Loc_Chain prev_loc = NULL;
+    Dwarf_Loc_Chain head_loc = NULL;
+
+    /* Count of the number of location operators. */
+    Dwarf_Unsigned op_count = 0;
+
+    /* Contiguous block of Dwarf_Loc's for Dwarf_Locdesc. */
+    Dwarf_Loc *block_loc = 0;
+
+    /* Dwarf_Locdesc pointer to be returned. */
+    Dwarf_Locdesc *locdesc = 0;
+
+    Dwarf_Word leb128_length = 0;
+    Dwarf_Unsigned i = 0;
+
+    /* ***** BEGIN CODE ***** */
+
+    loc_len = loc_block->bl_len;
+    loc_ptr = loc_block->bl_data;
+
+    offset = 0;
+    op_count = 0;
+    while (offset < loc_len) {
+
+	operand1 = 0;
+	operand2 = 0;
+	op_count++;
+
+	atom = *(Dwarf_Small *) loc_ptr;
+	loc_ptr++;
+	offset++;
+
+	curr_loc =
+	    (Dwarf_Loc_Chain) _dwarf_get_alloc(dbg, DW_DLA_LOC_CHAIN,
+					       1);
+	if (curr_loc == NULL) {
+	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	    return (NULL);
+	}
+	curr_loc->lc_offset = offset;
+	curr_loc->lc_atom = atom;
+	switch (atom) {
+
+	case DW_OP_reg0:
+	case DW_OP_reg1:
+	case DW_OP_reg2:
+	case DW_OP_reg3:
+	case DW_OP_reg4:
+	case DW_OP_reg5:
+	case DW_OP_reg6:
+	case DW_OP_reg7:
+	case DW_OP_reg8:
+	case DW_OP_reg9:
+	case DW_OP_reg10:
+	case DW_OP_reg11:
+	case DW_OP_reg12:
+	case DW_OP_reg13:
+	case DW_OP_reg14:
+	case DW_OP_reg15:
+	case DW_OP_reg16:
+	case DW_OP_reg17:
+	case DW_OP_reg18:
+	case DW_OP_reg19:
+	case DW_OP_reg20:
+	case DW_OP_reg21:
+	case DW_OP_reg22:
+	case DW_OP_reg23:
+	case DW_OP_reg24:
+	case DW_OP_reg25:
+	case DW_OP_reg26:
+	case DW_OP_reg27:
+	case DW_OP_reg28:
+	case DW_OP_reg29:
+	case DW_OP_reg30:
+	case DW_OP_reg31:
+	    break;
+
+	case DW_OP_regx:
+	    operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
+	    loc_ptr = loc_ptr + leb128_length;
+	    offset = offset + leb128_length;
+	    break;
+
+	case DW_OP_lit0:
+	case DW_OP_lit1:
+	case DW_OP_lit2:
+	case DW_OP_lit3:
+	case DW_OP_lit4:
+	case DW_OP_lit5:
+	case DW_OP_lit6:
+	case DW_OP_lit7:
+	case DW_OP_lit8:
+	case DW_OP_lit9:
+	case DW_OP_lit10:
+	case DW_OP_lit11:
+	case DW_OP_lit12:
+	case DW_OP_lit13:
+	case DW_OP_lit14:
+	case DW_OP_lit15:
+	case DW_OP_lit16:
+	case DW_OP_lit17:
+	case DW_OP_lit18:
+	case DW_OP_lit19:
+	case DW_OP_lit20:
+	case DW_OP_lit21:
+	case DW_OP_lit22:
+	case DW_OP_lit23:
+	case DW_OP_lit24:
+	case DW_OP_lit25:
+	case DW_OP_lit26:
+	case DW_OP_lit27:
+	case DW_OP_lit28:
+	case DW_OP_lit29:
+	case DW_OP_lit30:
+	case DW_OP_lit31:
+	    operand1 = atom - DW_OP_lit0;
+	    break;
+
+	case DW_OP_addr:
+	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned,
+			   loc_ptr, dbg->de_pointer_size);
+	    loc_ptr += dbg->de_pointer_size;
+	    offset += dbg->de_pointer_size;
+	    break;
+
+	case DW_OP_const1u:
+	    operand1 = *(Dwarf_Small *) loc_ptr;
+	    loc_ptr = loc_ptr + 1;
+	    offset = offset + 1;
+	    break;
+
+	case DW_OP_const1s:
+	    operand1 = *(Dwarf_Sbyte *) loc_ptr;
+            SIGN_EXTEND(operand1,1);
+	    loc_ptr = loc_ptr + 1;
+	    offset = offset + 1;
+	    break;
+
+	case DW_OP_const2u:
+	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
+	    loc_ptr = loc_ptr + 2;
+	    offset = offset + 2;
+	    break;
+
+	case DW_OP_const2s:
+	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
+            SIGN_EXTEND(operand1,2);
+	    loc_ptr = loc_ptr + 2;
+	    offset = offset + 2;
+	    break;
+
+	case DW_OP_const4u:
+	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
+	    loc_ptr = loc_ptr + 4;
+	    offset = offset + 4;
+	    break;
+
+	case DW_OP_const4s:
+	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
+            SIGN_EXTEND(operand1,4);
+	    loc_ptr = loc_ptr + 4;
+	    offset = offset + 4;
+	    break;
+
+	case DW_OP_const8u:
+	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8);
+	    loc_ptr = loc_ptr + 8;
+	    offset = offset + 8;
+	    break;
+
+	case DW_OP_const8s:
+	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8);
+	    loc_ptr = loc_ptr + 8;
+	    offset = offset + 8;
+	    break;
+
+	case DW_OP_constu:
+	    operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
+	    loc_ptr = loc_ptr + leb128_length;
+	    offset = offset + leb128_length;
+	    break;
+
+	case DW_OP_consts:
+	    operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
+	    loc_ptr = loc_ptr + leb128_length;
+	    offset = offset + leb128_length;
+	    break;
+
+	case DW_OP_fbreg:
+	    operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
+	    loc_ptr = loc_ptr + leb128_length;
+	    offset = offset + leb128_length;
+	    break;
+
+	case DW_OP_breg0:
+	case DW_OP_breg1:
+	case DW_OP_breg2:
+	case DW_OP_breg3:
+	case DW_OP_breg4:
+	case DW_OP_breg5:
+	case DW_OP_breg6:
+	case DW_OP_breg7:
+	case DW_OP_breg8:
+	case DW_OP_breg9:
+	case DW_OP_breg10:
+	case DW_OP_breg11:
+	case DW_OP_breg12:
+	case DW_OP_breg13:
+	case DW_OP_breg14:
+	case DW_OP_breg15:
+	case DW_OP_breg16:
+	case DW_OP_breg17:
+	case DW_OP_breg18:
+	case DW_OP_breg19:
+	case DW_OP_breg20:
+	case DW_OP_breg21:
+	case DW_OP_breg22:
+	case DW_OP_breg23:
+	case DW_OP_breg24:
+	case DW_OP_breg25:
+	case DW_OP_breg26:
+	case DW_OP_breg27:
+	case DW_OP_breg28:
+	case DW_OP_breg29:
+	case DW_OP_breg30:
+	case DW_OP_breg31:
+	    operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
+	    loc_ptr = loc_ptr + leb128_length;
+	    offset = offset + leb128_length;
+	    break;
+
+	case DW_OP_bregx:
+	    /* uleb reg num followed by sleb offset */
+	    operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
+	    loc_ptr = loc_ptr + leb128_length;
+	    offset = offset + leb128_length;
+
+	    operand2 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
+	    loc_ptr = loc_ptr + leb128_length;
+	    offset = offset + leb128_length;
+	    break;
+
+	case DW_OP_dup:
+	case DW_OP_drop:
+	    break;
+
+	case DW_OP_pick:
+	    operand1 = *(Dwarf_Small *) loc_ptr;
+	    loc_ptr = loc_ptr + 1;
+	    offset = offset + 1;
+	    break;
+
+	case DW_OP_over:
+	case DW_OP_swap:
+	case DW_OP_rot:
+	case DW_OP_deref:
+	    break;
+
+	case DW_OP_deref_size:
+	    operand1 = *(Dwarf_Small *) loc_ptr;
+	    loc_ptr = loc_ptr + 1;
+	    offset = offset + 1;
+	    break;
+
+	case DW_OP_xderef:
+	    break;
+
+	case DW_OP_xderef_size:
+	    operand1 = *(Dwarf_Small *) loc_ptr;
+	    loc_ptr = loc_ptr + 1;
+	    offset = offset + 1;
+	    break;
+
+	case DW_OP_abs:
+	case DW_OP_and:
+	case DW_OP_div:
+	case DW_OP_minus:
+	case DW_OP_mod:
+	case DW_OP_mul:
+	case DW_OP_neg:
+	case DW_OP_not:
+	case DW_OP_or:
+	case DW_OP_plus:
+	    break;
+
+	case DW_OP_plus_uconst:
+	    operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
+	    loc_ptr = loc_ptr + leb128_length;
+	    offset = offset + leb128_length;
+	    break;
+
+	case DW_OP_shl:
+	case DW_OP_shr:
+	case DW_OP_shra:
+	case DW_OP_xor:
+	    break;
+
+	case DW_OP_le:
+	case DW_OP_ge:
+	case DW_OP_eq:
+	case DW_OP_lt:
+	case DW_OP_gt:
+	case DW_OP_ne:
+	    break;
+
+	case DW_OP_skip:
+	case DW_OP_bra:
+	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
+	    loc_ptr = loc_ptr + 2;
+	    offset = offset + 2;
+	    break;
+
+	case DW_OP_piece:
+	    operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
+	    loc_ptr = loc_ptr + leb128_length;
+	    offset = offset + leb128_length;
+	    break;
+
+	case DW_OP_nop:
+	    break;
+	case DW_OP_push_object_address:	/* DWARF3 */
+	    break;
+	case DW_OP_call2:	/* DWARF3 */
+	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
+	    loc_ptr = loc_ptr + 2;
+	    offset = offset + 2;
+	    break;
+
+	case DW_OP_call4:	/* DWARF3 */
+	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
+	    loc_ptr = loc_ptr + 4;
+	    offset = offset + 4;
+	    break;
+	case DW_OP_call_ref:	/* DWARF3 */
+	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr,
+			   dbg->de_length_size);
+	    loc_ptr = loc_ptr + dbg->de_length_size;
+	    offset = offset + dbg->de_length_size;
+	    break;
+
+	case DW_OP_form_tls_address:	/* DWARF3f */
+	    break;
+	case DW_OP_call_frame_cfa:	/* DWARF3f */
+	    break;
+	case DW_OP_bit_piece:	/* DWARF3f */
+	    /* uleb size in bits followed by uleb offset in bits */
+	    operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
+	    loc_ptr = loc_ptr + leb128_length;
+	    offset = offset + leb128_length;
+
+	    operand2 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
+	    loc_ptr = loc_ptr + leb128_length;
+	    offset = offset + leb128_length;
+	    break;
+
+
+	default:
+	    _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
+	    return (NULL);
+	}
+
+
+	curr_loc->lc_number = operand1;
+	curr_loc->lc_number2 = operand2;
+
+	if (head_loc == NULL)
+	    head_loc = prev_loc = curr_loc;
+	else {
+	    prev_loc->lc_next = curr_loc;
+	    prev_loc = curr_loc;
+	}
+    }
+
+    block_loc =
+	(Dwarf_Loc *) _dwarf_get_alloc(dbg, DW_DLA_LOC_BLOCK, op_count);
+    if (block_loc == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (NULL);
+    }
+
+    curr_loc = head_loc;
+    for (i = 0; i < op_count; i++) {
+	(block_loc + i)->lr_atom = curr_loc->lc_atom;
+	(block_loc + i)->lr_number = curr_loc->lc_number;
+	(block_loc + i)->lr_number2 = curr_loc->lc_number2;
+	(block_loc + i)->lr_offset = curr_loc->lc_offset;
+
+	prev_loc = curr_loc;
+	curr_loc = curr_loc->lc_next;
+	dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN);
+    }
+
+    locdesc =
+	(Dwarf_Locdesc *) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC, 1);
+    if (locdesc == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (NULL);
+    }
+
+    locdesc->ld_cents = op_count;
+    locdesc->ld_s = block_loc;
+    locdesc->ld_from_loclist = loc_block->bl_from_loclist;
+    locdesc->ld_section_offset = loc_block->bl_section_offset;
+    locdesc->ld_lopc = lowpc;
+    locdesc->ld_hipc = highpc;
+
+    return (locdesc);
+}
+
+/* Using a loclist offset to get the in-memory
+   address of .debug_loc data to read, returns the loclist 
+   'header' info in return_block.
+*/
+
+#define MAX_ADDR ((address_size == 8)?0xffffffffffffffffULL:0xffffffff)
+
+static int
+_dwarf_read_loc_section(Dwarf_Debug dbg,
+			Dwarf_Block * return_block,
+			Dwarf_Addr * lowpc, Dwarf_Addr * hipc,
+			Dwarf_Off sec_offset, Dwarf_Error * error)
+{
+    Dwarf_Small *beg = dbg->de_debug_loc + sec_offset;
+    int address_size = dbg->de_pointer_size;
+
+    Dwarf_Addr start_addr = 0;
+    Dwarf_Addr end_addr = 0;
+    Dwarf_Half exprblock_size = 0;
+    Dwarf_Unsigned exprblock_off =
+	2 * address_size + sizeof(Dwarf_Half);
+
+    if (sec_offset >= dbg->de_debug_loc_size) {
+	/* We're at the end. No more present. */
+	return DW_DLV_NO_ENTRY;
+    }
+
+    /* If it goes past end, error */
+    if (exprblock_off > dbg->de_debug_loc_size) {
+	_dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
+	return DW_DLV_ERROR;
+    }
+
+    READ_UNALIGNED(dbg, start_addr, Dwarf_Addr, beg, address_size);
+    READ_UNALIGNED(dbg, end_addr, Dwarf_Addr,
+		   beg + address_size, address_size);
+    if (start_addr == 0 && end_addr == 0) {
+	/* If start_addr and end_addr are 0, it's the end and no
+	   exprblock_size field follows. */
+	exprblock_size = 0;
+	exprblock_off -= sizeof(Dwarf_Half);
+    } else if (start_addr == MAX_ADDR) {
+	/* end address is a base address, no exprblock_size field here
+	   either */
+	exprblock_size = 0;
+	exprblock_off -= sizeof(Dwarf_Half);
+    } else {
+
+	READ_UNALIGNED(dbg, exprblock_size, Dwarf_Half,
+		       beg + 2 * address_size, sizeof(Dwarf_Half));
+	/* exprblock_size can be zero, means no expression */
+	if ((exprblock_off + exprblock_size) > dbg->de_debug_loc_size) {
+	    _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
+	    return DW_DLV_ERROR;
+	}
+    }
+#undef MAX_ADDR
+    *lowpc = start_addr;
+    *hipc = end_addr;
+
+    return_block->bl_len = exprblock_size;
+    return_block->bl_from_loclist = 1;
+    return_block->bl_data = beg + exprblock_off;
+    return_block->bl_section_offset =
+	((Dwarf_Small *) return_block->bl_data) - dbg->de_debug_loc;
+
+    return DW_DLV_OK;
+
+}
+static int
+_dwarf_get_loclist_count(Dwarf_Debug dbg,
+			 Dwarf_Off loclist_offset,
+			 int *loclist_count, Dwarf_Error * error)
+{
+    int count = 0;
+    Dwarf_Off offset = loclist_offset;
+
+
+    for (;;) {
+	Dwarf_Block b;
+	Dwarf_Addr lowpc;
+	Dwarf_Addr highpc;
+	int res = _dwarf_read_loc_section(dbg, &b,
+
+					  &lowpc, &highpc,
+					  offset, error);
+
+	if (res != DW_DLV_OK) {
+	    return res;
+	}
+	offset = b.bl_len + b.bl_section_offset;
+	if (lowpc == 0 && highpc == 0) {
+	    break;
+	}
+	count++;
+    }
+    *loclist_count = count;
+    return DW_DLV_OK;
+}
+
+/* Helper routine to avoid code duplication. 
+*/
+static int
+_dwarf_setup_loc(Dwarf_Attribute attr,
+		 Dwarf_Debug * dbg_ret,
+		 Dwarf_Half * form_ret, Dwarf_Error * error)
+{
+    Dwarf_Debug dbg = 0;
+    Dwarf_Half form = 0;
+    int blkres;
+
+    if (attr == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
+	return (DW_DLV_ERROR);
+    }
+    if (attr->ar_cu_context == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
+	return (DW_DLV_ERROR);
+    }
+
+    dbg = attr->ar_cu_context->cc_dbg;
+    if (dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+    *dbg_ret = dbg;
+    blkres = dwarf_whatform(attr, &form, error);
+    if (blkres != DW_DLV_OK) {
+	_dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
+	return blkres;
+    }
+    *form_ret = form;
+
+    return DW_DLV_OK;
+}
+
+/* Helper routine  to avoid code duplication.
+*/
+static int
+_dwarf_get_loclist_header_start(Dwarf_Debug dbg,
+				Dwarf_Attribute attr,
+				Dwarf_Unsigned * loclist_offset,
+				Dwarf_Error * error)
+{
+    int secload = 0;
+    int blkres = dwarf_formudata(attr, loclist_offset, error);
+
+    if (blkres != DW_DLV_OK) {
+	return (blkres);
+    }
+
+    if (!dbg->de_debug_loc) {
+	secload = _dwarf_load_section(dbg,
+				      dbg->de_debug_loc_index,
+				      &dbg->de_debug_loc, error);
+	if (secload != DW_DLV_OK) {
+	    return secload;
+	}
+    }
+    return DW_DLV_OK;
+}
+
+/* When llbuf (see dwarf_loclist_n) is partially set up
+   and an error is encountered, tear it down as it
+   won't be used.
+*/
+static void
+_dwarf_cleanup_llbuf(Dwarf_Debug dbg, Dwarf_Locdesc ** llbuf, int count)
+{
+    int i;
+
+    for (i = 0; i < count; ++i) {
+	dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK);
+	dwarf_dealloc(dbg, llbuf[i], DW_DLA_LOCDESC);
+    }
+    dwarf_dealloc(dbg, llbuf, DW_DLA_LIST);
+}
+
+/* 
+	Handles simple location entries and loclists.
+	Returns all the Locdesc's thru llbuf. 
+	
+*/
+int
+dwarf_loclist_n(Dwarf_Attribute attr,
+		Dwarf_Locdesc *** llbuf_out,
+		Dwarf_Signed * listlen_out, Dwarf_Error * error)
+{
+    Dwarf_Debug dbg;
+
+    /* 
+       Dwarf_Attribute that describes the DW_AT_location in die, if
+       present. */
+    Dwarf_Attribute loc_attr = attr;
+
+    /* Dwarf_Block that describes a single location expression. */
+    Dwarf_Block loc_block;
+
+    /* A pointer to the current Dwarf_Locdesc read. */
+    Dwarf_Locdesc *locdesc = 0;
+
+    Dwarf_Half form = 0;
+    Dwarf_Addr lowpc = 0;
+    Dwarf_Addr highpc = 0;
+    Dwarf_Signed listlen = 0;
+    Dwarf_Locdesc **llbuf = 0;
+
+    int blkres;
+    int setup_res;
+
+    /* ***** BEGIN CODE ***** */
+    setup_res = _dwarf_setup_loc(attr, &dbg, &form, error);
+    if (setup_res != DW_DLV_OK) {
+	return setup_res;
+    }
+    /* If this is a form_block then it's a location expression. If it's 
+       DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */
+    if (form == DW_FORM_data4 || form == DW_FORM_data8) {
+
+	/* A reference to .debug_loc, with an offset in .debug_loc of a 
+	   loclist */
+	Dwarf_Unsigned loclist_offset = 0;
+	int off_res;
+	int count_res;
+	int loclist_count;
+	int lli;
+
+	off_res = _dwarf_get_loclist_header_start(dbg,
+						  attr, &loclist_offset,
+						  error);
+	if (off_res != DW_DLV_OK) {
+	    return off_res;
+	}
+	count_res = _dwarf_get_loclist_count(dbg, loclist_offset,
+					     &loclist_count, error);
+	listlen = loclist_count;
+	if (count_res != DW_DLV_OK) {
+	    return count_res;
+	}
+	if (loclist_count == 0) {
+	    return DW_DLV_NO_ENTRY;
+	}
+
+	llbuf = (Dwarf_Locdesc **)
+	    _dwarf_get_alloc(dbg, DW_DLA_LIST, loclist_count);
+	if (!llbuf) {
+	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	    return (DW_DLV_ERROR);
+	}
+
+	for (lli = 0; lli < loclist_count; ++lli) {
+	    blkres = _dwarf_read_loc_section(dbg, &loc_block,
+					     &lowpc,
+					     &highpc,
+					     loclist_offset, error);
+	    if (blkres != DW_DLV_OK) {
+		_dwarf_cleanup_llbuf(dbg, llbuf, lli);
+		return (blkres);
+	    }
+	    locdesc = _dwarf_get_locdesc(dbg, &loc_block,
+					 lowpc, highpc, error);
+	    if (locdesc == NULL) {
+		_dwarf_cleanup_llbuf(dbg, llbuf, lli);
+		/* low level error already set: let it be passed back */
+		return (DW_DLV_ERROR);
+	    }
+	    llbuf[lli] = locdesc;
+
+	    /* Now get to next loclist entry offset. */
+	    loclist_offset = loc_block.bl_section_offset +
+		loc_block.bl_len;
+	}
+
+
+    } else {
+	Dwarf_Block *tblock = 0;
+
+	blkres = dwarf_formblock(loc_attr, &tblock, error);
+	if (blkres != DW_DLV_OK) {
+	    return (blkres);
+	}
+	loc_block = *tblock;
+	/* We copied tblock contents to the stack var, so can dealloc
+	   tblock now.  Avoids leaks. */
+	dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
+	listlen = 1;		/* One by definition of a location
+				   entry. */
+	lowpc = 0;		/* HACK */
+	highpc = (Dwarf_Unsigned) (-1LL);	/* HACK */
+
+	/* An empty location description (block length 0) means the
+	   code generator emitted no variable, the variable was not
+	   generated, it was unused or perhaps never tested after being 
+	   set. Dwarf2, section 2.4.1 In other words, it is not an
+	   error, and we don't test for block length 0 specially here. */
+	locdesc = _dwarf_get_locdesc(dbg, &loc_block,
+				     lowpc, highpc, error);
+	if (locdesc == NULL) {
+	    /* low level error already set: let it be passed back */
+	    return (DW_DLV_ERROR);
+	}
+	llbuf = (Dwarf_Locdesc **)
+	    _dwarf_get_alloc(dbg, DW_DLA_LIST, listlen);
+	if (!llbuf) {
+	    /* Free the locdesc we allocated but won't use. */
+	    dwarf_dealloc(dbg, locdesc, DW_DLA_LOCDESC);
+	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	    return (DW_DLV_ERROR);
+	}
+	llbuf[0] = locdesc;
+    }
+
+    *llbuf_out = llbuf;
+    *listlen_out = listlen;
+    return (DW_DLV_OK);
+}
+
+
+/* 
+	Handles only a location expression.
+	If called on a loclist, just returns one of those.
+	Cannot not handle a real loclist. 
+ 	It returns the location expression as a loclist with
+	a single entry.
+	See dwarf_loclist_n() which handles any number
+        of location list entries.
+
+	This is the original definition, and it simply
+	does not work for loclists. Kept for compatibility.
+*/
+int
+dwarf_loclist(Dwarf_Attribute attr,
+	      Dwarf_Locdesc ** llbuf,
+	      Dwarf_Signed * listlen, Dwarf_Error * error)
+{
+    Dwarf_Debug dbg;
+
+    /* 
+       Dwarf_Attribute that describes the DW_AT_location in die, if
+       present. */
+    Dwarf_Attribute loc_attr = attr;
+
+    /* Dwarf_Block that describes a single location expression. */
+    Dwarf_Block loc_block;
+
+    /* A pointer to the current Dwarf_Locdesc read. */
+    Dwarf_Locdesc *locdesc = 0;
+
+    Dwarf_Half form = 0;
+    Dwarf_Addr lowpc = 0;
+    Dwarf_Addr highpc = 0;
+
+    int blkres;
+    int setup_res;
+
+    /* ***** BEGIN CODE ***** */
+    setup_res = _dwarf_setup_loc(attr, &dbg, &form, error);
+    if (setup_res != DW_DLV_OK) {
+	return setup_res;
+    }
+    /* If this is a form_block then it's a location expression. If it's 
+       DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */
+    if (form == DW_FORM_data4 || form == DW_FORM_data8) {
+
+	/* A reference to .debug_loc, with an offset in .debug_loc of a 
+	   loclist */
+	Dwarf_Unsigned loclist_offset = 0;
+	int off_res;
+
+	off_res = _dwarf_get_loclist_header_start(dbg,
+						  attr, &loclist_offset,
+						  error);
+	if (off_res != DW_DLV_OK) {
+	    return off_res;
+	}
+
+	/* With dwarf_loclist, just read a single entry */
+	blkres = _dwarf_read_loc_section(dbg, &loc_block,
+					 &lowpc,
+					 &highpc,
+					 loclist_offset, error);
+	if (blkres != DW_DLV_OK) {
+	    return (blkres);
+	}
+
+
+
+
+    } else {
+	Dwarf_Block *tblock = 0;
+
+	blkres = dwarf_formblock(loc_attr, &tblock, error);
+	if (blkres != DW_DLV_OK) {
+	    return (blkres);
+	}
+	loc_block = *tblock;
+	/* We copied tblock contents to the stack var, so can dealloc
+	   tblock now.  Avoids leaks. */
+	dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
+	lowpc = 0;		/* HACK */
+	highpc = (Dwarf_Unsigned) (-1LL);	/* HACK */
+    }
+
+    /* An empty location description (block length 0) means the code
+       generator emitted no variable, the variable was not generated,
+       it was unused or perhaps never tested after being set. Dwarf2,
+       section 2.4.1 In other words, it is not an error, and we don't
+       test for block length 0 specially here. FIXME: doing this once
+       is wrong, needs to handle low/hi pc sets. */
+    locdesc = _dwarf_get_locdesc(dbg, &loc_block, lowpc, highpc, error);
+    if (locdesc == NULL) {
+	/* low level error already set: let it be passed back */
+	return (DW_DLV_ERROR);
+    }
+
+    *llbuf = locdesc;
+    *listlen = 1;
+    return (DW_DLV_OK);
+}
+
+
+
+/* 
+	Handles only a location expression.
+ 	It returns the location expression as a loclist with
+	a single entry.
+
+        Usable to access dwarf expressions from any source, but
+        specifically from
+            DW_CFA_def_cfa_expression
+            DW_CFA_expression
+            DW_CFA_val_expression
+ 
+        expression_in must point to a valid dwarf expression
+        set of bytes of length expression_length. Not
+        a DW_FORM_block*, just the expression bytes.
+
+*/
+int
+dwarf_loclist_from_expr(Dwarf_Debug dbg,
+              Dwarf_Ptr expression_in,
+              Dwarf_Unsigned expression_length,
+	      Dwarf_Locdesc ** llbuf,
+	      Dwarf_Signed * listlen, Dwarf_Error * error)
+{
+    /* Dwarf_Block that describes a single location expression. */
+    Dwarf_Block loc_block;
+
+    /* A pointer to the current Dwarf_Locdesc read. */
+    Dwarf_Locdesc *locdesc = 0;
+    Dwarf_Addr lowpc = 0;
+    Dwarf_Addr highpc = (Dwarf_Unsigned) (-1LL);
+
+    memset(&loc_block,0,sizeof(loc_block));
+    loc_block.bl_len = expression_length;
+    loc_block.bl_data = expression_in;
+    loc_block.bl_from_loclist = 0; /* Not from loclist. */
+    loc_block.bl_section_offset = 0; /* Fake. Not meaningful. */
+
+
+    /* An empty location description (block length 0) means the code
+    generator emitted no variable, the variable was not generated,
+    it was unused or perhaps never tested after being set. Dwarf2,
+    section 2.4.1 In other words, it is not an error, and we don't
+    test for block length 0 specially here.  */
+    locdesc = _dwarf_get_locdesc(dbg, &loc_block, lowpc, highpc, error);
+    if (locdesc == NULL) {
+        /* low level error already set: let it be passed back */
+        return (DW_DLV_ERROR);
+    }
+
+    *llbuf = locdesc;
+    *listlen = 1;
+    return (DW_DLV_OK);
+}
+
+/* Usable to read a single loclist or to read a block of them
+   or to read an entire section's loclists.
+
+*/
+
+ /*ARGSUSED*/ int
+dwarf_get_loclist_entry(Dwarf_Debug dbg,
+			Dwarf_Unsigned offset,
+			Dwarf_Addr * hipc_offset,
+			Dwarf_Addr * lopc_offset,
+			Dwarf_Ptr * data,
+			Dwarf_Unsigned * entry_len,
+			Dwarf_Unsigned * next_entry,
+			Dwarf_Error * error)
+{
+    Dwarf_Block b;
+    Dwarf_Addr lowpc;
+    Dwarf_Addr highpc;
+    int res;
+
+    if (!dbg->de_debug_loc) {
+	int secload = _dwarf_load_section(dbg,
+					  dbg->de_debug_loc_index,
+					  &dbg->de_debug_loc,
+					  error);
+
+	if (secload != DW_DLV_OK) {
+	    return secload;
+	}
+    }
+
+    res = _dwarf_read_loc_section(dbg,
+				  &b, &lowpc, &highpc, offset, error);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+    *hipc_offset = highpc;
+    *lopc_offset = lowpc;
+    *entry_len = b.bl_len;
+    *data = b.bl_data;
+    *next_entry = b.bl_len + b.bl_section_offset;
+
+    return DW_DLV_OK;
+
+
+
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_loc.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,46 @@
+/*
+
+  Copyright (C) 2000, 2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+typedef struct Dwarf_Loc_Chain_s *Dwarf_Loc_Chain;
+
+struct Dwarf_Loc_Chain_s {
+    Dwarf_Small lc_atom;
+    Dwarf_Unsigned lc_number;
+    Dwarf_Unsigned lc_number2;
+    Dwarf_Unsigned lc_offset;
+    Dwarf_Loc_Chain lc_next;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_macro.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,473 @@
+/*
+
+  Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include <limits.h>
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif /* HAVE_STDLIB_H */
+#include "dwarf_macro.h"
+
+
+#define LEFTPAREN '('
+#define RIGHTPAREN ')'
+#define SPACE ' '
+
+/*
+	Given the dwarf macro string, return a pointer to
+	the value.  Returns pointer to 0 byte at end of string
+	if no value found (meaning the value is the empty string).
+
+	Only understands well-formed dwarf macinfo strings.
+*/
+char *
+dwarf_find_macro_value_start(char *str)
+{
+    char *lcp;
+    int funclike = 0;
+
+    for (lcp = str; *lcp; ++lcp) {
+	switch (*lcp) {
+	case LEFTPAREN:
+	    funclike = 1;
+	    break;
+	case RIGHTPAREN:
+	    /* lcp+1 must be a space, and following char is the value */
+	    return lcp + 2;
+	case SPACE:
+	    /* we allow extraneous spaces inside macro parameter **
+	       list, just in case... This is not really needed. */
+	    if (!funclike) {
+		return lcp + 1;
+	    }
+	    break;
+	}
+    }
+    /* never found value: returns pointer to the 0 byte at end of
+       string */
+    return lcp;
+
+}
+
+
+/*
+   Try to keep fileindex correct in every Macro_Details
+   record by tracking file starts and ends.
+   Uses high water mark: space reused, not freed.
+   Presumption is that this makes sense for most uses.
+   STARTERMAX is set so that the array need not be expanded for
+   most files: it is the initial include file depth.
+*/
+struct macro_stack_s {
+    Dwarf_Signed *st_base;
+    long max;
+    long next_to_use;
+    int was_fault;
+};
+
+static void _dwarf_reset_index_macro_stack(struct macro_stack_s *ms);
+static void
+free_macro_stack(Dwarf_Debug dbg, struct macro_stack_s *ms)
+{
+    dwarf_dealloc(dbg,ms->st_base,DW_DLA_STRING);
+    _dwarf_reset_index_macro_stack(ms);
+}
+
+#define STARTERMAX 10
+static void
+_dwarf_reset_index_macro_stack(struct macro_stack_s *ms)
+{
+    ms->st_base = 0;
+    ms->max = 0;
+    ms->next_to_use = 0;
+    ms->was_fault = 0;
+}
+static int
+_dwarf_macro_stack_push_index(Dwarf_Debug dbg, Dwarf_Signed indx,
+			      struct macro_stack_s *ms)
+{
+    Dwarf_Signed *newbase;
+
+    if (ms->next_to_use >= ms->max) {
+	long new_size;
+
+	if (ms->max == 0) {
+	    ms->max = STARTERMAX;
+	}
+	new_size = ms->max * 2;
+	newbase =
+	    _dwarf_get_alloc(dbg, DW_DLA_STRING,
+			     new_size * sizeof(Dwarf_Signed));
+	if (newbase == 0) {
+	    /* just leave the old array in place */
+	    ms->was_fault = 1;
+	    return DW_DLV_ERROR;
+	}
+        if(ms->st_base) {
+	    memcpy(newbase, ms->st_base,
+	       ms->next_to_use * sizeof(Dwarf_Signed));
+	    dwarf_dealloc(dbg, ms->st_base, DW_DLA_STRING);
+        }
+	ms->st_base = newbase;
+	ms->max = new_size;
+    }
+    ms->st_base[ms->next_to_use] = indx;
+    ++ms->next_to_use;
+    return DW_DLV_OK;
+}
+
+static Dwarf_Signed
+_dwarf_macro_stack_pop_index(struct macro_stack_s *ms)
+{
+    if (ms->was_fault) {
+	return -1;
+    }
+    if (ms->next_to_use > 0) {
+	ms->next_to_use--;
+	return (ms->st_base[ms->next_to_use]);
+    } else {
+        ms->was_fault = 1;
+    }
+    return -1;
+}
+
+/* starting at macro_offset in .debug_macinfo,
+	if maximum_count is 0, treat as if it is infinite.
+	get macro data up thru
+	maximum_count entries or the end of a compilation
+	unit's entries (whichever comes first). 
+*/
+
+int
+dwarf_get_macro_details(Dwarf_Debug dbg,
+			Dwarf_Off macro_offset,
+			Dwarf_Unsigned maximum_count,
+			Dwarf_Signed * entry_count,
+			Dwarf_Macro_Details ** details,
+			Dwarf_Error * error)
+{
+    Dwarf_Small *macro_base = 0;
+    Dwarf_Small *pnext = 0;
+    Dwarf_Unsigned endloc = 0;
+    unsigned char uc = 0;
+    unsigned long depth = 0;	/* By section 6.3.2 Dwarf3 draft 8/9,
+				   the base file should appear as
+				   DW_MACINFO_start_file. See
+				   http://gcc.gnu.org/ml/gcc-bugs/2005-02/msg03442.html
+				   on "[Bug debug/20253] New: [3.4/4.0 regression]:
+				   Macro debug info broken due to lexer change" for how
+				   gcc is broken in some versions. We no longer use
+				   depth as a stopping point, it's not needed as a
+				   stopping point anyway.  */
+
+
+    int res = 0;
+
+    /* count space used by strings */
+    unsigned long str_space = 0;
+    int done = 0;
+    unsigned long space_needed = 0;
+    unsigned long string_offset = 0;
+    Dwarf_Small *return_data = 0;
+    Dwarf_Small *pdata = 0;
+    unsigned long final_count = 0;
+    Dwarf_Signed fileindex = -1;
+    Dwarf_Small *latest_str_loc = 0;
+    struct macro_stack_s msdata;
+
+    unsigned long count = 0;
+    unsigned long max_count = (unsigned long) maximum_count;
+
+    _dwarf_reset_index_macro_stack(&msdata);
+    if (dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+	free_macro_stack(dbg,&msdata);
+	return (DW_DLV_ERROR);
+    }
+
+    res =
+	_dwarf_load_section(dbg,
+			    dbg->de_debug_macinfo_index,
+			    &dbg->de_debug_macinfo, error);
+    if (res != DW_DLV_OK) {
+	free_macro_stack(dbg,&msdata);
+	return res;
+    }
+
+    macro_base = dbg->de_debug_macinfo;
+    if (macro_base == NULL) {
+	free_macro_stack(dbg,&msdata);
+	return (DW_DLV_NO_ENTRY);
+    }
+    if (macro_offset >= dbg->de_debug_macinfo_size) {
+	free_macro_stack(dbg,&msdata);
+	return (DW_DLV_NO_ENTRY);
+    }
+
+    pnext = macro_base + macro_offset;
+    if (maximum_count == 0) {
+	max_count = ULONG_MAX;
+    }
+
+
+    /* how many entries and how much space will they take? */
+
+    endloc = (pnext - macro_base);
+    if (endloc >= dbg->de_debug_macinfo_size) {
+	if (endloc == dbg->de_debug_macinfo_size) {
+	    /* normal: found last entry */
+	    free_macro_stack(dbg,&msdata);
+	    return DW_DLV_NO_ENTRY;
+	}
+	_dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
+	free_macro_stack(dbg,&msdata);
+	return (DW_DLV_ERROR);
+    }
+    for (count = 0; !done && count < max_count; ++count) {
+	unsigned long slen;
+	Dwarf_Word len;
+
+	uc = *pnext;
+	++pnext;		/* get past the type code */
+	switch (uc) {
+	case DW_MACINFO_define:
+	case DW_MACINFO_undef:
+	    /* line, string */
+	case DW_MACINFO_vendor_ext:
+	    /* number, string */
+	    (void) _dwarf_decode_u_leb128(pnext, &len);
+
+	    pnext += len;
+	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
+		free_macro_stack(dbg,&msdata);
+		_dwarf_error(dbg, error,
+			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
+		return (DW_DLV_ERROR);
+	    }
+	    slen = strlen((char *) pnext) + 1;
+	    pnext += slen;
+	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
+		free_macro_stack(dbg,&msdata);
+		_dwarf_error(dbg, error,
+			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
+		return (DW_DLV_ERROR);
+	    }
+	    str_space += slen;
+	    break;
+	case DW_MACINFO_start_file:
+	    /* line, file index */
+	    (void) _dwarf_decode_u_leb128(pnext, &len);
+	    pnext += len;
+	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
+		free_macro_stack(dbg,&msdata);
+		_dwarf_error(dbg, error,
+			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
+		return (DW_DLV_ERROR);
+	    }
+	    (void) _dwarf_decode_u_leb128(pnext, &len);
+	    pnext += len;
+	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
+		free_macro_stack(dbg,&msdata);
+		_dwarf_error(dbg, error,
+			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
+		return (DW_DLV_ERROR);
+	    }
+	    ++depth;
+	    break;
+
+	case DW_MACINFO_end_file:
+	    if (--depth == 0) {
+		/* done = 1; no, do not stop here, at least one gcc had 
+		   the wrong depth settings in the gcc 3.4 timeframe. */
+	    }
+	    break;		/* no string or number here */
+	case 0:
+	    /* end of cu's entries */
+	    done = 1;
+	    break;
+	default:
+	    free_macro_stack(dbg,&msdata);
+	    _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT);
+	    return (DW_DLV_ERROR);
+	    /* bogus macinfo! */
+	}
+
+	endloc = (pnext - macro_base);
+	if (endloc == dbg->de_debug_macinfo_size) {
+	    done = 1;
+	} else if (endloc > dbg->de_debug_macinfo_size) {
+	    _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
+	    free_macro_stack(dbg,&msdata);
+	    return (DW_DLV_ERROR);
+	}
+    }
+    if (count == 0) {
+	free_macro_stack(dbg,&msdata);
+	_dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INTERNAL_ERR);
+	return (DW_DLV_ERROR);
+    }
+
+    /* we have 'count' array entries to allocate and str_space bytes of 
+       string space to provide for. */
+
+    string_offset = count * sizeof(Dwarf_Macro_Details);
+
+    /* extra 2 not really needed */
+    space_needed = string_offset + str_space + 2;
+    return_data = pdata =
+	_dwarf_get_alloc(dbg, DW_DLA_STRING, space_needed);
+    latest_str_loc = pdata + string_offset;
+    if (pdata == 0) {
+	free_macro_stack(dbg,&msdata);
+	_dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_MALLOC_SPACE);
+	return (DW_DLV_ERROR);
+    }
+    pnext = macro_base + macro_offset;
+
+    done = 0;
+
+    /* A series ends with a type code of 0. */
+
+    for (final_count = 0; !done && final_count < count; ++final_count) {
+	unsigned long slen;
+	Dwarf_Word len;
+	Dwarf_Unsigned v1;
+	Dwarf_Macro_Details *pdmd = (Dwarf_Macro_Details *) (pdata +
+		(final_count * sizeof (Dwarf_Macro_Details)));
+
+	endloc = (pnext - macro_base);
+	if (endloc > dbg->de_debug_macinfo_size) {
+	    free_macro_stack(dbg,&msdata);
+	    _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_LENGTH_BAD);
+	    return (DW_DLV_ERROR);
+	}
+	uc = *pnext;
+	pdmd->dmd_offset = (pnext - macro_base);
+	pdmd->dmd_type = uc;
+	pdmd->dmd_fileindex = fileindex;
+	pdmd->dmd_lineno = 0;
+	pdmd->dmd_macro = 0;
+	++pnext;		/* get past the type code */
+	switch (uc) {
+	case DW_MACINFO_define:
+	case DW_MACINFO_undef:
+	    /* line, string */
+	case DW_MACINFO_vendor_ext:
+	    /* number, string */
+	    v1 = _dwarf_decode_u_leb128(pnext, &len);
+	    pdmd->dmd_lineno = v1;
+
+	    pnext += len;
+	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
+		free_macro_stack(dbg,&msdata);
+                dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
+		_dwarf_error(dbg, error,
+			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
+		return (DW_DLV_ERROR);
+	    }
+	    slen = strlen((char *) pnext) + 1;
+	    strcpy((char *) latest_str_loc, (char *) pnext);
+	    pdmd->dmd_macro = (char *) latest_str_loc;
+	    latest_str_loc += slen;
+	    pnext += slen;
+	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
+		free_macro_stack(dbg,&msdata);
+                dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
+		_dwarf_error(dbg, error,
+			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
+		return (DW_DLV_ERROR);
+	    }
+	    break;
+	case DW_MACINFO_start_file:
+	    /* Line, file index */
+	    v1 = _dwarf_decode_u_leb128(pnext, &len);
+	    pdmd->dmd_lineno = v1;
+	    pnext += len;
+	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
+		free_macro_stack(dbg,&msdata);
+                dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
+		_dwarf_error(dbg, error,
+			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
+		return (DW_DLV_ERROR);
+	    }
+	    v1 = _dwarf_decode_u_leb128(pnext, &len);
+	    pdmd->dmd_fileindex = v1;
+	    (void) _dwarf_macro_stack_push_index(dbg, fileindex,
+						 &msdata);
+	    /* We ignore the error, we just let fileindex ** be -1 when 
+	       we pop this one. */
+	    fileindex = v1;
+	    pnext += len;
+	    if (((pnext - macro_base)) >= dbg->de_debug_macinfo_size) {
+		free_macro_stack(dbg,&msdata);
+                dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
+		_dwarf_error(dbg, error,
+			     DW_DLE_DEBUG_MACRO_INCONSISTENT);
+		return (DW_DLV_ERROR);
+	    }
+	    break;
+
+	case DW_MACINFO_end_file:
+	    fileindex = _dwarf_macro_stack_pop_index(&msdata);
+	    break;		/* no string or number here */
+	case 0:
+	    /* Type code of 0 means the end of cu's entries. */
+	    done = 1;
+	    break;
+	default:
+	    /* Bogus macinfo! */
+            dwarf_dealloc(dbg, return_data, DW_DLA_STRING);
+	    free_macro_stack(dbg,&msdata);
+	    _dwarf_error(dbg, error, DW_DLE_DEBUG_MACRO_INCONSISTENT);
+	    return (DW_DLV_ERROR);
+	}
+    }
+    *entry_count = count;
+    *details = (Dwarf_Macro_Details *) return_data;
+
+    free_macro_stack(dbg,&msdata);
+    return DW_DLV_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_macro.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,44 @@
+/*
+
+  Copyright (C) 2000, 2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+/*
+
+
+   dwarf_macro.h
+
+   $Revision: 1.4 $    $Date: 2004/10/28 22:19:14 $
+
+*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_opaque.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,301 @@
+/*
+
+  Copyright (C) 2000,2002,2003,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007  David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* The versions applicable by section are:
+                       DWARF2    DWARF3 DWARF4
+ .debug_info             2         3     4
+ .debug_abbrev           -         -     -
+ .debug_frame            1         3     3
+ .debug_str              -         -     -
+ .debug_loc              -         -     -
+ .debug_line             2         3     3
+ .debug_aranges          2         2     2
+ .debug_ranges           x         -     -
+ .debug_pubtypes         x         2     2
+ .debug_pubnames         2         2     2
+ .debug_macinfo          -         -     -
+*/
+
+#include <stddef.h>
+
+
+struct Dwarf_Die_s {
+    /* 
+       Points to the start of the portion corresponding to this Die in 
+       the .debug_info section. */
+    Dwarf_Byte_Ptr di_debug_info_ptr;
+
+    Dwarf_Abbrev_List di_abbrev_list;
+
+    /* Points to cu context for this die.  */
+    Dwarf_CU_Context di_cu_context;
+};
+
+struct Dwarf_Attribute_s {
+    Dwarf_Half ar_attribute;	/* Attribute Value. */
+    Dwarf_Half ar_attribute_form;	/* Attribute Form. */
+    Dwarf_Half ar_attribute_form_direct;
+	        /* Identical to ar_attribute_form except that if
+		the original form uleb was DW_FORM_indirect,
+		ar_attribute_form_direct contains DW_FORM_indirect
+		but ar_attribute_form contains the true form. */
+
+    Dwarf_CU_Context ar_cu_context;
+    Dwarf_Small *ar_debug_info_ptr;
+    Dwarf_Attribute ar_next;
+};
+
+/*
+    This structure provides the context for a compilation unit.  
+    Thus, it contains the Dwarf_Debug, cc_dbg, that this cu
+    belongs to.  It contains the information in the compilation 
+    unit header, cc_length, cc_version_stamp, cc_abbrev_offset,
+    and cc_address_size, in the .debug_info section for that cu.  
+    In addition, it contains the count, cc_count_cu, of the cu 
+    number of that cu in the list of cu's in the .debug_info.  
+    The count starts at 1, ie cc_count_cu is 1 for the first cu, 
+    2 for the second and so on.  This struct also contains a 
+    pointer, cc_abbrev_table, to a list of pairs of abbrev code 
+    and a pointer to the start of that abbrev 
+    in the .debug_abbrev section.
+
+    Each die will also contain a pointer to such a struct to 
+    record the context for that die.  
+    
+    **Updated by dwarf_next_cu_header in dwarf_die_deliv.c
+*/
+struct Dwarf_CU_Context_s {
+    Dwarf_Debug cc_dbg;
+    Dwarf_Word cc_length;
+    Dwarf_Small cc_length_size;
+    Dwarf_Small cc_extension_size;
+    Dwarf_Half cc_version_stamp;
+    Dwarf_Sword cc_abbrev_offset;
+    Dwarf_Small cc_address_size;
+    Dwarf_Word cc_debug_info_offset;
+    Dwarf_Byte_Ptr cc_last_abbrev_ptr;
+    Dwarf_Hash_Table cc_abbrev_hash_table;
+    Dwarf_CU_Context cc_next;
+    unsigned char cc_offset_length;
+};
+
+
+struct Dwarf_Debug_s {
+    dwarf_elf_handle de_elf; /* see de_elf_must_close at end of struct */
+
+    Dwarf_Unsigned de_access;
+    Dwarf_Handler de_errhand;
+    Dwarf_Ptr de_errarg;
+
+    /* 
+       Context for the compilation_unit just read by a call to
+       dwarf_next_cu_header. **Updated by dwarf_next_cu_header in
+       dwarf_die_deliv.c */
+    Dwarf_CU_Context de_cu_context;
+
+    /* 
+       Points to linked list of CU Contexts for the CU's already read.
+       These are only CU's read by dwarf_next_cu_header(). */
+    Dwarf_CU_Context de_cu_context_list;
+
+    /* 
+       Points to the last CU Context added to the list by
+       dwarf_next_cu_header(). */
+    Dwarf_CU_Context de_cu_context_list_end;
+
+    /* 
+       This is the list of CU contexts read for dwarf_offdie().  These
+       may read ahead of dwarf_next_cu_header(). */
+    Dwarf_CU_Context de_offdie_cu_context;
+    Dwarf_CU_Context de_offdie_cu_context_end;
+
+    /* Offset of last byte of last CU read. */
+    Dwarf_Word de_info_last_offset;
+
+    /* 
+       Number of bytes in the length, and offset field in various
+       .debug_* sections.  It's not very meaningful, and is
+       only used in one 'approximate' calculation.  */
+    Dwarf_Small de_length_size;
+
+    /* number of bytes in a pointer of the target in various .debug_
+       sections. 4 in 32bit, 8 in MIPS 64, ia64. */
+    Dwarf_Small de_pointer_size;
+
+    /* set at creation of a Dwarf_Debug to say if form_string should be 
+       checked for valid length at every call. 0 means do the check.
+       non-zero means do not do the check. */
+    Dwarf_Small de_assume_string_in_bounds;
+
+    /* 
+       Dwarf_Alloc_Hdr_s structs used to manage chunks that are
+       malloc'ed for each allocation type for structs. */
+    struct Dwarf_Alloc_Hdr_s de_alloc_hdr[ALLOC_AREA_REAL_TABLE_MAX];
+#ifdef DWARF_SIMPLE_MALLOC
+    struct simple_malloc_record_s *  de_simple_malloc_base;
+#endif
+    
+
+    /* 
+       These fields are used to process debug_frame section.  **Updated 
+       by dwarf_get_fde_list in dwarf_frame.h */
+    /* 
+       Points to contiguous block of pointers to Dwarf_Cie_s structs. */
+    Dwarf_Cie *de_cie_data;
+    /* Count of number of Dwarf_Cie_s structs. */
+    Dwarf_Signed de_cie_count;
+    /* 
+       Points to contiguous block of pointers to Dwarf_Fde_s structs. */
+    Dwarf_Fde *de_fde_data;
+    /* Count of number of Dwarf_Fde_s structs. */
+    Dwarf_Signed de_fde_count;
+
+    Dwarf_Small *de_debug_info;
+    Dwarf_Small *de_debug_abbrev;
+    Dwarf_Small *de_debug_line;
+    Dwarf_Small *de_debug_loc;
+    Dwarf_Small *de_debug_aranges;
+    Dwarf_Small *de_debug_macinfo;
+    Dwarf_Small *de_debug_pubnames;
+    Dwarf_Small *de_debug_str;
+    Dwarf_Small *de_debug_frame;
+    Dwarf_Small *de_debug_pubtypes; /* DWARF3 .debug_pubtypes */
+    Dwarf_Small *de_debug_frame_eh_gnu;	/* gnu for the g++ eh_frame
+					   section */
+    Dwarf_Addr   de_debug_frame_eh_addr; /* gnu for the g++ eh_frame
+                                           section. Section address
+		                           from Elf. Purpose: to handle
+					DW_EH_PE_pcrel encoding. */
+
+    Dwarf_Small *de_debug_funcnames;
+    Dwarf_Small *de_debug_typenames; /* SGI IRIX extension essentially
+			identical to DWARF3 .debug_pubtypes. */
+    Dwarf_Small *de_debug_varnames;
+    Dwarf_Small *de_debug_weaknames;
+
+    Dwarf_Unsigned de_debug_info_size;
+    Dwarf_Unsigned de_debug_abbrev_size;
+    Dwarf_Unsigned de_debug_line_size;
+    Dwarf_Unsigned de_debug_loc_size;
+    Dwarf_Unsigned de_debug_aranges_size;
+    Dwarf_Unsigned de_debug_macinfo_size;
+    Dwarf_Unsigned de_debug_pubnames_size;
+    Dwarf_Unsigned de_debug_str_size;
+    Dwarf_Unsigned de_debug_pubtypes_size; /* DWARF3 .debug_pubtypes*/
+
+
+    Dwarf_Unsigned de_debug_frame_size;
+
+    Dwarf_Unsigned de_debug_frame_size_eh_gnu;	/* gnu for the g++
+					   eh_frame section */
+
+    Dwarf_Unsigned de_debug_funcnames_size;
+    Dwarf_Unsigned de_debug_typenames_size;
+    Dwarf_Unsigned de_debug_varnames_size;
+    Dwarf_Unsigned de_debug_weaknames_size;
+
+    void *(*de_copy_word) (void *, const void *, size_t);
+    unsigned char de_same_endian;
+    unsigned char de_elf_must_close; /* if non-zero, then
+	it was dwarf_init (not dwarf_elf_init)
+	so must elf_end() */
+
+    /*
+       The following are used for storing section indicies.
+
+       After a Dwarf_Debug is initialized, a zero for any of
+       these indicies indicates an absent section.
+
+       If the ELF spec is ever changed to permit 32-bit section
+       indicies, these will need to be changed.
+     */
+    Dwarf_Half de_debug_aranges_index;
+    Dwarf_Half de_debug_line_index;
+    Dwarf_Half de_debug_loc_index;
+    Dwarf_Half de_debug_macinfo_index;
+    Dwarf_Half de_debug_pubnames_index;
+    Dwarf_Half de_debug_funcnames_index;
+    Dwarf_Half de_debug_typenames_index;
+    Dwarf_Half de_debug_varnames_index;
+    Dwarf_Half de_debug_weaknames_index;
+    Dwarf_Half de_debug_frame_index;
+    Dwarf_Half de_debug_frame_eh_gnu_index;
+    Dwarf_Half de_debug_str_index;
+    Dwarf_Half de_debug_info_index;
+    Dwarf_Half de_debug_abbrev_index;
+    Dwarf_Half de_debug_pubtypes_index; /* DWARF3 .debug_pubtypes */
+
+    /* Default is DW_FRAME_INITIAL_VALUE from header. */
+    Dwarf_Half de_frame_rule_initial_value;  
+
+    /* Default is   DW_FRAME_LAST_REG_NUM. */
+    Dwarf_Half de_frame_reg_rules_entry_count; 
+
+
+    unsigned char de_big_endian_object; /* non-zero if big-endian
+		object opened. */
+};
+
+typedef struct Dwarf_Chain_s *Dwarf_Chain;
+struct Dwarf_Chain_s {
+    void *ch_item;
+    Dwarf_Chain ch_next;
+};
+
+
+#define CURRENT_VERSION_STAMP		2 /* DWARF2 */
+#define CURRENT_VERSION_STAMP3		3 /* DWARF3 */
+#define CURRENT_VERSION_STAMP4		3 /* DWARF4 */
+
+    /* Size of cu header version stamp field. */
+#define CU_VERSION_STAMP_SIZE   sizeof(Dwarf_Half)
+
+    /* Size of cu header address size field. */
+#define CU_ADDRESS_SIZE_SIZE	sizeof(Dwarf_Small)
+
+void *_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len);
+
+#define ORIGINAL_DWARF_OFFSET_SIZE  4
+#define DISTINGUISHED_VALUE  0xffffffff
+#define DISTINGUISHED_VALUE_OFFSET_SIZE 8
+
+/*
+    We don't load the sections until they are needed. This function is
+    used to load the section.
+ */
+int _dwarf_load_section(Dwarf_Debug,
+		        Dwarf_Half,
+			Dwarf_Small **,
+			Dwarf_Error *);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_print_lines.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,655 @@
+/*
+
+  Copyright (C) 2000,2002,2004,2005,2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include <time.h>
+#include "dwarf_line.h"
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+
+/* FIXME Need to add prologue_end epilogue_begin isa fields. */
+static void
+print_line_header(void)
+{
+    printf
+	("                                                         s b e\n"
+	 "                                                         t l s\n"
+	 "                                                         m c e\n"
+	 " section    op                                       col t k q\n"
+	 " offset     code               address     file line umn ? ? ?\n");
+}
+
+/* FIXME: print new line values:   prologue_end epilogue_begin isa */
+static void
+print_line_detail(char *prefix,
+		  int opcode,
+		  unsigned long long address,
+		  unsigned long file,
+		  unsigned long line,
+		  unsigned long column,
+		  int is_stmt, int basic_block, int end_sequence,
+		  int prologue_end, int epilogue_begin, int isa)
+{
+    printf("%-15s %2d 0x%08llx "
+	   "%2lu   %4lu %2lu   %1d %1d %1d\n",
+	   prefix,
+	   (int) opcode,
+	   (long long) address,
+	   (unsigned long) file,
+	   (unsigned long) line,
+	   (unsigned long) column,
+	   (int) is_stmt, (int) basic_block, (int) end_sequence);
+
+}
+
+
+/*
+	return DW_DLV_OK if ok. else DW_DLV_NO_ENTRY or DW_DLV_ERROR
+*/
+int
+_dwarf_internal_printlines(Dwarf_Die die, Dwarf_Error * error)
+{
+    /* 
+       This pointer is used to scan the portion of the .debug_line
+       section for the current cu. */
+    Dwarf_Small *line_ptr;
+    Dwarf_Small *orig_line_ptr;
+
+    /* 
+       This points to the last byte of the .debug_line portion for the
+       current cu. */
+    Dwarf_Small *line_ptr_end = 0;
+
+    /* 
+       Pointer to a DW_AT_stmt_list attribute in case it exists in the
+       die. */
+    Dwarf_Attribute stmt_list_attr;
+
+    /* Pointer to DW_AT_comp_dir attribute in die. */
+    Dwarf_Attribute comp_dir_attr;
+
+    /* Pointer to name of compilation directory. */
+    Dwarf_Small *comp_dir = NULL;
+
+    /* 
+       Offset into .debug_line specified by a DW_AT_stmt_list
+       attribute. */
+    Dwarf_Unsigned line_offset;
+
+    struct Line_Table_Prefix_s prefix;
+
+
+    /* These are the state machine state variables. */
+    Dwarf_Addr address = 0;
+    Dwarf_Word file = 1;
+    Dwarf_Word line = 1;
+    Dwarf_Word column = 0;
+    Dwarf_Bool is_stmt = false;
+    Dwarf_Bool basic_block = false;
+    Dwarf_Bool end_sequence = false;
+    Dwarf_Bool prologue_end = false;
+    Dwarf_Bool epilogue_begin = false;
+    Dwarf_Small isa = 0;
+
+
+    Dwarf_Sword i;
+
+    /* 
+       This is the current opcode read from the statement program. */
+    Dwarf_Small opcode;
+
+
+    /* 
+       These variables are used to decode leb128 numbers. Leb128_num
+       holds the decoded number, and leb128_length is its length in
+       bytes. */
+    Dwarf_Word leb128_num;
+    Dwarf_Word leb128_length;
+    Dwarf_Sword advance_line;
+
+    /* 
+       This is the operand of the latest fixed_advance_pc extended
+       opcode. */
+    Dwarf_Half fixed_advance_pc;
+
+
+    /* The Dwarf_Debug this die belongs to. */
+    Dwarf_Debug dbg;
+    int resattr;
+    int lres;
+
+    int res;
+
+    /* ***** BEGIN CODE ***** */
+
+    if (error != NULL)
+	*error = NULL;
+
+    CHECK_DIE(die, DW_DLV_ERROR);
+    dbg = die->di_cu_context->cc_dbg;
+
+    res =
+	_dwarf_load_section(dbg,
+			    dbg->de_debug_line_index,
+			    &dbg->de_debug_line, error);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+
+    resattr = dwarf_attr(die, DW_AT_stmt_list, &stmt_list_attr, error);
+    if (resattr != DW_DLV_OK) {
+	return resattr;
+    }
+
+
+
+    lres = dwarf_formudata(stmt_list_attr, &line_offset, error);
+    if (lres != DW_DLV_OK) {
+	return lres;
+    }
+
+    if (line_offset >= dbg->de_debug_line_size) {
+	_dwarf_error(dbg, error, DW_DLE_LINE_OFFSET_BAD);
+	return (DW_DLV_ERROR);
+    }
+    orig_line_ptr = dbg->de_debug_line;
+    line_ptr = dbg->de_debug_line + line_offset;
+    dwarf_dealloc(dbg, stmt_list_attr, DW_DLA_ATTR);
+
+    /* 
+       If die has DW_AT_comp_dir attribute, get the string that names
+       the compilation directory. */
+    resattr = dwarf_attr(die, DW_AT_comp_dir, &comp_dir_attr, error);
+    if (resattr == DW_DLV_ERROR) {
+	return resattr;
+    }
+    if (resattr == DW_DLV_OK) {
+	int cres;
+	char *cdir;
+
+	cres = dwarf_formstring(comp_dir_attr, &cdir, error);
+	if (cres == DW_DLV_ERROR) {
+	    return cres;
+	} else if (cres == DW_DLV_OK) {
+	    comp_dir = (Dwarf_Small *) cdir;
+	}
+    }
+    if (resattr == DW_DLV_OK) {
+	dwarf_dealloc(dbg, comp_dir_attr, DW_DLA_ATTR);
+    }
+
+    dwarf_init_line_table_prefix(&prefix);
+    {
+	Dwarf_Small *line_ptr_out = 0;
+	int dres = dwarf_read_line_table_prefix(dbg,
+						line_ptr,
+						dbg->
+						de_debug_line_size -
+						line_offset,
+						&line_ptr_out,
+						&prefix, error);
+
+	if (dres == DW_DLV_ERROR) {
+	    dwarf_free_line_table_prefix(&prefix);
+	    return dres;
+	}
+	if (dres == DW_DLV_NO_ENTRY) {
+	    dwarf_free_line_table_prefix(&prefix);
+	    return dres;
+	}
+	line_ptr_end = prefix.pf_line_ptr_end;
+	line_ptr = line_ptr_out;
+    }
+
+
+
+    printf("total line info length %ld bytes, "
+	   "line offset 0x%llx %lld\n",
+	   (long) prefix.pf_total_length,
+	   (long long) line_offset, (long long) line_offset);
+    printf("compilation_directory %s\n",
+	   comp_dir ? ((char *) comp_dir) : "");
+
+    printf("  min instruction length %d\n",
+	   (int) prefix.pf_minimum_instruction_length);
+    printf("  default is stmt        %d\n", (int)
+	   prefix.pf_default_is_stmt);
+    printf("  line base              %d\n", (int)
+	   prefix.pf_line_base);
+    printf("  line_range             %d\n", (int)
+	   prefix.pf_line_range);
+
+
+    for (i = 1; i < prefix.pf_opcode_base; i++) {
+	printf("  opcode[%d] length %d\n", (int) i,
+	       (int) prefix.pf_opcode_length_table[i - 1]);
+    }
+
+    for (i = 0; i < prefix.pf_include_directories_count; ++i) {
+	printf("  include dir[%d] %s\n",
+	       (int) i, prefix.pf_include_directories[i]);
+    }
+
+
+    for (i = 0; i < prefix.pf_files_count; ++i) {
+	struct Line_Table_File_Entry_s *lfile =
+	    prefix.pf_line_table_file_entries + i;
+
+	Dwarf_Unsigned tlm2 = lfile->lte_last_modification_time;
+	Dwarf_Unsigned di = lfile->lte_directory_index;
+	Dwarf_Unsigned fl = lfile->lte_length_of_file;
+
+	printf("  file[%d]  %s\n",
+	       (int) i, (char *) lfile->lte_filename);
+
+	printf("    dir index %d\n", (int) di);
+	{
+	    time_t tt = (time_t) tlm2;
+
+	    printf("    last time 0x%x %s",	/* ctime supplies
+						   newline */
+		   (unsigned) tlm2, ctime(&tt));
+	}
+	printf("    file length %ld 0x%lx\n",
+	       (long) fl, (unsigned long) fl);
+
+
+    }
+
+
+    {
+	unsigned long long offset = line_ptr - orig_line_ptr;
+
+	printf("  statement prog offset in section: %llu 0x%llx\n",
+	       offset, offset);
+    }
+
+    /* Initialize the part of the state machine dependent on the
+       prefix.  */
+    is_stmt = prefix.pf_default_is_stmt;
+
+
+    print_line_header();
+    /* Start of statement program.  */
+    while (line_ptr < line_ptr_end) {
+	int type;
+
+	printf(" [0x%06llx] ", (long long) (line_ptr - orig_line_ptr));
+	opcode = *(Dwarf_Small *) line_ptr;
+	line_ptr++;
+	/* 'type' is the output */
+	WHAT_IS_OPCODE(type, opcode, prefix.pf_opcode_base,
+		       prefix.pf_opcode_length_table, line_ptr,
+		       prefix.pf_std_op_count);
+
+	if (type == LOP_DISCARD) {
+	    int oc;
+	    int opcnt = prefix.pf_opcode_length_table[opcode];
+
+	    printf(" DISCARD standard opcode %d with %d operands: "
+		   "not understood:", opcode, opcnt);
+	    for (oc = 0; oc < opcnt; oc++) {
+		/* 
+		 * Read and discard operands we don't
+		 * understand.
+		 * Arbitrary choice of unsigned read.
+		 * Signed read would work as well.
+		 */
+		Dwarf_Unsigned utmp2;
+
+		DECODE_LEB128_UWORD(line_ptr, utmp2);
+		printf(" %llu (0x%llx)",
+		       (unsigned long long) utmp2,
+		       (unsigned long long) utmp2);
+	    }
+
+	    printf("\n");
+	    /* do nothing, necessary ops done */
+	} else if (type == LOP_SPECIAL) {
+	    /* This op code is a special op in the object, no matter
+	       that it might fall into the standard op range in this
+	       compile Thatis, these are special opcodes between
+	       special_opcode_base and MAX_LINE_OP_CODE.  (including
+	       special_opcode_base and MAX_LINE_OP_CODE) */
+	    char special[50];
+	    unsigned origop = opcode;
+
+	    opcode = opcode - prefix.pf_opcode_base;
+	    address = address + prefix.pf_minimum_instruction_length *
+		(opcode / prefix.pf_line_range);
+	    line =
+		line + prefix.pf_line_base +
+		opcode % prefix.pf_line_range;
+
+	    sprintf(special, "Specialop %3u", origop);
+	    print_line_detail(special,
+			      opcode, address, (int) file, line, column,
+			      is_stmt, basic_block, end_sequence,
+			      prologue_end, epilogue_begin, isa);
+
+	    basic_block = false;
+
+	} else if (type == LOP_STANDARD) {
+	    switch (opcode) {
+
+	    case DW_LNS_copy:{
+
+		    print_line_detail("DW_LNS_copy",
+				      opcode, address, file, line,
+				      column, is_stmt, basic_block,
+				      end_sequence, prologue_end,
+				      epilogue_begin, isa);
+
+		    basic_block = false;
+		    break;
+		}
+
+	    case DW_LNS_advance_pc:{
+		    Dwarf_Unsigned utmp2;
+
+
+		    DECODE_LEB128_UWORD(line_ptr, utmp2);
+		    printf("DW_LNS_advance_pc val %lld 0x%llx\n",
+			   (long long) (Dwarf_Word) utmp2,
+			   (long long) (Dwarf_Word) utmp2);
+		    leb128_num = (Dwarf_Word) utmp2;
+		    address =
+			address +
+			prefix.pf_minimum_instruction_length *
+			leb128_num;
+		    break;
+		}
+
+	    case DW_LNS_advance_line:{
+		    Dwarf_Signed stmp;
+
+
+		    DECODE_LEB128_SWORD(line_ptr, stmp);
+		    advance_line = (Dwarf_Sword) stmp;
+		    printf("DW_LNS_advance_line val %lld 0x%llx\n",
+			   (long long) advance_line,
+			   (long long) advance_line);
+		    line = line + advance_line;
+		    break;
+		}
+
+	    case DW_LNS_set_file:{
+		    Dwarf_Unsigned utmp2;
+
+
+		    DECODE_LEB128_UWORD(line_ptr, utmp2);
+		    file = (Dwarf_Word) utmp2;
+		    printf("DW_LNS_set_file  %ld\n", (long) file);
+		    break;
+		}
+
+	    case DW_LNS_set_column:{
+		    Dwarf_Unsigned utmp2;
+
+
+		    DECODE_LEB128_UWORD(line_ptr, utmp2);
+		    column = (Dwarf_Word) utmp2;
+		    printf("DW_LNS_set_column val %lld 0x%llx\n",
+			   (long long) column, (long long) column);
+		    break;
+		}
+
+	    case DW_LNS_negate_stmt:{
+		    is_stmt = !is_stmt;
+		    printf("DW_LNS_negate_stmt\n");
+		    break;
+		}
+
+	    case DW_LNS_set_basic_block:{
+
+		    printf("DW_LNS_set_basic_block\n");
+		    basic_block = true;
+		    break;
+		}
+
+	    case DW_LNS_const_add_pc:{
+		    opcode = MAX_LINE_OP_CODE - prefix.pf_opcode_base;
+		    address =
+			address +
+			prefix.pf_minimum_instruction_length * (opcode /
+								prefix.
+								pf_line_range);
+
+		    printf("DW_LNS_const_add_pc new address 0x%llx\n",
+			   (long long) address);
+		    break;
+		}
+
+	    case DW_LNS_fixed_advance_pc:{
+
+		    READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half,
+				   line_ptr, sizeof(Dwarf_Half));
+		    line_ptr += sizeof(Dwarf_Half);
+		    address = address + fixed_advance_pc;
+		    printf("DW_LNS_fixed_advance_pc val %lld 0x%llx"
+			   " new address 0x%llx\n",
+			   (long long) fixed_advance_pc,
+			   (long long) fixed_advance_pc,
+			   (long long) address);
+		    break;
+		}
+	    case DW_LNS_set_prologue_end:{
+
+		    prologue_end = true;
+		    printf("DW_LNS_set_prologue_end set true.\n");
+		    break;
+
+
+		}
+		/* New in DWARF3 */
+	    case DW_LNS_set_epilogue_begin:{
+		    epilogue_begin = true;
+		    printf("DW_LNS_set_epilogue_begin set true.\n");
+		    break;
+		}
+
+		/* New in DWARF3 */
+	    case DW_LNS_set_isa:{
+		    Dwarf_Unsigned utmp2;
+
+		    DECODE_LEB128_UWORD(line_ptr, utmp2);
+		    isa = utmp2;
+		    printf("DW_LNS_set_isa new value 0x%llx.\n",
+			   (unsigned long long) utmp2);
+		    if (isa != utmp2) {
+			/* The value of the isa did not fit in our
+			   local so we record it wrong. declare an
+			   error. */
+			dwarf_free_line_table_prefix(&prefix);
+
+			_dwarf_error(dbg, error,
+				     DW_DLE_LINE_NUM_OPERANDS_BAD);
+			return (DW_DLV_ERROR);
+		    }
+		    break;
+		}
+	    }
+
+
+	} else if (type == LOP_EXTENDED) {
+	    Dwarf_Unsigned utmp3 = 0;
+	    Dwarf_Word instr_length = 0;
+	    Dwarf_Small ext_opcode = 0;
+
+	    DECODE_LEB128_UWORD(line_ptr, utmp3);
+	    instr_length = (Dwarf_Word) utmp3;
+	    ext_opcode = *(Dwarf_Small *) line_ptr;
+	    line_ptr++;
+	    switch (ext_opcode) {
+
+	    case DW_LNE_end_sequence:{
+		    end_sequence = true;
+
+		    print_line_detail("DW_LNE_end_sequence extended",
+				      opcode, address, file, line,
+				      column, is_stmt, basic_block,
+				      end_sequence, prologue_end,
+				      epilogue_begin, isa);
+
+		    address = 0;
+		    file = 1;
+		    line = 1;
+		    column = 0;
+		    is_stmt = prefix.pf_default_is_stmt;
+		    basic_block = false;
+		    end_sequence = false;
+		    prologue_end = false;
+		    epilogue_begin = false;
+
+
+		    break;
+		}
+
+	    case DW_LNE_set_address:{
+		    if (instr_length - 1 == dbg->de_pointer_size) {
+			READ_UNALIGNED(dbg, address, Dwarf_Addr,
+				       line_ptr, dbg->de_pointer_size);
+
+			line_ptr += dbg->de_pointer_size;
+			printf("DW_LNE_set_address address 0x%llx\n",
+			       (long long) address);
+		    } else {
+			dwarf_free_line_table_prefix(&prefix);
+			_dwarf_error(dbg, error,
+				     DW_DLE_LINE_SET_ADDR_ERROR);
+			return (DW_DLV_ERROR);
+		    }
+
+		    break;
+		}
+
+	    case DW_LNE_define_file:{
+
+
+		    Dwarf_Small *fn;
+		    Dwarf_Unsigned di;
+		    Dwarf_Unsigned tlm;
+		    Dwarf_Unsigned fl;
+
+		    fn = (Dwarf_Small *) line_ptr;
+		    line_ptr = line_ptr + strlen((char *) line_ptr) + 1;
+
+		    di = _dwarf_decode_u_leb128(line_ptr,
+						&leb128_length);
+		    line_ptr = line_ptr + leb128_length;
+
+		    tlm = _dwarf_decode_u_leb128(line_ptr,
+						 &leb128_length);
+		    line_ptr = line_ptr + leb128_length;
+
+		    fl = _dwarf_decode_u_leb128(line_ptr,
+						&leb128_length);
+		    line_ptr = line_ptr + leb128_length;
+
+
+		    printf("DW_LNE_define_file %s \n", fn);
+		    printf("    dir index %d\n", (int) di);
+		    {
+			time_t tt3 = (time_t) tlm;
+
+			/* ctime supplies newline */
+			printf("    last time 0x%x %s",
+			       (unsigned) tlm, ctime(&tt3));
+		    }
+		    printf("    file length %ld 0x%lx\n",
+			   (long) fl, (unsigned long) fl);
+
+		    break;
+		}
+
+	    default:{
+		    dwarf_free_line_table_prefix(&prefix);
+		    _dwarf_error(dbg, error,
+				 DW_DLE_LINE_EXT_OPCODE_BAD);
+		    return (DW_DLV_ERROR);
+		}
+	    }
+
+	}
+    }
+
+    dwarf_free_line_table_prefix(&prefix);
+    return (DW_DLV_OK);
+}
+
+/*
+        This is support for dwarfdump: making it possible
+        for clients wanting line detail info on stdout
+        to get that detail without including internal libdwarf
+        header information.
+	Caller passes in compilation unit DIE.
+        The _dwarf version is obsolete (though supported for
+        compatibility.
+        The dwarf_ version is preferred.
+*/
+int
+dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error)
+{
+    int res;
+
+    res = _dwarf_internal_printlines(die, error);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+    return res;
+}
+int
+_dwarf_print_lines(Dwarf_Die die, Dwarf_Error * error)
+{
+    int res;
+
+    res = _dwarf_internal_printlines(die, error);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+    return res;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_pubtypes.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,148 @@
+/*
+
+  Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+/* Reads DWARF3 .debug_pubtypes section. */
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include "dwarf_types.h"
+#include "dwarf_global.h"
+
+int
+dwarf_get_pubtypes(Dwarf_Debug dbg,
+		   Dwarf_Type ** types,
+		   Dwarf_Signed * ret_type_count, Dwarf_Error * error)
+{
+    int res;
+
+    res =
+	_dwarf_load_section(dbg,
+			    dbg->de_debug_pubtypes_index,
+			    &dbg->de_debug_pubtypes, error);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+
+    return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_pubtypes, dbg->de_debug_pubtypes_size, (Dwarf_Global **) types,	/* type 
+																	   punning,
+																	   Dwarf_Type 
+																	   is never
+																	   a
+																	   completed 
+																	   type */
+						  ret_type_count, error, DW_DLA_PUBTYPES_CONTEXT, DW_DLA_GLOBAL,	/* We 
+															   don't 
+															   have 
+															   DW_DLA_PUBTYPES,
+															   so use
+															   DW_DLA_GLOBAL. */
+						  DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD,
+						  DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR);
+}
+
+/* Deallocating fully requires deallocating the list
+   and all entries.  But some internal data is
+   not exposed, so we need a function with internal knowledge.
+*/
+
+void
+dwarf_pubtypes_dealloc(Dwarf_Debug dbg, Dwarf_Type * dwgl,
+		       Dwarf_Signed count)
+{
+    _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl, count, DW_DLA_PUBTYPES_CONTEXT, DW_DLA_GLOBAL,	/* We 
+														   don't 
+														   have 
+														   DW_DLA_PUBTYPES,
+														   so use
+														   DW_DLA_GLOBAL. */
+				    DW_DLA_LIST);
+    return;
+}
+
+
+
+int
+dwarf_pubtypename(Dwarf_Type type_in, char **ret_name,
+		  Dwarf_Error * error)
+{
+    Dwarf_Global type = (Dwarf_Global) type_in;
+
+    if (type == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_TYPE_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *ret_name = (char *) (type->gl_name);
+    return DW_DLV_OK;
+}
+
+
+int
+dwarf_pubtype_type_die_offset(Dwarf_Type type_in,
+			      Dwarf_Off * ret_offset,
+			      Dwarf_Error * error)
+{
+    Dwarf_Global type = (Dwarf_Global) type_in;
+
+    return dwarf_global_die_offset(type, ret_offset, error);
+}
+
+
+int
+dwarf_pubtype_cu_offset(Dwarf_Type type_in,
+			Dwarf_Off * ret_offset, Dwarf_Error * error)
+{
+    Dwarf_Global type = (Dwarf_Global) type_in;
+
+    return dwarf_global_cu_offset(type, ret_offset, error);
+
+}
+
+
+int
+dwarf_pubtype_name_offsets(Dwarf_Type type_in,
+			   char **returned_name,
+			   Dwarf_Off * die_offset,
+			   Dwarf_Off * cu_die_offset,
+			   Dwarf_Error * error)
+{
+    Dwarf_Global type = (Dwarf_Global) type_in;
+
+    return dwarf_global_name_offsets(type,
+				     returned_name,
+				     die_offset, cu_die_offset, error);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_query.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,619 @@
+/*
+
+  Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include "dwarf_die_deliv.h"
+
+int
+dwarf_get_address_size(Dwarf_Debug dbg,
+		       Dwarf_Half * ret_addr_size, Dwarf_Error * error)
+{
+    Dwarf_Half address_size;
+
+    if (dbg == 0) {
+	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+    /* length size same as address size */
+    address_size = dbg->de_pointer_size;
+    *ret_addr_size = address_size;
+    return DW_DLV_OK;
+}
+
+int
+dwarf_dieoffset(Dwarf_Die die,
+		Dwarf_Off * ret_offset, Dwarf_Error * error)
+{
+    CHECK_DIE(die, DW_DLV_ERROR);
+
+    *ret_offset = (die->di_debug_info_ptr -
+		   die->di_cu_context->cc_dbg->de_debug_info);
+    return DW_DLV_OK;
+}
+
+
+/*
+    This function returns the offset of
+    the die relative to the start of its
+    compilation-unit rather than .debug_info.
+    Returns DW_DLV_ERROR on error.
+*/
+int
+dwarf_die_CU_offset(Dwarf_Die die,
+		    Dwarf_Off * cu_off, Dwarf_Error * error)
+{
+    Dwarf_CU_Context cu_context;
+
+    CHECK_DIE(die, DW_DLV_ERROR);
+    cu_context = die->di_cu_context;
+
+    *cu_off =
+	(die->di_debug_info_ptr - cu_context->cc_dbg->de_debug_info -
+	 cu_context->cc_debug_info_offset);
+    return DW_DLV_OK;
+}
+
+
+int
+dwarf_tag(Dwarf_Die die, Dwarf_Half * tag, Dwarf_Error * error)
+{
+    CHECK_DIE(die, DW_DLV_ERROR);
+
+
+    *tag = (die->di_abbrev_list->ab_tag);
+    return DW_DLV_OK;
+}
+
+
+int
+dwarf_attrlist(Dwarf_Die die,
+	       Dwarf_Attribute ** attrbuf,
+	       Dwarf_Signed * attrcnt, Dwarf_Error * error)
+{
+    Dwarf_Word attr_count = 0;
+    Dwarf_Word i = 0;
+    Dwarf_Half attr = 0;
+    Dwarf_Half attr_form = 0;
+    Dwarf_Byte_Ptr abbrev_ptr = 0;
+    Dwarf_Abbrev_List abbrev_list = 0;
+    Dwarf_Attribute new_attr = 0;
+    Dwarf_Attribute head_attr = NULL;
+    Dwarf_Attribute curr_attr = NULL;
+    Dwarf_Attribute *attr_ptr = 0;
+    Dwarf_Debug dbg = 0;
+    Dwarf_Byte_Ptr info_ptr = 0;
+
+    CHECK_DIE(die, DW_DLV_ERROR);
+    dbg = die->di_cu_context->cc_dbg;
+
+    abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context,
+					     die->di_abbrev_list->
+					     ab_code);
+    if (abbrev_list == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_DIE_ABBREV_BAD);
+	return (DW_DLV_ERROR);
+    }
+    abbrev_ptr = abbrev_list->ab_abbrev_ptr;
+
+    info_ptr = die->di_debug_info_ptr;
+    SKIP_LEB128_WORD(info_ptr);
+
+    do {
+	Dwarf_Unsigned utmp2;
+
+	DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
+	attr = (Dwarf_Half) utmp2;
+	DECODE_LEB128_UWORD(abbrev_ptr, utmp2);
+	attr_form = (Dwarf_Half) utmp2;
+
+	if (attr != 0) {
+	    new_attr =
+		(Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
+	    if (new_attr == NULL) {
+		_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+		return (DW_DLV_ERROR);
+	    }
+
+	    new_attr->ar_attribute = attr;
+	    new_attr->ar_attribute_form_direct = attr_form;
+	    new_attr->ar_attribute_form = attr_form;
+	    if (attr_form == DW_FORM_indirect) {
+		Dwarf_Unsigned utmp6;
+
+		/* DECODE_LEB128_UWORD does info_ptr update */
+		DECODE_LEB128_UWORD(info_ptr, utmp6);
+		attr_form = (Dwarf_Half) utmp6;
+		new_attr->ar_attribute_form = attr_form;
+	    }
+	    new_attr->ar_cu_context = die->di_cu_context;
+	    new_attr->ar_debug_info_ptr = info_ptr;
+
+	    info_ptr += _dwarf_get_size_of_val(dbg, attr_form, info_ptr,
+					       die->di_cu_context->
+					       cc_length_size);
+
+	    if (head_attr == NULL)
+		head_attr = curr_attr = new_attr;
+	    else {
+		curr_attr->ar_next = new_attr;
+		curr_attr = new_attr;
+	    }
+	    attr_count++;
+	}
+    } while (attr != 0 || attr_form != 0);
+
+    if (attr_count == 0) {
+	*attrbuf = NULL;
+	*attrcnt = 0;
+	return (DW_DLV_NO_ENTRY);
+    }
+
+    attr_ptr = (Dwarf_Attribute *)
+	_dwarf_get_alloc(dbg, DW_DLA_LIST, attr_count);
+    if (attr_ptr == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+
+    curr_attr = head_attr;
+    for (i = 0; i < attr_count; i++) {
+	*(attr_ptr + i) = curr_attr;
+	curr_attr = curr_attr->ar_next;
+    }
+
+    *attrbuf = attr_ptr;
+    *attrcnt = attr_count;
+    return (DW_DLV_OK);
+}
+
+
+/*
+    This function takes a die, and an attr, and returns
+    a pointer to the start of the value of that attr in
+    the given die in the .debug_info section.  The form
+    is returned in *attr_form.
+
+    Returns NULL on error, or if attr is not found.
+    However, *attr_form is 0 on error, and positive 
+    otherwise.
+*/
+static Dwarf_Byte_Ptr
+_dwarf_get_value_ptr(Dwarf_Die die,
+		     Dwarf_Half attr, Dwarf_Half * attr_form)
+{
+    Dwarf_Byte_Ptr abbrev_ptr;
+    Dwarf_Abbrev_List abbrev_list;
+    Dwarf_Half curr_attr;
+    Dwarf_Half curr_attr_form;
+    Dwarf_Byte_Ptr info_ptr;
+
+    abbrev_list = _dwarf_get_abbrev_for_code(die->di_cu_context,
+					     die->di_abbrev_list->
+					     ab_code);
+    if (abbrev_list == NULL) {
+	*attr_form = 0;
+	return (NULL);
+    }
+    abbrev_ptr = abbrev_list->ab_abbrev_ptr;
+
+    info_ptr = die->di_debug_info_ptr;
+    SKIP_LEB128_WORD(info_ptr);
+
+    do {
+	Dwarf_Unsigned utmp3;
+
+	DECODE_LEB128_UWORD(abbrev_ptr, utmp3);
+	curr_attr = (Dwarf_Half) utmp3;
+	DECODE_LEB128_UWORD(abbrev_ptr, utmp3);
+	curr_attr_form = (Dwarf_Half) utmp3;
+	if (curr_attr_form == DW_FORM_indirect) {
+	    Dwarf_Unsigned utmp6;
+
+	    /* DECODE_LEB128_UWORD updates info_ptr */
+	    DECODE_LEB128_UWORD(info_ptr, utmp6);
+	    curr_attr_form = (Dwarf_Half) utmp6;
+	}
+
+	if (curr_attr == attr) {
+	    *attr_form = curr_attr_form;
+	    return (info_ptr);
+	}
+
+	info_ptr += _dwarf_get_size_of_val(die->di_cu_context->cc_dbg,
+					   curr_attr_form, info_ptr,
+					   die->di_cu_context->
+					   cc_length_size);
+    } while (curr_attr != 0 || curr_attr_form != 0);
+
+    *attr_form = 1;
+    return (NULL);
+}
+
+
+int
+dwarf_diename(Dwarf_Die die, char **ret_name, Dwarf_Error * error)
+{
+    Dwarf_Half attr_form;
+    Dwarf_Debug dbg;
+    Dwarf_Byte_Ptr info_ptr;
+    Dwarf_Unsigned string_offset;
+    int res;
+
+    CHECK_DIE(die, DW_DLV_ERROR);
+
+    info_ptr = _dwarf_get_value_ptr(die, DW_AT_name, &attr_form);
+    if (info_ptr == NULL) {
+	if (attr_form == 0) {
+	    _dwarf_error(die->di_cu_context->cc_dbg, error,
+			 DW_DLE_DIE_BAD);
+	    return (DW_DLV_ERROR);
+	}
+	return DW_DLV_NO_ENTRY;
+    }
+
+    if (attr_form == DW_FORM_string) {
+	*ret_name = (char *) (info_ptr);
+	return DW_DLV_OK;
+    }
+
+    dbg = die->di_cu_context->cc_dbg;
+    if (attr_form != DW_FORM_strp) {
+	_dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD);
+	return (DW_DLV_ERROR);
+    }
+
+    READ_UNALIGNED(dbg, string_offset, Dwarf_Unsigned,
+		   info_ptr, die->di_cu_context->cc_length_size);
+
+    if (string_offset >= dbg->de_debug_str_size) {
+	_dwarf_error(dbg, error, DW_DLE_STRING_OFFSET_BAD);
+	return (DW_DLV_ERROR);
+    }
+
+    res =
+	_dwarf_load_section(dbg,
+			    dbg->de_debug_str_index,
+			    &dbg->de_debug_str, error);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+
+    *ret_name = (char *) (dbg->de_debug_str + string_offset);
+    return DW_DLV_OK;
+}
+
+
+int
+dwarf_hasattr(Dwarf_Die die,
+	      Dwarf_Half attr,
+	      Dwarf_Bool * return_bool, Dwarf_Error * error)
+{
+    Dwarf_Half attr_form;
+
+    CHECK_DIE(die, DW_DLV_ERROR);
+
+    if (_dwarf_get_value_ptr(die, attr, &attr_form) == NULL) {
+	if (attr_form == 0) {
+	    _dwarf_error(die->di_cu_context->cc_dbg, error,
+			 DW_DLE_DIE_BAD);
+	    return (DW_DLV_ERROR);
+	}
+	*return_bool = false;
+	return DW_DLV_OK;
+    }
+
+    *return_bool = (true);
+    return DW_DLV_OK;
+}
+
+
+int
+dwarf_attr(Dwarf_Die die,
+	   Dwarf_Half attr,
+	   Dwarf_Attribute * ret_attr, Dwarf_Error * error)
+{
+    Dwarf_Half attr_form;
+    Dwarf_Attribute attrib;
+    Dwarf_Byte_Ptr info_ptr;
+    Dwarf_Debug dbg;
+
+    CHECK_DIE(die, DW_DLV_ERROR);
+    dbg = die->di_cu_context->cc_dbg;
+
+    info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form);
+    if (info_ptr == NULL) {
+	if (attr_form == 0) {
+	    _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
+	    return (DW_DLV_ERROR);
+	}
+	return DW_DLV_NO_ENTRY;
+    }
+
+    attrib = (Dwarf_Attribute) _dwarf_get_alloc(dbg, DW_DLA_ATTR, 1);
+    if (attrib == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (DW_DLV_ERROR);
+    }
+
+    attrib->ar_attribute = attr;
+    attrib->ar_attribute_form = attr_form;
+    attrib->ar_attribute_form_direct = attr_form;
+    attrib->ar_cu_context = die->di_cu_context;
+    attrib->ar_debug_info_ptr = info_ptr;
+    *ret_attr = (attrib);
+    return DW_DLV_OK;
+}
+
+
+int
+dwarf_lowpc(Dwarf_Die die,
+	    Dwarf_Addr * return_addr, Dwarf_Error * error)
+{
+    Dwarf_Addr ret_addr = 0;
+    Dwarf_Byte_Ptr info_ptr = 0;
+    Dwarf_Half attr_form = 0;
+    Dwarf_Debug dbg = 0;
+
+    CHECK_DIE(die, DW_DLV_ERROR);
+
+    dbg = die->di_cu_context->cc_dbg;
+    info_ptr = _dwarf_get_value_ptr(die, DW_AT_low_pc, &attr_form);
+    if ((info_ptr == NULL && attr_form == 0) ||
+	(info_ptr != NULL && attr_form != DW_FORM_addr)) {
+	_dwarf_error(dbg, error, DW_DLE_DIE_BAD);
+	return (DW_DLV_ERROR);
+    }
+    if (info_ptr == NULL) {
+	return (DW_DLV_NO_ENTRY);
+    }
+
+
+    READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
+		   info_ptr, dbg->de_pointer_size);
+
+    *return_addr = ret_addr;
+    return (DW_DLV_OK);
+}
+
+
+int
+dwarf_highpc(Dwarf_Die die,
+	     Dwarf_Addr * return_addr, Dwarf_Error * error)
+{
+    Dwarf_Addr ret_addr;
+    Dwarf_Byte_Ptr info_ptr;
+    Dwarf_Half attr_form;
+    Dwarf_Debug dbg;
+
+    CHECK_DIE(die, DW_DLV_ERROR);
+
+    dbg = die->di_cu_context->cc_dbg;
+    info_ptr = _dwarf_get_value_ptr(die, DW_AT_high_pc, &attr_form);
+    if ((info_ptr == NULL && attr_form == 0) ||
+	(info_ptr != NULL && attr_form != DW_FORM_addr)) {
+	_dwarf_error(dbg, error, DW_DLE_DIE_BAD);
+	return (DW_DLV_ERROR);
+    }
+    if (info_ptr == NULL) {
+	return (DW_DLV_NO_ENTRY);
+    }
+
+    READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr,
+		   info_ptr, dbg->de_pointer_size);
+
+    *return_addr = ret_addr;
+    return (DW_DLV_OK);
+}
+
+
+/*
+    Takes a die, an attribute attr, and checks if attr 
+    occurs in die.  Attr is required to be an attribute
+    whose form is in the "constant" class.  If attr occurs 
+    in die, the value is returned.  
+  Returns DW_DLV_OK, DW_DLV_ERROR, or DW_DLV_NO_ENTRY as
+    appropriate. Sets the value thru the pointer return_val.
+    This function is meant to do all the 
+    processing for dwarf_bytesize, dwarf_bitsize, dwarf_bitoffset, 
+    and dwarf_srclang.
+*/
+static int
+_dwarf_die_attr_unsigned_constant(Dwarf_Die die,
+				  Dwarf_Half attr,
+				  Dwarf_Unsigned * return_val,
+				  Dwarf_Error * error)
+{
+    Dwarf_Byte_Ptr info_ptr;
+    Dwarf_Half attr_form;
+    Dwarf_Unsigned ret_value;
+    Dwarf_Debug dbg;
+
+    CHECK_DIE(die, DW_DLV_ERROR);
+
+    dbg = die->di_cu_context->cc_dbg;
+    info_ptr = _dwarf_get_value_ptr(die, attr, &attr_form);
+    if (info_ptr != NULL) {
+	switch (attr_form) {
+
+	case DW_FORM_data1:
+	    *return_val = (*(Dwarf_Small *) info_ptr);
+	    return (DW_DLV_OK);
+
+	case DW_FORM_data2:
+	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+			   info_ptr, sizeof(Dwarf_Shalf));
+	    *return_val = ret_value;
+	    return (DW_DLV_OK);
+
+	case DW_FORM_data4:
+	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+			   info_ptr, sizeof(Dwarf_sfixed));
+	    *return_val = ret_value;
+	    return (DW_DLV_OK);
+
+	case DW_FORM_data8:
+	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+			   info_ptr, sizeof(Dwarf_Unsigned));
+	    *return_val = ret_value;
+	    return (DW_DLV_OK);
+
+	case DW_FORM_udata:
+	    *return_val = (_dwarf_decode_u_leb128(info_ptr, NULL));
+	    return (DW_DLV_OK);
+
+	default:
+	    _dwarf_error(dbg, error, DW_DLE_DIE_BAD);
+	    return (DW_DLV_ERROR);
+	}
+    }
+    if (attr_form == 0) {
+	_dwarf_error(dbg, error, DW_DLE_DIE_BAD);
+	return (DW_DLV_ERROR);
+    }
+    return DW_DLV_NO_ENTRY;
+}
+
+
+int
+dwarf_bytesize(Dwarf_Die die,
+	       Dwarf_Unsigned * ret_size, Dwarf_Error * error)
+{
+    Dwarf_Unsigned luns;
+    int res =
+	_dwarf_die_attr_unsigned_constant(die, DW_AT_byte_size, &luns,
+					  error);
+
+    *ret_size = luns;
+    return res;
+}
+
+
+int
+dwarf_bitsize(Dwarf_Die die,
+	      Dwarf_Unsigned * ret_size, Dwarf_Error * error)
+{
+    Dwarf_Unsigned luns;
+    int res;
+
+    res =
+	_dwarf_die_attr_unsigned_constant(die, DW_AT_bit_size, &luns,
+					  error);
+    *ret_size = luns;
+    return res;
+}
+
+
+int
+dwarf_bitoffset(Dwarf_Die die,
+		Dwarf_Unsigned * ret_size, Dwarf_Error * error)
+{
+    Dwarf_Unsigned luns;
+    int res;
+
+    res =
+	_dwarf_die_attr_unsigned_constant(die, DW_AT_bit_offset, &luns,
+					  error);
+    *ret_size = luns;
+    return res;
+}
+
+
+/* Refer section 3.1, page 21 in Dwarf Definition. */
+int
+dwarf_srclang(Dwarf_Die die,
+	      Dwarf_Unsigned * ret_size, Dwarf_Error * error)
+{
+    Dwarf_Unsigned luns;
+    int res;
+
+    res =
+	_dwarf_die_attr_unsigned_constant(die, DW_AT_language, &luns,
+					  error);
+    *ret_size = luns;
+    return res;
+}
+
+
+/* Refer section 5.4, page 37 in Dwarf Definition. */
+int
+dwarf_arrayorder(Dwarf_Die die,
+		 Dwarf_Unsigned * ret_size, Dwarf_Error * error)
+{
+    Dwarf_Unsigned luns;
+    int res;
+
+    res =
+	_dwarf_die_attr_unsigned_constant(die, DW_AT_ordering, &luns,
+					  error);
+    *ret_size = luns;
+    return res;
+}
+
+/*
+	Return DW_DLV_OK if ok
+	DW_DLV_ERROR if failure.
+
+	If the die and the attr are not related the result is
+	meaningless.
+*/
+int
+dwarf_attr_offset(Dwarf_Die die, Dwarf_Attribute attr, Dwarf_Off * offset,	/* return 
+										   offset 
+										   thru 
+										   this 
+										   ptr 
+										 */
+		  Dwarf_Error * error)
+{
+    Dwarf_Off attroff;
+
+    CHECK_DIE(die, DW_DLV_ERROR);
+
+    attroff = (attr->ar_debug_info_ptr -
+	       die->di_cu_context->cc_dbg->de_debug_info);
+    *offset = attroff;
+    return DW_DLV_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_sort_line.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,718 @@
+/*
+  Copyright (C) 2000,2002,2004,2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "dwarf_line.h"
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#define MINIMUM_POSSIBLE_PROLOG_LEN 10	/* 10 is based on */
+	/* the definition of the DWARF2/3 line table prolog. The value
+	   here should be >8 (accounting for a 64 bit read) and <= the
+	   length of a legal DWARF2/3 line prolog, which is at least 10 
+	   bytes long (but can be longer). What this constant helps
+	   avoid is reading past the end of a malloc'd buffer in
+	   _dwarf_update_line_sec(). */
+
+static int
+  _dwarf_update_line_sec(Dwarf_Small * line_ptr,
+			 unsigned long remaining_bytes,
+			 int *any_change,
+			 int length_size,
+			 int *err_code, Dwarf_Small ** new_line_ptr);
+
+/* Used to construct
+   a linked list of so we can sort and reorder the line info.
+*/
+struct a_line_area {
+    Dwarf_Addr ala_address;	/* from DW_LNE_set_address */
+    Dwarf_Unsigned ala_offset;	/* byte offset in buffer */
+    Dwarf_Unsigned ala_length;	/* byte length in buffer */
+    long ala_entry_num;		/* to guarantee stable sort */
+    struct a_line_area *ala_next;
+};
+
+
+/*
+        Written to support the SGI IRIX static linker. 
+        It helps SGI IRIX ld 
+        rearrange lines in .debug_line in a .o created with a text
+        section per function.   The SGI IRIX linker option is: 
+                -OPT:procedure_reorder=ON
+        where ld-cord (cord(1)ing by ld, 
+        not by cord(1)) may have changed the function order.
+
+	Returns
+	DW_DLV_OK if nothing went wrong.
+	DW_DLV_ERROR if could not do anything due to
+		error.  the original buffer is unchanged.
+
+	is_64_bit must be passed in by caller and tells
+	if this is a 32 or 64bit pointer object section
+	being processed.
+
+	err_code must be a non-null pointer to integer.
+	If DW_DLV_ERROR is returned that integer is set
+	to a dwarf error code so the caller may
+	print it for diagnostic purposes.
+
+	*any_change is set here 
+		set 0 if no sorting (movement) done.
+		set 1 if some sorting (movement) done.
+	on all returns. On error return sets to 0.
+	
+        The _dwarf name form is now obsolete,
+        the dwarf_ name for is preferred.
+        Both names supported.
+
+*/
+int
+_dwarf_ld_sort_lines(void *orig_buffer,
+		     unsigned long buffer_len,
+		     int is_64_bit, int *any_change, int *err_code)
+{
+    return dwarf_ld_sort_lines(orig_buffer,buffer_len,
+        is_64_bit,any_change,err_code);
+}
+int
+dwarf_ld_sort_lines(void *orig_buffer,
+		     unsigned long buffer_len,
+		     int is_64_bit, int *any_change, int *err_code)
+{
+
+    int length_size = 4;
+    Dwarf_Small *orig_line_ptr;	/* our local copy of the user's input
+				   buffer */
+    Dwarf_Small *line_ptr;	/* starts at orig_line_ptr, gets
+				   incremented thru to end of our copy
+				   of the input buffer */
+    Dwarf_Small *new_line_ptr;	/* output of _dwarf_update_line_sec(),
+				   used to update line_ptr as we pass
+				   thru compilation units in a .o
+				   .debug_line */
+
+    unsigned long remaining_bytes = buffer_len;	/* total length of
+						   original area left
+						   to be processed.
+						   Changes as we pass
+						   thru compilation
+						   units in a .o
+						   .debug_line */
+
+    int sec_res;
+    int lany_change = 0;
+    int did_change = 0;
+
+    if (is_64_bit)
+	length_size = 8;
+
+    *any_change = 0;
+    line_ptr = malloc(buffer_len);
+    if (!line_ptr) {
+	*err_code = DW_DLE_ALLOC_FAIL;
+	return DW_DLV_ERROR;
+    }
+    orig_line_ptr = line_ptr;
+    memcpy(line_ptr, orig_buffer, buffer_len);
+
+
+    /* 
+       We must iterate thru each of a set of prologues and line data.
+       We process each set in turn. If all pass, we update the
+       passed-in buffer. */
+    sec_res = DW_DLV_OK;
+
+    for (sec_res = _dwarf_update_line_sec(line_ptr,
+					  remaining_bytes,
+					  &lany_change,
+					  length_size,
+					  err_code,
+					  &new_line_ptr);
+	 (sec_res == DW_DLV_OK) && (remaining_bytes > 0);
+	 sec_res = _dwarf_update_line_sec(line_ptr,
+					  remaining_bytes,
+					  &lany_change,
+					  length_size,
+					  err_code, &new_line_ptr)) {
+	long bytes_used = new_line_ptr - line_ptr;
+
+	line_ptr = new_line_ptr;
+	remaining_bytes -= bytes_used;
+	if (lany_change) {
+	    did_change = 1;
+	}
+	if (remaining_bytes > 0) {
+	    continue;
+	}
+	break;
+    }
+    if (sec_res == DW_DLV_ERROR) {
+	free(orig_line_ptr);
+	return sec_res;
+    }
+
+
+    /* all passed */
+    if (did_change) {
+	/* So update the passed in buffer orig_buffer is caller's input 
+	   area. orig_line_ptr is our modified copy of input area. */
+	memcpy(orig_buffer, orig_line_ptr, buffer_len);
+	*any_change = 1;
+    }
+    free(orig_line_ptr);
+
+    return sec_res;
+}
+
+
+/* By setting ala_entry_num we guarantee a stable sort,
+	no duplicates
+   Sorting in address order.
+*/
+static int
+cmpr(const void *lin, const void *rin)
+{
+    const struct a_line_area *l = lin;
+    const struct a_line_area *r = rin;
+
+    if (l->ala_address < r->ala_address) {
+	return -1;
+    }
+    if (l->ala_address > r->ala_address) {
+	return 1;
+    }
+    if (l->ala_entry_num < r->ala_entry_num) {
+	return -1;
+    }
+    if (l->ala_entry_num > r->ala_entry_num) {
+	return 1;
+    }
+    return 0;			/* should never happen. */
+}
+
+
+/*
+	On entry:
+	  line_ptr must point to first
+	  byte of a line group for one (original) .o
+	  
+	  remaining_bytes is the size of the area pointed to
+	  by line_ptr: may be larger than the
+	  current original compilation unit .
+
+	  length size is 4 for 32bit pointers, 8 for 64bit pointers
+	  in the data pointed to.
+
+
+	On return:
+	  return DW_DLV_OK if all ok.  (ignore 
+		*err_code in this case)
+
+	  return DW_DLV_ERROR and set *err_code if an error.
+
+	  If some line data was moved around, set *any_change to 1.
+	  If error or no movement, set *any_change to 0;
+
+	  Set *new_line_ptr to one-byte-past the end of the
+	  current original compilation unit  (not necessary
+	  if returning DW_DLV_ERROR, but not harmful).
+
+
+	This copies the entire array to a malloc area, then
+	mallocs pieces of it (another malloc) for sorting a CU entries
+	and copying back.  Then at end  the whole new thing copied in.
+	The result is that on error, the input is not touched.
+
+	An alternative would be to just update a piece at a time
+	and on error stop updating but leave what was done, done.
+	This alternative would save some temporary malloc space.
+	
+	
+*/
+static int
+_dwarf_update_line_sec(Dwarf_Small * line_ptr,
+		       unsigned long remaining_bytes,
+		       int *any_change,
+		       int length_size,
+		       int *err_code, Dwarf_Small ** new_line_ptr)
+{
+
+
+    /* 
+       This points to the last byte of the .debug_line portion for the
+       current cu. */
+    Dwarf_Small *line_ptr_end = 0;
+
+    /* 
+       This points to the end of the statement program prologue for the 
+       current cu, and serves to check that the prologue was correctly
+       decoded. */
+
+    Dwarf_Small *orig_line_ptr = 0;
+
+    /* These are the fields of the statement program header. */
+    struct Dwarf_Debug_s dbg_data;
+    Dwarf_Debug dbg = &dbg_data;
+
+    /* These are the state machine state variables. */
+    Dwarf_Addr address = 0;
+    Dwarf_Word line = 1;
+    Dwarf_Bool is_stmt = false;
+
+    /* Dwarf_Bool prologue_end; Dwarf_Bool epilogue_begin; */
+    Dwarf_Small isa = 0;
+
+
+    struct a_line_area *area_base = 0;
+    struct a_line_area *area_current = 0;
+    long area_count = 0;
+
+    Dwarf_Addr last_address = 0;
+    int need_to_sort = 0;
+
+    /* 
+       This is the current opcode read from the statement program. */
+    Dwarf_Small opcode = 0;
+
+
+    /* 
+       These variables are used to decode leb128 numbers. Leb128_num
+       holds the decoded number, and leb128_length is its length in
+       bytes. */
+    Dwarf_Word leb128_num = 0;
+    Dwarf_Sword advance_line = 0;
+
+    /* 
+       This is the operand of the latest fixed_advance_pc extended
+       opcode. */
+    Dwarf_Half fixed_advance_pc = 0;
+
+    /* This is the length of an extended opcode instr.  */
+    Dwarf_Word instr_length = 0;
+    Dwarf_Small ext_opcode = 0;
+    struct Line_Table_Prefix_s prefix;
+
+
+
+    memset(dbg, 0, sizeof(struct Dwarf_Debug_s));
+    dbg->de_copy_word = memcpy;
+    /* 
+       Following is a straightforward decoding of the statement program 
+       prologue information. */
+    *any_change = 0;
+
+
+    orig_line_ptr = line_ptr;
+    if (remaining_bytes < MINIMUM_POSSIBLE_PROLOG_LEN) {
+	/* We are at the end. Remaining should be zero bytes, padding.
+	   This is really just 'end of CU buffer' not an error. The is
+	   no 'entry' left so report there is none. We don't want to
+	   READ_UNALIGNED the total_length below and then belatedly
+	   discover that we read off the end already. */
+	return (DW_DLV_NO_ENTRY);
+    }
+
+    dwarf_init_line_table_prefix(&prefix);
+    {
+	Dwarf_Small *line_ptr_out = 0;
+	Dwarf_Error error;
+	int dres = dwarf_read_line_table_prefix(dbg,
+						line_ptr,
+						remaining_bytes,
+						&line_ptr_out,
+						&prefix, &error);
+
+	if (dres == DW_DLV_ERROR) {
+	    dwarf_free_line_table_prefix(&prefix);
+	    *err_code = dwarf_errno(error);
+	    dwarf_dealloc(dbg, error, DW_DLA_ERROR);
+	    return dres;
+	}
+	if (dres == DW_DLV_NO_ENTRY) {
+	    dwarf_free_line_table_prefix(&prefix);
+	    return dres;
+	}
+	line_ptr_end = prefix.pf_line_ptr_end;
+
+	line_ptr = line_ptr_out;
+    }
+
+
+    /* Initialize the state machine.  */
+    /* file = 1; */
+    /* column = 0; */
+    is_stmt = prefix.pf_default_is_stmt;
+    /* basic_block = false; */
+    /* end_sequence = false; */
+    /* prologue_end = false; */
+    /* epilogue_begin = false; */
+    isa = 0;
+
+
+    /* Start of statement program.  */
+    while (line_ptr < line_ptr_end) {
+	int type;
+
+	Dwarf_Small *stmt_prog_entry_start = line_ptr;
+
+	opcode = *(Dwarf_Small *) line_ptr;
+	line_ptr++;
+	/* 'type' is the output */
+	WHAT_IS_OPCODE(type, opcode, prefix.pf_opcode_base,
+		       prefix.pf_opcode_length_table, line_ptr,
+		       prefix.pf_std_op_count);
+
+	if (type == LOP_DISCARD) {
+	    int oc;
+	    int opcnt = prefix.pf_opcode_length_table[opcode];
+
+	    for (oc = 0; oc < opcnt; oc++) {
+		/* 
+		 ** Read and discard operands we don't
+		 ** understand.
+		 ** arbitrary choice of unsigned read.
+		 ** signed read would work as well.
+		 */
+		Dwarf_Unsigned utmp2;
+
+		DECODE_LEB128_UWORD(line_ptr, utmp2);
+	    }
+
+	} else if (type == LOP_SPECIAL) {
+	    opcode = opcode - prefix.pf_opcode_base;
+	    address = address + prefix.pf_minimum_instruction_length *
+		(opcode / prefix.pf_line_range);
+	    line =
+		line + prefix.pf_line_base +
+		opcode % prefix.pf_line_range;
+
+	    /* basic_block = false; */
+
+
+	} else if (type == LOP_STANDARD) {
+
+
+	    switch (opcode) {
+
+
+	    case DW_LNS_copy:{
+
+		    /* basic_block = false; */
+		    break;
+		}
+
+	    case DW_LNS_advance_pc:{
+		    Dwarf_Unsigned utmp2;
+
+
+		    DECODE_LEB128_UWORD(line_ptr, utmp2);
+		    leb128_num = (Dwarf_Word) utmp2;
+		    address =
+			address +
+			prefix.pf_minimum_instruction_length *
+			leb128_num;
+		    break;
+		}
+
+	    case DW_LNS_advance_line:{
+		    Dwarf_Signed stmp;
+
+
+		    DECODE_LEB128_SWORD(line_ptr, stmp);
+		    advance_line = (Dwarf_Sword) stmp;
+		    line = line + advance_line;
+		    break;
+		}
+
+	    case DW_LNS_set_file:{
+		    Dwarf_Unsigned utmp2;
+
+
+		    DECODE_LEB128_UWORD(line_ptr, utmp2);
+		    /* file = (Dwarf_Word)utmp2; */
+		    break;
+		}
+
+	    case DW_LNS_set_column:{
+		    Dwarf_Unsigned utmp2;
+
+
+		    DECODE_LEB128_UWORD(line_ptr, utmp2);
+		    /* column = (Dwarf_Word)utmp2; */
+		    break;
+		}
+
+	    case DW_LNS_negate_stmt:{
+
+		    is_stmt = !is_stmt;
+		    break;
+		}
+
+	    case DW_LNS_set_basic_block:{
+
+		    /* basic_block = true; */
+		    break;
+		}
+
+	    case DW_LNS_const_add_pc:{
+		    opcode = MAX_LINE_OP_CODE - prefix.pf_opcode_base;
+		    address =
+			address +
+			prefix.pf_minimum_instruction_length * (opcode /
+								prefix.
+								pf_line_range);
+
+		    break;
+		}
+
+	    case DW_LNS_fixed_advance_pc:{
+
+		    READ_UNALIGNED(dbg, fixed_advance_pc, Dwarf_Half,
+				   line_ptr, sizeof(Dwarf_Half));
+		    line_ptr += sizeof(Dwarf_Half);
+		    address = address + fixed_advance_pc;
+		    break;
+		}
+		/* New in DWARF3 */
+	    case DW_LNS_set_prologue_end:{
+
+		    /* prologue_end = true; */
+		    break;
+
+
+		}
+		/* New in DWARF3 */
+	    case DW_LNS_set_epilogue_begin:{
+		    /* epilogue_begin = true; */
+		    break;
+		}
+
+		/* New in DWARF3 */
+	    case DW_LNS_set_isa:{
+		    Dwarf_Unsigned utmp2;
+
+		    DECODE_LEB128_UWORD(line_ptr, utmp2);
+		    isa = utmp2;
+		    if (isa != utmp2) {
+			/* The value of the isa did not fit in our
+			   local so we record it wrong. declare an
+			   error. */
+			dwarf_free_line_table_prefix(&prefix);
+
+			*err_code = DW_DLE_LINE_NUM_OPERANDS_BAD;
+			return (DW_DLV_ERROR);
+		    }
+		    break;
+		}
+
+	    }
+	} else if (type == LOP_EXTENDED) {
+
+
+	    Dwarf_Unsigned utmp3;
+
+	    DECODE_LEB128_UWORD(line_ptr, utmp3);
+	    instr_length = (Dwarf_Word) utmp3;
+	    ext_opcode = *(Dwarf_Small *) line_ptr;
+	    line_ptr++;
+	    switch (ext_opcode) {
+
+	    case DW_LNE_end_sequence:{
+		    /* end_sequence = true; */
+
+		    address = 0;
+		    /* file = 1; */
+		    line = 1;
+		    /* column = 0; */
+		    is_stmt = prefix.pf_default_is_stmt;
+		    /* basic_block = false; */
+		    /* end_sequence = false; */
+		    /* prologue_end = false; */
+		    /* epilogue_begin = false; */
+
+
+		    break;
+		}
+
+	    case DW_LNE_set_address:{
+		    if (instr_length - 1 == length_size) {
+			struct a_line_area *area;
+
+			READ_UNALIGNED(dbg, address, Dwarf_Addr,
+				       line_ptr, length_size);
+			/* Here we need to remember the offset into the 
+			   buffer and check to see if address went
+			   down. */
+			if (address < last_address) {
+			    need_to_sort = 1;
+			}
+			last_address = address;
+
+			area = alloca(sizeof(struct a_line_area));
+			area->ala_address = address;
+			area->ala_offset = stmt_prog_entry_start -
+			    orig_line_ptr;
+			area->ala_entry_num = area_count;
+			area->ala_next = 0;
+			area->ala_length = 0;
+			if (area_current) {
+			    area_current->ala_next = area;
+			    area_current->ala_length =
+				area->ala_offset -
+				area_current->ala_offset;
+			}
+			++area_count;
+			area_current = area;
+			if (area_base == 0) {
+			    area_base = area;
+			}
+
+			line_ptr += length_size;
+		    } else {
+			*err_code = DW_DLE_LINE_SET_ADDR_ERROR;
+			dwarf_free_line_table_prefix(&prefix);
+			return (DW_DLV_ERROR);
+		    }
+
+
+		    break;
+		}
+
+	    case DW_LNE_define_file:{
+
+		    break;
+		}
+
+	    default:{
+		    *err_code = DW_DLE_LINE_EXT_OPCODE_BAD;
+		    dwarf_free_line_table_prefix(&prefix);
+		    return (DW_DLV_ERROR);
+		}
+	    }
+
+	}
+    }
+
+
+    *new_line_ptr = line_ptr;
+    if (!need_to_sort) {
+	dwarf_free_line_table_prefix(&prefix);
+	return (DW_DLV_OK);
+    }
+
+    /* so now we have something to sort. First, finish off the last
+       area record: */
+    area_current->ala_length = (line_ptr - orig_line_ptr)	/* final 
+								   offset 
+								 */
+	-area_current->ala_offset;
+
+    /* Build and sort a simple array of sections. Forcing a stable sort 
+       by comparing on sequence number. We will use the sorted list to
+       move sections of this part of the line table. Each 'section'
+       starting with a DW_LNE_set_address opcode, on the assumption
+       that such only get out of order where there was an ld-cord
+       function rearrangement and that it is meaningful to restart the
+       line info there. */
+    {
+	struct a_line_area *ala_array;
+	struct a_line_area *local;
+	long start_len;
+	Dwarf_Small *new_area;
+	long i;
+
+	ala_array = malloc(area_count * sizeof(struct a_line_area));
+	if (!ala_array) {
+	    dwarf_free_line_table_prefix(&prefix);
+	    *err_code = DW_DLE_ALLOC_FAIL;
+	    return DW_DLV_ERROR;
+	}
+
+	for (local = area_base, i = 0; local;
+	     local = local->ala_next, ++i) {
+
+	    ala_array[i] = *local;
+	}
+
+	qsort(ala_array, area_count, sizeof(struct a_line_area), cmpr);
+
+	/* Now we must rearrange the pieces of the line table. */
+
+	start_len =
+	    (prefix.pf_line_prologue_start +
+	     prefix.pf_prologue_length) - orig_line_ptr;
+	new_area = malloc(remaining_bytes);
+	if (!new_area) {
+	    free(ala_array);
+	    *err_code = DW_DLE_ALLOC_FAIL;
+	    dwarf_free_line_table_prefix(&prefix);
+	    return DW_DLV_ERROR;
+	}
+	memcpy(new_area, orig_line_ptr, start_len);
+	line_ptr = new_area + start_len;
+	for (i = 0; i < area_count; ++i) {
+	    memcpy(line_ptr, orig_line_ptr +
+		   ala_array[i].ala_offset, ala_array[i].ala_length);
+	    line_ptr += ala_array[i].ala_length;
+	}
+
+	memcpy(orig_line_ptr, new_area, remaining_bytes);
+
+	free(new_area);
+	free(ala_array);
+	ala_array = 0;
+	new_area = 0;
+    }
+
+    *any_change = 1;
+    dwarf_free_line_table_prefix(&prefix);
+    return (DW_DLV_OK);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_string.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,81 @@
+/*
+
+  Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+
+int
+dwarf_get_str(Dwarf_Debug dbg,
+	      Dwarf_Off offset,
+	      char **string,
+	      Dwarf_Signed * returned_str_len, Dwarf_Error * error)
+{
+    int res;
+
+    if (dbg == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    if (offset == dbg->de_debug_str_size) {
+	/* Normal (if we've iterated thru the set of strings using
+	   dwarf_get_str and are at the end). */
+	return DW_DLV_NO_ENTRY;
+    }
+    if (offset > dbg->de_debug_str_size) {
+	_dwarf_error(dbg, error, DW_DLE_DEBUG_STR_OFFSET_BAD);
+	return (DW_DLV_ERROR);
+    }
+
+    if (string == NULL) {
+	_dwarf_error(dbg, error, DW_DLE_STRING_PTR_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    res =
+	_dwarf_load_section(dbg,
+			    dbg->de_debug_str_index,
+			    &dbg->de_debug_str, error);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+
+    *string = (char *) dbg->de_debug_str + offset;
+
+    *returned_str_len = (strlen(*string));
+    return DW_DLV_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_stubs.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,50 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+
+
+
+ /*ARGSUSED*/ int
+dwarf_nextglob(Dwarf_Debug dbg,
+	       Dwarf_Global glob,
+	       Dwarf_Global * returned_nextglob, Dwarf_Error * error)
+{
+    return (DW_DLV_NO_ENTRY);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_types.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,141 @@
+/*
+
+  Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include "dwarf_types.h"
+#include "dwarf_global.h"
+
+int
+dwarf_get_types(Dwarf_Debug dbg,
+		Dwarf_Type ** types,
+		Dwarf_Signed * ret_type_count, Dwarf_Error * error)
+{
+    int res;
+
+    res =
+	_dwarf_load_section(dbg,
+			    dbg->de_debug_typenames_index,
+			    &dbg->de_debug_typenames, error);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+
+    return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_typenames, dbg->de_debug_typenames_size, (Dwarf_Global **) types,	/* type 
+																	   punning, 
+																	   Dwarf_Type 
+																	   is 
+																	   never 
+																	   a 
+																	   completed 
+																	   type 
+																	 */
+						  ret_type_count,
+						  error,
+						  DW_DLA_TYPENAME_CONTEXT,
+						  DW_DLA_TYPENAME,
+						  DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD,
+						  DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR);
+
+}
+
+/* Deallocating fully requires deallocating the list
+   and all entries.  But some internal data is
+   not exposed, so we need a function with internal knowledge.
+*/
+
+void
+dwarf_types_dealloc(Dwarf_Debug dbg, Dwarf_Type * dwgl,
+		    Dwarf_Signed count)
+{
+    _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl,
+				    count,
+				    DW_DLA_TYPENAME_CONTEXT,
+				    DW_DLA_TYPENAME, DW_DLA_LIST);
+    return;
+}
+
+
+int
+dwarf_typename(Dwarf_Type type_in, char **ret_name, Dwarf_Error * error)
+{
+    Dwarf_Global type = (Dwarf_Global) type_in;
+
+    if (type == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_TYPE_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *ret_name = (char *) (type->gl_name);
+    return DW_DLV_OK;
+}
+
+
+int
+dwarf_type_die_offset(Dwarf_Type type_in,
+		      Dwarf_Off * ret_offset, Dwarf_Error * error)
+{
+    Dwarf_Global type = (Dwarf_Global) type_in;
+
+    return dwarf_global_die_offset(type, ret_offset, error);
+}
+
+
+int
+dwarf_type_cu_offset(Dwarf_Type type_in,
+		     Dwarf_Off * ret_offset, Dwarf_Error * error)
+{
+    Dwarf_Global type = (Dwarf_Global) type_in;
+
+    return dwarf_global_cu_offset(type, ret_offset, error);
+
+}
+
+
+int
+dwarf_type_name_offsets(Dwarf_Type type_in,
+			char **returned_name,
+			Dwarf_Off * die_offset,
+			Dwarf_Off * cu_die_offset, Dwarf_Error * error)
+{
+    Dwarf_Global type = (Dwarf_Global) type_in;
+
+    return dwarf_global_name_offsets(type,
+				     returned_name,
+				     die_offset, cu_die_offset, error);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_types.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,41 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+
+typedef struct Dwarf_Type_Context_s *Dwarf_Type_Context;
+
+/* type never completed  see dwarf_global.h */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_util.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,392 @@
+/*
+  Copyright (C) 2000,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include "dwarf_die_deliv.h"
+
+
+
+/*
+    Given a form, and a pointer to the bytes encoding 
+    a value of that form, val_ptr, this function returns
+    the length, in bytes, of a value of that form.
+    When using this function, check for a return of 0
+    a recursive DW_FORM_INDIRECT value.
+*/
+Dwarf_Unsigned
+_dwarf_get_size_of_val(Dwarf_Debug dbg,
+		       Dwarf_Unsigned form,
+		       Dwarf_Small * val_ptr, int v_length_size)
+{
+    Dwarf_Unsigned length = 0;
+    Dwarf_Word leb128_length = 0;
+    Dwarf_Unsigned form_indirect = 0;
+    Dwarf_Unsigned ret_value = 0;
+
+    switch (form) {
+
+    default:			/* Handles form = 0. */
+	return (form);
+
+    case DW_FORM_addr:
+	return (dbg->de_pointer_size);
+
+    case DW_FORM_ref_addr:
+	return (v_length_size);
+
+    case DW_FORM_block1:
+	return (*(Dwarf_Small *) val_ptr + 1);
+
+    case DW_FORM_block2:
+	READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+		       val_ptr, sizeof(Dwarf_Half));
+	return (ret_value + sizeof(Dwarf_Half));
+
+    case DW_FORM_block4:
+	READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
+		       val_ptr, sizeof(Dwarf_ufixed));
+	return (ret_value + sizeof(Dwarf_ufixed));
+
+
+    case DW_FORM_data1:
+	return (1);
+
+    case DW_FORM_data2:
+	return (2);
+
+    case DW_FORM_data4:
+	return (4);
+
+    case DW_FORM_data8:
+	return (8);
+
+    case DW_FORM_string:
+	return (strlen((char *) val_ptr) + 1);
+
+    case DW_FORM_block:
+	length = _dwarf_decode_u_leb128(val_ptr, &leb128_length);
+	return (length + leb128_length);
+
+    case DW_FORM_flag:
+	return (1);
+
+    case DW_FORM_ref_udata:
+	_dwarf_decode_u_leb128(val_ptr, &leb128_length);
+	return (leb128_length);
+
+    case DW_FORM_indirect:
+	{
+	    Dwarf_Word indir_len = 0;
+
+	    form_indirect = _dwarf_decode_u_leb128(val_ptr, &indir_len);
+	    if (form_indirect == DW_FORM_indirect) {
+		return (0);	/* We are in big trouble: The true form 
+				   of DW_FORM_indirect is
+				   DW_FORM_indirect? Nonsense. Should
+				   never happen. */
+	    }
+	    return (indir_len + _dwarf_get_size_of_val(dbg,
+						       form_indirect,
+						       val_ptr +
+						       indir_len,
+						       v_length_size));
+	}
+
+    case DW_FORM_ref1:
+	return (1);
+
+    case DW_FORM_ref2:
+	return (2);
+
+    case DW_FORM_ref4:
+	return (4);
+
+    case DW_FORM_ref8:
+	return (8);
+
+    case DW_FORM_sdata:
+	_dwarf_decode_s_leb128(val_ptr, &leb128_length);
+	return (leb128_length);
+
+    case DW_FORM_strp:
+	return (v_length_size);
+
+    case DW_FORM_udata:
+	_dwarf_decode_u_leb128(val_ptr, &leb128_length);
+	return (leb128_length);
+    }
+}
+
+
+/*
+    This function returns a pointer to a Dwarf_Abbrev_List_s
+    struct for the abbrev with the given code.  It puts the
+    struct on the appropriate hash table.  It also adds all
+    the abbrev between the last abbrev added and this one to
+    the hash table.  In other words, the .debug_abbrev section
+    is scanned sequentially from the top for an abbrev with
+    the given code.  All intervening abbrevs are also put 
+    into the hash table.
+
+    This function hashes the given code, and checks the chain
+    at that hash table entry to see if a Dwarf_Abbrev_List_s
+    with the given code exists.  If yes, it returns a pointer
+    to that struct.  Otherwise, it scans the .debug_abbrev
+    section from the last byte scanned for that CU till either
+    an abbrev with the given code is found, or an abbrev code
+    of 0 is read.  It puts Dwarf_Abbrev_List_s entries for all
+    abbrev's read till that point into the hash table.  The
+    hash table contains both a head pointer and a tail pointer
+    for each entry.
+
+    Returns NULL on error.
+*/
+Dwarf_Abbrev_List
+_dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context, Dwarf_Word code)
+{
+    Dwarf_Debug dbg = cu_context->cc_dbg;
+    Dwarf_Hash_Table hash_table = cu_context->cc_abbrev_hash_table;
+    Dwarf_Word hash_num;
+    Dwarf_Abbrev_List hash_abbrev_list;
+    Dwarf_Abbrev_List abbrev_list;
+    Dwarf_Byte_Ptr abbrev_ptr;
+    Dwarf_Half abbrev_code, abbrev_tag;
+    Dwarf_Half attr_name, attr_form;
+
+    hash_num = code % ABBREV_HASH_TABLE_SIZE;
+    for (hash_abbrev_list = hash_table[hash_num].at_head;
+	 hash_abbrev_list != NULL && hash_abbrev_list->ab_code != code;
+	 hash_abbrev_list = hash_abbrev_list->ab_next);
+    if (hash_abbrev_list != NULL)
+	return (hash_abbrev_list);
+
+    abbrev_ptr = cu_context->cc_last_abbrev_ptr != NULL ?
+	cu_context->cc_last_abbrev_ptr :
+	dbg->de_debug_abbrev + cu_context->cc_abbrev_offset;
+
+    /* End of abbrev's for this cu, since abbrev code is 0. */
+    if (*abbrev_ptr == 0) {
+	return (NULL);
+    }
+
+    do {
+	Dwarf_Unsigned utmp;
+
+	DECODE_LEB128_UWORD(abbrev_ptr, utmp);
+	abbrev_code = (Dwarf_Half) utmp;
+	DECODE_LEB128_UWORD(abbrev_ptr, utmp);
+	abbrev_tag = (Dwarf_Half) utmp;
+
+	abbrev_list = (Dwarf_Abbrev_List)
+	    _dwarf_get_alloc(cu_context->cc_dbg, DW_DLA_ABBREV_LIST, 1);
+	if (abbrev_list == NULL)
+	    return (NULL);
+
+	hash_num = abbrev_code % ABBREV_HASH_TABLE_SIZE;
+	if (hash_table[hash_num].at_head == NULL) {
+	    hash_table[hash_num].at_head =
+		hash_table[hash_num].at_tail = abbrev_list;
+	} else {
+	    hash_table[hash_num].at_tail->ab_next = abbrev_list;
+	    hash_table[hash_num].at_tail = abbrev_list;
+	}
+
+	abbrev_list->ab_code = abbrev_code;
+	abbrev_list->ab_tag = abbrev_tag;
+
+	abbrev_list->ab_has_child = *(abbrev_ptr++);
+	abbrev_list->ab_abbrev_ptr = abbrev_ptr;
+
+	/* Cycle thru the abbrev content, ignoring the content except
+	   to find the end of the content. */
+	do {
+	    Dwarf_Unsigned utmp3;
+
+	    DECODE_LEB128_UWORD(abbrev_ptr, utmp3);
+	    attr_name = (Dwarf_Half) utmp3;
+	    DECODE_LEB128_UWORD(abbrev_ptr, utmp3);
+	    attr_form = (Dwarf_Half) utmp3;
+	} while (attr_name != 0 && attr_form != 0);
+
+    } while (*abbrev_ptr != 0 && abbrev_code != code);
+
+    cu_context->cc_last_abbrev_ptr = abbrev_ptr;
+    return (abbrev_code == code ? abbrev_list : NULL);
+}
+
+
+/* return 1 if string ends before 'endptr' else
+** return 0 meaning string is not properly terminated.
+** Presumption is the 'endptr' pts to end of some dwarf section data.
+*/
+int
+_dwarf_string_valid(void *startptr, void *endptr)
+{
+
+    char *start = startptr;
+    char *end = endptr;
+
+    while (start < end) {
+	if (*start == 0) {
+	    return 1;		/* OK! */
+	}
+	++start;
+	++end;
+    }
+    return 0;			/* FAIL! bad string! */
+}
+
+/*
+  A byte-swapping version of memcpy
+  for cross-endian use.
+  Only 2,4,8 should be lengths passed in.
+*/
+void *
+_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len)
+{
+    void *orig_s1 = s1;
+    unsigned char *targ = (unsigned char *) s1;
+    unsigned char *src = (unsigned char *) s2;
+
+    if (len == 4) {
+	targ[3] = src[0];
+	targ[2] = src[1];
+	targ[1] = src[2];
+	targ[0] = src[3];
+    } else if (len == 8) {
+	targ[7] = src[0];
+	targ[6] = src[1];
+	targ[5] = src[2];
+	targ[4] = src[3];
+	targ[3] = src[4];
+	targ[2] = src[5];
+	targ[1] = src[6];
+	targ[0] = src[7];
+    } else if (len == 2) {
+	targ[1] = src[0];
+	targ[0] = src[1];
+    }
+/* should NOT get below here: is not the intended use */
+    else if (len == 1) {
+	targ[0] = src[0];
+    } else {
+	memcpy(s1, s2, len);
+    }
+
+    return orig_s1;
+}
+
+
+/*
+  This calculation used to be sprinkled all over.
+  Now brought to one place.
+
+  We try to accurately compute the size of a cu header
+  given a known cu header location ( an offset in .debug_info).
+
+*/
+/* ARGSUSED */
+Dwarf_Unsigned
+_dwarf_length_of_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned offset)
+{
+    int local_length_size = 0;
+    int local_extension_size = 0;
+    Dwarf_Unsigned length = 0;
+    Dwarf_Small *cuptr = dbg->de_debug_info + offset;
+
+    READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
+		     cuptr, local_length_size, local_extension_size);
+
+    return local_extension_size +	/* initial extesion, if present 
+					 */
+	local_length_size +	/* Size of cu length field. */
+	sizeof(Dwarf_Half) +	/* Size of version stamp field. */
+	local_length_size +	/* Size of abbrev offset field. */
+	sizeof(Dwarf_Small);	/* Size of address size field. */
+
+}
+
+/*
+	Pretend we know nothing about the CU
+	and just roughly compute the result. 
+*/
+Dwarf_Unsigned
+_dwarf_length_of_cu_header_simple(Dwarf_Debug dbg)
+{
+    return dbg->de_length_size +	/* Size of cu length field. */
+	sizeof(Dwarf_Half) +	/* Size of version stamp field. */
+	dbg->de_length_size +	/* Size of abbrev offset field. */
+	sizeof(Dwarf_Small);	/* Size of address size field. */
+}
+
+/* Now that we delay loading .debug_info, we need to do the
+   load in more places. So putting the load
+   code in one place now instead of replicating it in multiple
+   places.
+
+*/
+int
+_dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error * error)
+{
+    int res;
+
+    /* Testing de_debug_info allows us to avoid testing
+       de_debug_abbrev. One test instead of 2. .debug_info is useless
+       without .debug_abbrev. */
+    if (dbg->de_debug_info) {
+	return DW_DLV_OK;
+    }
+
+    res = _dwarf_load_section(dbg, dbg->de_debug_abbrev_index,
+			      &dbg->de_debug_abbrev, error);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+    res = _dwarf_load_section(dbg, dbg->de_debug_info_index,
+			      &dbg->de_debug_info, error);
+    return res;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_util.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,282 @@
+/*
+
+  Copyright (C) 2000,2003,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* The address of the Free Software Foundation is
+   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 
+   Boston, MA 02110-1301, USA.
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+
+/*
+    Decodes unsigned leb128 encoded numbers.
+    Make sure ptr is a pointer to a 1-byte type.  
+    In 2003 and earlier this was a hand-inlined
+    version of _dwarf_decode_u_leb128() which did
+    not work correctly if Dwarf_Word was 64 bits.
+*/
+#define DECODE_LEB128_UWORD(ptr, value) \
+    do { \
+       Dwarf_Word uleblen; \
+	value = _dwarf_decode_u_leb128(ptr,&uleblen); \
+        ptr += uleblen; \
+    } while (0)
+
+/*
+    Decodes signed leb128 encoded numbers.
+    Make sure ptr is a pointer to a 1-byte type.
+    In 2003 and earlier this was a hand-inlined
+    version of _dwarf_decode_s_leb128() which did
+    not work correctly if Dwarf_Word was 64 bits.
+
+*/
+#define DECODE_LEB128_SWORD(ptr, value) \
+    do { \
+       Dwarf_Word sleblen; \
+	value = _dwarf_decode_s_leb128(ptr,&sleblen); \
+        ptr += sleblen; \
+    } while(0)
+
+
+/*
+    Skips leb128_encoded numbers that are guaranteed 
+    to be no more than 4 bytes long.  Same for both
+    signed and unsigned numbers.
+*/
+#define SKIP_LEB128_WORD(ptr) \
+    do{ if ((*(ptr++) & 0x80) != 0) { \
+        if ((*(ptr++) & 0x80) != 0) { \
+            if ((*(ptr++) & 0x80) != 0) { \
+	        if ((*(ptr++) & 0x80) != 0) { \
+	        } \
+	    } \
+        } \
+    } } while (0)
+
+
+#define CHECK_DIE(die, error_ret_value) \
+do {if (die == NULL) { \
+	_dwarf_error(NULL, error, DW_DLE_DIE_NULL); \
+	return(error_ret_value); \
+    } \
+    if (die->di_cu_context == NULL) { \
+	_dwarf_error(NULL, error, DW_DLE_DIE_NO_CU_CONTEXT); \
+	return(error_ret_value); \
+    } \
+    if (die->di_cu_context->cc_dbg == NULL) { \
+	_dwarf_error(NULL, error, DW_DLE_DBG_NULL); \
+	return(error_ret_value); \
+    }  \
+} while (0)
+
+
+/* 
+   Reads 'source' for 'length' bytes from unaligned addr.
+
+   Avoids any constant-in-conditional warnings and
+   avoids a test in the generated code (for non-const cases,
+	which are in the majority.)
+   Uses a temp to avoid the test.
+   The decl here should avoid any problem of size in the temp.
+   This code is ENDIAN DEPENDENT
+   The memcpy args are the endian issue.
+*/
+typedef Dwarf_Unsigned BIGGEST_UINT;
+
+#ifdef WORDS_BIGENDIAN
+#define READ_UNALIGNED(dbg,dest,desttype, source, length) \
+    do { \
+      BIGGEST_UINT _ltmp = 0;  \
+      dbg->de_copy_word( (((char *)(&_ltmp)) + sizeof(_ltmp) - length), \
+			source, length) ; \
+      dest = (desttype)_ltmp;  \
+    } while (0)
+
+
+/*
+    This macro sign-extends a variable depending on the length.
+    It fills the bytes between the size of the destination and
+    the length with appropriate padding.
+    This code is ENDIAN DEPENDENT but dependent only
+    on host endianness, not object file endianness.
+    The memcpy args are the issue.
+*/
+#define SIGN_EXTEND(dest, length) \
+    do {if (*(Dwarf_Sbyte *)((char *)&dest + sizeof(dest) - length) < 0) {\
+	memcpy((char *)&dest, "\xff\xff\xff\xff\xff\xff\xff\xff", \
+	    sizeof(dest) - length);  \
+        } \
+     } while (0)
+#else /* LITTLE ENDIAN */
+
+#define READ_UNALIGNED(dbg,dest,desttype, source, length) \
+    do  { \
+      BIGGEST_UINT _ltmp = 0;  \
+      dbg->de_copy_word( (char *)(&_ltmp) , \
+                        source, length) ; \
+      dest = (desttype)_ltmp;  \
+     } while (0)
+
+
+/*
+    This macro sign-extends a variable depending on the length.
+    It fills the bytes between the size of the destination and
+    the length with appropriate padding.
+    This code is ENDIAN DEPENDENT but dependent only
+    on host endianness, not object file endianness.
+    The memcpy args are the issue.
+*/
+#define SIGN_EXTEND(dest, length) \
+    do {if (*(Dwarf_Sbyte *)((char *)&dest + (length-1)) < 0) {\
+        memcpy((char *)&dest+length,    \
+                "\xff\xff\xff\xff\xff\xff\xff\xff", \
+            sizeof(dest) - length); \
+        }  \
+    } while (0)
+
+#endif /* ! LITTLE_ENDIAN */
+
+
+
+/*
+   READ_AREA LENGTH reads the length (the older way
+   of pure 32 or 64 bit
+   or the new proposed dwarfv2.1 64bit-extension way)
+
+   It reads the bits from where rw_src_data_p  points to 
+   and updates the rw_src_data_p to point past what was just read.
+
+   It updates w_length_size and w_exten_size (which
+	are really issues only for the dwarfv2.1  64bit extension).
+
+   r_dbg is just the current dbg pointer.
+   w_target is the output length field.
+   r_targtype is the output type. Always Dwarf_Unsigned so far.
+  
+*/
+/* This one handles the v2.1 64bit extension  
+   and 32bit (and   MIPS fixed 64  bit via the
+	dwarf_init-set r_dbg->de_length_size)..
+   It does not recognize any but the one distingushed value
+   (the only one with defined meaning).
+   It assumes that no CU will have a length
+	0xffffffxx  (32bit length)
+	or
+	0xffffffxx xxxxxxxx (64bit length)
+   which makes possible auto-detection of the extension.
+
+   This depends on knowing that only a non-zero length
+   is legitimate (AFAICT), and for IRIX non-standard -64 
+   dwarf that the first 32 bits of the 64bit offset will be
+   zero (because the compiler could not handle a truly large 
+   value as of Jan 2003 and because no app has that much debug 
+   info anyway (yet)).
+
+   At present not testing for '64bit elf' here as that
+   does not seem necessary (none of the 64bit length seems 
+   appropriate unless it's  ident[EI_CLASS] == ELFCLASS64).
+   Might be a good idea though.
+
+*/
+#   define    READ_AREA_LENGTH(r_dbg,w_target,r_targtype,         \
+	rw_src_data_p,w_length_size,w_exten_size)                 \
+do {    READ_UNALIGNED(r_dbg,w_target,r_targtype,                     \
+                rw_src_data_p, ORIGINAL_DWARF_OFFSET_SIZE);       \
+    if(w_target == DISTINGUISHED_VALUE) {                         \
+	     /* dwarf3 64bit extension */                         \
+             w_length_size  = DISTINGUISHED_VALUE_OFFSET_SIZE;    \
+             rw_src_data_p += ORIGINAL_DWARF_OFFSET_SIZE;         \
+             w_exten_size   = ORIGINAL_DWARF_OFFSET_SIZE;         \
+             READ_UNALIGNED(r_dbg,w_target,r_targtype,            \
+                  rw_src_data_p, DISTINGUISHED_VALUE_OFFSET_SIZE);\
+             rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE;    \
+    } else {                                                      \
+	if(w_target == 0 && r_dbg->de_big_endian_object) {        \
+	     /* IRIX 64 bit, big endian */                        \
+             READ_UNALIGNED(r_dbg,w_target,r_targtype,            \
+                rw_src_data_p, DISTINGUISHED_VALUE_OFFSET_SIZE);  \
+	     w_length_size  = DISTINGUISHED_VALUE_OFFSET_SIZE;    \
+	     rw_src_data_p += DISTINGUISHED_VALUE_OFFSET_SIZE;    \
+	     w_exten_size = 0;                                    \
+	} else {                                                  \
+	     /* standard 32 bit dwarf2/dwarf3 */                  \
+	     w_exten_size   = 0;                                  \
+             w_length_size  = ORIGINAL_DWARF_OFFSET_SIZE;         \
+             rw_src_data_p += w_length_size;                      \
+	}                                                         \
+    } } while(0)
+
+
+
+Dwarf_Unsigned
+_dwarf_decode_u_leb128(Dwarf_Small * leb128,
+		       Dwarf_Word * leb128_length);
+
+Dwarf_Signed
+_dwarf_decode_s_leb128(Dwarf_Small * leb128,
+		       Dwarf_Word * leb128_length);
+
+Dwarf_Unsigned
+_dwarf_get_size_of_val(Dwarf_Debug dbg,
+		       Dwarf_Unsigned form,
+		       Dwarf_Small * val_ptr, int v_length_size);
+
+/*
+    This struct is used to build a hash table for the
+    abbreviation codes for a compile-unit.  
+*/
+struct Dwarf_Hash_Table_s {
+    Dwarf_Abbrev_List at_head;
+    Dwarf_Abbrev_List at_tail;
+};
+
+Dwarf_Abbrev_List
+_dwarf_get_abbrev_for_code(Dwarf_CU_Context cu_context,
+			   Dwarf_Word code);
+
+
+/* return 1 if string ends before 'endptr' else
+** return 0 meaning string is not properly terminated.
+** Presumption is the 'endptr' pts to end of some dwarf section data.
+*/
+int _dwarf_string_valid(void *startptr, void *endptr);
+
+Dwarf_Unsigned _dwarf_length_of_cu_header(Dwarf_Debug,
+					  Dwarf_Unsigned offset);
+Dwarf_Unsigned _dwarf_length_of_cu_header_simple(Dwarf_Debug);
+
+int _dwarf_load_debug_info(Dwarf_Debug dbg, Dwarf_Error *error);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_vars.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,138 @@
+/*
+
+  Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include "dwarf_vars.h"
+#include "dwarf_global.h"
+
+int
+dwarf_get_vars(Dwarf_Debug dbg,
+	       Dwarf_Var ** vars,
+	       Dwarf_Signed * ret_var_count, Dwarf_Error * error)
+{
+    int res;
+
+    res =
+	_dwarf_load_section(dbg,
+			    dbg->de_debug_varnames_index,
+			    &dbg->de_debug_varnames, error);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+
+    return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_varnames, dbg->de_debug_varnames_size, (Dwarf_Global **) vars,	/* type
+																	   punning,
+																	   Dwarf_Type
+																	   is never a
+																	   completed
+																	   type */
+						  ret_var_count,
+						  error,
+						  DW_DLA_VAR_CONTEXT,
+						  DW_DLA_VAR,
+						  DW_DLE_DEBUG_VARNAMES_LENGTH_BAD,
+						  DW_DLE_DEBUG_VARNAMES_VERSION_ERROR);
+}
+
+/* Deallocating fully requires deallocating the list
+   and all entries.  But some internal data is
+   not exposed, so we need a function with internal knowledge.
+*/
+
+void
+dwarf_vars_dealloc(Dwarf_Debug dbg, Dwarf_Var * dwgl,
+		   Dwarf_Signed count)
+{
+    _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl,
+				    count,
+				    DW_DLA_VAR_CONTEXT,
+				    DW_DLA_VAR, DW_DLA_LIST);
+    return;
+}
+
+
+int
+dwarf_varname(Dwarf_Var var_in, char **ret_varname, Dwarf_Error * error)
+{
+    Dwarf_Global var = (Dwarf_Global) var_in;
+
+    if (var == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_VAR_NULL);
+	return (DW_DLV_ERROR);
+    }
+
+    *ret_varname = (char *) (var->gl_name);
+    return DW_DLV_OK;
+}
+
+
+int
+dwarf_var_die_offset(Dwarf_Var var_in,
+		     Dwarf_Off * returned_offset, Dwarf_Error * error)
+{
+    Dwarf_Global var = (Dwarf_Global) var_in;
+
+    return dwarf_global_die_offset(var, returned_offset, error);
+
+}
+
+
+int
+dwarf_var_cu_offset(Dwarf_Var var_in,
+		    Dwarf_Off * returned_offset, Dwarf_Error * error)
+{
+    Dwarf_Global var = (Dwarf_Global) var_in;
+
+    return dwarf_global_cu_offset(var, returned_offset, error);
+}
+
+
+int
+dwarf_var_name_offsets(Dwarf_Var var_in,
+		       char **returned_name,
+		       Dwarf_Off * die_offset,
+		       Dwarf_Off * cu_offset, Dwarf_Error * error)
+{
+    Dwarf_Global var = (Dwarf_Global) var_in;
+
+    return
+	dwarf_global_name_offsets(var,
+				  returned_name, die_offset, cu_offset,
+				  error);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_vars.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,41 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+
+typedef struct Dwarf_Var_Context_s *Dwarf_Var_Context;
+
+/* struct  never completed: see dwarf_global.h */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_weaks.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,140 @@
+/*
+
+  Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "dwarf_incl.h"
+#include <stdio.h>
+#include "dwarf_weaks.h"
+#include "dwarf_global.h"
+
+int
+dwarf_get_weaks(Dwarf_Debug dbg,
+		Dwarf_Weak ** weaks,
+		Dwarf_Signed * ret_weak_count, Dwarf_Error * error)
+{
+    int res;
+
+    res =
+	_dwarf_load_section(dbg,
+			    dbg->de_debug_weaknames_index,
+			    &dbg->de_debug_weaknames, error);
+    if (res != DW_DLV_OK) {
+	return res;
+    }
+
+    return _dwarf_internal_get_pubnames_like_data(dbg, dbg->de_debug_weaknames, dbg->de_debug_weaknames_size, (Dwarf_Global **) weaks,	/* type 
+																	   punning, 
+																	   Dwarf_Type 
+																	   is 
+																	   never 
+																	   a 
+																	   completed 
+																	   type 
+																	 */
+						  ret_weak_count,
+						  error,
+						  DW_DLA_WEAK_CONTEXT,
+						  DW_DLA_WEAK,
+						  DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD,
+						  DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR);
+
+}
+
+/* Deallocating fully requires deallocating the list
+   and all entries.  But some internal data is
+   not exposed, so we need a function with internal knowledge.
+*/
+
+void
+dwarf_weaks_dealloc(Dwarf_Debug dbg, Dwarf_Weak * dwgl,
+		    Dwarf_Signed count)
+{
+    _dwarf_internal_globals_dealloc(dbg, (Dwarf_Global *) dwgl,
+				    count,
+				    DW_DLA_WEAK_CONTEXT,
+				    DW_DLA_WEAK, DW_DLA_LIST);
+    return;
+}
+
+
+
+int
+dwarf_weakname(Dwarf_Weak weak_in, char **ret_name, Dwarf_Error * error)
+{
+    Dwarf_Global weak = (Dwarf_Global) weak_in;
+
+    if (weak == NULL) {
+	_dwarf_error(NULL, error, DW_DLE_WEAK_NULL);
+	return (DW_DLV_ERROR);
+    }
+    *ret_name = (char *) (weak->gl_name);
+    return DW_DLV_OK;
+}
+
+
+int
+dwarf_weak_die_offset(Dwarf_Weak weak_in,
+		      Dwarf_Off * weak_off, Dwarf_Error * error)
+{
+    Dwarf_Global weak = (Dwarf_Global) weak_in;
+
+    return dwarf_global_die_offset(weak, weak_off, error);
+}
+
+
+int
+dwarf_weak_cu_offset(Dwarf_Weak weak_in,
+		     Dwarf_Off * weak_off, Dwarf_Error * error)
+{
+    Dwarf_Global weak = (Dwarf_Global) weak_in;
+
+    return dwarf_global_cu_offset(weak, weak_off, error);
+}
+
+
+int
+dwarf_weak_name_offsets(Dwarf_Weak weak_in,
+			char **weak_name,
+			Dwarf_Off * die_offset,
+			Dwarf_Off * cu_offset, Dwarf_Error * error)
+{
+    Dwarf_Global weak = (Dwarf_Global) weak_in;
+
+    return dwarf_global_name_offsets(weak,
+				     weak_name,
+				     die_offset, cu_offset, error);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_weaks.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,41 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+
+typedef struct Dwarf_Weak_Context_s *Dwarf_Weak_Context;
+
+/* struct  never completed: see dwarf_global.h */
Binary file tools/elf4rom/libs/dwarf-20071209/libdwarf/index.v2.pdf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/install.sh	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5; it is not part of GNU.
+#
+# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+
+instcmd="$mvprog"
+chmodcmd=""
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:  no input file specified"
+	exit 1
+fi
+
+if [ x"$dst" = x ]
+then
+	echo "install:  no destination specified"
+	exit 1
+fi
+
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+if [ -d $dst ]
+then
+	dst="$dst"/`basename $src`
+fi
+
+# Make a temp file name in the proper directory.
+
+dstdir=`dirname $dst`
+dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+$doit $instcmd $src $dsttmp
+
+# and set any options; do chmod last to preserve setuid bits
+
+if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
+if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
+if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
+if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
+
+# Now rename the file to the real destination.
+
+$doit $rmcmd $dst
+$doit $mvcmd $dsttmp $dst
+
+
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,2117 @@
+/*
+
+  Copyright (C) 2000,2001,2002,2005,2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+#ifndef _LIBDWARF_H
+#define _LIBDWARF_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+	libdwarf.h  
+	$Revision: 1.88 $ $Date: 2006/04/18 04:46:07 $
+
+	For libdwarf producers and consumers
+
+	The interface is defined as having 8-byte signed and unsigned
+	values so it can handle 64-or-32bit target on 64-or-32bit host.
+	Addr is the native size: it represents pointers on
+	the host machine (not the target!).
+
+	This contains declarations for types and all producer
+	and consumer functions.
+
+	Function declarations are written on a single line each here
+	so one can use grep  to each declaration in its entirety.
+	The declarations are a little harder to read this way, but...
+
+*/
+
+#ifdef __SGI_FAST_LIBELF
+struct elf_sgi;
+typedef struct elf_sgi* dwarf_elf_handle;
+#else
+struct Elf;
+typedef struct Elf* dwarf_elf_handle;
+#endif
+
+#if (_MIPS_SZLONG == 64)
+/* Special case for MIPS, so -64 (LP64) build gets simple -long-.
+   Non-MIPS LP64 or ILP64 environments should probably ensure
+   _MIPS_SZLONG set to 64 everywhere this header is #included.
+*/
+typedef int             Dwarf_Bool;         /* boolean type */
+typedef unsigned long   Dwarf_Off;          /* 4 or 8 byte file offset */
+typedef unsigned long   Dwarf_Unsigned;     /* 4 or 8 byte unsigned value */
+typedef unsigned short  Dwarf_Half;         /* 2 byte unsigned value */
+typedef unsigned char   Dwarf_Small;        /* 1 byte unsigned value */
+typedef signed   long   Dwarf_Signed;       /* 4 or 8 byte signed value */
+typedef unsigned long   Dwarf_Addr;         /* target memory address */
+#else /* 32-bit */
+/* This is for ILP32, allowing i/o of 64bit dwarf info.
+   Also should be fine for LP64 and ILP64 cases.
+*/
+typedef int                 Dwarf_Bool;     /* boolean type */
+typedef unsigned long long  Dwarf_Off;      /* 8 byte file offset */
+typedef unsigned long long  Dwarf_Unsigned; /* 8 byte unsigned value*/
+typedef unsigned short      Dwarf_Half;     /* 2 byte unsigned value */
+typedef unsigned char       Dwarf_Small;    /* 1 byte unsigned value */
+typedef signed   long long  Dwarf_Signed;   /* 8 byte signed value */
+typedef unsigned long long  Dwarf_Addr;     /* target memory address */
+#endif
+typedef void*		Dwarf_Ptr;          /* host machine pointer */
+
+/* Contains info on an uninterpreted block of data
+*/
+typedef struct {
+        Dwarf_Unsigned  bl_len;         /* length of block */
+        Dwarf_Ptr       bl_data;        /* uninterpreted data */
+	Dwarf_Small     bl_from_loclist; /*non-0 if loclist, else debug_info*/
+	Dwarf_Unsigned  bl_section_offset; /* Section (not CU) offset
+                                        which 'data' comes from. */
+} Dwarf_Block;
+
+
+/* location record
+*/
+typedef struct {
+        Dwarf_Small     lr_atom;        /* location operation */
+        Dwarf_Unsigned  lr_number;      /* operand */
+	Dwarf_Unsigned  lr_number2;     /* for OP_BREGx */
+	Dwarf_Unsigned  lr_offset;      /* offset in locexpr for OP_BRA etc */
+} Dwarf_Loc;
+
+
+/* location description
+*/
+typedef struct {
+        Dwarf_Addr      ld_lopc;        /* beginning of active range */ 
+        Dwarf_Addr      ld_hipc;        /* end of active range */
+        Dwarf_Half      ld_cents;       /* count of location records */
+        Dwarf_Loc*      ld_s;           /* pointer to list of same */
+	Dwarf_Small     ld_from_loclist; 
+				      /* non-0 if loclist, else debug_info*/
+
+	Dwarf_Unsigned  ld_section_offset; /* Section (not CU) offset
+					where loc-expr begins*/
+} Dwarf_Locdesc;
+
+/* Frame description instructions expanded.
+*/
+typedef struct {
+        Dwarf_Small     fp_base_op;
+        Dwarf_Small     fp_extended_op;
+        Dwarf_Half      fp_register;
+
+	/* Value may be signed, depends on op. 
+           Any applicable data_alignment_factor has
+           not been applied, this is the  raw offset. */
+        Dwarf_Unsigned  fp_offset;
+        Dwarf_Off       fp_instr_offset;
+} Dwarf_Frame_Op; /* DWARF2 */
+
+typedef struct {
+        Dwarf_Small     fp_base_op;
+        Dwarf_Small     fp_extended_op;
+        Dwarf_Half      fp_register;
+
+	/* Value may be signed, depends on op. 
+           Any applicable data_alignment_factor has
+           not been applied, this is the  raw offset. */
+        Dwarf_Unsigned  fp_offset_or_block_len; 
+	Dwarf_Small     *fp_expr_block;
+
+        Dwarf_Off       fp_instr_offset;
+} Dwarf_Frame_Op3;  /* DWARF3 and DWARF2 compatible */
+
+/*  ***IMPORTANT NOTE, TARGET DEPENDENCY ****
+   DW_REG_TABLE_SIZE must be at least as large as
+   the number of registers
+   (DW_FRAME_LAST_REG_NUM) as defined in dwarf.h
+   Preferably identical to DW_FRAME_LAST_REG_NUM.
+   Ensure [0-DW_REG_TABLE_SIZE] does not overlap 
+   DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL. 
+   Also ensure DW_FRAME_REG_INITIAL_VALUE is set to what
+   is appropriate to your cpu.
+   For various CPUs  DW_FRAME_UNDEFINED_VAL is correct
+   as the value for DW_FRAME_REG_INITIAL_VALUE.
+
+   For consumer apps, this can be set dynamically: see
+   dwarf_set_frame_rule_table_size();
+ */
+#ifndef DW_REG_TABLE_SIZE
+#define DW_REG_TABLE_SIZE  66
+#endif
+
+/* For MIPS, DW_FRAME_SAME_VAL is the correct default value 
+   for a frame register value. For other CPUS another value
+   may be better, such as DW_FRAME_UNDEFINED_VAL.
+   See dwarf_set_frame_rule_table_size
+*/
+#ifndef DW_FRAME_REG_INITIAL_VALUE
+#define DW_FRAME_REG_INITIAL_VALUE DW_FRAME_SAME_VAL
+#endif
+
+/* Taken as meaning 'undefined value', this is not
+   a column or register number.
+   Only present at libdwarf runtime. Never on disk.
+   DW_FRAME_* Values present on disk are in dwarf.h
+   Ensure this is > DW_REG_TABLE_SIZE.
+*/
+#define DW_FRAME_UNDEFINED_VAL          1034
+
+/* Taken as meaning 'same value' as caller had, not a column
+   or register number
+   Only present at libdwarf runtime. Never on disk.
+   DW_FRAME_* Values present on disk are in dwarf.h
+   Ensure this is > DW_REG_TABLE_SIZE.
+*/
+#define DW_FRAME_SAME_VAL               1035
+
+/* For DWARF3 interfaces, make the CFA a column with no
+   real table number.  This is what should have been done
+   for the DWARF2 interfaces.  This actually works for
+   both DWARF2 and DWARF3, but see the libdwarf documentation
+   on Dwarf_Regtable3 and  dwarf_get_fde_info_for_reg3()
+   and  dwarf_get_fde_info_for_all_regs3()  
+   Do NOT use this with the older dwarf_get_fde_info_for_reg()
+   or dwarf_get_fde_info_for_all_regs() consumer interfaces.
+*/
+#define DW_FRAME_CFA_COL3               1036
+
+/* The following are all needed to evaluate DWARF3 register rules.
+*/
+#define DW_EXPR_OFFSET 0  /* DWARF2 only sees this. */
+#define DW_EXPR_VAL_OFFSET 1
+#define DW_EXPR_EXPRESSION 2
+#define DW_EXPR_VAL_EXPRESSION 3
+
+typedef struct Dwarf_Regtable_Entry_s {
+	/*  For each index i (naming a hardware register with dwarf number
+            i) the following is true and defines the value of that register:
+
+           If dw_regnum is Register DW_FRAME_UNDEFINED_VAL  
+	     it is not DWARF register number but
+		a place holder indicating the register has no defined value.
+           If dw_regnum is Register DW_FRAME_SAME_VAL 
+  	     it  is not DWARF register number but
+		a place holder indicating the register has the same
+                value in the previous frame.
+	   DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL are
+           only present at libdwarf runtime. Never on disk.
+           DW_FRAME_* Values present on disk are in dwarf.h
+
+          Otherwise: the register number is a DWARF register number
+          (see ABI documents for how this translates to hardware/
+           software register numbers in the machine hardware)
+	  and the following applies:
+
+          if dw_value_type == DW_EXPR_OFFSET (the only  possible case for dwarf2):
+	    If dw_offset_relevant is non-zero, then
+	     the value is stored at at the address CFA+N where N is a signed offset. 
+	     Rule: Offset(N)
+            If dw_offset_relevant is zero, then the value of the register
+             is the value of (DWARF) register number dw_regnum.
+             Rule: register(F)
+          Other values of dw_value_type are an error.
+        */
+	Dwarf_Small         dw_offset_relevant;
+
+	/* For DWARF2, always 0 */
+        Dwarf_Small         dw_value_type; 
+
+	Dwarf_Half          dw_regnum;
+
+	/* The data type here should  the larger of Dwarf_Addr
+           and Dwarf_Unsigned and Dwarf_Signed. */
+	Dwarf_Addr          dw_offset;
+} Dwarf_Regtable_Entry;
+
+typedef struct Dwarf_Regtable_s {
+    struct Dwarf_Regtable_Entry_s rules[DW_REG_TABLE_SIZE];
+} Dwarf_Regtable;
+
+/* opaque type. Functional interface shown later. */
+struct Dwarf_Reg_value3_s;
+typedef struct Dwarf_Reg_value3_s Dwarf_Reg_Value3; 
+
+typedef struct Dwarf_Regtable_Entry3_s {
+	/*  For each index i (naming a hardware register with dwarf number
+            i) the following is true and defines the value of that register:
+
+           If dw_regnum is Register DW_FRAME_UNDEFINED_VAL  
+	     it is not DWARF register number but
+		a place holder indicating the register has no defined value.
+           If dw_regnum is Register DW_FRAME_SAME_VAL 
+  	     it  is not DWARF register number but
+		a place holder indicating the register has the same
+                value in the previous frame.
+	   DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL are
+           only present at libdwarf runtime. Never on disk.
+           DW_FRAME_* Values present on disk are in dwarf.h
+
+          Otherwise: the register number is a DWARF register number
+          (see ABI documnets for how this translates to hardware/
+           software register numbers in the machine hardware)
+	  and the following applies:
+
+          if dw_value_type == DW_EXPR_OFFSET (the only  possible case for 
+		dwarf2):
+	    If dw_offset_relevant is non-zero, then
+	     the value is stored at at the address 
+	     CFA+N where N is a signed offset. 
+	     Rule: Offset(N)
+            If dw_offset_relevant is zero, then the value of the register
+             is the value of (DWARF) register number dw_regnum.
+             Rule: register(R)
+          if dw_value_type  == DW_EXPR_VAL_OFFSET
+            the  value of this register is CFA +N where N is a signed offset.
+            Rule: val_offset(N)
+
+          if dw_value_type  == DW_EXPR_EXPRESSION
+	    The value of the register is the value at the address
+            computed by evaluating the DWARF expression E.
+            Rule: expression(E)
+            The expression E byte stream is pointed to by dw_block_ptr.
+            The expression length in bytes is given by
+            dw_offset_or_block_len.
+          if dw_value_type  == DW_EXPR_VAL_EXPRESSION
+	    The value of the register is the value
+            computed by evaluating the DWARF expression E.
+            Rule: val_expression(E)
+            The expression E byte stream is pointed to by dw_block_ptr.
+            The expression length in bytes is given by
+            dw_offset_or_block_len.
+          Other values of dw_value_type are an error.
+        */
+	Dwarf_Small         dw_offset_relevant;
+        Dwarf_Small         dw_value_type; 
+	Dwarf_Half          dw_regnum;
+	Dwarf_Unsigned      dw_offset_or_block_len;
+	Dwarf_Ptr           dw_block_ptr;
+
+}Dwarf_Regtable_Entry3;
+
+/* For the DWARF3 version, moved the DW_FRAME_CFA_COL
+   out of the array and into its own struct.  
+   Having it part of the array is not very easy to work
+   with from a portability point of view: changing
+   the number for every architecture is a pain (if one fails
+   to set it correctly a register rule gets clobbered when
+   setting CFA).
+   With MIPS it just happened to be easy to use DW_FRAME_CFA_COL.
+
+   rt3_rules and rt3_reg_table_size must be filled in 
+    before calling libdwarf.
+    Filled in with a pointer to an array (pointer and
+    array  set up by the calling application) of rt3_reg_table_size 
+    Dwarf_Regtable_Entry3_s structs.   
+    libdwarf does not allocate or deallocate space for the
+    rules, you must do so.   libdwarf will initialize the
+    contents rules array, you do not need to do so (though
+    if you choose to initialize the array somehow that is ok:
+    libdwarf will overwrite your initializations with its own).
+
+*/
+typedef struct Dwarf_Regtable3_s {
+    struct Dwarf_Regtable_Entry3_s   rt3_cfa_rule;
+
+    Dwarf_Half                       rt3_reg_table_size;
+    struct Dwarf_Regtable_Entry3_s * rt3_rules;
+} Dwarf_Regtable3;
+
+
+/* Use for DW_EPXR_STANDARD., DW_EXPR_VAL_OFFSET. 
+   Returns DW_DLV_OK if the value is available.
+   If DW_DLV_OK returns the regnum and offset thru the pointers
+   (which the consumer must use appropriately). 
+*/
+int dwarf_frame_get_reg_register(struct Dwarf_Regtable_Entry3_s *reg_in,
+	Dwarf_Small *offset_relevant,
+	Dwarf_Half *regnum_out,
+	Dwarf_Signed *offset_out);
+
+/* Use for DW_EXPR_EXPRESSION, DW_EXPR_VAL_EXPRESSION.
+   Returns DW_DLV_OK if the value is available.
+   The caller must pass in the address of a valid
+   Dwarf_Block (the caller need not initialize it).
+*/
+int dwarf_frame_get_reg_expression(struct Dwarf_Regtable_Entry3_s *reg_in,
+	Dwarf_Block *block_out);
+
+
+/* for DW_DLC_SYMBOLIC_RELOCATIONS output to caller 
+   v2, adding drd_length: some relocations are 4 and
+   some 8 bytes (pointers are 8, section offsets 4) in
+   some dwarf environments. (MIPS relocations are all one
+   size in any given ABI.) Changing drd_type to an unsigned char
+   to keep struct size down.
+*/
+enum Dwarf_Rel_Type {
+		dwarf_drt_none, /* should not get to caller */
+                dwarf_drt_data_reloc, /* simple normal relocation */
+                dwarf_drt_segment_rel, /* special reloc, exceptions*/
+                dwarf_drt_first_of_length_pair,/* this and drt_second 
+				for .word end - begin
+			 	case */
+                dwarf_drt_second_of_length_pair
+};
+
+typedef struct Dwarf_P_Marker_s * Dwarf_P_Marker;
+struct Dwarf_P_Marker_s {
+    Dwarf_Unsigned ma_marker;
+    Dwarf_Unsigned ma_offset;
+};
+
+typedef struct Dwarf_Relocation_Data_s  * Dwarf_Relocation_Data;
+struct Dwarf_Relocation_Data_s {
+        unsigned char drd_type; /* cast to/from Dwarf_Rel_Type
+					  to keep size small in struct */
+	unsigned char drd_length; /* length in bytes
+			         of data being relocated. 4 for 32bit.
+				 8 for 64bit data */
+        Dwarf_Unsigned       drd_offset; /* where the data to reloc is */
+        Dwarf_Unsigned       drd_symbol_index;
+};
+
+typedef struct Dwarf_P_String_Attr_s  * Dwarf_P_String_Attr;
+struct Dwarf_P_String_Attr_s {
+    Dwarf_Unsigned        sa_offset;  /* Offset of string attribute data */
+    Dwarf_Unsigned        sa_nbytes;  
+};
+    
+
+/* Opaque types for Consumer Library. */
+typedef struct Dwarf_Debug_s*      Dwarf_Debug;
+typedef struct Dwarf_Die_s*        Dwarf_Die;
+typedef struct Dwarf_Line_s*       Dwarf_Line;
+typedef struct Dwarf_Global_s*     Dwarf_Global;
+typedef struct Dwarf_Func_s*       Dwarf_Func;
+typedef struct Dwarf_Type_s*       Dwarf_Type;
+typedef struct Dwarf_Var_s*        Dwarf_Var;
+typedef struct Dwarf_Weak_s*       Dwarf_Weak;
+typedef struct Dwarf_Error_s*      Dwarf_Error;
+typedef struct Dwarf_Attribute_s*  Dwarf_Attribute;
+typedef struct Dwarf_Abbrev_s*	   Dwarf_Abbrev;
+typedef struct Dwarf_Fde_s*  	   Dwarf_Fde;
+typedef struct Dwarf_Cie_s*  	   Dwarf_Cie;
+typedef struct Dwarf_Arange_s*	   Dwarf_Arange;
+
+/* Opaque types for Producer Library. */
+typedef struct Dwarf_P_Debug_s*	   	Dwarf_P_Debug;
+typedef struct Dwarf_P_Die_s*	   	Dwarf_P_Die;
+typedef struct Dwarf_P_Attribute_s*	Dwarf_P_Attribute;
+typedef struct Dwarf_P_Fde_s*		Dwarf_P_Fde;
+typedef struct Dwarf_P_Expr_s*		Dwarf_P_Expr;
+typedef Dwarf_Unsigned 		   	Dwarf_Tag;
+
+
+/* error handler function
+*/
+typedef void  (*Dwarf_Handler)(Dwarf_Error /*error*/, Dwarf_Ptr /*errarg*/); 
+
+
+/* 
+    Dwarf_dealloc() alloc_type arguments.
+    Argument points to:
+*/
+#define DW_DLA_STRING      	0x01     /* char* */
+#define DW_DLA_LOC         	0x02     /* Dwarf_Loc */
+#define DW_DLA_LOCDESC     	0x03     /* Dwarf_Locdesc */
+#define DW_DLA_ELLIST      	0x04     /* Dwarf_Ellist (not used)*/
+#define DW_DLA_BOUNDS      	0x05     /* Dwarf_Bounds (not used) */
+#define DW_DLA_BLOCK       	0x06     /* Dwarf_Block */
+#define DW_DLA_DEBUG       	0x07     /* Dwarf_Debug */
+#define DW_DLA_DIE         	0x08     /* Dwarf_Die */
+#define DW_DLA_LINE        	0x09     /* Dwarf_Line */
+#define DW_DLA_ATTR        	0x0a     /* Dwarf_Attribute */
+#define DW_DLA_TYPE        	0x0b     /* Dwarf_Type  (not used) */
+#define DW_DLA_SUBSCR      	0x0c     /* Dwarf_Subscr (not used) */
+#define DW_DLA_GLOBAL      	0x0d     /* Dwarf_Global */
+#define DW_DLA_ERROR       	0x0e     /* Dwarf_Error */
+#define DW_DLA_LIST        	0x0f     /* a list */
+#define DW_DLA_LINEBUF     	0x10     /* Dwarf_Line* (not used) */
+#define DW_DLA_ARANGE      	0x11     /* Dwarf_Arange */
+#define DW_DLA_ABBREV		0x12 	 /* Dwarf_Abbrev */
+#define DW_DLA_FRAME_OP		0x13 	 /* Dwarf_Frame_Op */
+#define DW_DLA_CIE		0x14	 /* Dwarf_Cie */
+#define DW_DLA_FDE		0x15	 /* Dwarf_Fde */
+#define DW_DLA_LOC_BLOCK	0x16	 /* Dwarf_Loc Block (not used) */
+#define DW_DLA_FRAME_BLOCK	0x17	 /* Dwarf_Frame Block (not used) */
+#define DW_DLA_FUNC		0x18	 /* Dwarf_Func */
+#define DW_DLA_TYPENAME		0x19	 /* Dwarf_Type */
+#define DW_DLA_VAR		0x1a	 /* Dwarf_Var */
+#define DW_DLA_WEAK		0x1b	 /* Dwarf_Weak */
+#define DW_DLA_ADDR		0x1c	 /* Dwarf_Addr sized entries */
+
+/* The augmenter string for CIE */
+#define DW_CIE_AUGMENTER_STRING_V0              "z"
+
+/* dwarf_init() access arguments
+*/
+#define DW_DLC_READ        0        /* read only access */
+#define DW_DLC_WRITE       1        /* write only access */
+#define DW_DLC_RDWR        2        /* read/write access NOT SUPPORTED*/
+
+/* dwarf_init() access flag modifiers
+*/
+#define DW_DLC_SIZE_64     0x40000000 /* 32-bit target */
+#define DW_DLC_SIZE_32     0x20000000 /* 64-bit target */
+
+/* dwarf_init() access flag modifiers
+*/
+#define DW_DLC_ISA_MIPS             0x00000000 /* MIPS target */
+#define DW_DLC_ISA_IA64             0x01000000 /* IA64 target */
+#define DW_DLC_STREAM_RELOCATIONS   0x02000000 /* old style binary relocs */
+#define DW_DLC_SYMBOLIC_RELOCATIONS 0x04000000 /* usable with assem output */
+#define DW_DLC_TARGET_BIGENDIAN     0x08000000 /* big    endian target */
+#define DW_DLC_TARGET_LITTLEENDIAN  0x00100000 /* little endian target */
+
+#if 0
+  /*
+   The libdwarf producer interfaces jumble these two semantics together in
+   confusing ways.  We *should* have flags like these...
+   But changing the code means a lot of diffs.  So for now,
+   we leave things as they are 
+  */
+  #define DW_DLC_SUN_OFFSET32	    0x00010000 /* use 32-bit sec offsets */
+  #define DW_DLC_SUN_OFFSET64	    0x00020000 /* use 64-bit sec offsets */
+  #define DW_DLC_SUN_POINTER32	    0x00040000 /* use 4 for address_size */
+  #define DW_DLC_SUN_POINTER64	    0x00080000 /* use 8 for address_size */
+#endif
+
+/* dwarf_pcline() slide arguments
+*/
+#define DW_DLS_BACKWARD   -1       /* slide backward to find line */
+#define DW_DLS_NOSLIDE     0       /* match exactly without sliding */ 
+#define DW_DLS_FORWARD     1       /* slide forward to find line */
+
+/* libdwarf error numbers
+*/
+#define DW_DLE_NE          0     /* no error */ 
+#define DW_DLE_VMM         1     /* dwarf format/library version mismatch */
+#define DW_DLE_MAP         2     /* memory map failure */
+#define DW_DLE_LEE         3     /* libelf error */
+#define DW_DLE_NDS         4     /* no debug section */
+#define DW_DLE_NLS         5     /* no line section */
+#define DW_DLE_ID          6     /* invalid descriptor for query */
+#define DW_DLE_IOF         7     /* I/O failure */
+#define DW_DLE_MAF         8     /* memory allocation failure */
+#define DW_DLE_IA          9     /* invalid argument */ 
+#define DW_DLE_MDE         10     /* mangled debugging entry */
+#define DW_DLE_MLE         11     /* mangled line number entry */
+#define DW_DLE_FNO         12     /* file not open */
+#define DW_DLE_FNR         13     /* file not a regular file */
+#define DW_DLE_FWA         14     /* file open with wrong access */
+#define DW_DLE_NOB         15     /* not an object file */
+#define DW_DLE_MOF         16     /* mangled object file header */
+#define DW_DLE_EOLL        17     /* end of location list entries */
+#define DW_DLE_NOLL        18     /* no location list section */
+#define DW_DLE_BADOFF      19     /* Invalid offset */
+#define DW_DLE_EOS         20     /* end of section  */
+#define DW_DLE_ATRUNC      21     /* abbreviations section appears truncated*/
+#define DW_DLE_BADBITC     22     /* Address size passed to dwarf bad*/
+				    /* It is not an allowed size (64 or 32) */
+    /* Error codes defined by the current Libdwarf Implementation. */
+#define DW_DLE_DBG_ALLOC                        23
+#define DW_DLE_FSTAT_ERROR                      24
+#define DW_DLE_FSTAT_MODE_ERROR                 25
+#define DW_DLE_INIT_ACCESS_WRONG                26
+#define DW_DLE_ELF_BEGIN_ERROR                  27
+#define DW_DLE_ELF_GETEHDR_ERROR                28
+#define DW_DLE_ELF_GETSHDR_ERROR                29
+#define DW_DLE_ELF_STRPTR_ERROR                 30
+#define DW_DLE_DEBUG_INFO_DUPLICATE             31
+#define DW_DLE_DEBUG_INFO_NULL                  32
+#define DW_DLE_DEBUG_ABBREV_DUPLICATE           33
+#define DW_DLE_DEBUG_ABBREV_NULL                34
+#define DW_DLE_DEBUG_ARANGES_DUPLICATE          35
+#define DW_DLE_DEBUG_ARANGES_NULL               36
+#define DW_DLE_DEBUG_LINE_DUPLICATE             37
+#define DW_DLE_DEBUG_LINE_NULL                  38
+#define DW_DLE_DEBUG_LOC_DUPLICATE              39
+#define DW_DLE_DEBUG_LOC_NULL                   40
+#define DW_DLE_DEBUG_MACINFO_DUPLICATE          41
+#define DW_DLE_DEBUG_MACINFO_NULL               42
+#define DW_DLE_DEBUG_PUBNAMES_DUPLICATE         43
+#define DW_DLE_DEBUG_PUBNAMES_NULL              44
+#define DW_DLE_DEBUG_STR_DUPLICATE              45
+#define DW_DLE_DEBUG_STR_NULL                   46
+#define DW_DLE_CU_LENGTH_ERROR                  47
+#define DW_DLE_VERSION_STAMP_ERROR              48
+#define DW_DLE_ABBREV_OFFSET_ERROR              49
+#define DW_DLE_ADDRESS_SIZE_ERROR               50
+#define DW_DLE_DEBUG_INFO_PTR_NULL              51
+#define DW_DLE_DIE_NULL                         52
+#define DW_DLE_STRING_OFFSET_BAD                53
+#define DW_DLE_DEBUG_LINE_LENGTH_BAD            54
+#define DW_DLE_LINE_PROLOG_LENGTH_BAD           55
+#define DW_DLE_LINE_NUM_OPERANDS_BAD            56
+#define DW_DLE_LINE_SET_ADDR_ERROR              57
+#define DW_DLE_LINE_EXT_OPCODE_BAD              58
+#define DW_DLE_DWARF_LINE_NULL                  59
+#define DW_DLE_INCL_DIR_NUM_BAD                 60
+#define DW_DLE_LINE_FILE_NUM_BAD                61
+#define DW_DLE_ALLOC_FAIL                       62
+#define DW_DLE_NO_CALLBACK_FUNC		    	63
+#define DW_DLE_SECT_ALLOC		    	64
+#define DW_DLE_FILE_ENTRY_ALLOC		    	65
+#define DW_DLE_LINE_ALLOC		    	66
+#define DW_DLE_FPGM_ALLOC		    	67
+#define DW_DLE_INCDIR_ALLOC		    	68
+#define DW_DLE_STRING_ALLOC		    	69
+#define DW_DLE_CHUNK_ALLOC		    	70
+#define DW_DLE_BYTEOFF_ERR		    	71
+#define	DW_DLE_CIE_ALLOC		    	72
+#define DW_DLE_FDE_ALLOC		    	73
+#define DW_DLE_REGNO_OVFL		    	74
+#define DW_DLE_CIE_OFFS_ALLOC		    	75
+#define DW_DLE_WRONG_ADDRESS		    	76
+#define DW_DLE_EXTRA_NEIGHBORS		    	77
+#define	DW_DLE_WRONG_TAG		    	78
+#define DW_DLE_DIE_ALLOC		    	79
+#define DW_DLE_PARENT_EXISTS		    	80
+#define DW_DLE_DBG_NULL                         81
+#define DW_DLE_DEBUGLINE_ERROR		    	82
+#define DW_DLE_DEBUGFRAME_ERROR		    	83
+#define DW_DLE_DEBUGINFO_ERROR		    	84
+#define DW_DLE_ATTR_ALLOC		    	85
+#define DW_DLE_ABBREV_ALLOC		    	86
+#define DW_DLE_OFFSET_UFLW		    	87
+#define DW_DLE_ELF_SECT_ERR		    	88
+#define DW_DLE_DEBUG_FRAME_LENGTH_BAD	    	89
+#define DW_DLE_FRAME_VERSION_BAD	    	90
+#define DW_DLE_CIE_RET_ADDR_REG_ERROR	    	91
+#define DW_DLE_FDE_NULL			    	92
+#define DW_DLE_FDE_DBG_NULL		    	93
+#define DW_DLE_CIE_NULL			    	94
+#define DW_DLE_CIE_DBG_NULL		    	95
+#define DW_DLE_FRAME_TABLE_COL_BAD	    	96
+#define DW_DLE_PC_NOT_IN_FDE_RANGE	    	97
+#define DW_DLE_CIE_INSTR_EXEC_ERROR	    	98
+#define DW_DLE_FRAME_INSTR_EXEC_ERROR	    	99
+#define DW_DLE_FDE_PTR_NULL		    	100
+#define DW_DLE_RET_OP_LIST_NULL		    	101
+#define DW_DLE_LINE_CONTEXT_NULL	    	102
+#define DW_DLE_DBG_NO_CU_CONTEXT	    	103
+#define DW_DLE_DIE_NO_CU_CONTEXT	    	104
+#define DW_DLE_FIRST_DIE_NOT_CU		    	105
+#define DW_DLE_NEXT_DIE_PTR_NULL	    	106
+#define DW_DLE_DEBUG_FRAME_DUPLICATE	    	107
+#define DW_DLE_DEBUG_FRAME_NULL		    	108
+#define DW_DLE_ABBREV_DECODE_ERROR	    	109
+#define DW_DLE_DWARF_ABBREV_NULL		110
+#define DW_DLE_ATTR_NULL		    	111
+#define DW_DLE_DIE_BAD			    	112
+#define DW_DLE_DIE_ABBREV_BAD		    	113
+#define DW_DLE_ATTR_FORM_BAD		    	114
+#define DW_DLE_ATTR_NO_CU_CONTEXT	    	115
+#define DW_DLE_ATTR_FORM_SIZE_BAD	    	116
+#define DW_DLE_ATTR_DBG_NULL		    	117
+#define DW_DLE_BAD_REF_FORM		    	118
+#define DW_DLE_ATTR_FORM_OFFSET_BAD	    	119
+#define DW_DLE_LINE_OFFSET_BAD		    	120
+#define DW_DLE_DEBUG_STR_OFFSET_BAD	    	121
+#define DW_DLE_STRING_PTR_NULL		    	122
+#define DW_DLE_PUBNAMES_VERSION_ERROR	    	123
+#define DW_DLE_PUBNAMES_LENGTH_BAD	    	124
+#define DW_DLE_GLOBAL_NULL		    	125
+#define DW_DLE_GLOBAL_CONTEXT_NULL	    	126
+#define DW_DLE_DIR_INDEX_BAD		    	127
+#define DW_DLE_LOC_EXPR_BAD		    	128
+#define DW_DLE_DIE_LOC_EXPR_BAD		    	129
+#define DW_DLE_ADDR_ALLOC		    	130
+#define DW_DLE_OFFSET_BAD		    	131
+#define DW_DLE_MAKE_CU_CONTEXT_FAIL	    	132
+#define DW_DLE_REL_ALLOC		    	133
+#define DW_DLE_ARANGE_OFFSET_BAD	    	134
+#define DW_DLE_SEGMENT_SIZE_BAD		    	135
+#define DW_DLE_ARANGE_LENGTH_BAD	    	136
+#define DW_DLE_ARANGE_DECODE_ERROR	    	137
+#define DW_DLE_ARANGES_NULL		    	138
+#define DW_DLE_ARANGE_NULL		    	139
+#define DW_DLE_NO_FILE_NAME		    	140
+#define DW_DLE_NO_COMP_DIR		    	141
+#define DW_DLE_CU_ADDRESS_SIZE_BAD	    	142
+#define DW_DLE_INPUT_ATTR_BAD		    	143
+#define DW_DLE_EXPR_NULL		    	144
+#define DW_DLE_BAD_EXPR_OPCODE		    	145
+#define DW_DLE_EXPR_LENGTH_BAD		    	146
+#define DW_DLE_MULTIPLE_RELOC_IN_EXPR	    	147
+#define DW_DLE_ELF_GETIDENT_ERROR	    	148
+#define DW_DLE_NO_AT_MIPS_FDE		    	149
+#define DW_DLE_NO_CIE_FOR_FDE		    	150
+#define DW_DLE_DIE_ABBREV_LIST_NULL	    	151
+#define DW_DLE_DEBUG_FUNCNAMES_DUPLICATE    	152
+#define DW_DLE_DEBUG_FUNCNAMES_NULL	    	153
+#define DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR    154
+#define DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD       155
+#define DW_DLE_FUNC_NULL		    	156
+#define DW_DLE_FUNC_CONTEXT_NULL	    	157
+#define DW_DLE_DEBUG_TYPENAMES_DUPLICATE    	158
+#define DW_DLE_DEBUG_TYPENAMES_NULL	    	159
+#define DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR    160
+#define DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD       161
+#define DW_DLE_TYPE_NULL		    	162
+#define DW_DLE_TYPE_CONTEXT_NULL	    	163
+#define DW_DLE_DEBUG_VARNAMES_DUPLICATE	    	164
+#define DW_DLE_DEBUG_VARNAMES_NULL	    	165
+#define DW_DLE_DEBUG_VARNAMES_VERSION_ERROR     166
+#define DW_DLE_DEBUG_VARNAMES_LENGTH_BAD        167
+#define DW_DLE_VAR_NULL			    	168
+#define DW_DLE_VAR_CONTEXT_NULL		    	169
+#define DW_DLE_DEBUG_WEAKNAMES_DUPLICATE    	170
+#define DW_DLE_DEBUG_WEAKNAMES_NULL	    	171
+#define DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR    172
+#define DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD       173
+#define DW_DLE_WEAK_NULL		    	174
+#define DW_DLE_WEAK_CONTEXT_NULL	    	175
+#define DW_DLE_LOCDESC_COUNT_WRONG              176
+#define DW_DLE_MACINFO_STRING_NULL              177
+#define DW_DLE_MACINFO_STRING_EMPTY             178
+#define DW_DLE_MACINFO_INTERNAL_ERROR_SPACE     179
+#define DW_DLE_MACINFO_MALLOC_FAIL              180
+#define DW_DLE_DEBUGMACINFO_ERROR		181
+#define DW_DLE_DEBUG_MACRO_LENGTH_BAD		182
+#define DW_DLE_DEBUG_MACRO_MAX_BAD		183
+#define DW_DLE_DEBUG_MACRO_INTERNAL_ERR		184
+#define DW_DLE_DEBUG_MACRO_MALLOC_SPACE	        185
+#define DW_DLE_DEBUG_MACRO_INCONSISTENT	        186
+#define DW_DLE_DF_NO_CIE_AUGMENTATION          	187
+#define DW_DLE_DF_REG_NUM_TOO_HIGH  		188 
+#define DW_DLE_DF_MAKE_INSTR_NO_INIT          	189 
+#define DW_DLE_DF_NEW_LOC_LESS_OLD_LOC         	190
+#define DW_DLE_DF_POP_EMPTY_STACK              	191
+#define DW_DLE_DF_ALLOC_FAIL                   	192
+#define DW_DLE_DF_FRAME_DECODING_ERROR         	193
+#define DW_DLE_DEBUG_LOC_SECTION_SHORT         	194
+#define DW_DLE_FRAME_AUGMENTATION_UNKNOWN       195
+#define DW_DLA_PUBTYPE_CONTEXT                  196
+#define DW_DLE_DEBUG_PUBTYPES_LENGTH_BAD        197
+#define DW_DLE_DEBUG_PUBTYPES_VERSION_ERROR     198
+#define DW_DLE_DEBUG_PUBTYPES_DUPLICATE         199
+#define DW_DLE_FRAME_CIE_DECODE_ERROR           200
+#define DW_DLE_FRAME_REGISTER_UNREPRESENTABLE   201
+#define DW_DLE_FRAME_REGISTER_COUNT_MISMATCH    202
+#define DW_DLE_LINK_LOOP                        203
+
+
+
+    /* DW_DLE_LAST MUST EQUAL LAST ERROR NUMBER */
+#define DW_DLE_LAST        			203
+#define DW_DLE_LO_USER     0x10000
+
+        /* taken as meaning 'undefined value', this is not
+           a column or register number.
+           Only present at libdwarf runtime. Never on disk.
+	   DW_FRAME_* Values present on disk are in dwarf.h
+        */
+#define DW_FRAME_UNDEFINED_VAL          1034
+
+        /* taken as meaning 'same value' as caller had, not a column
+           or register number
+           Only present at libdwarf runtime. Never on disk.
+	   DW_FRAME_* Values present on disk are in dwarf.h
+        */
+#define DW_FRAME_SAME_VAL               1035
+
+
+
+/* error return values  
+*/
+#define DW_DLV_BADADDR     (~(Dwarf_Addr)0)   
+	/* for functions returning target address */
+
+#define DW_DLV_NOCOUNT     ((Dwarf_Signed)-1) 
+	/* for functions returning count */
+
+#define DW_DLV_BADOFFSET   (~(Dwarf_Off)0)    
+	/* for functions returning offset */
+
+/* standard return values for functions */
+#define DW_DLV_NO_ENTRY -1
+#define DW_DLV_OK        0
+#define DW_DLV_ERROR     1
+
+/* Special values for offset_into_exception_table field of dwarf fde's. */
+/* The following value indicates that there is no Exception table offset
+   associated with a dwarf frame. */
+#define DW_DLX_NO_EH_OFFSET  	   (-1LL)
+/* The following value indicates that the producer was unable to analyse the
+   source file to generate Exception tables for this function. */
+#define DW_DLX_EH_OFFSET_UNAVAILABLE  (-2LL)
+
+
+/*===========================================================================*/
+/*  Dwarf consumer interface initialization and termination operations */
+
+/* non-elf initialization */
+int dwarf_init(int 	/*fd*/, 
+    Dwarf_Unsigned 	/*access*/, 
+    Dwarf_Handler 	/*errhand*/, 
+    Dwarf_Ptr 		/*errarg*/, 
+    Dwarf_Debug      *  /*dbg*/,
+    Dwarf_Error* 	/*error*/);
+
+/* elf intialization */
+int dwarf_elf_init(dwarf_elf_handle /*elf*/,
+    Dwarf_Unsigned 	/*access*/, 
+    Dwarf_Handler 	/*errhand*/, 
+    Dwarf_Ptr 		/*errarg*/, 
+    Dwarf_Debug      *  /*dbg*/,
+    Dwarf_Error* 	/*error*/);
+
+/* Undocumented function for memory allocator. */
+void dwarf_print_memory_stats(Dwarf_Debug  /*dbg*/);
+
+
+int dwarf_get_elf(Dwarf_Debug /*dbg*/,
+    dwarf_elf_handle*   /*return_elfptr*/,
+    Dwarf_Error*	/*error*/);
+
+int dwarf_finish(Dwarf_Debug /*dbg*/, Dwarf_Error* /*error*/);
+
+/* die traversal operations */
+int dwarf_next_cu_header(Dwarf_Debug /*dbg*/, 
+    Dwarf_Unsigned* 	/*cu_header_length*/, 
+    Dwarf_Half*     	/*version_stamp*/, 
+    Dwarf_Off*  	/*abbrev_offset*/, 
+    Dwarf_Half* 	/*address_size*/, 
+    Dwarf_Unsigned*     /*next_cu_header_offset*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_siblingof(Dwarf_Debug /*dbg*/, 
+    Dwarf_Die 		/*die*/, 
+    Dwarf_Die*          /*return_siblingdie*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_child(Dwarf_Die /*die*/, 
+    Dwarf_Die*          /*return_childdie*/,
+    Dwarf_Error* 	/*error*/);
+
+/* finding die given offset */
+int dwarf_offdie(Dwarf_Debug /*dbg*/, 
+    Dwarf_Off 		/*offset*/, 
+    Dwarf_Die*          /*return_die*/,
+    Dwarf_Error* 	/*error*/);
+
+/* higher level functions (Unimplemented) */
+int dwarf_pcfile(Dwarf_Debug /*dbg*/, 
+    Dwarf_Addr 		/*pc*/, 
+    Dwarf_Die*          /*return_die*/,
+    Dwarf_Error* 	/*error*/);
+
+/* Unimplemented */
+int dwarf_pcsubr(Dwarf_Debug /*dbg*/, 
+    Dwarf_Addr 		/*pc*/, 
+    Dwarf_Die*          /*return_die*/,
+    Dwarf_Error* 	/*error*/);
+
+/* Unimplemented */
+int dwarf_pcscope(Dwarf_Debug /*dbg*/, 
+    Dwarf_Addr 		/*pc*/, 
+    Dwarf_Die*          /*return_die*/,
+    Dwarf_Error* 	/*error*/);
+
+/* operations on DIEs */
+int dwarf_tag(Dwarf_Die /*die*/, 
+    Dwarf_Half*	        /*return_tag*/,
+    Dwarf_Error* 	/*error*/);
+
+/* utility? */
+int dwarf_dieoffset(Dwarf_Die /*die*/, 
+    Dwarf_Off*          /*return_offset*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_die_CU_offset(Dwarf_Die /*die*/,
+    Dwarf_Off*          /*return_offset*/,
+    Dwarf_Error*	/*error*/);
+
+int dwarf_attr (Dwarf_Die /*die*/, 
+    Dwarf_Half 		/*attr*/, 
+    Dwarf_Attribute *   /*returned_attr*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_diename(Dwarf_Die /*die*/, 
+    char   **           /*diename*/,
+    Dwarf_Error* 	/*error*/);
+
+/* convenience functions, alternative to using dwarf_attrlist() */
+int dwarf_hasattr(Dwarf_Die /*die*/, 
+    Dwarf_Half 		/*attr*/, 
+    Dwarf_Bool     *    /*returned_bool*/,
+    Dwarf_Error* 	/*error*/);
+
+/* dwarf_loclist_n preferred over dwarf_loclist */
+int dwarf_loclist_n(Dwarf_Attribute /*attr*/,  
+    Dwarf_Locdesc***	/*llbuf*/, 
+    Dwarf_Signed *      /*locCount*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_loclist(Dwarf_Attribute /*attr*/,  /* inflexible! */
+    Dwarf_Locdesc** 	/*llbuf*/, 
+    Dwarf_Signed *      /*locCount*/,
+    Dwarf_Error* 	/*error*/);
+
+/* Extracts a dwarf expression from an expression byte stream.
+   Useful to get expressions from DW_CFA_def_cfa_expression
+   DW_CFA_expression DW_CFA_val_expression expression bytes.
+*/
+int 
+dwarf_loclist_from_expr(Dwarf_Debug dbg,
+              Dwarf_Ptr expression_in,
+              Dwarf_Unsigned expression_length,
+              Dwarf_Locdesc ** llbuf,
+              Dwarf_Signed * listlen, Dwarf_Error * error);
+
+/* Unimplemented */
+int dwarf_stringlen(Dwarf_Die /*die*/, 
+    Dwarf_Locdesc **    /*returned_locdesc*/,
+    Dwarf_Error* 	/*error*/);
+
+/* Unimplemented */
+int dwarf_subscrcnt(Dwarf_Die /*die*/, 
+    Dwarf_Signed *      /*returned_count*/,
+    Dwarf_Error* 	/*error*/);
+
+/* Unimplemented */
+int dwarf_nthsubscr(Dwarf_Die /*die*/, 
+    Dwarf_Unsigned 	/*ssndx*/, 
+    Dwarf_Die *         /*returned_die*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_lowpc(Dwarf_Die /*die*/, 
+    Dwarf_Addr  *       /*returned_addr*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_highpc(Dwarf_Die /*die*/, 
+    Dwarf_Addr  *       /*returned_addr*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_bytesize(Dwarf_Die /*die*/, 
+    Dwarf_Unsigned *    /*returned_size*/,
+    Dwarf_Error* 	/*error*/);
+
+/* Unimplemented */
+int dwarf_isbitfield(Dwarf_Die /*die*/, 
+    Dwarf_Bool  *       /*returned_bool*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_bitsize(Dwarf_Die /*die*/, 
+    Dwarf_Unsigned *    /*returned_size*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_bitoffset(Dwarf_Die /*die*/, 
+    Dwarf_Unsigned *    /*returned_offset*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_srclang(Dwarf_Die /*die*/, 
+    Dwarf_Unsigned *    /*returned_lang*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_arrayorder(Dwarf_Die /*die*/, 
+    Dwarf_Unsigned *    /*returned_order*/,
+    Dwarf_Error* 	/*error*/);
+
+/* end of convenience function list */
+
+/* this is the main interface to attributes of a DIE */
+int dwarf_attrlist(Dwarf_Die /*die*/, 
+    Dwarf_Attribute** 	/*attrbuf*/, 
+    Dwarf_Signed   *    /*attrcount*/,
+    Dwarf_Error* 	/*error*/);
+
+/* query operations for attributes */
+int dwarf_hasform(Dwarf_Attribute /*attr*/, 
+    Dwarf_Half 		/*form*/, 
+    Dwarf_Bool *        /*returned_bool*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_whatform(Dwarf_Attribute /*attr*/, 
+    Dwarf_Half *        /*returned_form*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_whatform_direct(Dwarf_Attribute /*attr*/, 
+    Dwarf_Half *        /*returned_form*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_whatattr(Dwarf_Attribute /*attr*/, 
+    Dwarf_Half *        /*returned_attr_num*/,
+    Dwarf_Error* 	/*error*/);
+
+/* 
+    The following are concerned with the Primary Interface: getting
+    the actual data values. One function per 'kind' of FORM.
+*/
+	/*dwarf_formref returns, thru return_offset, a CU-relative offset
+	** and does not allow DW_FORM_ref_addr*/
+int dwarf_formref(Dwarf_Attribute /*attr*/, 
+    Dwarf_Off*          /*return_offset*/,
+    Dwarf_Error* 	/*error*/);
+	/*dwarf_global_formref returns, thru return_offset, 
+	 a debug_info-relative offset and does allow all reference forms*/
+int dwarf_global_formref(Dwarf_Attribute /*attr*/, 
+    Dwarf_Off*          /*return_offset*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_formaddr(Dwarf_Attribute /*attr*/, 
+    Dwarf_Addr   *      /*returned_addr*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_formflag(Dwarf_Attribute /*attr*/,
+    Dwarf_Bool *        /*returned_bool*/,
+    Dwarf_Error*	/*error*/);
+
+int dwarf_formudata(Dwarf_Attribute /*attr*/, 
+    Dwarf_Unsigned  *   /*returned_val*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_formsdata(Dwarf_Attribute 	/*attr*/, 
+    Dwarf_Signed  *     /*returned_val*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_formblock(Dwarf_Attribute /*attr*/, 
+    Dwarf_Block    **   /*returned_block*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_formstring(Dwarf_Attribute /*attr*/, 
+    char   **           /*returned_string*/,
+    Dwarf_Error* 	/*error*/);
+
+/* end attribute query operations. */
+
+/* line number operations */
+/* dwarf_srclines  is the normal interface */
+int dwarf_srclines(Dwarf_Die /*die*/, 
+    Dwarf_Line** 	/*linebuf*/, 
+    Dwarf_Signed *      /*linecount*/,
+    Dwarf_Error* 	/*error*/);
+
+/* dwarf_srclines_dealloc, created July 2005, is the new
+   method for deallocating what dwarf_srclines returns.
+   More complete free than using dwarf_dealloc directly. */
+void dwarf_srclines_dealloc(Dwarf_Debug /*dbg*/, 
+   Dwarf_Line*  /*linebuf*/,
+   Dwarf_Signed /*count */);
+
+
+int dwarf_srcfiles(Dwarf_Die /*die*/, 
+    char*** 		/*srcfiles*/, 
+    Dwarf_Signed *      /*filecount*/,
+    Dwarf_Error* 	/*error*/);
+
+/* Unimplemented. */
+int dwarf_dieline(Dwarf_Die /*die*/, 
+    Dwarf_Line  *       /*returned_line*/,
+    Dwarf_Error *       /*error*/);
+
+int dwarf_linebeginstatement(Dwarf_Line /*line*/, 
+    Dwarf_Bool  *       /*returned_bool*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_lineendsequence(Dwarf_Line /*line*/,
+    Dwarf_Bool  *       /*returned_bool*/,
+    Dwarf_Error*        /*error*/);
+
+int dwarf_lineno(Dwarf_Line /*line*/, 
+    Dwarf_Unsigned *    /*returned_lineno*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_line_srcfileno(Dwarf_Line /*line*/,
+    Dwarf_Unsigned * /*ret_fileno*/, 
+    Dwarf_Error *    /*error*/);
+
+int dwarf_lineaddr(Dwarf_Line /*line*/, 
+    Dwarf_Addr *        /*returned_addr*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_lineoff(Dwarf_Line /*line*/, 
+    Dwarf_Signed  *     /*returned_lineoffset*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_linesrc(Dwarf_Line /*line*/, 
+    char   **           /*returned_name*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_lineblock(Dwarf_Line /*line*/, 
+    Dwarf_Bool  *       /*returned_bool*/,
+    Dwarf_Error* 	/*error*/);
+
+/* tertiary interface to line info */
+/* Unimplemented */
+int dwarf_pclines(Dwarf_Debug /*dbg*/, 
+    Dwarf_Addr 		/*pc*/, 
+    Dwarf_Line** 	/*linebuf*/, 
+    Dwarf_Signed *      /*linecount*/,
+    Dwarf_Signed 	/*slide*/, 
+    Dwarf_Error* 	/*error*/);
+/* end line number operations */
+
+/* global name space operations (.debug_pubnames access) */
+int dwarf_get_globals(Dwarf_Debug /*dbg*/, 
+    Dwarf_Global** 	/*globals*/, 
+    Dwarf_Signed *      /*number_of_globals*/,
+    Dwarf_Error* 	/*error*/);
+void dwarf_globals_dealloc(Dwarf_Debug /*dbg*/,
+    Dwarf_Global* /*globals*/,
+    Dwarf_Signed /*number_of_globals*/);
+
+int dwarf_globname(Dwarf_Global /*glob*/, 
+    char   **           /*returned_name*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_global_die_offset(Dwarf_Global /*global*/, 
+    Dwarf_Off*          /*return_offset*/,
+    Dwarf_Error * 	/*error*/);
+
+int dwarf_get_cu_die_offset_given_cu_header_offset(
+	Dwarf_Debug     /*dbg*/,
+	Dwarf_Off       /*in_cu_header_offset*/,
+        Dwarf_Off *     /*out_cu_die_offset*/, 
+	Dwarf_Error *   /*err*/);
+#ifdef __sgi /* pragma is sgi MIPS only */
+#pragma optional dwarf_get_cu_die_offset_given_cu_header_offset
+#endif
+
+int dwarf_global_cu_offset(Dwarf_Global /*global*/, 
+    Dwarf_Off*          /*return_offset*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_global_name_offsets(Dwarf_Global /*global*/, 
+    char   **           /*returned_name*/,
+    Dwarf_Off* 		/*die_offset*/, 
+    Dwarf_Off* 		/*cu_offset*/, 
+    Dwarf_Error* 	/*error*/);
+
+/* Static function name operations.  */
+int dwarf_get_funcs(Dwarf_Debug	/*dbg*/,
+    Dwarf_Func**	/*funcs*/,
+    Dwarf_Signed *      /*number_of_funcs*/,
+    Dwarf_Error*	/*error*/);
+void dwarf_funcs_dealloc(Dwarf_Debug /*dbg*/,
+    Dwarf_Func* /*funcs*/,
+    Dwarf_Signed /*number_of_funcs*/);
+
+int dwarf_funcname(Dwarf_Func /*func*/,
+    char   **           /*returned_name*/,
+    Dwarf_Error*	/*error*/);
+
+int dwarf_func_die_offset(Dwarf_Func /*func*/,
+    Dwarf_Off*          /*return_offset*/,
+    Dwarf_Error*	/*error*/);
+
+int dwarf_func_cu_offset(Dwarf_Func /*func*/,
+    Dwarf_Off*          /*return_offset*/,
+    Dwarf_Error*	/*error*/);
+
+int dwarf_func_name_offsets(Dwarf_Func /*func*/,
+    char   **           /*returned_name*/,
+    Dwarf_Off*		/*die_offset*/,
+    Dwarf_Off*		/*cu_offset*/,
+    Dwarf_Error*	/*error*/);
+
+/* User-defined type name operations, SGI IRIX .debug_typenames section.
+   Same content as DWARF3 .debug_pubtypes, but defined years before
+   .debug_pubtypes was defined.   SGI IRIX only. */
+int dwarf_get_types(Dwarf_Debug	/*dbg*/,
+    Dwarf_Type**	/*types*/,
+    Dwarf_Signed *      /*number_of_types*/,
+    Dwarf_Error*	/*error*/);
+void dwarf_types_dealloc(Dwarf_Debug /*dbg*/,
+    Dwarf_Type* /*types*/,
+    Dwarf_Signed /*number_of_types*/);
+
+
+int dwarf_typename(Dwarf_Type /*type*/,
+    char   **           /*returned_name*/,
+    Dwarf_Error*	/*error*/);
+
+int dwarf_type_die_offset(Dwarf_Type /*type*/,
+    Dwarf_Off*          /*return_offset*/,
+    Dwarf_Error*	/*error*/);
+
+int dwarf_type_cu_offset(Dwarf_Type /*type*/,
+    Dwarf_Off*          /*return_offset*/,
+    Dwarf_Error*	/*error*/);
+
+int dwarf_type_name_offsets(Dwarf_Type	/*type*/,
+    char   **           /*returned_name*/,
+    Dwarf_Off*		/*die_offset*/,
+    Dwarf_Off*		/*cu_offset*/,
+    Dwarf_Error*	/*error*/);
+
+/* User-defined type name operations, DWARF3  .debug_pubtypes section. 
+*/
+int dwarf_get_pubtypes(Dwarf_Debug	/*dbg*/,
+    Dwarf_Type**	/*types*/,
+    Dwarf_Signed *      /*number_of_types*/,
+    Dwarf_Error*	/*error*/);
+void dwarf_pubtypes_dealloc(Dwarf_Debug /*dbg*/,
+    Dwarf_Type* /*pubtypes*/,
+    Dwarf_Signed /*number_of_pubtypes*/);
+
+
+int dwarf_pubtypename(Dwarf_Type /*type*/,
+    char   **           /*returned_name*/,
+    Dwarf_Error*	/*error*/);
+
+int dwarf_pubtype_die_offset(Dwarf_Type /*type*/,
+    Dwarf_Off*          /*return_offset*/,
+    Dwarf_Error*	/*error*/);
+
+int dwarf_pubtype_cu_offset(Dwarf_Type /*type*/,
+    Dwarf_Off*          /*return_offset*/,
+    Dwarf_Error*	/*error*/);
+
+int dwarf_pubtype_name_offsets(Dwarf_Type	/*type*/,
+    char   **           /*returned_name*/,
+    Dwarf_Off*		/*die_offset*/,
+    Dwarf_Off*		/*cu_offset*/,
+    Dwarf_Error*	/*error*/);
+
+/* File-scope static variable name operations.  */
+int dwarf_get_vars(Dwarf_Debug	/*dbg*/,
+    Dwarf_Var**		/*vars*/,
+    Dwarf_Signed *      /*number_of_vars*/,
+    Dwarf_Error*	/*error*/);
+void dwarf_vars_dealloc(Dwarf_Debug /*dbg*/,
+    Dwarf_Var* /*vars*/,
+    Dwarf_Signed /*number_of_vars*/);
+
+
+int dwarf_varname(Dwarf_Var /*var*/,
+    char   **           /*returned_name*/,
+    Dwarf_Error*	/*error*/);
+
+int dwarf_var_die_offset(Dwarf_Var /*var*/,
+    Dwarf_Off*          /*return_offset*/,
+    Dwarf_Error*	/*error*/);
+
+int dwarf_var_cu_offset(Dwarf_Var /*var*/,
+    Dwarf_Off*          /*return_offset*/,
+    Dwarf_Error*	/*error*/);
+
+int dwarf_var_name_offsets(Dwarf_Var /*var*/,
+    char   **           /*returned_name*/,
+    Dwarf_Off*		/*die_offset*/,
+    Dwarf_Off*		/*cu_offset*/,
+    Dwarf_Error*	/*error*/);
+
+/* weak name operations.  */
+int dwarf_get_weaks(Dwarf_Debug	/*dbg*/,
+    Dwarf_Weak**	/*weaks*/,
+    Dwarf_Signed *      /*number_of_weaks*/,
+    Dwarf_Error*	/*error*/);
+void dwarf_weaks_dealloc(Dwarf_Debug /*dbg*/,
+    Dwarf_Weak* /*weaks*/,
+    Dwarf_Signed /*number_of_weaks*/);
+
+
+int dwarf_weakname(Dwarf_Weak /*weak*/,
+    char   **           /*returned_name*/,
+    Dwarf_Error*	/*error*/);
+
+int dwarf_weak_die_offset(Dwarf_Weak /*weak*/,
+    Dwarf_Off*          /*return_offset*/,
+    Dwarf_Error*	/*error*/);
+
+int dwarf_weak_cu_offset(Dwarf_Weak /*weak*/,
+    Dwarf_Off*          /*return_offset*/,
+    Dwarf_Error*	/*error*/);
+
+int dwarf_weak_name_offsets(Dwarf_Weak	/*weak*/,
+    char   **           /*returned_name*/,
+    Dwarf_Off*		/*die_offset*/,
+    Dwarf_Off*		/*cu_offset*/,
+    Dwarf_Error*	/*error*/);
+
+/* location list section operation.  (.debug_loc access) */
+int dwarf_get_loclist_entry(Dwarf_Debug /*dbg*/, 
+    Dwarf_Unsigned 	/*offset*/, 
+    Dwarf_Addr* 	/*hipc*/, 
+    Dwarf_Addr* 	/*lopc*/, 
+    Dwarf_Ptr* 		/*data*/, 
+    Dwarf_Unsigned* 	/*entry_len*/, 
+    Dwarf_Unsigned* 	/*next_entry*/, 
+    Dwarf_Error* 	/*error*/);
+
+/* abbreviation section operations */
+int dwarf_get_abbrev(Dwarf_Debug /*dbg*/, 
+    Dwarf_Unsigned 	/*offset*/, 
+    Dwarf_Abbrev  *     /*returned_abbrev*/,
+    Dwarf_Unsigned* 	/*length*/, 
+    Dwarf_Unsigned* 	/*attr_count*/, 
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_get_abbrev_tag(Dwarf_Abbrev /*abbrev*/, 
+    Dwarf_Half*        /*return_tag_number*/,
+    Dwarf_Error* 	/*error*/);
+int dwarf_get_abbrev_code(Dwarf_Abbrev /*abbrev*/, 
+    Dwarf_Unsigned*        /*return_code_number*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_get_abbrev_children_flag(Dwarf_Abbrev /*abbrev*/, 
+    Dwarf_Signed*        /*return_flag*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_get_abbrev_entry(Dwarf_Abbrev /*abbrev*/, 
+    Dwarf_Signed  	/*index*/, 
+    Dwarf_Half  *       /*returned_attr_num*/,
+    Dwarf_Signed* 	/*form*/, 
+    Dwarf_Off*    	/*offset*/, 
+    Dwarf_Error*  	/*error*/);
+
+/* consumer string section operation */
+int dwarf_get_str(Dwarf_Debug /*dbg*/, 
+    Dwarf_Off    	/*offset*/, 
+    char** 		/*string*/, 
+    Dwarf_Signed *      /*strlen_of_string*/,
+    Dwarf_Error*  	/*error*/);
+
+/* Consumer op on  gnu .eh_frame info */
+int dwarf_get_fde_list_eh(
+    Dwarf_Debug        /*dbg*/,
+    Dwarf_Cie       ** /*cie_data*/,
+    Dwarf_Signed    *  /*cie_element_count*/,
+    Dwarf_Fde       ** /*fde_data*/,
+    Dwarf_Signed    *  /*fde_element_count*/,
+    Dwarf_Error     *  /*error*/);
+
+
+/* consumer operations on frame info: .debug_frame */
+int dwarf_get_fde_list(Dwarf_Debug /*dbg*/, 
+    Dwarf_Cie**   	/*cie_data*/, 
+    Dwarf_Signed* 	/*cie_element_count*/, 
+    Dwarf_Fde**   	/*fde_data*/, 
+    Dwarf_Signed* 	/*fde_element_count*/, 
+    Dwarf_Error* 	/*error*/);
+
+/* Release storage gotten by dwarf_get_fde_list_eh() or
+   dwarf_get_fde_list() */
+void dwarf_fde_cie_list_dealloc(Dwarf_Debug dbg,
+        Dwarf_Cie *cie_data,
+        Dwarf_Signed cie_element_count,
+        Dwarf_Fde *fde_data,
+        Dwarf_Signed fde_element_count);
+
+
+
+int dwarf_get_fde_range(Dwarf_Fde /*fde*/, 
+    Dwarf_Addr* 	/*low_pc*/, 
+    Dwarf_Unsigned* 	/*func_length*/, 
+    Dwarf_Ptr*    	/*fde_bytes*/, 
+    Dwarf_Unsigned* 	/*fde_byte_length*/, 
+    Dwarf_Off*    	/*cie_offset*/, 
+    Dwarf_Signed*  	/*cie_index*/, 
+    Dwarf_Off*   	/*fde_offset*/, 
+    Dwarf_Error* 	/*error*/);
+
+/*  Useful for IRIX only:  see dwarf_get_cie_augmentation_data()
+       dwarf_get_fde_augmentation_data() for GNU .eh_frame. */
+int dwarf_get_fde_exception_info(Dwarf_Fde /*fde*/,
+    Dwarf_Signed*	/* offset_into_exception_tables */,
+    Dwarf_Error*        /*error*/);
+
+
+int dwarf_get_cie_of_fde(Dwarf_Fde /*fde*/,
+    Dwarf_Cie *         /*cie_returned*/,
+    Dwarf_Error*        /*error*/);
+
+int dwarf_get_cie_info(Dwarf_Cie /*cie*/, 
+    Dwarf_Unsigned *    /*bytes_in_cie*/,
+    Dwarf_Small*    	/*version*/, 
+    char        **      /*augmenter*/,
+    Dwarf_Unsigned* 	/*code_alignment_factor*/, 
+    Dwarf_Signed* 	/*data_alignment_factor*/, 
+    Dwarf_Half*     	/*return_address_register_rule*/, 
+    Dwarf_Ptr*     	/*initial_instructions*/, 
+    Dwarf_Unsigned*  	/*initial_instructions_length*/, 
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_get_fde_instr_bytes(Dwarf_Fde /*fde*/, 
+    Dwarf_Ptr * /*outinstrs*/, Dwarf_Unsigned * /*outlen*/, 
+    Dwarf_Error * /*error*/);
+
+int dwarf_get_fde_info_for_all_regs(Dwarf_Fde /*fde*/, 
+    Dwarf_Addr          /*pc_requested*/,
+    Dwarf_Regtable*     /*reg_table*/,
+    Dwarf_Addr*         /*row_pc*/,
+    Dwarf_Error*        /*error*/);
+
+int dwarf_get_fde_info_for_all_regs3(Dwarf_Fde /*fde*/, 
+    Dwarf_Addr          /*pc_requested*/,
+    Dwarf_Regtable3*     /*reg_table*/,
+    Dwarf_Addr*         /*row_pc*/,
+    Dwarf_Error*        /*error*/);
+
+/* In this older interface DW_FRAME_CFA_COL is a meaningful
+    column (which does not work well with DWARF3 or
+    non-MIPS architectures). */
+int dwarf_get_fde_info_for_reg(Dwarf_Fde /*fde*/, 
+    Dwarf_Half    	/*table_column*/, 
+    Dwarf_Addr    	/*pc_requested*/, 
+    Dwarf_Signed*       /*offset_relevant*/,
+    Dwarf_Signed* 	/*register*/,  
+    Dwarf_Signed* 	/*offset*/, 
+    Dwarf_Addr* 	/*row_pc*/, 
+    Dwarf_Error* 	/*error*/);
+
+/* See discussion of dw_value_type, libdwarf.h. 
+   Use of DW_FRAME_CFA_COL is not meaningful in this interface.
+   Nor is DDW_FRAME_CFA_COL3.
+   See dwarf_get_fde_info_for_cfa_reg3().
+*/
+int dwarf_get_fde_info_for_reg3(Dwarf_Fde /*fde*/, 
+    Dwarf_Half    	/*table_column*/, 
+    Dwarf_Addr    	/*pc_requested*/, 
+    Dwarf_Small  *  	/*value_type*/, 
+    Dwarf_Signed *      /*offset_relevant*/,
+    Dwarf_Signed* 	/*register*/,  
+    Dwarf_Signed* 	/*offset_or_block_len*/, 
+    Dwarf_Ptr   *       /*block_ptr */,
+    Dwarf_Addr* 	/*row_pc_out*/, 
+    Dwarf_Error* 	/*error*/);
+
+/* Use this to get the cfa. */
+int dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde /*fde*/, 
+    Dwarf_Addr    	/*pc_requested*/, 
+    Dwarf_Small  *  	/*value_type*/, 
+    Dwarf_Signed *      /*offset_relevant*/,
+    Dwarf_Signed* 	/*register*/,  
+    Dwarf_Signed* 	/*offset_or_block_len*/, 
+    Dwarf_Ptr   *       /*block_ptr */,
+    Dwarf_Addr* 	/*row_pc_out*/, 
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_get_fde_for_die(Dwarf_Debug /*dbg*/, 
+    Dwarf_Die 		/*subr_die */, 
+    Dwarf_Fde  *        /*returned_fde*/,
+    Dwarf_Error*	/*error*/);
+
+int dwarf_get_fde_n(Dwarf_Fde* /*fde_data*/, 
+    Dwarf_Unsigned 	/*fde_index*/, 
+    Dwarf_Fde  *        /*returned_fde*/,
+    Dwarf_Error*  	/*error*/);
+
+int dwarf_get_fde_at_pc(Dwarf_Fde* /*fde_data*/, 
+    Dwarf_Addr 		/*pc_of_interest*/, 
+    Dwarf_Fde  *        /*returned_fde*/,
+    Dwarf_Addr* 	/*lopc*/, 
+    Dwarf_Addr* 	/*hipc*/, 
+    Dwarf_Error* 	/*error*/);
+
+/* GNU .eh_frame augmentation information, raw form, see
+   Linux Standard Base Core Specification version 3.0 . */
+int dwarf_get_cie_augmentation_data(Dwarf_Cie /* cie*/,
+    Dwarf_Small **         /* augdata */,
+    Dwarf_Unsigned *    /* augdata_len */,
+    Dwarf_Error*        /*error*/);
+/* GNU .eh_frame augmentation information, raw form, see
+   Linux Standard Base Core Specification version 3.0 . */
+int dwarf_get_fde_augmentation_data(Dwarf_Fde /* fde*/,
+    Dwarf_Small **         /* augdata */,
+    Dwarf_Unsigned *    /* augdata_len */,
+    Dwarf_Error*        /*error*/);
+
+int dwarf_expand_frame_instructions(Dwarf_Debug /*dbg*/, 
+    Dwarf_Ptr 		/*instruction*/, 
+    Dwarf_Unsigned  	/*i_length*/, 
+    Dwarf_Frame_Op** 	/*returned_op_list*/, 
+    Dwarf_Signed*       /*op_count*/,
+    Dwarf_Error* 	/*error*/);
+
+/* Operations on .debug_aranges. */
+int dwarf_get_aranges(Dwarf_Debug /*dbg*/, 
+    Dwarf_Arange** 	/*aranges*/, 
+    Dwarf_Signed *      /*arange_count*/,
+    Dwarf_Error* 	/*error*/);
+
+
+
+int dwarf_get_arange(
+    Dwarf_Arange* 	/*aranges*/, 
+    Dwarf_Unsigned 	/*arange_count*/, 
+    Dwarf_Addr 		/*address*/, 
+    Dwarf_Arange *      /*returned_arange*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_get_cu_die_offset(
+    Dwarf_Arange 	/*arange*/, 
+    Dwarf_Off*          /*return_offset*/,
+    Dwarf_Error* 	/*error*/);
+
+int dwarf_get_arange_cu_header_offset(
+    Dwarf_Arange 	/*arange*/, 
+    Dwarf_Off*          /*return_cu_header_offset*/,
+    Dwarf_Error* 	/*error*/);
+#ifdef __sgi /* pragma is sgi MIPS only */
+#pragma optional dwarf_get_arange_cu_header_offset
+#endif
+
+int dwarf_get_arange_info(
+    Dwarf_Arange 	/*arange*/, 
+    Dwarf_Addr* 	/*start*/, 
+    Dwarf_Unsigned* 	/*length*/, 
+    Dwarf_Off* 		/*cu_die_offset*/, 
+    Dwarf_Error* 	/*error*/);
+
+
+/* consumer .debug_macinfo information interface.
+*/
+struct Dwarf_Macro_Details_s {
+  Dwarf_Off    dmd_offset; /* offset, in the section,
+                              of this macro info */
+  Dwarf_Small  dmd_type;   /* the type, DW_MACINFO_define etc*/
+  Dwarf_Signed dmd_lineno; /* the source line number where
+                              applicable and vend_def # if
+                              vendor_extension op
+                           */
+
+  Dwarf_Signed dmd_fileindex;/* the source file index:
+                              applies to define undef start_file
+                             */
+  char *       dmd_macro;  /* macro name (with value for defineop)
+                              string from vendor ext
+                           */
+};
+
+/* dwarf_print_lines is for use by dwarfdump: it prints
+   line info to stdout.
+   The _dwarf name is obsolete. Use dwarf_ instead.
+*/
+int _dwarf_print_lines(Dwarf_Die cu_die,Dwarf_Error * /*error*/);
+int dwarf_print_lines(Dwarf_Die cu_die,Dwarf_Error * /*error*/);
+
+/* dwarf_ld_sort_lines helps SGI IRIX ld 
+   rearrange lines in .debug_line in a .o created with a text
+   section per function.  
+		-OPT:procedure_reorder=ON
+   where ld-cord (cord(1)ing by ld, 
+   not by cord(1)) may have changed the function order.
+   The _dwarf name is obsolete. Use dwarf_ instead.
+*/
+int _dwarf_ld_sort_lines(
+        void * orig_buffer,
+        unsigned long   buffer_len,
+        int is_64_bit,
+        int *any_change,
+        int * err_code);
+int dwarf_ld_sort_lines(
+        void * orig_buffer,
+        unsigned long   buffer_len,
+        int is_64_bit,
+        int *any_change,
+        int * err_code);
+
+/* Used by dwarfdump -v to print fde offsets from debugging
+   info.
+   The _dwarf name is obsolete. Use dwarf_ instead.
+*/
+int _dwarf_fde_section_offset(Dwarf_Debug dbg,Dwarf_Fde in_fde,
+        Dwarf_Off *fde_off, Dwarf_Off *cie_off,
+        Dwarf_Error *err);
+int dwarf_fde_section_offset(Dwarf_Debug dbg,Dwarf_Fde in_fde,
+        Dwarf_Off *fde_off, Dwarf_Off *cie_off,
+        Dwarf_Error *err);
+
+/* Used by dwarfdump -v to print cie offsets from debugging
+   info.
+   The _dwarf name is obsolete. Use dwarf_ instead.
+*/
+int dwarf_cie_section_offset(Dwarf_Debug dbg,Dwarf_Cie in_cie,
+        Dwarf_Off *cie_off,
+        Dwarf_Error *err);
+int _dwarf_cie_section_offset(Dwarf_Debug dbg,Dwarf_Cie in_cie,
+        Dwarf_Off *cie_off,
+        Dwarf_Error *err);
+
+
+
+
+typedef struct Dwarf_Macro_Details_s Dwarf_Macro_Details;
+
+int dwarf_get_macro(Dwarf_Debug /*dbg*/,
+    char *        /*requested_macro_name*/,
+    Dwarf_Addr    /*pc_of_request*/,
+    char **       /*returned_macro_value*/,
+    Dwarf_Error * /*error*/);
+
+int dwarf_get_all_defined_macros(Dwarf_Debug /*dbg*/,
+    Dwarf_Addr     /*pc_of_request*/,
+    Dwarf_Signed * /*returned_count*/,
+    char ***       /*returned_pointers_to_macros*/,
+    Dwarf_Error *  /*error*/);
+
+char *dwarf_find_macro_value_start(char * /*macro_string*/);
+
+int dwarf_get_macro_details(Dwarf_Debug /*dbg*/,
+    Dwarf_Off              /*macro_offset*/,
+    Dwarf_Unsigned	   /*maximum_count*/,
+    Dwarf_Signed         * /*entry_count*/,
+    Dwarf_Macro_Details ** /*details*/,
+    Dwarf_Error *          /*err*/);
+
+
+int dwarf_get_address_size(Dwarf_Debug /*dbg*/,
+        Dwarf_Half  * /*addr_size*/,
+        Dwarf_Error * /*error*/);
+
+/* utility operations */
+Dwarf_Unsigned dwarf_errno(Dwarf_Error 	/*error*/);
+
+char* dwarf_errmsg(Dwarf_Error	/*error*/);
+
+/* stringcheck zero is default and means do all
+** string length validity checks.
+** Call with parameter value 1 to turn off many such checks (and
+** increase performance).
+** Call with zero for safest running.
+** Actual value saved and returned is only 8 bits! Upper bits
+** ignored by libdwarf (and zero on return).
+** Returns previous value.
+*/
+int dwarf_set_stringcheck(int /*stringcheck*/);
+
+/* Unimplemented */
+Dwarf_Handler dwarf_seterrhand(Dwarf_Debug /*dbg*/, Dwarf_Handler /*errhand*/);
+
+/* Unimplemented */
+Dwarf_Ptr dwarf_seterrarg(Dwarf_Debug /*dbg*/, Dwarf_Ptr /*errarg*/);
+
+void dwarf_dealloc(Dwarf_Debug /*dbg*/, void* /*space*/, 
+    Dwarf_Unsigned /*type*/);
+
+/* DWARF Producer Interface */
+
+typedef int (*Dwarf_Callback_Func)(
+    char* /*name*/, 
+    int 		/*size*/, 
+    Dwarf_Unsigned 	/*type*/,
+    Dwarf_Unsigned 	/*flags*/, 
+    Dwarf_Unsigned 	/*link*/, 
+    Dwarf_Unsigned 	/*info*/, 
+    int* 		/*sect name index*/, 
+    int* 		/*error*/);
+
+Dwarf_P_Debug dwarf_producer_init(
+    Dwarf_Unsigned      /*creation_flags*/, 
+    Dwarf_Callback_Func	/*func*/,
+    Dwarf_Handler 	/*errhand*/, 
+    Dwarf_Ptr 		/*errarg*/, 
+    Dwarf_Error* 	/*error*/);
+
+typedef int (*Dwarf_Callback_Func_b)(
+    char* 		/*name*/,
+    int                 /*size*/,
+    Dwarf_Unsigned      /*type*/,
+    Dwarf_Unsigned      /*flags*/,
+    Dwarf_Unsigned      /*link*/,
+    Dwarf_Unsigned      /*info*/,
+    Dwarf_Unsigned*     /*sect_name_index*/,
+    int*                /*error*/);
+
+
+Dwarf_P_Debug dwarf_producer_init_b(
+    Dwarf_Unsigned        /*flags*/,
+    Dwarf_Callback_Func_b /*func*/,
+    Dwarf_Handler         /*errhand*/,
+    Dwarf_Ptr             /*errarg*/,
+    Dwarf_Error *         /*error*/);
+
+
+Dwarf_Signed dwarf_transform_to_disk_form(Dwarf_P_Debug /*dbg*/,
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_Ptr dwarf_get_section_bytes(Dwarf_P_Debug /*dbg*/, 
+    Dwarf_Signed 	/*dwarf_section*/,
+    Dwarf_Signed* 	/*elf_section_index*/, 
+    Dwarf_Unsigned* 	/*length*/, 
+    Dwarf_Error* 	/*error*/);
+
+int  dwarf_get_relocation_info_count(
+        Dwarf_P_Debug    /*dbg*/,
+        Dwarf_Unsigned * /*count_of_relocation_sections*/,
+	int *            /*drd_buffer_version*/,
+        Dwarf_Error*     /*error*/);
+
+int dwarf_get_relocation_info(
+        Dwarf_P_Debug           /*dbg*/,
+        Dwarf_Signed          * /*elf_section_index*/,
+        Dwarf_Signed          * /*elf_section_index_link*/,
+        Dwarf_Unsigned        * /*relocation_buffer_count*/,
+        Dwarf_Relocation_Data * /*reldata_buffer*/,
+        Dwarf_Error*            /*error*/);
+
+/* v1:  no drd_length field, enum explicit */
+/* v2:  has the drd_length field, enum value in uchar member */
+#define DWARF_DRD_BUFFER_VERSION 2
+
+Dwarf_Signed dwarf_get_die_markers(
+    Dwarf_P_Debug     /*dbg*/,
+    Dwarf_P_Marker *  /*marker_list*/,
+    Dwarf_Unsigned *  /*marker_count*/,
+    Dwarf_Error *     /*error*/);
+
+int dwarf_get_string_attributes_count(Dwarf_P_Debug,
+                                      Dwarf_Unsigned *,
+                                      int *,
+                                      Dwarf_Error *);
+
+int dwarf_get_string_attributes_info(Dwarf_P_Debug, 
+                                     Dwarf_Signed *,
+                                     Dwarf_Unsigned *,
+                                     Dwarf_P_String_Attr *,
+                                     Dwarf_Error *);
+
+void dwarf_reset_section_bytes(Dwarf_P_Debug /*dbg*/);
+
+Dwarf_Unsigned dwarf_producer_finish(Dwarf_P_Debug /*dbg*/, 
+    Dwarf_Error* /*error*/);
+
+/* Producer attribute addition functions. */
+Dwarf_P_Attribute dwarf_add_AT_targ_address(Dwarf_P_Debug /*dbg*/, 
+    Dwarf_P_Die 	/*ownerdie*/, 
+    Dwarf_Half 		/*attr*/, 
+    Dwarf_Unsigned 	/*pc_value*/, 
+    Dwarf_Signed 	/*sym_index*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_block(Dwarf_P_Debug /*dbg*/, 
+    Dwarf_P_Die         /*ownerdie*/, 
+    Dwarf_Half          /*attr*/, 
+    Dwarf_Small*        /*block_data*/,
+    Dwarf_Unsigned      /*block_len*/,
+    Dwarf_Error*        /*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_targ_address_b(Dwarf_P_Debug /*dbg*/, 
+    Dwarf_P_Die 	/*ownerdie*/, 
+    Dwarf_Half 		/*attr*/, 
+    Dwarf_Unsigned 	/*pc_value*/, 
+    Dwarf_Unsigned 	/*sym_index*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_ref_address(Dwarf_P_Debug /*dbg*/, 
+    Dwarf_P_Die 	/*ownerdie*/, 
+    Dwarf_Half 		/*attr*/, 
+    Dwarf_Unsigned 	/*pc_value*/, 
+    Dwarf_Unsigned 	/*sym_index*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_unsigned_const(Dwarf_P_Debug /*dbg*/, 
+    Dwarf_P_Die 	/*ownerdie*/, 
+    Dwarf_Half 		/*attr*/, 
+    Dwarf_Unsigned 	/*value*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_signed_const(Dwarf_P_Debug /*dbg*/, 
+    Dwarf_P_Die 	/*ownerdie*/, 
+    Dwarf_Half 		/*attr*/, 
+    Dwarf_Signed 	/*value*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_reference(Dwarf_P_Debug /*dbg*/, 
+    Dwarf_P_Die 	/*ownerdie*/, 
+    Dwarf_Half 		/*attr*/, 
+    Dwarf_P_Die 	/*otherdie*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_dataref(
+    Dwarf_P_Debug /* dbg*/,
+    Dwarf_P_Die /*ownerdie*/, 
+    Dwarf_Half 	   /*attr*/,
+    Dwarf_Unsigned /*pcvalue*/,
+    Dwarf_Unsigned  /*sym_index*/,
+    Dwarf_Error*    /*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_const_value_string(Dwarf_P_Die /*ownerdie*/, 
+    char* 		/*string_value*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_location_expr(Dwarf_P_Debug /*dbg*/, 
+    Dwarf_P_Die 	/*ownerdie*/, 
+    Dwarf_Half 		/*attr*/, 
+    Dwarf_P_Expr 	/*loc_expr*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_string(Dwarf_P_Debug /*dbg*/, 
+    Dwarf_P_Die 	/*ownerdie*/, 
+    Dwarf_Half 		/*attr*/, 
+    char* 		/*string*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_flag(Dwarf_P_Debug /*dbg*/, 
+    Dwarf_P_Die 	/*ownerdie*/, 
+    Dwarf_Half 		/*attr*/, 
+    Dwarf_Small 	/*flag*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_producer(Dwarf_P_Die /*ownerdie*/, 
+    char* 		/*producer_string*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_const_value_signedint(Dwarf_P_Die /*ownerdie*/, 
+    Dwarf_Signed 	/*signed_value*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_const_value_unsignedint(
+    Dwarf_P_Die         /*ownerdie*/, 
+    Dwarf_Unsigned 	/*unsigned_value*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_comp_dir(Dwarf_P_Die /*ownerdie*/, 
+    char* 		/*current_working_directory*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_P_Attribute dwarf_add_AT_name(Dwarf_P_Die	/*die*/,
+    char* 		/*name*/,
+    Dwarf_Error* 	/*error*/);
+
+/* Producer line creation functions (.debug_line) */
+Dwarf_Unsigned dwarf_add_directory_decl(Dwarf_P_Debug /*dbg*/, 
+    char* 		/*name*/, 
+    Dwarf_Error*	/*error*/);
+
+Dwarf_Unsigned dwarf_add_file_decl(Dwarf_P_Debug /*dbg*/, 
+    char* 		/*name*/,
+    Dwarf_Unsigned 	/*dir_index*/, 
+    Dwarf_Unsigned 	/*time_last_modified*/, 
+    Dwarf_Unsigned 	/*length*/, 
+    Dwarf_Error*	/*error*/);
+
+Dwarf_Unsigned dwarf_add_line_entry(Dwarf_P_Debug /*dbg*/, 
+    Dwarf_Unsigned 	/*file_index*/, 
+    Dwarf_Addr 		/*code_address*/, 
+    Dwarf_Unsigned 	/*lineno*/, 
+    Dwarf_Signed 	/*column_number*/, 
+    Dwarf_Bool 		/*is_source_stmt_begin*/, 
+    Dwarf_Bool 		/*is_basic_block_begin*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_Unsigned dwarf_lne_set_address(Dwarf_P_Debug /*dbg*/, 
+    Dwarf_Unsigned 	/*offset*/, 
+    Dwarf_Unsigned 	/*symbol_index*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_Unsigned dwarf_lne_end_sequence(Dwarf_P_Debug /*dbg*/, 
+    Dwarf_Addr		/*end_address*/,
+    Dwarf_Error* 	/*error*/);
+
+/* Producer .debug_frame functions */
+Dwarf_Unsigned dwarf_add_frame_cie(Dwarf_P_Debug /*dbg*/, 
+    char* 		/*augmenter*/, 
+    Dwarf_Small 	/*code_alignent_factor*/, 
+    Dwarf_Small 	/*data_alignment_factor*/, 
+    Dwarf_Small 	/*return_address_reg*/, 
+    Dwarf_Ptr 		/*initialization_bytes*/, 
+    Dwarf_Unsigned 	/*init_byte_len*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_Unsigned dwarf_add_frame_fde( 
+    Dwarf_P_Debug 	/*dbg*/,
+    Dwarf_P_Fde 	/*fde*/, 
+    Dwarf_P_Die 	/*corresponding subprogram die*/,
+    Dwarf_Unsigned 	/*cie_to_use*/, 
+    Dwarf_Unsigned  	/*virt_addr_of_described_code*/, 
+    Dwarf_Unsigned  	/*length_of_code*/, 
+    Dwarf_Unsigned 	/*symbol_index*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_Unsigned dwarf_add_frame_fde_b(
+        Dwarf_P_Debug  /*dbg*/,
+        Dwarf_P_Fde    /*fde*/,
+        Dwarf_P_Die    /*die*/,
+        Dwarf_Unsigned /*cie*/,
+        Dwarf_Addr     /*virt_addr*/,
+        Dwarf_Unsigned /*code_len*/,
+        Dwarf_Unsigned /*sym_idx*/,
+        Dwarf_Unsigned /*sym_idx_of_end*/,
+        Dwarf_Addr     /*offset_from_end_sym*/,
+        Dwarf_Error*   /*error*/);
+
+Dwarf_Unsigned dwarf_add_frame_info_b( 
+    Dwarf_P_Debug dbg   /*dbg*/,
+    Dwarf_P_Fde 	/*fde*/,
+    Dwarf_P_Die 	/*die*/,
+    Dwarf_Unsigned 	/*cie*/,
+    Dwarf_Addr 	        /*virt_addr*/,
+    Dwarf_Unsigned 	/*code_len*/,
+    Dwarf_Unsigned 	/*symidx*/,
+    Dwarf_Unsigned      /* end_symbol */,
+    Dwarf_Addr          /* offset_from_end_symbol */,
+    Dwarf_Signed   	/*offset_into_exception_tables*/,
+    Dwarf_Unsigned 	/*exception_table_symbol*/,
+    Dwarf_Error*	/*error*/);
+
+Dwarf_Unsigned dwarf_add_frame_info( 
+    Dwarf_P_Debug dbg   /*dbg*/,
+    Dwarf_P_Fde 	/*fde*/,
+    Dwarf_P_Die 	/*die*/,
+    Dwarf_Unsigned 	/*cie*/,
+    Dwarf_Addr 	        /*virt_addr*/,
+    Dwarf_Unsigned 	/*code_len*/,
+    Dwarf_Unsigned 	/*symidx*/,
+    Dwarf_Signed   	/*offset_into_exception_tables*/,
+    Dwarf_Unsigned 	/*exception_table_symbol*/,
+    Dwarf_Error*	/*error*/);
+
+Dwarf_P_Fde dwarf_add_fde_inst(
+    Dwarf_P_Fde         /*fde*/,
+    Dwarf_Small 	/*op*/, 
+    Dwarf_Unsigned 	/*val1*/, 
+    Dwarf_Unsigned 	/*val2*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_P_Fde dwarf_new_fde(Dwarf_P_Debug	/*dbg*/, Dwarf_Error* /*error*/);
+
+Dwarf_P_Fde dwarf_fde_cfa_offset(
+    Dwarf_P_Fde         /*fde*/, 
+    Dwarf_Unsigned  	/*register_number*/, 
+    Dwarf_Signed    	/*offset*/, 
+    Dwarf_Error* 	/*error*/);
+
+/* die creation & addition routines */
+Dwarf_P_Die dwarf_new_die(
+    Dwarf_P_Debug	/*dbg*/,
+    Dwarf_Tag 		/*tag*/,
+    Dwarf_P_Die 	/*parent*/, 
+    Dwarf_P_Die 	/*child*/, 
+    Dwarf_P_Die 	/*left */,
+    Dwarf_P_Die 	/*right*/,
+    Dwarf_Error*	/*error*/);
+
+Dwarf_Unsigned dwarf_add_die_to_debug(
+    Dwarf_P_Debug       /*dbg*/,
+    Dwarf_P_Die		/*die*/,
+    Dwarf_Error*	/*error*/);
+
+Dwarf_Unsigned dwarf_add_die_marker(
+    Dwarf_P_Debug     /*dbg*/,
+    Dwarf_P_Die       /*die*/,
+    Dwarf_Unsigned    /*marker*/,
+    Dwarf_Error *     /*error*/);
+
+Dwarf_Unsigned dwarf_get_die_marker(
+    Dwarf_P_Debug     /*dbg*/,
+    Dwarf_P_Die       /*die*/,
+    Dwarf_Unsigned *  /*marker*/,
+    Dwarf_Error *     /*error*/);
+
+Dwarf_P_Die dwarf_die_link(
+    Dwarf_P_Die         /*die*/,
+    Dwarf_P_Die 	/*parent*/,
+    Dwarf_P_Die 	/*child*/, 
+    Dwarf_P_Die		/*left*/,
+    Dwarf_P_Die		/*right*/, 
+    Dwarf_Error* 	/*error*/);
+
+void dwarf_dealloc_compressed_block(
+    Dwarf_P_Debug,
+    void *
+);
+
+void dwarf_dealloc_uncompressed_block(
+    Dwarf_Debug,
+    void *
+);
+
+void * dwarf_compress_integer_block(
+    Dwarf_P_Debug,    /* dbg */
+    Dwarf_Bool,       /* signed==true (or unsigned) */
+    Dwarf_Small,      /* size of integer units: 8, 16, 32, 64 */
+    void*,            /* data */
+    Dwarf_Unsigned,   /* number of elements */
+    Dwarf_Unsigned*,  /* number of bytes in output block */
+    Dwarf_Error*      /* error */
+);
+
+void * dwarf_uncompress_integer_block(
+    Dwarf_Debug,    /* dbg */
+    Dwarf_Bool,       /* signed==true (or unsigned) */
+    Dwarf_Small,      /* size of integer units: 8, 16, 32, 64 */
+    void*,            /* data */
+    Dwarf_Unsigned,   /* number of bytes in input */
+    Dwarf_Unsigned*,  /* number of units in output block */
+    Dwarf_Error*      /* error */
+);
+
+/* Operations to create location expressions. */
+Dwarf_P_Expr dwarf_new_expr(Dwarf_P_Debug /*dbg*/, Dwarf_Error* /*error*/);
+
+void dwarf_expr_reset(
+    Dwarf_P_Expr     /*expr*/,
+    Dwarf_Error*     /*error*/);
+
+Dwarf_Unsigned dwarf_add_expr_gen(
+    Dwarf_P_Expr        /*expr*/, 
+    Dwarf_Small 	/*opcode*/, 
+    Dwarf_Unsigned 	/*val1*/, 
+    Dwarf_Unsigned 	/*val2*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_Unsigned dwarf_add_expr_addr(
+    Dwarf_P_Expr        /*expr*/, 
+    Dwarf_Unsigned 	/*addr*/, 
+    Dwarf_Signed 	/*sym_index*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_Unsigned dwarf_add_expr_addr_b(
+    Dwarf_P_Expr        /*expr*/,
+    Dwarf_Unsigned      /*addr*/,
+    Dwarf_Unsigned      /*sym_index*/,
+    Dwarf_Error*        /*error*/);
+
+Dwarf_Unsigned dwarf_expr_current_offset(
+    Dwarf_P_Expr /*expr*/, 
+    Dwarf_Error* /*error*/);
+
+Dwarf_Addr dwarf_expr_into_block(
+    Dwarf_P_Expr        /*expr*/, 
+    Dwarf_Unsigned* 	/*length*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_Unsigned dwarf_add_arange(Dwarf_P_Debug /*dbg*/, 
+    Dwarf_Addr 		/*begin_address*/, 
+    Dwarf_Unsigned 	/*length*/, 
+    Dwarf_Signed 	/*symbol_index*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_Unsigned dwarf_add_arange_b(
+        Dwarf_P_Debug  /*dbg*/,
+        Dwarf_Addr     /*begin_address*/,
+        Dwarf_Unsigned /*length*/,
+        Dwarf_Unsigned /*symbol_index*/,
+        Dwarf_Unsigned /*end_symbol_index*/,
+        Dwarf_Addr     /*offset_from_end_symbol*/,
+        Dwarf_Error *  /*error*/);
+
+Dwarf_Unsigned dwarf_add_pubname(
+    Dwarf_P_Debug       /*dbg*/, 
+    Dwarf_P_Die 	/*die*/, 
+    char* 		/*pubname_name*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_Unsigned dwarf_add_funcname(
+    Dwarf_P_Debug       /*dbg*/, 
+    Dwarf_P_Die 	/*die*/, 
+    char* 		/*func_name*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_Unsigned dwarf_add_typename(
+    Dwarf_P_Debug       /*dbg*/, 
+    Dwarf_P_Die 	/*die*/, 
+    char* 		/*type_name*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_Unsigned dwarf_add_varname(
+    Dwarf_P_Debug       /*dbg*/, 
+    Dwarf_P_Die 	/*die*/, 
+    char* 		/*var_name*/, 
+    Dwarf_Error* 	/*error*/);
+
+Dwarf_Unsigned dwarf_add_weakname(
+    Dwarf_P_Debug       /*dbg*/, 
+    Dwarf_P_Die 	/*die*/, 
+    char* 		/*weak_name*/, 
+    Dwarf_Error* 	/*error*/);
+
+/* .debug_macinfo producer functions
+   Functions must be called in right order: the section is output
+   In the order these are presented.
+*/
+int dwarf_def_macro(Dwarf_P_Debug /*dbg*/,
+    Dwarf_Unsigned  /*line*/,
+    char *          /*macname, with (arglist), no space before (*/, 
+    char *	    /*macvalue*/,
+    Dwarf_Error*    /*error*/);
+
+int dwarf_undef_macro(Dwarf_P_Debug /*dbg*/,
+    Dwarf_Unsigned  /*line*/,
+    char *          /*macname, no arglist, of course*/,
+    Dwarf_Error*    /*error*/);
+
+int dwarf_start_macro_file(Dwarf_P_Debug /*dbg*/,
+    Dwarf_Unsigned /*fileindex*/,
+    Dwarf_Unsigned /*linenumber*/,
+    Dwarf_Error*   /*error*/);
+
+int dwarf_end_macro_file(Dwarf_P_Debug /*dbg*/,
+    Dwarf_Error*   /*error*/);
+
+int dwarf_vendor_ext(Dwarf_P_Debug /*dbg*/,
+    Dwarf_Unsigned /*constant*/,
+    char *         /*string*/,
+    Dwarf_Error*   /*error*/);
+
+/* end macinfo producer functions */
+
+int dwarf_attr_offset(Dwarf_Die /*die*/,
+    Dwarf_Attribute /*attr of above die*/,
+    Dwarf_Off     * /*returns offset thru this ptr */,
+    Dwarf_Error   * /*error*/);
+
+/* This is a hack so clients can verify offsets.
+   Added April 2005 so that debugger can detect broken offsets
+   (which happened in an IRIX executable larger than 2GB
+    with MIPSpro 7.3.1.3 toolchain.).
+*/
+int
+dwarf_get_section_max_offsets(Dwarf_Debug /*dbg*/,
+    Dwarf_Unsigned * /*debug_info_size*/,
+    Dwarf_Unsigned * /*debug_abbrev_size*/,
+    Dwarf_Unsigned * /*debug_line_size*/,
+    Dwarf_Unsigned * /*debug_loc_size*/,
+    Dwarf_Unsigned * /*debug_aranges_size*/,
+    Dwarf_Unsigned * /*debug_macinfo_size*/,
+    Dwarf_Unsigned * /*debug_pubnames_size*/,
+    Dwarf_Unsigned * /*debug_str_size*/,
+    Dwarf_Unsigned * /*debug_frame_size*/,
+    Dwarf_Unsigned * /*debug_ranges_size*/,
+    Dwarf_Unsigned * /*debug_pubtypes_size*/);
+
+Dwarf_Half
+dwarf_set_frame_rule_inital_value(Dwarf_Debug /*dbg*/,
+	Dwarf_Half /*value*/);
+
+Dwarf_Half
+dwarf_set_frame_rule_table_size(Dwarf_Debug dbg,
+        Dwarf_Half value);
+
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _LIBDWARF_H */
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf2.1.mm	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,5215 @@
+\."
+\." the following line may be removed if the ff ligature works on your machine
+.lg 0
+\." set up heading formats
+.ds HF 3 3 3 3 3 2 2
+.ds HP +2 +2 +1 +0 +0
+.nr Hs 5
+.nr Hb 5
+\." ==============================================
+\." Put current date in the following at each rev
+.ds vE rev 1.66, 04 July 2007
+\." ==============================================
+\." ==============================================
+.ds | |
+.ds ~ ~
+.ds ' '
+.if t .ds Cw \&\f(CW
+.if n .ds Cw \fB
+.de Cf          \" Place every other arg in Cw font, beginning with first
+.if \\n(.$=1 \&\*(Cw\\$1\fP
+.if \\n(.$=2 \&\*(Cw\\$1\fP\\$2
+.if \\n(.$=3 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP
+.if \\n(.$=4 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4
+.if \\n(.$=5 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP
+.if \\n(.$=6 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6
+.if \\n(.$=7 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP
+.if \\n(.$=8 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8
+.if \\n(.$=9 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8\
+*(Cw
+..
+.nr Cl 4
+.SA 1
+.TL
+A Consumer Library Interface to DWARF 
+.AF ""
+.AU "David Anderson"
+.PF "'\*(vE'- \\\\nP -''"
+.AS 1
+This document describes an interface to a library of functions
+.FS 
+UNIX is a registered trademark of UNIX System Laboratories, Inc.
+in the United States and other countries.
+.FE
+to access DWARF debugging information entries and DWARF line number
+information (and other DWARF2/3 information). 
+It does not make recommendations as to how the functions
+described in this document should be implemented nor does it
+suggest possible optimizations. 
+.P
+The document is oriented to reading DWARF version 2 
+and version 3.
+There are certain sections which are SGI-specific (those
+are clearly identified in the document).
+.P
+\*(vE
+
+.AE
+.MT 4
+
+.H 1 "INTRODUCTION"
+This document describes an interface to \fIlibdwarf\fP, a
+library of functions to provide access to DWARF debugging information
+records, DWARF line number information, DWARF address range and global 
+names information, weak names information, DWARF frame description 
+information, DWARF static function names, DWARF static variables, and 
+DWARF type information.
+.P
+The document has long mentioned the  
+"Unix International Programming Languages Special Interest Group" 
+(PLSIG), under whose auspices the
+DWARF committtee was formed around 1991.
+"Unix International"  
+was disbanded in the 1990's and no longer exists.
+.P
+The DWARF committee published DWARF2 July 27, 1993.
+.P
+In the mid 1990's this document and the library it describes
+(which the committee never endorsed, having decided
+not to endorse or approve any particular library interface)
+was made available on the internet by Silcon Graphics, Inc.
+.P
+In 2005 the DWARF committee began an affiliation with FreeStandards.org.
+In 2007 FreeStandards.org merged with The Linux Foundation.
+The DWARF committee dropped its affiliation with FreeStandards.org
+in 2007 and established the dwarfstd.org website.
+See "http://www.dwarfstd.org" for current
+information on standardization activities 
+and a copy of the standard.
+.H 2 "Copyright"
+Copyright 1993-2006 Silicon Graphics, Inc.
+
+Copyright 2007 David Anderson. 
+
+Permission is hereby granted to 
+copy or republish or use any or all of this document without
+restriction except that when publishing more than a small amount
+of the document
+please acknowledge Silicon Graphics, Inc and David Anderson.
+
+This document is distributed in the hope that it would be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+.P
+
+.H 2 "Purpose and Scope"
+The purpose of this document is to document a library of functions 
+to access DWARF debugging information. There is no effort made in 
+this document to address the creation of these records as those
+issues are addressed separately 
+(see "A Producer Library Interface to DWARF").
+
+.P
+Additionally, the focus of this document is the functional interface,
+and as such, implementation as well as optimization issues are
+intentionally ignored.
+
+
+.H 2 "Document History"
+.P
+A document was written about 1991 which had similar
+layout and interfaces. 
+Written by people from Hal Corporation,
+That document described a library for reading DWARF1.
+The authors distributed paper copies to the committee
+with the clearly expressed intent to propose the document as
+a supported interface definition.
+The committee decided not to pursue a library definition.
+.P
+SGI wrote the document you are now reading in 1993
+with a similar layout and content and organization, but 
+it was complete document rewrite with the intent to read DWARF2
+(the DWARF version then in existence).
+The intent was (and is) to also cover
+future revisions of DWARF.
+All the function interfaces were changed 
+in 1994 to uniformly
+return a simple integer success-code (see DW_DLV_OK etc), 
+generally following
+the recomendations in the chapter titled "Candy Machine Interfaces"
+of "Writing Solid Code", a book by
+Steve Maguire (published by Microsoft Press).
+.H 2 "Definitions"
+DWARF debugging information entries (DIEs) are the segments of information 
+placed in the \f(CW.debug_*\fP sections by compilers, assemblers, and 
+linkage editors that, in conjunction with line number entries, are 
+necessary for symbolic source-level debugging.  
+Refer to the latest
+"\fIDWARF Debugging Information Format\fP" from www.dwarfstd.org for a more 
+complete description of these entries.
+
+.P
+This document adopts all the terms and definitions in "\fIDWARF Debugging 
+Information Format\fP" versions 2 and 3.  
+It originally focused on the implementation at
+Silicon Graphics, Inc., but now
+attempts to be more generally useful.
+
+.H 2 "Overview"
+The remaining sections of this document describe the proposed interface
+to \f(CWlibdwarf\fP, first by describing the purpose of additional types
+defined by the interface, followed by descriptions of the available 
+operations.  This document assumes you are thoroughly familiar with the 
+information contained in the \fIDWARF Debugging Information Format\fP 
+document. 
+.P
+We separate the functions into several categories to emphasize that not 
+all consumers want to use all the functions.  We call the categories 
+Debugger, Internal-level, High-level, and Miscellaneous not because one is more 
+important than another but as a way of making the rather large set of 
+function calls easier to understand.
+.P
+Unless otherwise specified, all functions and structures should be
+taken as being designed for Debugger consumers.
+.P
+The Debugger Interface of this library is intended to be used by debuggers. 
+The interface is low-level (close to dwarf) but suppresses irrelevant detail.
+A debugger will want to absorb all of some sections at startup and will 
+want to see little or nothing of some sections except at need.  And even 
+then will probably want to absorb only the information in a single compilation 
+unit at a time.  A debugger does not care about
+implementation details of the library.
+.P
+The Internal-level Interface is for a DWARF prettyprinter and checker.  
+A 
+thorough prettyprinter will want to know all kinds of internal things 
+(like actual FORM numbers and actual offsets) so it can check for 
+appropriate structure in the DWARF data and print (on request) all 
+that internal information for human users and libdwarf authors and 
+compiler-writers.  
+Calls in this interface provide data a debugger 
+does not care about.
+.P
+The High-level Interface is for higher level access
+(it's not really a high level interface!).  
+Programs such as 
+disassemblers will want to be able to display relevant information 
+about functions and line numbers without having to invest too much 
+effort in looking at DWARF.
+.P
+The miscellaneous interface is just what is left over: the error handler 
+functions.
+.P
+The following is a brief mention of the changes in this libdwarf from 
+the libdwarf draft for DWARF Version 1 and recent changes.
+.H 2 "Items Changed"
+.P
+Added support for various DWARF3 features, but primarily
+a new frame-information interface tailorable at run-time
+to more than a single ABI.
+See dwarf_set_frame_rule_inital_value() and dwarf_set_frame_rule_table_size().
+See also dwarf_get_fde_info_for_reg3() and
+dwarf_get_fde_info_for_cfa_reg3().  (April 2006)
+.P
+Added support for DWARF3 .debug_pubtypes section.
+Corrected various leaks (revising dealloc() calls, adding
+new functions) and corrected dwarf_formstring() documentation.
+.P 
+Added dwarf_srclines_dealloc() as the previous deallocation
+method documented for data returned by
+dwarf_srclines() was incapable of freeing
+all the allocated storage (14 July 2005).
+.P
+dwarf_nextglob(), dwarf_globname(), and dwarf_globdie() were all changed 
+to operate on the items in the .debug_pubnames section.
+.P
+All functions were modified to return solely an error code.
+Data is returned through pointer arguments.
+This makes writing safe and correct library-using-code far easier.
+For justification for this approach, see the book by
+Steve Maguire titled "Writing Solid Code" at your bookstore.
+
+
+.H 2 "Items Removed"
+.P
+Dwarf_Type
+was removed since types are no longer special.
+.P
+dwarf_typeof()
+was removed since types are no longer special.
+.P
+Dwarf_Ellist
+was removed since element lists no longer are a special format.
+.P
+Dwarf_Bounds
+was removed since bounds have been generalized.
+.P
+dwarf_nextdie()
+was replaced by dwarf_next_cu_header() to reflect the
+real way DWARF is organized.
+The dwarf_nextdie() was only useful for getting to compilation
+unit beginnings, so it does not seem harmful to remove it in favor
+of a more direct function.
+.P
+dwarf_childcnt() is removed on grounds
+that no good use was apparent.
+.P
+dwarf_prevline() and dwarf_nextline() were removed on grounds this
+is better left to a debugger to do.
+Similarly, dwarf_dieline() was removed.
+.P
+dwarf_is1stline() was removed as it was not meaningful for the
+revised DWARF line operations.
+.P
+Any libdwarf implementation might well decide to support all the
+removed functionality and to retain the DWARF Version 1 meanings
+of that functionality.  
+This would be difficult because the
+original libdwarf draft
+specification used traditional C library interfaces which
+confuse the values returned by successful calls with
+exceptional conditions like failures and 'no more data' indications.
+
+.H 2 "Revision History"
+.VL 15
+.LI "March 93"
+Work on DWARF2 SGI draft begins
+.LI "June 94"
+The function returns are changed to return an error/success code
+only.
+.LI "April 2006:
+Support for DWARF3 consumer operations is close to completion.
+.LE
+
+.H 1 "Types Definitions"
+
+.H 2 "General Description"
+The \fIlibdwarf.h\fP header file contains typedefs and preprocessor 
+definitions of types and symbolic names used to reference objects 
+of \fIlibdwarf\fP. The types defined by typedefs contained in 
+\fIlibdwarf.h\fP all use the convention of adding \f(CWDwarf_\fP 
+as a prefix and can be placed in three categories: 
+
+.BL
+.LI
+Scalar types : The scalar types defined in \fIlibdwarf.h\fP are
+defined primarily for notational convenience and identification.
+Depending on the individual definition, they are interpreted as a 
+value, a pointer, or as a flag.
+.LI
+Aggregate types : Some values can not be represented by a single 
+scalar type; they must be represented by a collection of, or as a 
+union of, scalar and/or aggregate types. 
+.LI
+Opaque types : The complete definition of these types is intentionally
+omitted; their use is as handles for query operations, which will yield
+either an instance of another opaque type to be used in another query, or 
+an instance of a scalar or aggregate type, which is the actual result.
+.P
+
+.H 2 "Scalar Types"
+The following are the defined by \fIlibdwarf.h\fP:
+
+.DS
+\f(CW
+typedef int                Dwarf_Bool;
+typedef unsigned long long Dwarf_Off;
+typedef unsigned long long Dwarf_Unsigned;
+typedef unsigned short     Dwarf_Half;
+typedef unsigned char      Dwarf_Small;
+typedef signed long long   Dwarf_Signed;
+typedef unsigned long long Dwarf_Addr;
+typedef void 		   *Dwarf_Ptr;
+typedef void   (*Dwarf_Handler)(Dwarf_Error *error, Dwarf_Ptr errarg);
+.DE
+
+.nr aX \n(Fg+1
+Dwarf_Ptr is an address for use by the host program calling the library,
+not for representing pc-values/addresses within the target object file.
+Dwarf_Addr is for pc-values within the target object file.  The sample 
+scalar type assignments above are for a \fIlibdwarf.h\fP that can read 
+and write
+32-bit or 64-bit binaries on a 32-bit or 64-bit host machine.
+The types must be  defined appropriately
+for each implementation of libdwarf.
+A description of these scalar types in the SGI/MIPS
+environment is given in Figure \n(aX.
+
+.DS
+.TS
+center box, tab(:);
+lfB lfB lfB lfB
+l c c l.
+NAME:SIZE:ALIGNMENT:PURPOSE
+_
+Dwarf_Bool:4:4:Boolean states
+Dwarf_Off:8:8:Unsigned file offset
+Dwarf_Unsigned:8:8:Unsigned large integer
+Dwarf_Half:2:2:Unsigned medium integer
+Dwarf_Small:1:1:Unsigned small integer
+Dwarf_Signed:8:8:Signed large integer
+Dwarf_Addr:8:8:Program address
+:::(target program)
+Dwarf_Ptr:4|8:4|8:Dwarf section pointer 
+:::(host program)
+Dwarf_Handler:4|8:4|8:Pointer to
+:::error handler function 
+.TE
+.FG "Scalar Types"
+.DE
+
+.H 2 "Aggregate Types"
+The following aggregate types are defined by 
+\fIlibdwarf.h\fP:
+\f(CWDwarf_Loc\fP,
+\f(CWDwarf_Locdesc\fP,
+\f(CWDwarf_Block\fP, 
+\f(CWDwarf_Frame_Op\fP. 
+\f(CWDwarf_Regtable\fP. 
+\f(CWDwarf_Regtable3\fP. 
+While most of \f(CWlibdwarf\fP acts on or returns simple values or
+opaque pointer types, this small set of structures seems useful.
+
+.H 3 "Location Record"
+The \f(CWDwarf_Loc\fP type identifies a single atom of a location description
+or a location expression.
+
+.DS
+\f(CWtypedef struct {
+        Dwarf_Small        lr_atom;
+        Dwarf_Unsigned     lr_number;
+        Dwarf_Unsigned     lr_number2;
+        Dwarf_Unsigned     lr_offset;  
+} Dwarf_Loc;\fP
+.DE
+
+The \f(CWlr_atom\fP identifies the atom corresponding to the \f(CWDW_OP_*\fP 
+definition in \fIdwarf.h\fP and it represents the operation to be performed 
+in order to locate the item in question.
+
+.P
+The \f(CWlr_number\fP field is the operand to be used in the calculation
+specified by the \f(CWlr_atom\fP field; not all atoms use this field.
+Some atom operations imply signed numbers so it is necessary to cast 
+this to a \f(CWDwarf_Signed\fP type for those operations.
+
+.P
+The \f(CWlr_number2\fP field is the second operand specified by the 
+\f(CWlr_atom\fP field; only \f(CWDW_OP_BREGX\fP has this field.  Some 
+atom operations imply signed numbers so it may be necessary to cast 
+this to a \f(CWDwarf_Signed\fP type for those operations.
+
+.P
+The \f(CWlr_offset\fP field is the byte offset (within the block the 
+location record came from) of the atom specified by the \f(CWlr_atom\fP 
+field.  This is set on all atoms.  This is useful for operations 
+\f(CWDW_OP_SKIP\fP and \f(CWDW_OP_BRA\fP.
+
+.H 3 "Location Description"
+The \f(CWDwarf_Locdesc\fP type represents an ordered list of 
+\f(CWDwarf_Loc\fP records used in the calculation to locate 
+an item.  Note that in many cases, the location can only be 
+calculated at runtime of the associated program.
+
+.DS
+\f(CWtypedef struct {
+        Dwarf_Addr        ld_lopc;
+        Dwarf_Addr        ld_hipc;
+        Dwarf_Unsigned    ld_cents;
+        Dwarf_Loc*        ld_s;
+} Dwarf_Locdesc;\fP
+.DE
+
+The \f(CWld_lopc\fP and \f(CWld_hipc\fP fields provide an address range for
+which this location descriptor is valid.  Both of these fields are set to
+\fIzero\fP if the location descriptor is valid throughout the scope of the
+item it is associated with.  These addresses are virtual memory addresses, 
+not offsets-from-something.  The virtual memory addresses do not account 
+for dso movement (none of the pc values from libdwarf do that, it is up to 
+the consumer to do that).
+
+.P
+The \f(CWld_cents\fP field contains a count of the number of \f(CWDwarf_Loc\fP 
+entries pointed to by the \f(CWld_s\fP field.
+
+.P
+The \f(CWld_s\fP field points to an array of \f(CWDwarf_Loc\fP records. 
+
+.H 3 "Data Block"
+.SP
+The \f(CWDwarf_Block\fP type is used to contain the value of an attribute
+whose form is either \f(CWDW_FORM_block1\fP, \f(CWDW_FORM_block2\fP, 
+\f(CWDW_FORM_block4\fP, \f(CWDW_FORM_block8\fP, or \f(CWDW_FORM_block\fP.
+Its intended use is to deliver the value for an attribute of any of these 
+forms.
+
+.DS
+\f(CWtypedef struct {
+        Dwarf_Unsigned     bl_len;
+        Dwarf_Ptr          bl_data;
+} Dwarf_Block;\fP
+.DE
+
+.P
+The \f(CWbl_len\fP field contains the length in bytes of the data pointed
+to by the \f(CWbl_data\fP field. 
+
+.P
+The \f(CWbl_data\fP field contains a pointer to the uninterpreted data.
+Since we use  a \f(CWDwarf_Ptr\fP here one must copy the pointer to some 
+other type (typically an \f(CWunsigned char *\fP) so one can add increments 
+to index through the data.  The data pointed to by \f(CWbl_data\fP is not 
+necessarily at any useful alignment.
+
+.H 3 "Frame Operation Codes: DWARF 2"
+This interface is adequate for DWARF2 but not for DWARF3.
+A separate interface usable for DWARF3 and for DWARF2 is described below.
+.P
+The DWARF2 \f(CWDwarf_Frame_Op\fP type is used to contain the data of a single
+instruction of an instruction-sequence of low-level information from the 
+section containing frame information.  This is ordinarily used by 
+Internal-level Consumers trying to print everything in detail.
+
+.DS
+\f(CWtypedef struct {
+	Dwarf_Small  fp_base_op;
+	Dwarf_Small  fp_extended_op;
+	Dwarf_Half   fp_register;
+	Dwarf_Signed fp_offset;
+	Dwarf_Offset fp_instr_offset;
+} Dwarf_Frame_Op;
+.DE
+
+\f(CWfp_base_op\fP is the 2-bit basic op code.  \f(CWfp_extended_op\fP is 
+the 6-bit extended opcode (if \f(CWfp_base_op\fP indicated there was an 
+extended op code) and is zero otherwise.
+.P
+\f(CWfp_register\fP 
+is any (or the first) register value as defined
+in the \f(CWCall Frame Instruction Encodings\fP figure
+in the \f(CWdwarf\fP document.
+If not used with the Op it is 0.
+.P
+\f(CWfp_offset\fP
+is the address, delta, offset, or second register as defined
+in the \f(CWCall Frame Instruction Encodings\fP figure
+in the \f(CWdwarf\fP document.
+If this is an \f(CWaddress\fP then the value should be cast to
+\f(CW(Dwarf_Addr)\fP before being used.
+In any implementation this field *must* be as large as the
+larger of Dwarf_Signed and Dwarf_Addr for this to work properly.
+If not used with the op it is 0.
+.P
+\f(CWfp_instr_offset\fP is the byte_offset (within the instruction
+stream of the frame instructions) of this operation.  It starts at 0
+for a given frame descriptor.
+
+.H 3 "Frame Regtable: DWARF 2"
+This interface is adequate for DWARF2 but not for DWARF3.
+A separate interface usable for DWARF3 and for DWARF2 is described below.
+.P
+The \f(CWDwarf_Regtable\fP type is used to contain the 
+register-restore information for all registers at a given
+PC value.
+Normally used by debuggers.
+.DS
+/* DW_REG_TABLE_SIZE must reflect the number of registers
+ *(DW_FRAME_LAST_REG_NUM) as defined in dwarf.h
+ */
+#define DW_REG_TABLE_SIZE  <fill in size here, 66 for MIPS/IRIX>
+\f(CWtypedef struct {
+    struct {
+        Dwarf_Small         dw_offset_relevant;
+        Dwarf_Half          dw_regnum;
+        Dwarf_Addr          dw_offset;
+    }                       rules[DW_REG_TABLE_SIZE];
+} Dwarf_Regtable;\fP
+.DE
+.P
+The array is indexed by register number.
+The field values for each index are described next.
+For clarity we describe the field values for index rules[M]
+(M being any legal array element index).
+.P
+\f(CWdw_offset_relevant\fP is non-zero to indicate the \f(CWdw_offset\fP
+field is meaningful. If zero then the \f(CWdw_offset\fP is zero
+and should be ignored.
+.P
+\f(CWdw_regnum \fPis the register number\fP applicable.
+If \f(CWdw_offset_relevant\fP is zero, then this is the register
+number of the register containing the value for register M.
+If \f(CWdw_offset_relevant\fP is non-zero, then this is
+the register number of the register to use as a base (M may be
+DW_FRAME_CFA_COL, for example) and the \f(CWdw_offset\fP
+value applies.  The value of register M is therefore
+the value of register \f(CWdw_regnum\vP .
+.P
+\f(CWdw_offset\fP should be ignored if \f(CWdw_offset_relevant\fP is zero.
+If \f(CWdw_offset_relevant\fP is non-zero, then 
+the consumer code should add the value to
+the value of the register \f(CWdw_regnum\fP to produce the
+value.  
+
+.H 3 "Frame Operation Codes: DWARF 3 (and DWARF2)"
+This interface is adequate for DWARF3 and for DWARF2.
+It is new in libdwarf in April 2006.
+.P
+The DWARF2 \f(CWDwarf_Frame_Op3\fP type is used to contain the data of a single
+instruction of an instruction-sequence of low-level information from the 
+section containing frame information.  This is ordinarily used by 
+Internal-level Consumers trying to print everything in detail.
+
+.DS
+\f(CWtypedef struct {
+        Dwarf_Small     fp_base_op;
+        Dwarf_Small     fp_extended_op;
+        Dwarf_Half      fp_register;
+
+        /* Value may be signed, depends on op.
+           Any applicable data_alignment_factor has
+           not been applied, this is the  raw offset. */
+        Dwarf_Unsigned  fp_offset_or_block_len;
+        Dwarf_Small     *fp_expr_block;
+
+        Dwarf_Off       fp_instr_offset;
+} Dwarf_Frame_Op3;\fP
+.DE
+
+\f(CWfp_base_op\fP is the 2-bit basic op code.  \f(CWfp_extended_op\fP is 
+the 6-bit extended opcode (if \f(CWfp_base_op\fP indicated there was an 
+extended op code) and is zero otherwise.
+.P
+\f(CWfp_register\fP 
+is any (or the first) register value as defined
+in the \f(CWCall Frame Instruction Encodings\fP figure
+in the \f(CWdwarf\fP document.
+If not used with the Op it is 0.
+.P
+\f(CWfp_offset_or_block_len\fP
+is the address, delta, offset, or second register as defined
+in the \f(CWCall Frame Instruction Encodings\fP figure
+in the \f(CWdwarf\fP document. Or (depending on the op, it
+may be the length of the dwarf-expression block pointed to
+by \f(CWfp_expr_block\fP.
+If this is an \f(CWaddress\fP then the value should be cast to
+\f(CW(Dwarf_Addr)\fP before being used.
+In any implementation this field *must* be as large as the
+larger of Dwarf_Signed and Dwarf_Addr for this to work properly.
+If not used with the op it is 0.
+.P
+\f(CWfp_expr_block\fP (if applicable to the op)
+points to a dwarf-expression block whch is \f(CWfp_offset_or_block_len\fP
+bytes long.
+.P
+\f(CWfp_instr_offset\fP is the byte_offset (within the instruction
+stream of the frame instructions) of this operation.  It starts at 0
+for a given frame descriptor.
+
+.H 3 "Frame Regtable: DWARF 3"
+This interface is adequate for DWARF3 and for DWARF2.
+It is new in libdwarf as of April 2006.
+.P
+The \f(CWDwarf_Regtable3\fP type is used to contain the 
+register-restore information for all registers at a given
+PC value.
+Normally used by debuggers.
+.DS
+\f(CWtypedef struct Dwarf_Regtable_Entry3_s {
+        Dwarf_Small         dw_offset_relevant;
+        Dwarf_Small         dw_value_type;
+        Dwarf_Half          dw_regnum;
+        Dwarf_Unsigned      dw_offset_or_block_len;
+        Dwarf_Ptr           dw_block_ptr;
+}Dwarf_Regtable_Entry3;
+
+typedef struct Dwarf_Regtable3_s {
+    struct Dwarf_Regtable_Entry3_s   rt3_cfa_rule;
+
+    Dwarf_Half                       rt3_reg_table_size;
+    struct Dwarf_Regtable_Entry3_s * rt3_rules;
+} Dwarf_Regtable3;\fP
+
+.DE
+.P
+The array is indexed by register number.
+The field values for each index are described next.
+For clarity we describe the field values for index rules[M]
+(M being any legal array element index).
+(DW_FRAME_CFA_COL3  DW_FRAME_SAME_VAL, DW_FRAME_UNDEFINED_VAL
+are not legal array indexes, nor is any index < 0 or >
+rt3_reg_table_size);
+The caller  of routines using this
+struct must create data space for rt3_reg_table_size entries
+of struct Dwarf_Regtable_Entry3_s and arrange that
+rt3_rules points to that space and that rt3_reg_table_size
+is set correctly.  The caller need not (but may)
+initialize the contents of the rt3_cfa_rule or the rt3_rules array.
+The following applies to each rt3_rules rule M:
+.P
+.in +4
+\f(CWdw_regnum\fP is the register number applicable.
+If \f(CWdw_regnum\fP is DW_FRAME_UNDEFINED_VAL, then the
+register I has undefined value.
+If \f(CWdw_regnum\fP is DW_FRAME_SAME_VAL, then the
+register I has the same value as in the previous frame.
+.P
+If \f(CWdw_regnum\fP is neither of these two, then the following apply:
+.P
+.P
+\f(CWdw_value_type\fP determines the meaning of the other fields.
+It is one of DW_EXPR_OFFSET (0),
+DW_EXPR_VAL_OFFSET(1), DW_EXPR_EXPRESSION(2) or 
+DW_EXPR_VAL_EXPRESSION(3).
+
+.P
+If \f(CWdw_value_type\fP  is DW_EXPR_OFFSET (0) then
+this is as in DWARF2 and the offset(N) rule  or the register(R)
+rule
+of the DWARF3 and DWARF2 document applies.
+The value is either:
+.in +4
+If \f(CWdw_offset_relevant\fP is non-zero, then \f(CWdw_regnum\fP  
+is effectively ignored but must be identical to
+DW_FRAME_CFA_COL3 and the \f(CWdw_offset\fP value applies. 
+The value of register M is therefore
+the value of CFA plus the value
+of \f(CWdw_offset\fP.   The result of the calculation
+is the address in memory where the value of register M resides.
+This is the offset(N) rule of the DWARF2 and DWARF3 documents.
+.P
+\f(CWdw_offset_relevant\fP is zero it indicates the \f(CWdw_offset\fP
+field is not meaningful. 
+The value of register M is 
+the value currently in register \f(CWdw_regnum\fP (the
+value DW_FRAME_CFA_COL3 must not appear, only real registers).
+This is the register(R) rule of the DWARF3 spec.
+.in -4
+
+.P
+If \f(CWdw_value_type\fP  is DW_EXPR_OFFSET (1) then
+this is the the val_offset(N) rule of the DWARF3 spec applies.
+The calculation is identical to that of DW_EXPR_OFFSET (0) 
+but the value is interpreted as the value of register M
+(rather than the address where register M's value is stored).
+.P
+If \f(CWdw_value_type\fP  is DW_EXPR_EXPRESSION (2) then
+this is the the expression(E) rule of the DWARF3 document.
+.P
+.in +4
+\f(CWdw_offset_or_block_len\fP is the length in bytes of
+the in-memory block  pointed at by \f(CWdw_block_ptr\fP.
+\f(CWdw_block_ptr\fP is a DWARF expression.
+Evaluate that expression and the result is the address
+where the previous value of register M is found.
+.in -4
+.P
+If \f(CWdw_value_type\fP  is DW_EXPR_VAL_EXPRESSION (3) then
+this is the the val_expression(E) rule of the DWARF3 spec.
+.P
+.in +4
+\f(CWdw_offset_or_block_len\fP is the length in bytes of
+the in-memory block  pointed at by \f(CWdw_block_ptr\fP.
+\f(CWdw_block_ptr\fP is a DWARF expression.
+Evaluate that expression and the result is the 
+previous value of register M.
+.in -4
+.P
+The rule \f(CWrt3_cfa_rule\fP is the current value of
+the CFA. It is interpreted exactly like
+any register M rule (as described just above) except that 
+\f(CWdw_regnum\fP cannot be CW_FRAME_CFA_REG3 or
+DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL but must
+be a real register number.
+.in -4
+
+
+
+.H 3 "Macro Details Record"
+The \f(CWDwarf_Macro_Details\fP type gives information about
+a single entry in the .debug.macinfo section.
+.DS
+\f(CWstruct Dwarf_Macro_Details_s {
+  Dwarf_Off    dmd_offset;
+  Dwarf_Small  dmd_type;  
+  Dwarf_Signed dmd_lineno;
+  Dwarf_Signed dmd_fileindex;
+  char *       dmd_macro;
+};
+typedef struct Dwarf_Macro_Details_s Dwarf_Macro_Details;
+.DE
+.P
+\f(CWdmd_offset\fP is the byte offset, within the .debug_macinfo
+section, of this macro information.
+.P
+\f(CWdmd_type\fP is the type code of this macro info entry
+(or 0, the type code indicating that this is the end of
+macro information entries for a compilation unit.
+See \f(CWDW_MACINFO_define\fP, etc in the DWARF document.
+.P
+\f(CWdmd_lineno\fP is the line number where this entry was found,
+or 0 if there is no applicable line number.
+.P
+\f(CWdmd_fileindex\fP is the file index of the file involved.
+This is only guaranteed meaningful on a \f(CWDW_MACINFO_start_file\fP
+\f(CWdmd_type\fP.  Set to -1 if unknown (see the functional
+interface for more details).
+.P
+\f(CWdmd_macro\fP is the applicable string.
+For a \f(CWDW_MACINFO_define\fP
+this is the macro name and value.
+For a
+\f(CWDW_MACINFO_undef\fP, or
+this is the macro name.
+For a
+\f(CWDW_MACINFO_vendor_ext\fP
+this is the vendor-defined string value.
+For other \f(CWdmd_type\fPs this is 0.
+
+.H 2 "Opaque Types"
+The opaque types declared in \fIlibdwarf.h\fP are used as descriptors
+for queries against DWARF information stored in various debugging 
+sections.  Each time an instance of an opaque type is returned as a 
+result of a \fIlibdwarf\fP operation (\f(CWDwarf_Debug\fP excepted), 
+it should be free'd, using \f(CWdwarf_dealloc()\fP when it is no longer 
+of use (read the following documentation for details, as in at least
+one case there is a special routine provided for deallocation
+and \f(CWdwarf_dealloc()\fP is not directly called: 
+see \f(CWdwarf_srclines()\fP).
+Some functions return a number of instances of an opaque type 
+in a block, by means of a pointer to the block and a count of the number
+of opaque descriptors in the block:
+see the function description for deallocation rules for such functions.
+The list of opaque types defined 
+in \fIlibdwarf.h\fP that are pertinent to the Consumer Library, and their 
+intended use is described below.
+
+.DS
+\f(CWtypedef struct Dwarf_Debug_s* Dwarf_Debug;\fP
+.DE
+An instance of the \f(CWDwarf_Debug\fP type is created as a result of a 
+successful call to \f(CWdwarf_init()\fP, or \f(CWdwarf_elf_init()\fP, 
+and is used as a descriptor for subsequent access to most \f(CWlibdwarf\fP
+functions on that object.  The storage pointed to by this descriptor 
+should be not be free'd, using the \f(CWdwarf_dealloc()\fP function.
+Instead free it with \f(CWdwarf_finish()\fP.
+.P
+
+.DS
+\f(CWtypedef struct Dwarf_Die_s* Dwarf_Die;\fP
+.DE
+An instance of a \f(CWDwarf_Die\fP type is returned from a successful 
+call to the \f(CWdwarf_siblingof()\fP, \f(CWdwarf_child\fP, or 
+\f(CWdwarf_offdie()\fP function, and is used as a descriptor for queries 
+about information related to that DIE.  The storage pointed to by this 
+descriptor should be free'd, using \f(CWdwarf_dealloc()\fP with the allocation 
+type \f(CWDW_DLA_DIE\fP when no longer needed.
+
+.DS
+\f(CWtypedef struct Dwarf_Line_s* Dwarf_Line;\fP
+.DE
+Instances of \f(CWDwarf_Line\fP type are returned from a successful call 
+to the \f(CWdwarf_srclines()\fP function, and are used as descriptors for 
+queries about source lines.  The storage pointed to by these descriptors
+should be individually free'd, using \f(CWdwarf_dealloc()\fP with the 
+allocation type \f(CWDW_DLA_LINE\fP when no longer needed.
+
+.DS
+\f(CWtypedef struct Dwarf_Global_s* Dwarf_Global;\fP
+.DE
+Instances of \f(CWDwarf_Global\fP type are returned from a successful 
+call to the \f(CWdwarf_get_globals()\fP function, and are used as 
+descriptors for queries about global names (pubnames).
+
+.DS
+\f(CWtypedef struct Dwarf_Weak_s* Dwarf_Weak;\fP
+.DE
+Instances of \f(CWDwarf_Weak\fP type are returned from a successful call 
+to the 
+SGI-specific \f(CWdwarf_get_weaks()\fP
+function, and are used as descriptors for 
+queries about weak names.  The storage pointed to by these descriptors 
+should be individually free'd, using \f(CWdwarf_dealloc()\fP with the 
+allocation type 
+\f(CWDW_DLA_WEAK_CONTEXT\fP 
+(or
+\f(CWDW_DLA_WEAK\fP, an older name, supported for compatibility)
+when no longer needed.
+
+.DS
+\f(CWtypedef struct Dwarf_Func_s* Dwarf_Func;\fP
+.DE
+Instances of \f(CWDwarf_Func\fP type are returned from a successful
+call to the 
+SGI-specific \f(CWdwarf_get_funcs()\fP
+function, and are used as 
+descriptors for queries about static function names.  
+
+.DS
+\f(CWtypedef struct Dwarf_Type_s* Dwarf_Type;\fP
+.DE
+Instances of \f(CWDwarf_Type\fP type are returned from a successful call 
+to the 
+SGI-specific \f(CWdwarf_get_types()\fP
+function, and are used as descriptors for 
+queries about user defined types.  
+
+.DS
+\f(CWtypedef struct Dwarf_Var_s* Dwarf_Var;\fP
+.DE
+Instances of \f(CWDwarf_Var\fP type are returned from a successful call 
+to the SGI-specific \f(CWdwarf_get_vars()\fP
+function, and are used as descriptors for 
+queries about static variables.  
+
+.DS
+\f(CWtypedef struct Dwarf_Error_s* Dwarf_Error;\fP
+.DE
+This descriptor points to a structure that provides detailed information
+about errors detected by \f(CWlibdwarf\fP.  Users typically provide a
+location for \f(CWlibdwarf\fP to store this descriptor for the user to
+obtain more information about the error.  The storage pointed to by this
+descriptor should be free'd, using \f(CWdwarf_dealloc()\fP with the 
+allocation type \f(CWDW_DLA_ERROR\fP when no longer needed.
+
+.DS
+\f(CWtypedef struct Dwarf_Attribute_s* Dwarf_Attribute;\fP
+.DE
+Instances of \f(CWDwarf_Attribute\fP type are returned from a successful 
+call to the \f(CWdwarf_attrlist()\fP, or \f(CWdwarf_attr()\fP functions, 
+and are used as descriptors for queries about attribute values.  The storage 
+pointed to by this descriptor should be individually free'd, using 
+\f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_ATTR\fP when 
+no longer needed.
+
+.DS
+\f(CWtypedef struct Dwarf_Abbrev_s* Dwarf_Abbrev;\fP
+.DE
+An instance of a \f(CWDwarf_Abbrev\fP type is returned from a successful 
+call to \f(CWdwarf_get_abbrev()\fP, and is used as a descriptor for queries 
+about abbreviations in the .debug_abbrev section.  The storage pointed to 
+by this descriptor should be free'd, using \f(CWdwarf_dealloc()\fP with the
+allocation type \f(CWDW_DLA_ABBREV\fP when no longer needed.
+
+.DS
+\f(CWtypedef struct Dwarf_Fde_s* Dwarf_Fde;\fP
+.DE
+Instances of \f(CWDwarf_Fde\fP type are returned from a successful call 
+to the \f(CWdwarf_get_fde_list()\fP, \f(CWdwarf_get_fde_for_die()\fP, or
+\f(CWdwarf_get_fde_at_pc()\fP functions, and are used as descriptors for 
+queries about frames descriptors.
+
+.DS
+\f(CWtypedef struct Dwarf_Cie_s* Dwarf_Cie;\fP
+.DE
+Instances of \f(CWDwarf_Cie\fP type are returned from a successful call 
+to the \f(CWdwarf_get_fde_list()\fP function, and are used as descriptors 
+for queries about information that is common to several frames.
+
+.DS
+\f(CWtypedef struct Dwarf_Arange_s* Dwarf_Arange;\fP
+.DE
+Instances of \f(CWDwarf_Arange\fP type are returned from successful calls 
+to the \f(CWdwarf_get_aranges()\fP, or \f(CWdwarf_get_arange()\fP functions, 
+and are used as descriptors for queries about address ranges.  The storage 
+pointed to by this descriptor should be individually free'd, using 
+\f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_ARANGE\fP when 
+no longer needed.
+
+.H 1 "Error Handling"
+The method for detection and disposition of error conditions that arise 
+during access of debugging information via \fIlibdwarf\fP is consistent
+across all \fIlibdwarf\fP functions that are capable of producing an
+error.  This section describes the method used by \fIlibdwarf\fP in
+notifying client programs of error conditions. 
+
+.P
+Most functions within \fIlibdwarf\fP accept as an argument a pointer to 
+a \f(CWDwarf_Error\fP descriptor where a \f(CWDwarf_Error\fP descriptor 
+is stored if an error is detected by the function.  Routines in the client 
+program that provide this argument can query the \f(CWDwarf_Error\fP 
+descriptor to determine the nature of the error and perform appropriate 
+processing. 
+
+.P
+A client program can also specify a function to be invoked upon detection 
+of an error at the time the library is initialized (see \f(CWdwarf_init()\fP). 
+When a \fIlibdwarf\fP routine detects an error, this function is called
+with two arguments: a code indicating the nature of the error and a pointer
+provided by the client at initialization (again see \f(CWdwarf_init()\fP).
+This pointer argument can be used to relay information between the error 
+handler and other routines of the client program.  A client program can 
+specify or change both the error handling function and the pointer argument 
+after initialization using \f(CWdwarf_seterrhand()\fP and 
+\f(CWdwarf_seterrarg()\fP.
+
+.P
+In the case where \fIlibdwarf\fP functions are not provided a pointer
+to a \f(CWDwarf_Error\fP descriptor, and no error handling function was 
+provided at initialization, \fIlibdwarf\fP functions terminate execution 
+by calling \f(CWabort(3C)\fP.
+
+.P
+The following lists the processing steps taken upon detection of an
+error:
+.AL 1
+.LI
+Check the \f(CWerror\fP argument; if not a \fINULL\fP pointer, allocate
+and initialize a \f(CWDwarf_Error\fP descriptor with information describing
+the error, place this descriptor in the area pointed to by \f(CWerror\fP,
+and return a value indicating an error condition.
+.LI
+If an \f(CWerrhand\fP argument was provided to \f(CWdwarf_init()\fP
+at initialization, call \f(CWerrhand()\fP passing it the error descriptor
+and the value of the \f(CWerrarg\fP argument provided to \f(CWdwarf_init()\fP. 
+If the error handling function returns, return a value indicating an 
+error condition.
+.LI
+Terminate program execution by calling \f(CWabort(3C)\fP.
+.LE
+.SP
+
+In all cases, it is clear from the value returned from a function 
+that an error occurred in executing the function, since
+DW_DLV_ERROR is returned.
+.P
+As can be seen from the above steps, the client program can provide
+an error handler at initialization, and still provide an \f(CWerror\fP
+argument to \fIlibdwarf\fP functions when it is not desired to have
+the error handler invoked.
+
+.P
+If a \f(CWlibdwarf\fP function is called with invalid arguments, the 
+behaviour is undefined.  In particular, supplying a \f(CWNULL\fP pointer 
+to a \f(CWlibdwarf\fP function (except where explicitly permitted), 
+or pointers to invalid addresses or uninitialized data causes undefined 
+behaviour; the return value in such cases is undefined, and the function 
+may fail to invoke the caller supplied error handler or to return a 
+meaningful error number.  Implementations also may abort execution for 
+such cases.
+
+.P
+.H 2 "Returned values in the functional interface"
+Values returned by \f(CWlibdwarf\fP functions to indicate 
+success and errors
+.nr aX \n(Fg+1
+are enumerated in Figure \n(aX.
+The \f(CWDW_DLV_NO_ENTRY\fP
+case is useful for functions 
+need to indicate that while there was no data to return
+there was no error either.
+For example, \f(CWdwarf_siblingof()\fP
+may return \f(CWDW_DLV_NO_ENTRY\fP to indicate that that there was
+no sibling to return.
+.DS
+.TS
+center box, tab(:);
+lfB cfB lfB 
+l c l.
+SYMBOLIC NAME:VALUE:MEANING
+_
+DW_DLV_ERROR:1:Error
+DW_DLV_OK:0:Successful call
+DW_DLV_NO_ENTRY:-1:No applicable value
+.TE
+.FG "Error Indications"
+.DE
+.P
+Each function in the interface that returns a value returns one
+of the integers in the above figure.
+.P
+If \f(CWDW_DLV_ERROR\fP is returned and a pointer to a \f(CWDwarf_Error\fP
+pointer is passed to the function, then a Dwarf_Error handle is returned
+thru the pointer. No other pointer value in the interface returns a value.
+After the \f(CWDwarf_Error\fP is no longer of interest,
+a  \f(CWdwarf_dealloc(dbg,dw_err,DW_DLA_ERROR)\fP on the error
+pointer is appropriate to free any space used by the error information.
+.P
+If \f(CWDW_DLV_NO_ENTRY\fP is returned no pointer value in the
+interface returns a value.
+.P
+If \f(CWDW_DLV_OK\fP is returned  the \f(CWDwarf_Error\fP pointer, if
+supplied, is not touched, but any other values to be returned
+through pointers are returned.
+In this case calls (depending on the exact function
+returning the error) to \f(CWdwarf_dealloc()\fP may be appropriate
+once the particular pointer returned is no longer of interest.
+.P
+Pointers passed to allow values to be returned thru them are 
+uniformly the last pointers
+in each argument list.
+.P
+All the interface functions are defined from the point of view of
+the writer-of-the-library (as is traditional for UN*X library
+documentation), not from the point of view of the user of the library.
+The caller might code:
+.P
+.DS
+Dwarf_Line line;
+Dwarf_Signed ret_loff;
+Dwarf_Error  err;
+int retval = dwarf_lineoff(line,&ret_loff,&err); 
+.DE
+for the function defined as
+.P
+.DS
+int dwarf_lineoff(Dwarf_Line line,Dwarf_Signed *return_lineoff,
+  Dwarf_Error* err);
+.DE
+and this document refers to the function as 
+returning the value thru *err or *return_lineoff or 
+uses the phrase "returns in
+the location pointed to by err".
+Sometimes other similar phrases are used.
+
+.H 1 "Memory Management"
+Several of the functions that comprise \fIlibdwarf\fP return pointers 
+(opaque descriptors) to structures that have been dynamically allocated 
+by the library.  To aid in the management of dynamic memory, the function 
+\f(CWdwarf_dealloc()\fP is provided to free storage allocated as a result 
+of a call to a \fIlibdwarf\fP function.  This section describes the strategy 
+that should be taken by a client program in managing dynamic storage.
+
+.H 2 "Read-only Properties"
+All pointers (opaque descriptors) returned by or as a result of a 
+\fIlibdwarf Consumer Library\fP 
+call should be assumed to point to read-only memory.  
+The results are undefined for \fIlibdwarf\fP  clients that attempt 
+to write to a region pointed to by a value returned by a 
+\fIlibdwarf Consumer Library\fP 
+call.
+
+.H 2 "Storage Deallocation"
+See the section "Returned values in the functional interface",
+above, for the general rules where 
+calls to \f(CWdwarf_dealloc()\fP
+is appropriate.
+.P
+In some cases the pointers returned by a \fIlibdwarf\fP call are pointers
+to data which is not free-able.  
+The library knows from the allocation type
+provided to it whether the space is freeable or not and will not free 
+inappropriately when \f(CWdwarf_dealloc()\fP is called.  
+So it is vital
+that \f(CWdwarf_dealloc()\fP be called with the proper allocation type.
+.P
+For most storage allocated by \fIlibdwarf\fP, the client can free the
+storage for reuse by calling \f(CWdwarf_dealloc()\fP, providing it with 
+the \f(CWDwarf_Debug\fP descriptor specifying the object for which the
+storage was allocated, a pointer to the area to be free-ed, and an 
+identifier that specifies what the pointer points to (the allocation
+type).  For example, to free a \f(CWDwarf_Die die\fP belonging the the
+object represented by \f(CWDwarf_Debug dbg\fP, allocated by a call to 
+\f(CWdwarf_siblingof()\fP, the call to \f(CWdwarf_dealloc()\fP would be:
+.DS
+    \f(CWdwarf_dealloc(dbg, die, DW_DLA_DIE);\fP
+.DE
+
+To free storage allocated in the form of a list of pointers (opaque 
+descriptors), each member of the list should be deallocated, followed 
+by deallocation of the actual list itself.  The following code fragment 
+uses an invocation of \f(CWdwarf_attrlist()\fP as an example to illustrate 
+a technique that can be used to free storage from any \fIlibdwarf\fP 
+routine that returns a list:
+.DS
+\f(CWDwarf_Unsigned atcnt;
+Dwarf_Attribute *atlist;
+int errv;
+
+errv = dwarf_attrlist(somedie, &atlist,&atcnt, &error);
+if (errv == DW_DLV_OK) {
+
+        for (i = 0; i < atcnt; ++i) {
+                /* use atlist[i] */
+                dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);
+        }
+        dwarf_dealloc(dbg, atlist, DW_DLA_LIST);
+}\fP
+.DE
+
+The \f(CWDwarf_Debug\fP returned from \f(CWdwarf_init()\fP 
+or \f(CWdwarf_elf_init()\fP 
+cannot be free'd using \f(CWdwarf_dealloc()\fP.
+The function \f(CWdwarf_finish()\fP will deallocate all dynamic storage
+associated with an instance of a \f(CWDwarf_Debug\fP type.  In particular,
+it will deallocate all dynamically allocated space associated with the
+\f(CWDwarf_Debug\fP descriptor, and finally make the descriptor invalid.
+
+An \f(CWDwarf_Error\fP returned from \f(CWdwarf_init()\fP
+or \f(CWdwarf_elf_init()\fP
+in case of a failure cannot be free'd
+using \f(CWdwarf_dealloc()\fP.
+The only way to free the \f(CWDwarf_Error\fP from either of those
+calls is to use \f2free(3)\fP directly.
+Every \f(CWDwarf_Error\fP must be free'd 
+by \f(CWdwarf_dealloc()\fP except those
+returned by \f(CWdwarf_init()\fP
+or \f(CWdwarf_elf_init()\fP.
+
+.P
+The codes that identify the storage pointed to in calls to 
+.nr aX \n(Fg+1
+\f(CWdwarf_dealloc()\fP are described in figure \n(aX.
+.DS
+.TS
+center box, tab(:);
+lfB lfB 
+l l.
+IDENTIFIER:USED TO FREE 
+_
+DW_DLA_STRING           :     char* 
+DW_DLA_LOC              :     Dwarf_Loc 
+DW_DLA_LOCDESC          :     Dwarf_Locdesc 
+DW_DLA_ELLIST           :     Dwarf_Ellist (not used)
+DW_DLA_BOUNDS           :     Dwarf_Bounds (not used) 
+DW_DLA_BLOCK            :     Dwarf_Block 
+DW_DLA_DEBUG            :     Dwarf_Debug (do not use)
+DW_DLA_DIE              :     Dwarf_Die
+DW_DLA_LINE             :     Dwarf_Line 
+DW_DLA_ATTR             :     Dwarf_Attribute 
+DW_DLA_TYPE             :     Dwarf_Type  (not used) 
+DW_DLA_SUBSCR           :     Dwarf_Subscr (not used) 
+DW_DLA_GLOBAL_CONTEXT   :     Dwarf_Global 
+DW_DLA_ERROR            :     Dwarf_Error 
+DW_DLA_LIST             :     a list of opaque descriptors
+DW_DLA_LINEBUF          :     Dwarf_Line* (not used) 
+DW_DLA_ARANGE           :     Dwarf_Arange 
+DW_DLA_ABBREV           :     Dwarf_Abbrev 
+DW_DLA_FRAME_OP         :     Dwarf_Frame_Op 
+DW_DLA_CIE              :     Dwarf_Cie 
+DW_DLA_FDE              :     Dwarf_Fde
+DW_DLA_LOC_BLOCK        :     Dwarf_Loc Block
+DW_DLA_FRAME_BLOCK      :     Dwarf_Frame Block (not used) 
+DW_DLA_FUNC_CONTEXT     :     Dwarf_Func 
+DW_DLA_TYPENAME_CONTEXT :     Dwarf_Type
+DW_DLA_VAR_CONTEXT      :     Dwarf_Var
+DW_DLA_WEAK_CONTEXT	:     Dwarf_Weak
+DW_DLA_PUBTYPES_CONTEXT	:     Dwarf_Pubtype
+.TE
+.FG "Allocation/Deallocation Identifiers"
+.DE
+
+.P
+.H 1 "Functional Interface"
+This section describes the functions available in the \fIlibdwarf\fP
+library.  Each function description includes its definition, followed 
+by one or more paragraph describing the function's operation.
+
+.P
+The following sections describe these functions.
+
+.H 2 "Initialization Operations"
+These functions are concerned with preparing an object file for subsequent
+access by the functions in \fIlibdwarf\fP and with releasing allocated
+resources when access is complete. 
+
+.H 3 "dwarf_init()"
+
+.DS
+\f(CWint dwarf_init(
+        int fd,
+        Dwarf_Unsigned access,
+        Dwarf_Handler errhand, 
+        Dwarf_Ptr errarg,
+	Dwarf_Debug * dbg,
+        Dwarf_Error *error)\fP
+.DE
+When it returns \f(CWDW_DLV_OK\fP,
+the function \f(CWdwarf_init()\fP returns  thru
+\f(CWdbg\fP a \f(CWDwarf_Debug\fP descriptor 
+that represents a handle for accessing debugging records associated with 
+the open file descriptor \f(CWfd\fP.  
+\f(CWDW_DLV_NO_ENTRY\fP is returned if the object
+does not contain DWARF debugging information.
+\f(CWDW_DLV_ERROR\fP is returned if
+an error occurred.
+The 
+\f(CWaccess\fP argument indicates what access is allowed for the section. 
+The \f(CWDW_DLC_READ\fP parameter is valid
+for read access (only read access is defined or discussed in this
+document).  
+The \f(CWerrhand\fP 
+argument is a pointer to a function that will be invoked whenever an error 
+is detected as a result of a \fIlibdwarf\fP operation.  The \f(CWerrarg\fP 
+argument is passed as an argument to the \f(CWerrhand\fP function.  
+The file 
+descriptor associated with the \f(CWfd\fP argument must refer to an ordinary 
+file (i.e. not a pipe, socket, device, /proc entry, etc.), be opened with 
+the at least as much permission as specified by the \f(CWaccess\fP argument, 
+and cannot be closed or used as an argument to any system calls by the 
+client until after \f(CWdwarf_finish()\fP is called.  
+The seek position of 
+the file associated with \f(CWfd\fP is undefined upon return of 
+\f(CWdwarf_init()\fP.
+
+With SGI IRIX, by default it is allowed that the app
+\f(CWclose()\fP \f(CWfd\fP immediately after calling \f(CWdwarf_init()\fP,
+but that is not  a portable approach (that it
+works is an accidental
+side effect of the fact that SGI IRIX uses \f(CWELF_C_READ_MMAP\fP 
+in its hidden internal call to \f(CWelf_begin()\fP).
+The portable approach is to consider that \f(CWfd\fP
+must be left open till after the corresponding dwarf_finish() call
+has returned.
+
+Since \f(CWdwarf_init()\fP uses the same error handling processing as other 
+\fIlibdwarf\fP functions (see \fIError Handling\fP above), client programs 
+will generally supply an \f(CWerror\fP parameter to bypass the default actions 
+during initialization unless the default actions are appropriate. 
+
+.H 3 "dwarf_elf_init()"
+.DS
+\f(CWint dwarf_elf_init(
+        Elf * elf_file_pointer,
+        Dwarf_Unsigned access,
+        Dwarf_Handler errhand, 
+        Dwarf_Ptr errarg,
+	Dwarf_Debug * dbg,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_elf_init()\fP is identical to \f(CWdwarf_init()\fP 
+except that an open \f(CWElf *\fP pointer is passed instead of a file 
+descriptor.  
+In systems supporting \f(CWELF\fP object files this may be 
+more space or time-efficient than using \f(CWdwarf_init()\fP.
+The client is allowed to use the \f(CWElf *\fP pointer
+for its own purposes without restriction during the time the 
+\f(CWDwarf_Debug\fP
+is open, except that the client should not  \f(CWelf_end()\fP the
+pointer till after  \f(CWdwarf_finish\fP is called.
+
+.H 3 "dwarf_get_elf()"
+.DS
+\f(CWint dwarf_get_elf(
+        Dwarf_Debug dbg,
+        Elf **      elf,
+        Dwarf_Error *error)\fP
+.DE
+When it returns \f(CWDW_DLV_OK\fP,
+the function \f(CWdwarf_get_elf()\fP returns thru the
+pointer \f(CWelf\fP the \f(CWElf *\fP handle
+used to access the object represented by the \f(CWDwarf_Debug\fP
+descriptor \f(CWdbg\fP.  It returns \f(CWDW_DLV_ERROR\fP on error.
+
+Because \f(CWint dwarf_init()\fP opens an Elf descriptor
+on its fd and \f(CWdwarf_finish()\fP does not close that
+descriptor, an app should use \f(CWdwarf_get_elf\fP
+and should call \f(CWelf_end\fP with the pointer returned
+thru the \f(CWElf**\fP handle created by \f(CWint dwarf_init()\fP.
+
+This function is not meaningful for a system that does not use the
+Elf format for objects.
+
+.H 3 "dwarf_finish()"
+.DS
+\f(CWint dwarf_finish(
+        Dwarf_Debug dbg,
+	Dwarf_Error *error)\fP
+.DE
+The function
+\f(CWdwarf_finish()\fP releases all \fILibdwarf\fP internal resources 
+associated with the descriptor \f(CWdbg\fP, and invalidates \f(CWdbg\fP.  
+It returns \f(CWDW_DLV_ERROR\fP if there is an error during the
+finishing operation.  It returns \f(CWDW_DLV_OK\fP 
+for a successful operation.
+
+Because \f(CWint dwarf_init()\fP opens an Elf descriptor
+on its fd and \f(CWdwarf_finish()\fP does not close that
+descriptor, an app should use \f(CWdwarf_get_elf\fP
+and should call \f(CWelf_end\fP with the pointer returned
+thru the \f(CWElf**\fP handle created by \f(CWint dwarf_init()\fP.
+
+.H 2 "Debugging Information Entry Delivery Operations"
+These functions are concerned with accessing debugging information 
+entries. 
+
+.H 3 "Debugging Information Entry Debugger Delivery Operations"
+
+.H 3 "dwarf_next_cu_header()"
+.DS
+\f(CWint dwarf_next_cu_header(
+        Dwarf_debug dbg,
+        Dwarf_Unsigned *cu_header_length,
+        Dwarf_Half     *version_stamp,
+        Dwarf_Unsigned *abbrev_offset,
+        Dwarf_Half     *address_size,
+        Dwarf_Unsigned *next_cu_header,
+        Dwarf_Error    *error);
+.DE
+The function
+\f(CWdwarf_next_cu_header()\fP returns \f(CWDW_DLV_ERROR\fP 
+if it fails, and
+\f(CWDW_DLV_OK\fP if it succeeds.
+.P
+If it succeeds, \f(CW*next_cu_header\fP is set to
+the offset in the .debug_info section of the next 
+compilation-unit header if it succeeds.  On reading the last 
+compilation-unit header in the .debug_info section it contains 
+the size of the .debug_info section.
+The next call to 
+\f(CWdwarf_next_cu_header()\fP returns \f(CWDW_DLV_NO_ENTRY\fP
+without reading a 
+compilation-unit or setting \f(CW*next_cu_header\fP.  
+Subsequent calls to \f(CWdwarf_next_cu_header()\fP 
+repeat the cycle by reading the first compilation-unit and so on.  
+.P
+The other 
+values returned through pointers are the values in the compilation-unit 
+header.  If any of \f(CWcu_header_length\fP, \f(CWversion_stamp\fP,
+\f(CWabbrev_offset\fP, or \f(CWaddress_size\fP is \f(CWNULL\fP, the 
+argument is ignored (meaning it is not an error to provide a 
+\f(CWNULL\fP pointer).
+
+.H 3 "dwarf_siblingof()"
+.DS
+\f(CWint dwarf_siblingof(
+        Dwarf_Debug dbg, 
+        Dwarf_Die die, 
+	Dwarf_Die *return_sib,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_siblingof()\fP 
+returns \f(CWDW_DLV_ERROR\fP and sets the \f(CWerror\fP pointer on error.
+If there is no sibling it returns \f(CWDW_DLV_NO_ENTRY\fP.
+When it succeeds,
+\f(CWdwarf_siblingof()\fP returns
+\f(CWDW_DLV_OK\fP  and sets \f(CW*return_sib\fP to the \f(CWDwarf_Die\fP 
+descriptor of the sibling of \f(CWdie\fP.
+If \f(CWdie\fP is \fINULL\fP, the \f(CWDwarf_Die\fP descriptor of the
+first die in the compilation-unit is returned.  
+This die has the
+\f(CWDW_TAG_compile_unit\fP tag.
+.H 3 "dwarf_child()"
+.DS
+\f(CWint dwarf_child(
+        Dwarf_Die die, 
+	Dwarf_Die *return_kid,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_child()\fP 
+returns \f(CWDW_DLV_ERROR\fP and sets the \f(CWerror\fP die on error.
+If there is no child it returns \f(CWDW_DLV_NO_ENTRY\fP.
+When it succeeds,
+\f(CWdwarf_child()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_kid\fP
+to the \f(CWDwarf_Die\fP descriptor 
+of the first child of \f(CWdie\fP.
+The function 
+\f(CWdwarf_siblingof()\fP can be used with the return value of 
+\f(CWdwarf_child()\fP to access the other children of \f(CWdie\fP. 
+
+.H 3 "dwarf_offdie()"
+.DS
+\f(CWint dwarf_offdie(
+        Dwarf_Debug dbg,
+        Dwarf_Off offset, 
+	Dwarf_Die *return_die,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_offdie()\fP 
+returns \f(CWDW_DLV_ERROR\fP and sets the \f(CWerror\fP die on error.
+When it succeeds,
+\f(CWdwarf_offdie()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_die\fP
+to the
+the \f(CWDwarf_Die\fP 
+descriptor of the debugging information entry at \f(CWoffset\fP in 
+the section containing debugging information entries i.e the .debug_info
+section.  
+A return of \f(CWDW_DLV_NO_ENTRY\fP
+means that the \f(CWoffset\fP in the section is of a byte containing
+all 0 bits, indicating that there
+is no abbreviation code. Meaning this 'die offset' is not
+the offset of a real die, but is instead an offset of a null die,
+a padding die, or of some random zero byte: this should
+not be returned in normal use.
+It is the user's 
+responsibility to make sure that \f(CWoffset\fP is the start of a valid 
+debugging information entry.  The result of passing it an invalid 
+offset could be chaos.
+
+.\"#if 0
+.\".H 3 "Debugging Entry Delivery High-level Operations"
+.\"The following "higher level" operations are typically not used by 
+.\"debuggers or DWARF prettyprinters.  A disassembler (for example) 
+.\"might find them useful.
+.\"
+.\".DS
+.\"\f(CWDwarf_Die dwarf_pcfile(
+.\"        Dwarf_Debug dbg, 
+.\"        Dwarf_Addr pc, 
+.\"        Dwarf_Error *error)\fP
+.\".DE
+.\"The function \f(CWdwarf_pcfile()\fP returns the \f(CWDwarf_Die\fP 
+.\"descriptor of the compilation unit debugging information entry that 
+.\"contains the address of \f(CWpc\fP.  It returns \fINULL\fP if no 
+.\"entry exists or an error occurred.  Currently compilation unit 
+.\"debugging information entries are defined as those having a tag of: 
+.\"\f(CWDW_TAG_compile_unit\fP.  This function is currently unimplemented.
+.\"
+.\".DS
+.\"\f(CWDwarf_Die dwarf_pcsubr(
+.\"        Dwarf_Debug dbg, 
+.\"        Dwarf_Addr pc, 
+.\"        Dwarf_Error *error)\fP
+.\".DE
+.\"The function
+.\"\f(CWdwarf_pcsubr()\fP returns the \f(CWDwarf_Die\fP descriptor of the 
+.\"subroutine debugging entry that contains the address of \f(CWpc\fP.  It 
+.\"returns \fINULL\fP if no entry exists or an error occurred.  Currently 
+.\"subroutine debugging information entries are defined as those having a 
+.\"tag of: \f(CWDW_TAG_subprogram\fP, or \f(CWTAG_inlined_subroutine\fP.
+.\"This function is currently unimplemented.
+.\"
+.\".DS
+.\"\f(CWDwarf_Die dwarf_pcscope(
+.\"        Dwarf_Debug dbg, 
+.\"        Dwarf_Addr pc, 
+.\"        Dwarf_Error *error)\fP
+.\".DE
+.\"The function
+.\"\f(CWdwarf_pcscope()\fP returns the \f(CWDwarf_Die\fP descriptor for 
+.\"the debugging information entry that represents the innermost enclosing 
+.\"scope containing \f(CWpc\fP, or \fINULL\fP if no entry exists or an 
+.\"error occurred. Debugging information entries that represent a \fIscope\fP 
+.\"are those containing a low pc attribute and either a high pc or byte 
+.\"size attribute that delineates a range. For example: a debugging information 
+.\"entry for a lexical block is considered one having a scope whereas a 
+.\"debugging information entry for a label is not.  This function is
+.\"currently unimplemented.
+.\"#endif
+
+
+.H 2 "Debugging Information Entry Query Operations"
+These queries return specific information about debugging information 
+entries or a descriptor that can be used on subsequent queries when 
+given a \f(CWDwarf_Die\fP descriptor.  Note that some operations are 
+specific to debugging information entries that are represented by a 
+\f(CWDwarf_Die\fP descriptor of a specific type. 
+For example, not all 
+debugging information entries contain an attribute having a name, so 
+consequently, a call to \f(CWdwarf_diename()\fP using a \f(CWDwarf_Die\fP 
+descriptor that does not have a name attribute will return
+\f(CWDW_DLV_NO_ENTRY\fP.
+This is not an error, i.e. calling a function that needs a specific
+attribute is not an error for a die that does not contain that specific
+attribute.
+.P
+There are several methods that can be used to obtain the value of an
+attribute in a given die:
+.AL 1
+.LI
+Call \f(CWdwarf_hasattr()\fP to determine if the debugging information
+entry has the attribute of interest prior to issuing the query for
+information about the attribute.
+
+.LI
+Supply an \f(CWerror\fP argument, and check its value after the call to 
+a query indicates an unsuccessful return, to determine the nature of the 
+problem.  The \f(CWerror\fP argument will indicate whether an error occurred, 
+or the specific attribute needed was missing in that die.
+
+.LI
+Arrange to have an error handling function invoked upon detection of an 
+error (see \f(CWdwarf_init()\fP).
+
+.LI
+Call \f(CWdwarf_attrlist()\fP and iterate through the returned list of
+attributes, dealing with each one as appropriate.
+.LE
+.P
+
+.H 3 "dwarf_tag()"
+.DS
+\f(CWint dwarf_tag(
+        Dwarf_Die die, 
+	Dwarf_Half *tagval,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_tag()\fP returns the \fItag\fP of \f(CWdie\fP
+thru the pointer  \f(CWtagval\fP if it succeeds. 
+It returns \f(CWDW_DLV_OK\fP if it succeeds.
+It returns \f(CWDW_DLV_ERROR\fP on error.
+
+.H 3 "dwarf_dieoffset()"
+.DS
+\f(CWint dwarf_dieoffset(
+        Dwarf_Die die, 
+	Dwarf_Off * return_offset,
+        Dwarf_Error *error)\fP
+.DE
+When it succeeds,
+the function \f(CWdwarf_dieoffset()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP
+to the position of \f(CWdie\fP 
+in the section containing debugging information entries
+(the \f(CWreturn_offset\fP is a section-relative offset).  
+In other words,
+it sets \f(CWreturn_offset\fP 
+to the offset of the start of the debugging information entry
+described by \f(CWdie\fP in the section containing die's i.e .debug_info.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+
+.H 3 "dwarf_die_CU_offset()"
+.DS
+\f(CWint dwarf_die_CU_offset(
+        Dwarf_Die die,
+  	Dwarf_Off *return_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_die_CU_offset()\fP is similar to 
+\f(CWdwarf_dieoffset()\fP, except that it puts the offset of the DIE 
+represented by the \f(CWDwarf_Die\fP \f(CWdie\fP, from the 
+start of the compilation-unit that it belongs to rather than the start 
+of .debug_info (the \f(CWreturn_offset\fP is a CU-relative offset).  
+
+
+.H 3 "dwarf_diename()"
+.DS
+\f(CWint dwarf_diename(
+        Dwarf_Die die, 
+	char  ** return_name,
+        Dwarf_Error *error)\fP
+.DE
+When it succeeds,
+the function \f(CWdwarf_diename()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP
+to
+a pointer to a
+null-terminated string of characters that represents the name
+attribute of \f(CWdie\fP.
+It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not have a name attribute.
+It returns \f(CWDW_DLV_ERROR\fP if
+an error occurred.  
+The storage pointed to by a successful return of 
+\f(CWdwarf_diename()\fP should be free'd using the allocation type
+\f(CWDW_DLA_STRING\fP when no longer of interest (see 
+\f(CWdwarf_dealloc()\fP).
+
+.H 3 "dwarf_attrlist()"
+.DS
+\f(CWint dwarf_attrlist(
+        Dwarf_Die die, 
+        Dwarf_Attribute** attrbuf, 
+	Dwarf_Signed *attrcount,
+        Dwarf_Error *error)\fP
+.DE
+When it returns \f(CWDW_DLV_OK\fP,
+the function \f(CWdwarf_attrlist()\fP sets \f(CWattrbuf\fP to point 
+to an array of \f(CWDwarf_Attribute\fP descriptors corresponding to
+each of the attributes in die, and returns the number of elements in 
+the array thru \f(CWattrcount\fP.  
+\f(CWDW_DLV_NO_ENTRY\fP is returned if the count is zero (no 
+\f(CWattrbuf\fP is allocated in this case).
+\f(CWDW_DLV_ERROR\fP is returned on error.
+On a successful return from \f(CWdwarf_attrlist()\fP, each of the
+\f(CWDwarf_Attribute\fP descriptors should be individually free'd using 
+\f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_ATTR\fP, 
+followed by free-ing the list pointed to by \f(CW*attrbuf\fP using
+\f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_LIST\fP, 
+when no longer of interest (see \f(CWdwarf_dealloc()\fP).
+
+Freeing the attrlist:
+.in +2
+.DS
+\f(CWDwarf_Unsigned atcnt;
+Dwarf_Attribute *atlist;
+int errv;
+
+errv = dwarf_attrlist(somedie, &atlist,&atcnt, &error);
+if (errv == DW_DLV_OK) {
+
+        for (i = 0; i < atcnt; ++i) {
+                /* use atlist[i] */
+                dwarf_dealloc(dbg, atlist[i], DW_DLA_ATTR);
+        }
+        dwarf_dealloc(dbg, atlist, DW_DLA_LIST);
+}\fP
+.DE
+.in -2
+.P
+.H 3 "dwarf_hasattr()"
+.DS
+\f(CWint dwarf_hasattr(
+        Dwarf_Die die, 
+        Dwarf_Half attr, 
+	Dwarf_Bool *return_bool,
+        Dwarf_Error *error)\fP
+.DE
+When it succeeds, the
+function \f(CWdwarf_hasattr()\fP returns \f(CWDW_DLV_OK\fP
+and sets \f(CW*return_bool\fP to \fInon-zero\fP if 
+\f(CWdie\fP has the attribute \f(CWattr\fP and \fIzero\fP otherwise.
+If it fails, it returns \f(CWDW_DLV_ERROR\fP.
+
+.H 3 "dwarf_attr()"
+.DS
+\f(CWint dwarf_attr(
+        Dwarf_Die die, 
+        Dwarf_Half attr, 
+	Dwarf_Attribute *return_attr,
+        Dwarf_Error *error)\fP
+.DE
+When it returns \f(CWDW_DLV_OK\fP,
+the function \f(CWdwarf_attr()\fP
+sets 
+\f(CW*return_attr\fP to the  \f(CWDwarf_Attribute\fP 
+descriptor of \f(CWdie\fP having the attribute \f(CWattr\fP.
+It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWattr\fP is not contained 
+in \f(CWdie\fP. 
+It returns \f(CWDW_DLV_ERROR\fP if an error occurred.
+
+.\"#if 0
+.\".DS
+.\"\f(CWDwarf_Locdesc* dwarf_stringlen(
+.\"        Dwarf_Die die, 
+.\"        Dwarf_Error *error)\fP
+.\".DE
+.\"The function \f(CWdwarf_stringlen()\fP returns a pointer to a 
+.\"\f(CWDwarf_Locdesc\fP with one Locdesc entry that when evaluated,
+.\"yields the length of the string represented by \f(CWdie\fP.  It
+.\"returns \f(CWNULL\fP if \f(CWdie\fP does not contain a string length 
+.\"attribute or the string length attribute is not a location-description 
+.\"or an error occurred. The address range of the list is set to 0 thru 
+.\"the highest possible address if a loclist pointer is returned.  The 
+.\"storage pointed to by a successful return of \f(CWdwarf_stringlen()\fP 
+.\"should be free'd when no longer of interest (see \f(CWdwarf_dealloc()\fP).
+.\"This function is currently unimplemented.
+.\"#endif
+
+.\"#if 0
+.\".DS
+.\"\f(CWDwarf_Signed dwarf_subscrcnt(
+.\"        Dwarf_Die die, 
+.\"        Dwarf_Error *error)\fP
+.\".DE
+.\"The function \f(CWdwarf_subscrcnt()\fP returns the number of subscript 
+.\"die's that are owned by the array type represented by \f(CWdie\fP.  It
+.\"returns \f(CWDW_DLV_NOCOUNT\fP on error.  This function is currently
+.\"unimplemented.
+.\"
+.\".DS
+.\"\f(CWDwarf_Die dwarf_nthsubscr(
+.\"        Dwarf_Die die, 
+.\"        Dwarf_Unsigned ssndx, 
+.\"        Dwarf_Error *error)\fP
+.\".DE
+.\"The function \f(CWdwarf_nthsubscr()\fP returns a \f(CWDwarf_Die\fP 
+.\"descriptor that describes the \f(CWssndx\fP subscript of the array 
+.\"type debugging information entry represented by \f(CWdie\fP, where 
+.\"\fI1\fP is the first member.  It returns \fINULL\fP if \f(CWdie\fP 
+.\"does not have an \f(CWssndx\fP subscript, or an error occurred.  
+.\"This function is currently unimplemented.
+.\"#endif
+
+.H 3 "dwarf_lowpc()"
+.DS
+\f(CWint dwarf_lowpc(
+        Dwarf_Die     die, 
+	Dwarf_Addr  * return_lowpc,
+        Dwarf_Error * error)\fP
+.DE
+The function \f(CWdwarf_lowpc()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_lowpc\fP
+to the low program counter 
+value associated with the \f(CWdie\fP descriptor if \f(CWdie\fP 
+represents a debugging information entry with this attribute.  
+It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not have this 
+attribute. 
+It returns \f(CWDW_DLV_ERROR\fP if an error occurred. 
+
+.H 3 "dwarf_highpc()"
+.DS
+\f(CWint dwarf_highpc(
+        Dwarf_Die die, 
+	Dwarf_Addr  * return_highpc,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_highpc()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_highpc\fP
+the high program counter 
+value associated with the \f(CWdie\fP descriptor if \f(CWdie\fP 
+represents a debugging information entry with this attribute.  
+It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not have this 
+attribute. 
+It returns \f(CWDW_DLV_ERROR\fP if an error occurred. 
+
+.H 3 "dwarf_bytesize()"
+.DS
+\f(CWDwarf_Signed dwarf_bytesize(
+        Dwarf_Die        die, 
+	Dwarf_Unsigned  *return_size,
+        Dwarf_Error     *error)\fP
+.DE
+When it succeeds,
+\f(CWdwarf_bytesize()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_size\fP
+to the number of bytes 
+needed to contain an instance of the aggregate debugging information 
+entry represented by \f(CWdie\fP.  
+It returns \f(CWDW_DLV_NO_ENTRY\fP if 
+\f(CWdie\fP does not contain the byte size attribute \f(CWDW_AT_byte_size\fP.
+It returns \f(CWDW_DLV_ERROR\fP if 
+an error occurred.
+
+.\"#if 0
+.\".DS
+.\"\f(CWDwarf_Bool dwarf_isbitfield(
+.\"        Dwarf_Die die, 
+.\"        Dwarf_Error *error)\fP
+.\".DE
+.\"The function \f(CWdwarf_isbitfield()\fP returns \fInon-zero\fP if 
+.\"\f(CWdie\fP is a descriptor for a debugging information entry that 
+.\"represents a bit field member.  It returns \fIzero\fP if \f(CWdie\fP 
+.\"is not associated with a bit field member.  This function is currently
+.\"unimplemented.
+.\"#endif
+
+.H 3 "dwarf_bitsize()"
+.DS
+\f(CWint dwarf_bitsize(
+        Dwarf_Die die, 
+	Dwarf_Unsigned  *return_size,
+        Dwarf_Error *error)\fP
+.DE
+When it succeeds,
+\f(CWdwarf_bitsize()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_size\fP
+to the number of 
+bits 
+occupied by the bit field value that is an attribute of the given
+die.  
+It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not 
+contain the bit size attribute \f(CWDW_AT_bit_size\fP.
+It returns \f(CWDW_DLV_ERROR\fP if 
+an error occurred.
+
+.H 3 "dwarf_bitoffset()"
+.DS
+\f(CWint dwarf_bitoffset(
+        Dwarf_Die die, 
+	Dwarf_Unsigned  *return_size,
+        Dwarf_Error *error)\fP
+.DE
+When it succeeds,
+\f(CWdwarf_bitoffset()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_size\fP
+to the number of bits 
+to the left of the most significant bit of the bit field value. 
+This bit offset is not necessarily the net bit offset within the
+structure or class , since \f(CWDW_AT_data_member_location\fP
+may give a byte offset to this \f(CWDIE\fP and the bit offset
+returned through the pointer
+does not include the bits in the byte offset.
+It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not contain the 
+bit offset attribute \f(CWDW_AT_bit_offset\fP.
+It returns \f(CWDW_DLV_ERROR\fP if 
+an error occurred.
+
+.H 3 "dwarf_srclang()"
+.DS
+\f(CWint dwarf_srclang(
+        Dwarf_Die die, 
+	Dwarf_Unsigned  *return_lang,
+        Dwarf_Error *error)\fP
+.DE
+When it succeeds,
+\f(CWdwarf_srclang()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_lang\fP
+to
+a code indicating the 
+source language of the compilation unit represented by the descriptor 
+\f(CWdie\fP.  
+It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not 
+represent a source file debugging information entry (i.e. contain the 
+attribute \f(CWDW_AT_language\fP).
+It returns \f(CWDW_DLV_ERROR\fP if 
+an error occurred.
+
+.H 3 "dwarf_arrayorder()"
+.DS
+\f(CWint dwarf_arrayorder(
+        Dwarf_Die die, 
+	Dwarf_Unsigned  *return_order,
+        Dwarf_Error *error)\fP
+.DE
+When it succeeds,
+\f(CWdwarf_arrayorder()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_order\fP
+a code indicating 
+the ordering of the array represented by the descriptor \f(CWdie\fP.
+It returns \f(CWDW_DLV_NO_ENTRY\fP if \f(CWdie\fP does not contain the
+array order attribute \f(CWDW_AT_ordering\fP.
+It returns \f(CWDW_DLV_ERROR\fP if 
+an error occurred.
+
+.H 2 "Attribute Form Queries"
+Based on the attribute's form, these operations are concerned with 
+returning uninterpreted attribute data.  Since it is not always 
+obvious from the return value of these functions if an error occurred, 
+one should always supply an \f(CWerror\fP parameter or have arranged 
+to have an error handling function invoked (see \f(CWdwarf_init()\fP)
+to determine the validity of the returned value and the nature of any 
+errors that may have occurred.
+
+A \f(CWDwarf_Attribute\fP descriptor describes an attribute of a
+specific die.  Thus, each \f(CWDwarf_Attribute\fP descriptor is
+implicitly associated with a specific die.
+
+.H 3 "dwarf_hasform()"
+.DS
+\f(CWnt dwarf_hasform(
+        Dwarf_Attribute attr, 
+        Dwarf_Half form, 
+        Dwarf_Bool  *return_hasform,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_hasform()\fP returns 
+\f(CWDW_DLV_OK\fP and  and puts a 
+\fInon-zero\fP
+ value in the 
+\f(CW*return_hasform\fP boolean if the 
+attribute represented by the \f(CWDwarf_Attribute\fP descriptor 
+\f(CWattr\fP has the attribute form \f(CWform\fP.  
+If the attribute does not have that form \fIzero\fP
+is put into \f(CW*return_hasform\fP. 
+\f(CWDW_DLV_ERROR\fP is returned on error.
+
+.H 3 "dwarf_whatform()"
+.DS
+\f(CWint dwarf_whatform(
+        Dwarf_Attribute attr,
+        Dwarf_Half     *return_form,
+        Dwarf_Error *error)\fP
+.DE
+When it succeeds,
+\f(CWdwarf_whatform()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_form\fP
+to the attribute form code of 
+the attribute represented by the \f(CWDwarf_Attribute\fP descriptor 
+\f(CWattr\fP.  
+It returns  \f(CWDW_DLV_ERROR\fP  on error.
+An attribute using DW_FORM_indirect effectively has two forms.
+This function returns the 'final' form for \f(CWDW_FORM_indirect\fP,
+not the \f(CWDW_FORM_indirect\fP itself. This function is
+what most applications will want to call.
+
+.H 3 "dwarf_whatform_direct()"
+.DS
+\f(CWint dwarf_whatform_direct(
+        Dwarf_Attribute attr,
+        Dwarf_Half     *return_form,
+        Dwarf_Error *error)\fP
+.DE
+When it succeeds,
+\f(CWdwarf_whatform_direct()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_form\fP
+to the attribute form code of 
+the attribute represented by the \f(CWDwarf_Attribute\fP descriptor 
+\f(CWattr\fP.  
+It returns  \f(CWDW_DLV_ERROR\fP  on error.
+An attribute using \f(CWDW_FORM_indirect\fP effectively has two forms.
+This returns the form 'directly' in the initial form field.
+So when the form field is \f(CWDW_FORM_indirect\fP
+this call returns the \f(CWDW_FORM_indirect\fP form, 
+which is sometimes useful for dump utilities.
+
+.H 3 "dwarf_whatattr()"
+.DS
+\f(CWint dwarf_whatattr(
+        Dwarf_Attribute attr,
+        Dwarf_Half     *return_attr,
+        Dwarf_Error *error)\fP
+.DE
+When it succeeds,
+\f(CWdwarf_whatattr()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_attr\fP
+to the attribute code 
+represented by the \f(CWDwarf_Attribute\fP descriptor \f(CWattr\fP.  
+It returns  \f(CWDW_DLV_ERROR\fP  on error.
+
+.H 3 "dwarf_formref()"
+.DS
+\f(CWint dwarf_formref(
+        Dwarf_Attribute attr, 
+	Dwarf_Off     *return_offset,
+        Dwarf_Error *error)\fP
+.DE
+When it succeeds,
+\f(CWdwarf_formref()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP
+to the CU-relative offset
+represented by the descriptor \f(CWattr\fP if the form of the attribute 
+belongs to the \f(CWREFERENCE\fP class.
+\f(CWattr\fP must be a CU-local reference, 
+not form \f(CWDW_FORM_ref_addr\fP.  
+It is an error for the form to
+not belong to this class or to be form \f(CWDW_FORM_ref_addr\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+See also \f(CWdwarf_global_formref\fP below.
+
+.H 3 "dwarf_global_formref()"
+.DS
+\f(CWint dwarf_global_formref(
+        Dwarf_Attribute attr, 
+	Dwarf_Off     *return_offset,
+        Dwarf_Error *error)\fP
+.DE
+When it succeeds,
+\f(CWdwarf_global_formref()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP
+to the .debug_info-section-relative offset
+represented by the descriptor \f(CWattr\fP if the form of the attribute 
+belongs to the \f(CWREFERENCE\fP class. 
+\f(CWattr\fP can be any legal 
+\f(CWREFERENCE\fP class form including \f(CWDW_FORM_ref_addr\fP.
+It is an error for the form to
+not belong to this class.
+It returns \f(CWDW_DLV_ERROR\fP on error.
+See also \f(CWdwarf_formref\fP above.
+
+.H 3 "dwarf_formaddr()"
+.DS
+\f(CWint dwarf_formaddr(
+        Dwarf_Attribute attr, 
+        Dwarf_Addr    * return_addr,
+        Dwarf_Error *error)\fP
+.DE
+When it succeeds,
+\f(CWdwarf_formaddr()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_addr\fP
+to
+the address 
+represented by the descriptor \f(CWattr\fP if the form of the attribute
+belongs to the \f(CWADDRESS\fP class.  
+It is an error for the form to
+not belong to this class.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+
+.H 3 "dwarf_formflag()"
+.DS
+\f(CWint dwarf_formflag(
+	Dwarf_Attribute attr,
+	Dwarf_Bool * return_bool,
+	Dwarf_Error *error)\fP
+.DE
+When it succeeds,
+\f(CWdwarf_formflag()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP
+\f(CW1\fP (i.e. true) (if the attribute has a non-zero value)
+or \f(CW0\fP (i.e. false) (if the attribute has a zero value).
+It returns \f(CWDW_DLV_ERROR\fP on error or if the \f(CWattr\fP
+does not have form flag.
+
+.H 3 "dwarf_formudata()"
+.DS
+\f(CWint dwarf_formudata(
+        Dwarf_Attribute   attr, 
+	Dwarf_Unsigned  * return_uvalue,
+        Dwarf_Error     * error)\fP
+.DE
+The function
+\f(CWdwarf_formudata()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_uvalue\fP
+to
+the \f(CWDwarf_Unsigned\fP 
+value of the attribute represented by the descriptor \f(CWattr\fP if the
+form of the attribute belongs to the \f(CWCONSTANT\fP class.  
+It is an 
+error for the form to not belong to this class.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+
+.H 3 "dwarf_formsdata()"
+.DS
+\f(CWint dwarf_formsdata(
+        Dwarf_Attribute attr, 
+	Dwarf_Signed  * return_svalue,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_formsdata()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_svalue\fP
+to
+the \f(CWDwarf_Signed\fP 
+value of the attribute represented by the descriptor \f(CWattr\fP if the
+form of the attribute belongs to the \f(CWCONSTANT\fP class.  
+It is an 
+error for the form to not belong to this class.  
+If the size of the data 
+attribute referenced is smaller than the size of the \f(CWDwarf_Signed\fP
+type, its value is sign extended.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+
+.H 3 "dwarf_formblock()"
+.DS
+\f(CWint dwarf_formblock(
+        Dwarf_Attribute attr, 
+	Dwarf_Block  ** return_block,
+        Dwarf_Error *   error)\fP
+.DE
+The function \f(CWdwarf_formblock()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_block\fP
+to
+a pointer to a 
+\f(CWDwarf_Block\fP structure containing the value of the attribute 
+represented by the descriptor \f(CWattr\fP if the form of the 
+attribute belongs to the \f(CWBLOCK\fP class.  
+It is an error
+for the form to not belong to this class.  
+The storage pointed 
+to by a successful return of \f(CWdwarf_formblock()\fP should 
+be free'd using the allocation type \f(CWDW_DLA_BLOCK\fP,  when 
+no longer of interest (see \f(CWdwarf_dealloc()\fP).  
+It returns
+\f(CWDW_DLV_ERROR\fP on error.
+
+.H 3 "dwarf_formstring()"
+
+.DS
+\f(CWint dwarf_formstring(
+        Dwarf_Attribute attr, 
+	char        **  return_string,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_formstring()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_string\fP
+to
+a pointer to a 
+null-terminated string containing  the value of the attribute 
+represented by the descriptor \f(CWattr\fP if the form of the
+attribute belongs to the \f(CWSTRING\fP class.  
+It is an error
+for the form to not belong to this class.  
+The storage pointed 
+to by a successful return of \f(CWdwarf_formstring()\fP 
+should not be free'd.  The pointer points into
+existing DWARF memory and the pointer becomes stale/invalid
+after a call to \f(CWdwarf_finish\fP.
+\f(CWdwarf_formstring()\fP returns \f(CWDW_DLV_ERROR\fP on error.
+
+.H 4 "dwarf_loclist_n()"
+.DS
+\f(CWint dwarf_loclist_n(
+        Dwarf_Attribute attr, 
+        Dwarf_Locdesc ***llbuf,
+        Dwarf_Signed  *listlen,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_loclist_n()\fP sets \f(CW*llbuf\fP to point to 
+an array of \f(CWDwarf_Locdesc\fP pointers corresponding to each of
+the location expressions in a location list, and sets
+\f(CW*listlen\fP to the number 
+of elements in the array and 
+returns \f(CWDW_DLV_OK\fP if the attribute is
+appropriate.
+.P
+This is the preferred function for Dwarf_Locdesc as
+it is the interface allowing access to an entire
+loclist. (use of \f(CWdwarf_loclist_n()\fP is
+suggested as the better interface, though 
+\f(CWdwarf_loclist()\fP is still
+supported.)
+.P
+If the attribute is a reference to a location list
+(DW_FORM_data4 or DW_FORM_data8)
+the location list entries are used to fill
+in all the fields of the \f(CWDwarf_Locdesc\fP(s) returned.
+.P
+If the attribute is a location description
+(DW_FORM_block2 or DW_FORM_block4)
+then some of the \f(CWDwarf_Locdesc\fP values of the single
+\f(CWDwarf_Locdesc\fP record are set to 'sensible'
+but arbitrary values.  Specifically, ld_lopc is set to 0 and
+ld_hipc is set to all-bits-on. And \f(CW*listlen\fP is set to 1.
+.P
+It returns \f(CWDW_DLV_ERROR\fP on error. 
+\f(CWdwarf_loclist_n()\fP works on \f(CWDW_AT_location\fP, 
+\f(CWDW_AT_data_member_location\fP, \f(CWDW_AT_vtable_elem_location\fP,
+\f(CWDW_AT_string_length\fP, \f(CWDW_AT_use_location\fP, and 
+\f(CWDW_AT_return_addr\fP attributes.  
+.P
+Storage allocated by a successful call of \f(CWdwarf_loclist_n()\fP should 
+be deallocated when no longer of interest (see \f(CWdwarf_dealloc()\fP).
+The block of \f(CWDwarf_Loc\fP structs pointed to by the \f(CWld_s\fP 
+field of each \f(CWDwarf_Locdesc\fP structure 
+should be deallocated with the allocation type 
+\f(CWDW_DLA_LOC_BLOCK\fP. 
+and  the \f(CWllbuf[]\fP space pointed to should be deallocated with
+allocation type \f(CWDW_DLA_LOCDESC\fP.
+This should be followed by deallocation of the \f(CWllbuf\fP
+using the allocation type \f(CWDW_DLA_LIST\fP.
+.in +2
+.DS
+\f(CWDwarf_Signed lcnt;
+Dwarf_Locdesc **llbuf;
+int lres;
+
+lres = dwarf_loclist_n(someattr, &llbuf,&lcnt &error);
+if (lres == DW_DLV_OK) {
+        for (i = 0; i < lcnt; ++i) {
+            /* use llbuf[i] */
+
+            dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK);
+	    dwarf_dealloc(dbg,llbuf[i], DW_DLA_LOCDESC);
+        }
+        dwarf_dealloc(dbg, llbuf, DW_DLA_LIST);
+}\fP
+.DE
+.in -2
+.P
+
+.H 4 "dwarf_loclist()"
+.DS
+\f(CWint dwarf_loclist(
+        Dwarf_Attribute attr, 
+        Dwarf_Locdesc **llbuf,
+        Dwarf_Signed  *listlen,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_loclist()\fP sets \f(CW*llbuf\fP to point to 
+a \f(CWDwarf_Locdesc\fP pointer for the single location expression
+it can return.
+It sets
+\f(CW*listlen\fP to 1.
+and returns \f(CWDW_DLV_OK\fP 
+if the attribute is
+appropriate.
+.P
+It is less flexible than \f(CWdwarf_loclist_n()\fP in that
+\f(CWdwarf_loclist()\fP can handle a maximum of one
+location expression, not a full location list.
+If a location-list is present it returns only
+the first location-list entry location description.
+Use \f(CWdwarf_loclist_n()\fP instead.
+.P
+It returns \f(CWDW_DLV_ERROR\fP on error. 
+\f(CWdwarf_loclist()\fP works on \f(CWDW_AT_location\fP, 
+\f(CWDW_AT_data_member_location\fP, \f(CWDW_AT_vtable_elem_location\fP,
+\f(CWDW_AT_string_length\fP, \f(CWDW_AT_use_location\fP, and 
+\f(CWDW_AT_return_addr\fP attributes.  
+.P
+Storage allocated by a successful call of \f(CWdwarf_loclist()\fP should 
+be deallocated when no longer of interest (see \f(CWdwarf_dealloc()\fP).
+The block of \f(CWDwarf_Loc\fP structs pointed to by the \f(CWld_s\fP 
+field of each \f(CWDwarf_Locdesc\fP structure 
+should be deallocated with the allocation type \f(CWDW_DLA_LOC_BLOCK\fP. 
+This should be followed by deallocation of the \f(CWllbuf\fP
+using the allocation type \f(CWDW_DLA_LOCDESC\fP.
+.in +2
+.DS
+\f(CWDwarf_Signed lcnt;
+Dwarf_Locdesc *llbuf;
+int lres;
+
+lres = dwarf_loclist(someattr, &llbuf,&lcnt,&error);
+if (lres == DW_DLV_OK) {
+	/* lcnt is always 1, (and has always been 1) */ */
+
+	/* Use llbuf here. */
+
+
+        dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK);
+        dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC);
+/*      Earlier version. 
+*         for (i = 0; i < lcnt; ++i) {
+*             /* use llbuf[i] */
+* 
+*             /* Deallocate Dwarf_Loc block of llbuf[i] */
+*             dwarf_dealloc(dbg, llbuf[i].ld_s, DW_DLA_LOC_BLOCK);
+*         }
+*         dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC);
+*/
+
+}\fP
+.DE
+.in -2
+.P
+
+.H 4 "dwarf_loclist_from_expr()"
+.DS
+\f(CWint dwarf_loclist_from_expr(
+        Dwarf_Ptr bytes_in, 
+        Dwarf_Unsigned bytes_len,
+        Dwarf_Locdesc **llbuf,
+        Dwarf_Signed  *listlen,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_loclist_from_expr()\fP sets \f(CW*llbuf\fP to point to 
+a \f(CWDwarf_Locdesc\fP pointer for the single location expression
+which is pointed to by \f(CW*bytes_in\fP (whose length is
+\f(CW*bytes_len\fP).
+It sets
+\f(CW*listlen\fP to 1.
+and returns \f(CWDW_DLV_OK\fP 
+if decoding is successful.
+Some sources of bytes of expressions are dwarf expressions
+in frame operations like \f(CWDW_CFA_def_cfa_expression\fP,
+\f(CWDW_CFA_expression\fP, and  \f(CWDW_CFA_val_expression\fP.
+.P
+It returns \f(CWDW_DLV_ERROR\fP on error. 
+.P
+Storage allocated by a successful call of \f(CWdwarf_loclist_from_expr()\fP should 
+be deallocated when no longer of interest (see \f(CWdwarf_dealloc()\fP).
+The block of \f(CWDwarf_Loc\fP structs pointed to by the \f(CWld_s\fP 
+field of each \f(CWDwarf_Locdesc\fP structure 
+should be deallocated with the allocation type \f(CWDW_DLA_LOC_BLOCK\fP. 
+This should be followed by deallocation of the \f(CWllbuf\fP
+using the allocation type \f(CWDW_DLA_LOCDESC\fP.
+.in +2
+.DS
+\f(CWDwarf_Signed lcnt;
+Dwarf_Locdesc *llbuf;
+int lres;
+/* Example with an empty buffer here. */
+Dwarf_Ptr data = "";
+Dwarf_Unsigned len = 0;
+
+lres = dwarf_loclist_from_expr(data,len, &llbuf,&lcnt, &error);
+if (lres == DW_DLV_OK) {
+	/* lcnt is always 1 */
+
+	/* Use llbuf  here.*/
+
+        dwarf_dealloc(dbg, llbuf->ld_s, DW_DLA_LOC_BLOCK);
+        dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC);
+
+}\fP
+.DE
+.in -2
+.P
+
+
+.P
+.H 2 "Line Number Operations"
+These functions are concerned with accessing line number entries,
+mapping debugging information entry objects to their corresponding
+source lines, and providing a mechanism for obtaining information
+about line number entries.  Although, the interface talks of "lines"
+what is really meant is "statements".  In case there is more than
+one statement on the same line, there will be at least one descriptor
+per statement, all with the same line number.  If column number is
+also being represented they will have the column numbers of the start
+of the statements also represented.
+.P
+There can also be more than one Dwarf_Line per statement.
+For example, if a file is preprocessed by a language translator,
+this could result in translator output showing 2 or more sets of line
+numbers per translated line of output.
+
+.H 3 "Get A Set of Lines"
+The function returns information about every source line for a 
+particular compilation-unit.  
+The compilation-unit is specified
+by the corresponding die.
+.H 4 "dwarf_srclines()"
+.DS
+\f(CWint dwarf_srclines(
+        Dwarf_Die die, 
+        Dwarf_Line **linebuf, 
+	Dwarf_Signed *linecount,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_srclines()\fP places all line number descriptors 
+for a single compilation unit into a single block, sets \f(CW*linebuf\fP 
+to point to that block, 
+sets \f(CW*linecount\fP to the number of descriptors in this block
+and returns \f(CWDW_DLV_OK\fP.
+The compilation-unit is indicated by the given \f(CWdie\fP which must be
+a compilation-unit die.  
+It returns \f(CWDW_DLV_ERROR\fP on error.  
+On
+successful return, line number information 
+should be free'd using \f(CWdwarf_srclines_dealloc()\fP
+when no longer of interest. 
+.P
+.in +2
+.DS
+\f(CWDwarf_Signed cnt;
+Dwarf_Line *linebuf;
+int sres;
+
+sres = dwarf_srclines(somedie, &linebuf,&cnt, &error);
+if (sres == DW_DLV_OK) {
+        for (i = 0; i < cnt; ++i) {
+                /* use linebuf[i] */
+        }
+        dwarf_srclines_dealloc(dbg, linebuf, cnt);
+}\fP
+.DE
+
+.in -2
+.P
+The following dealloc code (the only documented method before July 2005)
+still works, but does not completely free all data allocated.
+The \f(CWdwarf_srclines_dealloc()\fP routine was created
+to fix the problem of incomplete deallocation.
+.P
+.in +2
+.DS
+\f(CWDwarf_Signed cnt;
+Dwarf_Line *linebuf;
+int sres;
+
+sres = dwarf_srclines(somedie, &linebuf,&cnt, &error);
+if (sres == DW_DLV_OK) {
+        for (i = 0; i < cnt; ++i) {
+                /* use linebuf[i] */
+                dwarf_dealloc(dbg, linebuf[i], DW_DLA_LINE);
+        }
+        dwarf_dealloc(dbg, linebuf, DW_DLA_LIST);
+}\fP
+.DE
+.in -2
+
+.H 3 "Get the set of Source File Names"
+
+The function returns the names of the source files that have contributed
+to the compilation-unit represented by the given DIE.  Only the source
+files named in the statement program prologue are returned.
+
+
+.DS
+\f(CWint dwarf_srcfiles(
+        Dwarf_Die die,
+        char ***srcfiles,
+        Dwarf_Signed *srccount,
+        Dwarf_Error *error)\fP
+.DE
+When it succeeds
+\f(CWdwarf_srcfiles()\fP returns 
+\f(CWDW_DLV_OK\fP
+and
+puts
+the number of source
+files named in the statement program prologue indicated by the given
+\f(CWdie\fP
+into \f(CW*srccount\fP.  
+Source files defined in the statement program are ignored.
+The given \f(CWdie\fP should have the tag \f(CWDW_TAG_compile_unit\fP.
+The location pointed to by \f(CWsrcfiles\fP is set to point to a list
+of pointers to null-terminated strings that name the source
+files.  
+On a successful return from this function, each of the
+strings returned should be individually free'd using \f(CWdwarf_dealloc()\fP
+with the allocation type \f(CWDW_DLA_STRING\fP when no longer of
+interest.  
+This should be followed by free-ing the list using
+\f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_LIST\fP.
+It returns \f(CWDW_DLV_ERROR\fP on error. 
+It returns \f(CWDW_DLV_NO_ENTRY\fP
+if there is no
+corresponding statement program (i.e., if there is no line information).
+.in +2
+.DS
+\f(CWDwarf_Signed cnt;
+char **srcfiles;
+int res;
+
+res = dwarf_srcfiles(somedie, &srcfiles,&cnt &error);
+if (res == DW_DLV_OK) {
+
+        for (i = 0; i < cnt; ++i) {
+                /* use srcfiles[i] */
+                dwarf_dealloc(dbg, srcfiles[i], DW_DLA_STRING);
+        }
+        dwarf_dealloc(dbg, srcfiles, DW_DLA_LIST);
+}\fP
+.DE
+.in -2
+.H 3 "Get information about a Single Table Line"
+The following functions can be used on the \f(CWDwarf_Line\fP descriptors
+returned by \f(CWdwarf_srclines()\fP to obtain information about the
+source lines.
+
+.H 4 "dwarf_linebeginstatement()"
+.DS
+\f(CWint dwarf_linebeginstatement(
+        Dwarf_Line line, 
+	Dwarf_Bool *return_bool,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_linebeginstatement()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP
+to
+\fInon-zero\fP 
+(if \f(CWline\fP represents a line number entry that is marked as
+beginning a statement).  
+or
+\fIzero\fP ((if \f(CWline\fP represents a line number entry
+that is not marked as beginning a statement).
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.P
+.H 4 "dwarf_lineendsequence()"
+.DS
+\f(CWint dwarf_lineendsequence(
+	Dwarf_Line line,
+	Dwarf_Bool *return_bool,
+	Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_lineendsequence()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_bool\fP
+\fInon-zero\fP
+(in which case 
+\f(CWline\fP represents a line number entry that is marked as
+ending a text sequence)
+or
+\fIzero\fP (in which case 
+\f(CWline\fP represents a line number entry
+that is not marked as ending a text sequence).
+A line number entry that is marked as
+ending a text sequence is an entry with an address 
+one beyond the highest address used by the current
+sequence of line table entries (that is, the table entry is
+a DW_LNE_end_sequence entry (see the DWARF specification)).
+.P
+The function \f(CWdwarf_lineendsequence()\fP 
+returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.P
+.H 4 "dwarf_lineno()"
+.DS
+\f(CWint dwarf_lineno(
+        Dwarf_Line       line, 
+	Dwarf_Unsigned * returned_lineno,
+        Dwarf_Error    * error)\fP
+.DE
+The function \f(CWdwarf_lineno()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_lineno\fP to
+the source statement line 
+number corresponding to the descriptor \f(CWline\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.P
+.H 4 "dwarf_line_srcfileno()"
+.DS
+\f(CWint dwarf_line_srcfileno(
+        Dwarf_Line       line, 
+	Dwarf_Unsigned * returned_fileno,
+        Dwarf_Error    * error)\fP
+.DE
+The function \f(CWdwarf_line_srcfileno()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*returned_fileno\fP to
+the source statement line 
+number corresponding to the descriptor \f(CWfile number\fP.  
+When the number returned thru \f(CW*returned_fileno\fP is zero it means
+the file name is unknown (see the DWARF2/3 line table specification).
+When the number returned thru \f(CW*returned_fileno\fP is non-zero
+it is a file number:
+subtract 1 from this file number
+to get an
+index into the array of strings returned by \f(CWdwarf_srcfiles()\fP
+(verify the resulting index is in range for the array of strings
+before indexing into the array of strings).
+The file number may exceed the size of 
+the array of strings returned by \f(CWdwarf_srcfiles()\fP
+because \f(CWdwarf_srcfiles()\fP does not return files names defined with
+the  \f(CWDW_DLE_define_file\fP  operator.
+The function \f(CWdwarf_line_srcfileno()\fP returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.P
+.H 4 "dwarf_lineaddr()"
+.DS
+\f(CWint dwarf_lineaddr(
+        Dwarf_Line   line, 
+	Dwarf_Addr  *return_lineaddr,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_lineaddr()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_lineaddr\fP to
+the address associated 
+with the descriptor \f(CWline\fP.  
+It returns \f(CWDW_DLV_ERROR\fP  on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.P
+.H 4 "dwarf_lineoff()"
+.DS
+\f(CWint dwarf_lineoff(
+        Dwarf_Line line, 
+	Dwarf_Signed   * return_lineoff,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_lineoff()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_lineoff\fP to
+the column number at which
+the statement represented by \f(CWline\fP begins.  
+It sets \f(CWreturn_lineoff\fP to \fI-1\fP 
+if the column number of the statement is not represented
+(meaning the producer library call was given zero
+as the column number). 
+.P
+On error it returns \f(CWDW_DLV_ERROR\fP.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.H 4 "dwarf_linesrc()"
+.DS
+\f(CWint dwarf_linesrc(
+        Dwarf_Line line, 
+	char  **   return_linesrc,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_linesrc()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_linesrc\fP to
+a pointer to a
+null-terminated string of characters that represents the name of the 
+source-file where \f(CWline\fP occurs.  
+It returns \f(CWDW_DLV_ERROR\fP on 
+error.  
+.P
+If the applicable file name in the line table Statement Program Prolog 
+does not start with a '/' character
+the string in \f(CWDW_AT_comp_dir\fP (if applicable and present)
+or the applicable
+directory name from the line Statement Program Prolog 
+is prepended to the
+file name in the line table Statement Program Prolog
+to make a full path.
+.P
+The storage pointed to by a successful return of 
+\f(CWdwarf_linesrc()\fP should be free'd using \f(CWdwarf_dealloc()\fP with
+the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.H 4 "dwarf_lineblock()"
+.DS
+\f(CWint dwarf_lineblock(
+        Dwarf_Line line, 
+	Dwarf_Bool *return_bool,
+        Dwarf_Error *error)\fP
+.DE
+The function
+\f(CWdwarf_lineblock()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_linesrc\fP to
+non-zero (i.e. true)(if the line is marked as 
+beginning a basic block)
+or zero (i.e. false) (if the line is marked as not
+beginning a basic block).  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.\"#if 0
+.\".H 3 "Finding a Line Given A PC value"
+.\"This is a 'higher level' (High-level) interface to line information.
+.\"
+.\".DS
+.\"\f(CWint dwarf_pclines(
+.\"        Dwarf_Debug dbg,
+.\"        Dwarf_Addr pc,
+.\"        Dwarf_Line **linebuf,
+.\"        Dwarf_Signed slide,
+.\"        Dwarf_Signed *linecount,
+.\"        Dwarf_Error *error)\fP
+.\".DE
+.\"The function \f(CWdwarf_pclines()\fP places all line number descriptors 
+.\"that correspond to the value of \f(CWpc\fP into a single block and sets 
+.\"\f(CWlinebuf\fP to point to that block.  A count of the number of 
+.\"\f(CWDwarf_Line\fP descriptors that are in this block is returned.  For 
+.\"most cases, the count returned will be \fIone\fP, though it may be higher 
+.\"if optimizations such as common subexpression elimination result in multiple 
+.\"line number entries for a given value of \f(CWpc\fP.  The \f(CWslide\fP 
+.\"argument specifies the direction to search for the nearest line number 
+.\"entry in the event that there is no line number entry that contains an 
+.\"exact match for \f(CWpc\fP.  This argument may be one of: 
+.\"\f(CWDLS_BACKWARD\fP, \f(CWDLS_NOSLIDE\fP, \f(CWDLS_FORWARD\fP.
+.\"\f(CWDW_DLV_NOCOUNT\fP is returned on error.  On successful return, each 
+.\"line information structure pointed to by an entry in the block should be 
+.\"free'd using \f(CWdwarf_dealloc()\fP with the allocation type 
+.\"\f(CWDW_DLA_LINE\fP when no longer of interest.  The block itself should 
+.\"be free'd using \f(CWdwarf_dealloc()\fP with the allocation type 
+.\"\f(CWDW_DLA_LIST\fP when no longer of interest.
+.\"#endif
+
+.H 2 "Global Name Space Operations" 
+These operations operate on the .debug_pubnames section of the debugging 
+information.
+
+.H 3 "Debugger Interface Operations"
+
+.H 4 "dwarf_get_globals()"
+.DS
+\f(CWint dwarf_get_globals(
+        Dwarf_Debug dbg,
+        Dwarf_Global **globals,
+        Dwarf_Signed * return_count,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_get_globals()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_count\fP to
+the count of pubnames
+represented in the section containing pubnames i.e. .debug_pubnames.  
+It also stores at \f(CW*globals\fP, a pointer 
+to a list of \f(CWDwarf_Global\fP descriptors, one for each of the 
+pubnames in the .debug_pubnames section.  
+It returns \f(CWDW_DLV_ERROR\fP on error. 
+It returns \f(CWDW_DLV_NO_ENTRY\fP if the .debug_pubnames 
+section does not exist.
+
+.P
+On a successful return from
+\f(CWdwarf_get_globals()\fP, the \f(CWDwarf_Global\fP 
+descriptors should be
+free'd using \f(CWdwarf_globals_dealloc()\fP.
+\f(CWdwarf_globals_dealloc()\fP is new as of July 15, 2005
+and is the preferred approach to freeing this memory..
+
+.in +2
+.DS
+\f(CWDwarf_Signed cnt;
+Dwarf_Global *globs;
+int res;
+
+res = dwarf_get_globals(dbg, &globs,&cnt, &error);
+if (res == DW_DLV_OK) {
+
+        for (i = 0; i < cnt; ++i) {
+                /* use globs[i] */
+        }
+        dwarf_globals_dealloc(dbg, globs, cnt);
+}\fP
+.DE
+.in -2
+
+
+.P
+The following code is deprecated as of July 15, 2005 as it does not
+free all relevant memory.
+This approach  still works as well as it ever did.
+On a successful return from 
+\f(CWdwarf_get_globals()\fP, the \f(CWDwarf_Global\fP 
+descriptors should be individually 
+free'd using \f(CWdwarf_dealloc()\fP with the allocation type 
+\f(CWDW_DLA_GLOBAL_CONTEXT\fP, 
+(or
+\f(CWDW_DLA_GLOBAL\fP, an older name, supported for compatibility)
+followed by the deallocation of the list itself 
+with the allocation type \f(CWDW_DLA_LIST\fP when the descriptors are 
+no longer of interest.
+
+.in +2
+.DS
+\f(CWDwarf_Signed cnt;
+Dwarf_Global *globs;
+int res;
+
+res = dwarf_get_globals(dbg, &globs,&cnt, &error);
+if (res == DW_DLV_OK) {
+
+        for (i = 0; i < cnt; ++i) {
+                /* use globs[i] */
+                dwarf_dealloc(dbg, globs[i], DW_DLA_GLOBAL_CONTEXT);
+        }
+        dwarf_dealloc(dbg, globs, DW_DLA_LIST);
+}\fP
+.DE
+.in -2
+
+.H 4 "dwarf_globname()"
+.DS
+\f(CWint dwarf_globname(
+        Dwarf_Global global,
+        char **      return_name,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_globname()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to
+a pointer to a 
+null-terminated string that names the pubname represented by the 
+\f(CWDwarf_Global\fP descriptor, \f(CWglobal\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.  
+On a successful return from this function, the string should
+be free'd using \f(CWdwarf_dealloc()\fP, with the allocation type
+\f(CWDW_DLA_STRING\fP when no longer of interest.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.H 4 "dwarf_global_die_offset()"
+.DS
+\f(CWint dwarf_global_die_offset(
+        Dwarf_Global global,
+	Dwarf_Off   *return_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_global_die_offset()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to
+the offset in
+the section containing DIE's, i.e. .debug_info, of the DIE representing
+the pubname that is described by the \f(CWDwarf_Global\fP descriptor, 
+\f(CWglob\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.H 4 "dwarf_global_cu_offset()"
+.DS
+\f(CWint dwarf_global_cu_offset(
+        Dwarf_Global global,
+	Dwarf_Off   *return_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_global_cu_offset()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to
+the offset in
+the section containing DIE's, i.e. .debug_info, of the compilation-unit
+header of the compilation-unit that contains the pubname described 
+by the \f(CWDwarf_Global\fP descriptor, \f(CWglobal\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.H 4 "dwarf_get_cu_die_offset_given_cu_header_offset()"
+.DS
+\f(CWint dwarf_get_cu_die_offset_given_cu_header_offset(
+	Dwarf_Debug dbg,
+	Dwarf_Off   in_cu_header_offset,
+        Dwarf_Off * out_cu_die_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_get_cu_die_offset_given_cu_header_offset()\fP 
+returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*out_cu_die_offset\fP to
+the offset of the compilation-unit DIE given the
+offset \f(CWin_cu_header_offset\fP of a compilation-unit header.
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+
+This effectively turns a compilation-unit-header offset
+into a compilation-unit DIE offset (by adding the
+size of the applicable CU header).
+This function is also sometimes useful with the 
+\f(CWdwarf_weak_cu_offset()\fP,
+\f(CWdwarf_func_cu_offset()\fP,
+\f(CWdwarf_type_cu_offset()\fP,
+and
+\f(CWint dwarf_var_cu_offset()\fP 
+functions.
+
+\f(CWdwarf_get_cu_die_offset_given_cu_header_offset()\fP 
+added Rev 1.45, June, 2001.
+
+This function is declared as 'optional' in libdwarf.h
+on IRIX systems so the _MIPS_SYMBOL_PRESENT
+predicate may be used at run time to determine if the version of
+libdwarf linked into an application has this function.
+
+.H 4 "dwarf_global_name_offsets()"
+.DS
+\f(CWint dwarf_global_name_offsets(
+        Dwarf_Global global,
+        char     **return_name,
+        Dwarf_Off *die_offset,
+        Dwarf_Off *cu_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_global_name_offsets()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to
+a pointer to
+a null-terminated string that gives the name of the pubname
+described by the \f(CWDwarf_Global\fP descriptor \f(CWglobal\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.  
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+It also returns in the locations 
+pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets
+of the DIE representing the 
+pubname, and the DIE
+representing the compilation-unit containing the 
+pubname, respectively.
+On a 
+successful return from \f(CWdwarf_global_name_offsets()\fP the storage 
+pointed to by \f(CWreturn_name\fP 
+should be free'd using \f(CWdwarf_dealloc()\fP, 
+with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest.
+
+
+.H 2 "DWARF3 Type Names Operations"
+Section ".debug_pubtypes"  is new in DWARF3.
+.P
+These functions operate on the .debug_pubtypes section of the debugging
+information.  The .debug_pubtypes section contains the names of file-scope
+user-defined types, the offsets of the \f(CWDIE\fPs that represent the
+definitions of those types, and the offsets of the compilation-units 
+that contain the definitions of those types.
+
+.H 3 "Debugger Interface Operations"
+
+.H 4 "dwarf_get_pubtypes()"
+.DS
+\f(CWint dwarf_get_pubtypes(
+        Dwarf_Debug dbg,
+        Dwarf_Type **types,
+        Dwarf_Signed *typecount,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_get_pubtypes()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*typecount\fP to
+the count of user-defined
+type names represented in the section containing user-defined type names,
+i.e. .debug_pubtypes.  
+It also stores at \f(CW*types\fP, 
+a pointer to a list of \f(CWDwarf_Pubtype\fP descriptors, one for each of the 
+user-defined type names in the .debug_pubtypes section.  
+It returns \f(CWDW_DLV_NOCOUNT\fP on error. 
+It returns \f(CWDW_DLV_NO_ENTRY\fP if 
+the .debug_pubtypes section does not exist.  
+
+.P
+On a successful 
+return from \f(CWdwarf_get_pubtypes()\fP, 
+the \f(CWDwarf_Type\fP descriptors should be 
+free'd using \f(CWdwarf_types_dealloc()\fP.
+\f(CWdwarf_types_dealloc()\fP is used for both
+\f(CWdwarf_get_pubtypes()\fP and \f(CWdwarf_get_types()\fP
+as the data types are the same.
+
+.in +2
+.DS
+\f(CWDwarf_Signed cnt;
+Dwarf_Pubtype *types;
+int res;
+
+res = dwarf_get_pubtypes(dbg, &types,&cnt, &error);
+if (res == DW_DLV_OK) {
+
+        for (i = 0; i < cnt; ++i) {
+                /* use types[i] */
+        }
+        dwarf_types_dealloc(dbg, types, cnt);
+}\fP
+.DE
+.in -2
+
+.H 4 "dwarf_pubtypename()"
+.DS
+\f(CWint dwarf_pubtypename(
+        Dwarf_Pubtype   type,
+        char       **return_name,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_pubtypename()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to
+a pointer to a
+null-terminated string that names the user-defined type represented by the
+\f(CWDwarf_Pubtype\fP descriptor, \f(CWtype\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.  
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+On a successful return from this function, the string should
+be free'd using \f(CWdwarf_dealloc()\fP, with the allocation type
+\f(CWDW_DLA_STRING\fP when no longer of interest.
+
+.H 4 "dwarf_pubtype_die_offset()"
+.DS
+\f(CWint dwarf_pubtype_die_offset(
+        Dwarf_Pubtype type,
+        Dwarf_Off  *return_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_pubtype_die_offset()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to
+the offset in
+the section containing DIE's, i.e. .debug_info, of the DIE representing
+the user-defined type that is described by the \f(CWDwarf_Pubtype\fP 
+descriptor, \f(CWtype\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.H 4 "dwarf_pubtype_cu_offset()"
+.DS
+\f(CWint dwarf_pubtype_cu_offset(
+        Dwarf_Pubtype type,
+        Dwarf_Off  *return_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_pubtype_cu_offset()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to
+the offset in
+the section containing DIE's, i.e. .debug_info, of the compilation-unit
+header of the compilation-unit that contains the user-defined type
+described by the \f(CWDwarf_Pubtype\fP descriptor, \f(CWtype\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.H 4 "dwarf_pubtype_name_offsets()"
+.DS
+\f(CWint dwarf_pubtype_name_offsets(
+        Dwarf_Pubtype   type,
+        char      ** returned_name,
+        Dwarf_Off *  die_offset,
+        Dwarf_Off *  cu_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_pubtype_name_offsets()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to
+a pointer to
+a null-terminated string that gives the name of the user-defined
+type described by the \f(CWDwarf_Pubtype\fP descriptor \f(CWtype\fP.
+It also returns in the locations
+pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets
+of the DIE representing the 
+user-defined type, and the DIE
+representing the compilation-unit containing the 
+user-defined type, respectively.
+It returns \f(CWDW_DLV_ERROR\fP on error.  
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+On a successful return from \f(CWdwarf_pubtype_name_offsets()\fP
+the storage pointed to by \f(CWreturned_name\fP should
+be free'd using
+\f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP
+when no longer of interest.
+
+
+.H 2 "User Defined Static Variable Names Operations"
+This section is SGI specific and is not part of standard DWARF version 2.
+.P
+These functions operate on the .debug_varnames section of the debugging
+information.  The .debug_varnames section contains the names of file-scope
+static variables, the offsets of the \f(CWDIE\fPs that represent the 
+definitions of those variables, and the offsets of the compilation-units
+that contain the definitions of those variables.
+.P
+
+
+.H 2 "Weak Name Space Operations" 
+These operations operate on the .debug_weaknames section of the debugging 
+information.
+.P
+These operations are SGI specific, not part of standard DWARF.
+.P
+
+.H 3 "Debugger Interface Operations"
+
+.H 4 "dwarf_get_weaks()"
+.DS
+\f(CWint dwarf_get_weaks(
+        Dwarf_Debug dbg,
+        Dwarf_Weak **weaks,
+	Dwarf_Signed *weak_count,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_get_weaks()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*weak_count\fP to
+the count of weak names
+represented in the section containing weak names i.e. .debug_weaknames.  
+It returns \f(CWDW_DLV_ERROR\fP on error. 
+It returns \f(CWDW_DLV_NO_ENTRY\fP if the section does not exist.  
+It also stores in \f(CW*weaks\fP, a pointer to 
+a list of \f(CWDwarf_Weak\fP descriptors, one for each of the weak names 
+in the .debug_weaknames section.  
+
+.P
+On a successful return from this function,
+the \f(CWDwarf_Weak\fP descriptors should be free'd using
+\f(CWdwarf_weaks_dealloc()\fP when the data is no longer of
+interest.  \f(CWdwarf_weaks_dealloc()\fPis new as of July 15, 2005.
+
+.in +2
+.DS
+\f(CWDwarf_Signed cnt;
+Dwarf_Weak *weaks;
+int res;
+
+res = dwarf_get_weaks(dbg, &weaks,&cnt, &error);
+if (res == DW_DLV_OK) {
+
+        for (i = 0; i < cnt; ++i) {
+                /* use weaks[i] */
+        }
+        dwarf_weaks_dealloc(dbg, weaks, cnt);
+}\fP
+.DE
+.in -2
+
+
+
+.P
+The following code is deprecated as of July 15, 2005 as it does not
+free all relevant memory.
+This approach  still works as well as it ever did.
+On a successful return from \f(CWdwarf_get_weaks()\fP
+the \f(CWDwarf_Weak\fP descriptors should be individually free'd using 
+\f(CWdwarf_dealloc()\fP with the allocation type 
+\f(CWDW_DLA_WEAK_CONTEXT\fP, 
+(or
+\f(CWDW_DLA_WEAK\fP, an older name, supported for compatibility)
+followed by the deallocation of the list itself with the allocation type 
+\f(CWDW_DLA_LIST\fP when the descriptors are no longer of interest.
+
+.in +2
+.DS
+\f(CWDwarf_Signed cnt;
+Dwarf_Weak *weaks;
+int res;
+
+res = dwarf_get_weaks(dbg, &weaks,&cnt, &error);
+if (res == DW_DLV_OK) {
+
+        for (i = 0; i < cnt; ++i) {
+                /* use weaks[i] */
+                dwarf_dealloc(dbg, weaks[i], DW_DLA_WEAK_CONTEXT);
+        }
+        dwarf_dealloc(dbg, weaks, DW_DLA_LIST);
+}\fP
+.DE
+.in -2
+
+.H 4 "dwarf_weakname()"
+.DS
+\f(CWint dwarf_weakname(
+        Dwarf_Weak weak,
+	char    ** return_name,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_weakname()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to
+a pointer to a null-terminated
+string that names the weak name represented by the 
+\f(CWDwarf_Weak\fP descriptor, \f(CWweak\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.  
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+On a successful return from this function, the string should
+be free'd using \f(CWdwarf_dealloc()\fP, with the allocation type
+\f(CWDW_DLA_STRING\fP when no longer of interest.
+
+.DS
+\f(CWint dwarf_weak_die_offset(
+        Dwarf_Weak weak,
+	Dwarf_Off  *return_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_weak_die_offset()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in
+the section containing DIE's, i.e. .debug_info, of the DIE representing
+the weak name that is described by the \f(CWDwarf_Weak\fP descriptor, 
+\f(CWweak\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.H 4 "dwarf_weak_cu_offset()"
+.DS
+\f(CWint dwarf_weak_cu_offset(
+        Dwarf_Weak weak,
+	Dwarf_Off  *return_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_weak_cu_offset()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to the offset in
+the section containing DIE's, i.e. .debug_info, of the compilation-unit
+header of the compilation-unit that contains the weak name described 
+by the \f(CWDwarf_Weak\fP descriptor, \f(CWweak\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.H 4 "dwarf_weak_name_offsets()"
+.DS
+\f(CWint dwarf_weak_name_offsets(
+        Dwarf_Weak weak,
+	char **  weak_name,
+        Dwarf_Off *die_offset,
+        Dwarf_Off *cu_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_weak_name_offsets()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*weak_name\fP to
+a pointer to
+a null-terminated string that gives the name of the weak name
+described by the \f(CWDwarf_Weak\fP descriptor \f(CWweak\fP.  
+It also returns in the locations 
+pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets
+of the DIE representing the 
+weakname, and the DIE
+representing the compilation-unit containing the 
+weakname, respectively.
+It returns \f(CWDW_DLV_ERROR\fP on error.  
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+On a 
+successful return from \f(CWdwarf_weak_name_offsets()\fP the storage 
+pointed to by \f(CWweak_name\fP
+should be free'd using \f(CWdwarf_dealloc()\fP, 
+with the allocation type \f(CWDW_DLA_STRING\fP when no longer of interest.
+
+.H 2 "Static Function Names Operations"
+This section is SGI specific and is not part of standard DWARF version 2.
+.P
+These function operate on the .debug_funcnames section of the debugging
+information.  The .debug_funcnames section contains the names of static
+functions defined in the object, the offsets of the \f(CWDIE\fPs that
+represent the definitions of the corresponding functions, and the offsets
+of the start of the compilation-units that contain the definitions of
+those functions.
+
+.H 3 "Debugger Interface Operations"
+
+.H 4 "dwarf_get_funcs()"
+.DS
+\f(CWint dwarf_get_funcs(
+        Dwarf_Debug dbg,
+        Dwarf_Func **funcs,
+        Dwarf_Signed *func_count,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_get_funcs()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*func_count\fP to
+the count of static
+function names represented in the section containing static function
+names, i.e. .debug_funcnames.  
+It also 
+stores, at \f(CW*funcs\fP, a pointer to a list of \f(CWDwarf_Func\fP 
+descriptors, one for each of the static functions in the .debug_funcnames 
+section.  
+It returns \f(CWDW_DLV_NOCOUNT\fP on error.
+It returns \f(CWDW_DLV_NO_ENTRY\fP
+if the .debug_funcnames section does not exist.  
+.P
+On a successful return from \f(CWdwarf_get_funcs()\fP, 
+the \f(CWDwarf_Func\fP
+descriptors should be free'd using \f(CWdwarf_funcs_dealloc()\fP.
+\f(CWdwarf_funcs_dealloc()\fP is new as of July 15, 2005.
+
+.in +2
+.DS
+\f(CWDwarf_Signed cnt;
+Dwarf_Func *funcs;
+int fres;
+
+fres = dwarf_get_funcs(dbg, &funcs, &error);
+if (fres == DW_DLV_OK) {
+
+        for (i = 0; i < cnt; ++i) {
+                /* use funcs[i] */
+        }
+        dwarf_funcs_dealloc(dbg, funcs, cnt);
+}\fP
+.DE
+.in -2
+
+
+.P
+The following code is deprecated as of July 15, 2005 as it does not
+free all relevant memory.
+This approach  still works as well as it ever did.
+On a successful return from \f(CWdwarf_get_funcs()\fP, 
+the \f(CWDwarf_Func\fP 
+descriptors should be individually free'd using \f(CWdwarf_dealloc()\fP 
+with the allocation type 
+\f(CWDW_DLA_FUNC_CONTEXT\fP, 
+(or
+\f(CWDW_DLA_FUNC\fP, an older name, supported for compatibility)
+followed by the deallocation 
+of the list itself with the allocation type \f(CWDW_DLA_LIST\fP when 
+the descriptors are no longer of interest.
+
+.in +2
+.DS
+\f(CWDwarf_Signed cnt;
+Dwarf_Func *funcs;
+int fres;
+
+fres = dwarf_get_funcs(dbg, &funcs, &error);
+if (fres == DW_DLV_OK) {
+
+        for (i = 0; i < cnt; ++i) {
+                /* use funcs[i] */
+                dwarf_dealloc(dbg, funcs[i], DW_DLA_FUNC_CONTEXT);
+        }
+        dwarf_dealloc(dbg, funcs, DW_DLA_LIST);
+}\fP
+.DE
+.in -2
+
+.H 4 "dwarf_funcname()"
+.DS
+\f(CWint dwarf_funcname(
+        Dwarf_Func func,
+        char **    return_name,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_funcname()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to
+a pointer to a
+null-terminated string that names the static function represented by the
+\f(CWDwarf_Func\fP descriptor, \f(CWfunc\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.  
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+On a successful return from this function, the string should
+be free'd using \f(CWdwarf_dealloc()\fP, with the allocation type
+\f(CWDW_DLA_STRING\fP when no longer of interest.
+
+.H 4 "dwarf_func_die_offset()"
+.DS
+\f(CWint dwarf_func_die_offset(
+        Dwarf_Func func,
+	Dwarf_Off  *return_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_func_die_offset()\fP, returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to
+the offset in
+the section containing DIE's, i.e. .debug_info, of the DIE representing
+the static function that is described by the \f(CWDwarf_Func\fP 
+descriptor, \f(CWfunc\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.H 4 "dwarf_func_cu_offset()"
+.DS
+\f(CWint dwarf_func_cu_offset(
+        Dwarf_Func func,
+	Dwarf_Off  *return_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_func_cu_offset()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to
+the offset in
+the section containing DIE's, i.e. .debug_info, of the compilation-unit
+header of the 
+compilation-unit that contains the static function
+described by the \f(CWDwarf_Func\fP descriptor, \f(CWfunc\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.H 4 "dwarf_func_name_offsets()"
+.DS
+\f(CWint dwarf_func_name_offsets(
+        Dwarf_Func func,
+	char     **func_name,
+        Dwarf_Off *die_offset,
+        Dwarf_Off *cu_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_func_name_offsets()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*func_name\fP to
+a pointer to
+a null-terminated string that gives the name of the static
+function described by the \f(CWDwarf_Func\fP descriptor \f(CWfunc\fP.
+It also returns in the locations
+pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets
+of the DIE representing the 
+static function, and the DIE
+representing the compilation-unit containing the 
+static function, respectively.
+It returns \f(CWDW_DLV_ERROR\fP on error.  
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+On a successful return from \f(CWdwarf_func_name_offsets()\fP
+the storage pointed to by  \f(CWfunc_name\fP should be free'd using
+\f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP
+when no longer of interest.
+
+.H 2 "User Defined Type Names Operations"
+Section "debug_typenames"  is SGI specific 
+and is not part of standard DWARF version 2.
+(However, an identical section is part of DWARF version 3
+named ".debug_pubtypes", see  \f(CWdwarf_get_pubtypes()\fP above.)
+.P
+These functions operate on the .debug_typenames section of the debugging
+information.  The .debug_typenames section contains the names of file-scope
+user-defined types, the offsets of the \f(CWDIE\fPs that represent the
+definitions of those types, and the offsets of the compilation-units 
+that contain the definitions of those types.
+
+.H 3 "Debugger Interface Operations"
+
+.H 4 "dwarf_get_types()"
+.DS
+\f(CWint dwarf_get_types(
+        Dwarf_Debug dbg,
+        Dwarf_Type **types,
+        Dwarf_Signed *typecount,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_get_types()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*typecount\fP to
+the count of user-defined
+type names represented in the section containing user-defined type names,
+i.e. .debug_typenames.  
+It also stores at \f(CW*types\fP, 
+a pointer to a list of \f(CWDwarf_Type\fP descriptors, one for each of the 
+user-defined type names in the .debug_typenames section.  
+It returns \f(CWDW_DLV_NOCOUNT\fP on error. 
+It returns \f(CWDW_DLV_NO_ENTRY\fP if 
+the .debug_typenames section does not exist.  
+
+.P
+
+On a successful
+return from \f(CWdwarf_get_types()\fP, 
+the \f(CWDwarf_Type\fP descriptors should be
+free'd using \f(CWdwarf_types_dealloc()\fP.
+\f(CWdwarf_types_dealloc()\fP is new as of July 15, 2005
+and frees all memory allocated by \f(CWdwarf_get_types()\fP.
+
+.in +2
+.DS
+\f(CWDwarf_Signed cnt;
+Dwarf_Type *types;
+int res;
+
+res = dwarf_get_types(dbg, &types,&cnt, &error);
+if (res == DW_DLV_OK) {
+
+        for (i = 0; i < cnt; ++i) {
+                /* use types[i] */
+        }
+        dwarf_types_dealloc(dbg, types, cnt);
+}\fP
+.DE
+.in -2
+
+
+
+.P
+The following code is deprecated as of July 15, 2005 as it does not
+free all relevant memory.
+This approach  still works as well as it ever did.
+On a successful 
+return from \f(CWdwarf_get_types()\fP, 
+the \f(CWDwarf_Type\fP descriptors should be 
+individually free'd using \f(CWdwarf_dealloc()\fP with the allocation type 
+\f(CWDW_DLA_TYPENAME_CONTEXT\fP, 
+(or
+\f(CWDW_DLA_TYPENAME\fP, an older name, supported for compatibility)
+followed by the deallocation of the list itself 
+with the allocation type \f(CWDW_DLA_LIST\fP when the descriptors are no 
+longer of interest.
+
+.in +2
+.DS
+\f(CWDwarf_Signed cnt;
+Dwarf_Type *types;
+int res;
+
+res = dwarf_get_types(dbg, &types,&cnt, &error);
+if (res == DW_DLV_OK) {
+
+        for (i = 0; i < cnt; ++i) {
+                /* use types[i] */
+                dwarf_dealloc(dbg, types[i], DW_DLA_TYPENAME_CONTEXT);
+        }
+        dwarf_dealloc(dbg, types, DW_DLA_LIST);
+}\fP
+.DE
+.in -2
+
+.H 4 "dwarf_typename()"
+.DS
+\f(CWint dwarf_typename(
+        Dwarf_Type   type,
+        char       **return_name,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_typename()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_name\fP to
+a pointer to a
+null-terminated string that names the user-defined type represented by the
+\f(CWDwarf_Type\fP descriptor, \f(CWtype\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.  
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+On a successful return from this function, the string should
+be free'd using \f(CWdwarf_dealloc()\fP, with the allocation type
+\f(CWDW_DLA_STRING\fP when no longer of interest.
+
+.H 4 "dwarf_type_die_offset()"
+.DS
+\f(CWint dwarf_type_die_offset(
+        Dwarf_Type type,
+        Dwarf_Off  *return_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_type_die_offset()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to
+the offset in
+the section containing DIE's, i.e. .debug_info, of the DIE representing
+the user-defined type that is described by the \f(CWDwarf_Type\fP 
+descriptor, \f(CWtype\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.H 4 "dwarf_type_cu_offset()"
+.DS
+\f(CWint dwarf_type_cu_offset(
+        Dwarf_Type type,
+        Dwarf_Off  *return_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_type_cu_offset()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_offset\fP to
+the offset in
+the section containing DIE's, i.e. .debug_info, of the compilation-unit
+header of the compilation-unit that contains the user-defined type
+described by the \f(CWDwarf_Type\fP descriptor, \f(CWtype\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.H 4 "dwarf_type_name_offsets()"
+.DS
+\f(CWint dwarf_type_name_offsets(
+        Dwarf_Type   type,
+        char      ** returned_name,
+        Dwarf_Off *  die_offset,
+        Dwarf_Off *  cu_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_type_name_offsets()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to
+a pointer to
+a null-terminated string that gives the name of the user-defined
+type described by the \f(CWDwarf_Type\fP descriptor \f(CWtype\fP.
+It also returns in the locations
+pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets
+of the DIE representing the 
+user-defined type, and the DIE
+representing the compilation-unit containing the 
+user-defined type, respectively.
+It returns \f(CWDW_DLV_ERROR\fP on error.  
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+On a successful return from \f(CWdwarf_type_name_offsets()\fP
+the storage pointed to by \f(CWreturned_name\fP should
+be free'd using
+\f(CWdwarf_dealloc()\fP, with the allocation type \f(CWDW_DLA_STRING\fP
+when no longer of interest.
+
+
+.H 2 "User Defined Static Variable Names Operations"
+This section is SGI specific and is not part of standard DWARF version 2.
+.P
+These functions operate on the .debug_varnames section of the debugging
+information.  The .debug_varnames section contains the names of file-scope
+static variables, the offsets of the \f(CWDIE\fPs that represent the 
+definitions of those variables, and the offsets of the compilation-units
+that contain the definitions of those variables.
+.P
+
+.H 3 "Debugger Interface Operations"
+
+.H 4 "dwarf_get_vars()"
+
+.DS
+\f(CWint dwarf_get_vars(
+        Dwarf_Debug dbg,
+        Dwarf_Var **vars,
+        Dwarf_Signed *var_count,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_get_vars()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*var_count\fP to
+the count of file-scope
+static variable names represented in the section containing file-scope 
+static variable names, i.e. .debug_varnames.  
+It also stores, at \f(CW*vars\fP, a pointer to a list of 
+\f(CWDwarf_Var\fP descriptors, one for each of the file-scope static
+variable names in the .debug_varnames section.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It returns \f(CWDW_DLV_NO_ENTRY\fP if the .debug_varnames section does 
+not exist.  
+
+.P 
+The following is new as of July 15, 2005.
+On a successful return
+from \f(CWdwarf_get_vars()\fP, the \f(CWDwarf_Var\fP descriptors should be
+free'd using \f(CWdwarf_vars_dealloc()\fP.
+
+.in +2
+.DS
+\f(CWDwarf_Signed cnt;
+Dwarf_Var *vars;
+int res;
+
+res = dwarf_get_vars(dbg, &vars,&cnt &error);
+if (res == DW_DLV_OK) {
+
+        for (i = 0; i < cnt; ++i) {
+                /* use vars[i] */
+        }
+        dwarf_vars_dealloc(dbg, vars, cnt);
+}\fP
+.DE
+.in -2
+
+.P 
+The following code is deprecated as of July 15, 2005 as it does not
+free all relevant memory.
+This approach  still works as well as it ever did.
+On a successful return 
+from \f(CWdwarf_get_vars()\fP, the \f(CWDwarf_Var\fP descriptors should be individually 
+free'd using \f(CWdwarf_dealloc()\fP with the allocation type 
+\f(CWDW_DLA_VAR_CONTEXT\fP, 
+(or
+\f(CWDW_DLA_VAR\fP, an older name, supported for compatibility)
+followed by the deallocation of the list itself with 
+the allocation type \f(CWDW_DLA_LIST\fP when the descriptors are no 
+longer of interest.
+
+.in +2
+.DS
+\f(CWDwarf_Signed cnt;
+Dwarf_Var *vars;
+int res;
+
+res = dwarf_get_vars(dbg, &vars,&cnt &error);
+if (res == DW_DLV_OK) {
+
+        for (i = 0; i < cnt; ++i) {
+                /* use vars[i] */
+                dwarf_dealloc(dbg, vars[i], DW_DLA_VAR_CONTEXT);
+        }
+        dwarf_dealloc(dbg, vars, DW_DLA_LIST);
+}\fP
+.DE
+.in -2
+
+.H 4 "dwarf_varname()"
+.DS
+\f(CWint dwarf_varname(
+        Dwarf_Var var,
+        char **    returned_name,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_varname()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to
+a pointer to a
+null-terminated string that names the file-scope static variable represented 
+by the \f(CWDwarf_Var\fP descriptor, \f(CWvar\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.  
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+On a successful return from this function, the string should
+be free'd using \f(CWdwarf_dealloc()\fP, with the allocation type
+\f(CWDW_DLA_STRING\fP when no longer of interest.
+
+.H 4 "dwarf_var_die_offset()"
+.DS
+\f(CWint dwarf_var_die_offset(
+        Dwarf_Var    var,
+        Dwarf_Off   *returned_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_var_die_offset()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*returned_offset\fP to
+the offset in
+the section containing DIE's, i.e. .debug_info, of the DIE representing
+the file-scope static variable that is described by the \f(CWDwarf_Var\fP 
+descriptor, \f(CWvar\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.H 4 "dwarf_var_cu_offset()"
+.DS
+\f(CWint dwarf_var_cu_offset(
+        Dwarf_Var var,
+        Dwarf_Off   *returned_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_var_cu_offset()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*returned_offset\fP to
+the offset in
+the section containing DIE's, i.e. .debug_info, of the compilation-unit
+header of the compilation-unit that contains the file-scope static
+variable described by the \f(CWDwarf_Var\fP descriptor, \f(CWvar\fP.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.H 4 "dwarf_var_name_offsets()"
+.DS
+\f(CWint dwarf_var_name_offsets(
+        Dwarf_Var var,
+	char     **returned_name,
+        Dwarf_Off *die_offset,
+        Dwarf_Off *cu_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_var_name_offsets()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*returned_name\fP to
+a pointer to
+a null-terminated string that gives the name of the file-scope
+static variable described by the \f(CWDwarf_Var\fP descriptor \f(CWvar\fP.
+It also returns in the locations
+pointed to by \f(CWdie_offset\fP, and \f(CWcu_offset\fP, the offsets
+of the DIE representing the 
+file-scope static variable, and the DIE
+representing the compilation-unit containing the 
+file-scope static variable, respectively.
+It returns \f(CWDW_DLV_ERROR\fP on error.  
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+On a successful return from 
+\f(CWdwarf_var_name_offsets()\fP the storage pointed to by
+\f(CWreturned_name\fP
+should be free'd using \f(CWdwarf_dealloc()\fP, with the allocation 
+type \f(CWDW_DLA_STRING\fP when no longer of interest.
+
+.H 2 "Macro Information Operations"
+.H 3 "General Macro Operations"
+.H 4 "dwarf_find_macro_value_start()"
+.DS
+\f(CWchar *dwarf_find_macro_value_start(char * macro_string);\fP
+.DE
+Given a macro string in the standard form defined in the DWARF
+document ("name <space> value" or "name(args)<space>value")
+this returns a pointer to the first byte of the macro value.
+It does not alter the string pointed to by macro_string or copy
+the string: it returns a pointer into the string whose
+address was passed in.
+.H 3 "Debugger Interface Macro Operations"
+Macro information is accessed from the .debug_info section via the
+DW_AT_macro_info attribute (whose value is an offset into .debug_macinfo).
+.P
+No Functions yet defined.
+.H 3 "Low Level Macro Information Operations"
+.H 4 "dwarf_get_macro_details()"
+.DS
+\f(CWint dwarf_get_macro_details(Dwarf_Debug /*dbg*/,
+  Dwarf_Off              macro_offset,
+  Dwarf_Unsigned         maximum_count,
+  Dwarf_Signed         * entry_count,
+  Dwarf_Macro_Details ** details,
+  Dwarf_Error *          err);\fP
+.DE
+\f(CWdwarf_get_macro_details()\fP
+returns  
+\f(CWDW_DLV_OK\fP and sets
+\f(CWentry_count\fP to the number of \f(CWdetails\fP records
+returned through the \f(CWdetails\fP pointer.
+The data returned thru  \f(CWdetails\fP should be freed
+by a call to \f(CWdwarf_dealloc()\fP with the allocation type
+\f(CWDW_DLA_STRING\fP.
+If \f(CWDW_DLV_OK\fP is returned, the \f(CWentry_count\fP will
+be at least 1, since
+a compilation unit with macro information but no macros will
+have at least one macro data byte of 0.
+.P
+\f(CWdwarf_get_macro_details()\fP
+begins at the \f(CWmacro_offset\fP offset you supply
+and ends at the end of a compilation unit or at \f(CWmaximum_count\fP
+detail records (whichever comes first).
+If \f(CWmaximum_count\fP is 0, it is treated as if it were the maximum
+possible unsigned integer.
+.P
+\f(CWdwarf_get_macro_details()\fP
+attempts to set \f(CWdmd_fileindex\fP to the correct file in every
+\f(CWdetails\fP record. If it is unable to do so (or whenever
+the current file index is unknown, it sets \f(CWdmd_fileindex\fP
+to -1.
+.P
+\f(CWdwarf_get_macro_details()\fP returns \f(CWDW_DLV_ERROR\fP on error.
+It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no more
+macro information at that \f(CWmacro_offset\fP. If \f(CWmacro_offset\fP
+is passed in as 0, a \f(CWDW_DLV_NO_ENTRY\fP return means there is
+no macro information.
+.P
+.in +2
+.DS
+\f(CWDwarf_Unsigned max = 0;
+Dwarf_Off cur_off = 0;
+Dwarf_Signed count = 0;
+Dwarf_Macro_Details *maclist;
+int errv;
+
+/* loop thru all the compilation units macro info */
+while((errv = dwarf_macro_details(dbg, cur_off,max,
+     &count,&maclist,&error))== DW_DLV_OK) {
+    for (i = 0; i < count; ++i) {
+      /* use maclist[i] */
+    }
+    cur_off = maclist[count-1].dmd_offset + 1;
+    dwarf_dealloc(dbg, maclist, DW_DLA_STRING);
+}\fP
+.DE
+
+
+.H 2 "Low Level Frame Operations"
+These functions provide information about stack frames to be
+used to perform stack traces.  The information is an abstraction
+of a table with a row per instruction and a column per register
+and a column for the canonical frame address (CFA, which corresponds
+to the notion of a frame pointer), 
+as well as a column for the return address.  
+.P
+From 1993-2006 the interface we'll here refer to as DWARF2
+made the CFA be a column in the matrix, but left
+DW_FRAME_UNDEFINED_VAL, and DW_FRAME_SAME_VAL out of the matrix
+(giving them high numbers). As of the DWARF3 interfaces
+introduced in this document in April 2006, there are *two*
+interfaces. 
+.P
+The original still exists (see.
+dwarf_get_fde_info_for_reg() and dwarf_get_fde_info_for_all_regs() below)
+and works adequately for MIPS/IRIX DWARF2 and ABI/ISA sets
+that are sufficiently similar (but the settings for non-MIPS
+must be set into libdwarf.h and cannot be changed at runtime).
+.P
+A new interface  set of dwarf_get_fde_info_for_reg3(),
+dwarf_get_fde_info_for_cfa_reg3(), dwarf_get_fde_info_for_all_regs3()
+dwarf_set_frame_rule_inital_value(), dwarf_set_frame_rule_table_size()
+is more flexible
+and should work for many more architectures
+and the setting of  DW_FRAME_CFA_COL and the size of
+the table can be set at runtime.
+.P
+Each cell in the table contains one of the following:
+
+.AL 
+.LI
+A register + offset(a)(b)
+
+.LI
+A register(c)(d)
+
+
+.LI
+A marker (DW_FRAME_UNDEFINED_VAL) meaning \fIregister value undefined\fP
+
+.LI
+A marker (DW_FRAME_SAME_VAL) meaning \fIregister value same as in caller\fP
+.LE
+.P
+(a old DWARF2 interface) When  the column is DW_FRAME_CFA_COL: the register
+number is a real hardware register, not a reference
+to DW_FRAME_CFA_COL, not  DW_FRAME_UNDEFINED_VAL,
+and not DW_FRAME_SAME_VAL. 
+The CFA rule value should be the stack pointer
+plus offset 0 when no other value makes sense.
+A value of DW_FRAME_SAME_VAL would
+be semi-logical, but since the CFA is not a real register,
+not really correct.
+A value of DW_FRAME_UNDEFINED_VAL would imply
+the CFA is undefined  --
+this seems to be a useless notion, as
+the CFA is a means to finding real registers,
+so those real registers should be marked DW_FRAME_UNDEFINED_VAL,
+and the CFA column content (whatever register it
+specifies) becomes unreferenced by anything.
+.P
+(a new April 2006 DWARF2/3 interface): The CFA is
+separately accessible and not part of the table.
+The 'rule number' for the CFA is a number outside the table. 
+So the CFA is a marker, not a register number.
+See  DW_FRAME_CFA_COL3 in libdwarf.h and
+dwarf_get_fde_info_for_cfa_reg3().
+.P
+(b) When the column is not DW_FRAME_CFA_COL, the 'register'
+will and must be DW_FRAME_CFA_COL, implying that
+to get the final location for the column one must add
+the offset here plus the DW_FRAME_CFA_COL rule value.
+.P
+(c) When the column is DW_FRAME_CFA_COL, then the register
+number is (must be) a real hardware register .
+If it were DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL
+it would be a marker, not a register number.
+.P
+(d) When the column is not DW_FRAME_CFA_COL, the register
+may be a hardware register.
+It will not be DW_FRAME_CFA_COL.
+.P
+There is no 'column' for DW_FRAME_UNDEFINED_VAL or DW_FRAME_SAME_VAL.
+
+Figure \n(aX
+is machine dependent and represents MIPS cpu register
+assignments.
+
+.DS
+.TS
+center box, tab(:);
+lfB lfB lfB
+l c l.
+NAME:value:PURPOSE
+_
+DW_FRAME_CFA_COL:0:column used for CFA
+DW_FRAME_REG1:1:integer regster 1
+DW_FRAME_REG2:2:integer register 2
+---::obvious names and values here
+DW_FRAME_REG30:30:integer register 30 
+DW_FRAME_REG31:31:integer register 31
+DW_FRAME_FREG0:32:floating point register 0
+DW_FRAME_FREG1:33:floating point register 1
+---::obvious names and values here
+DW_FRAME_FREG30:62:floating point register 30
+DW_FRAME_FREG31:63:floating point register 31
+DW_FRAME_RA_COL:64:column recording ra
+DW_FRAME_UNDEFINED_VAL:1034:register val undefined
+DW_FRAME_SAME_VAL:1035:register same as in caller
+.TE
+
+.FG "Frame Information Rule Assignments"
+.DE
+
+.P
+The following table shows SGI/MIPS specific
+special cell values: these values mean 
+that the cell has the value \fIundefined\fP or \fIsame value\fP
+respectively, rather than containing a \fIregister\fP or
+\fIregister+offset\fP.  
+It assumes DW_FRAME_CFA_COL is a table rule, which
+is not readily accomplished or sensible for some architectures.
+.P
+.DS
+.TS
+center box, tab(:);
+lfB lfB lfB
+l c l.
+NAME:value:PURPOSE
+_
+DW_FRAME_UNDEFINED_VAL:1034:means undefined value.
+::Not a column or register value
+DW_FRAME_SAME_VAL:1035:means 'same value' as
+::caller had. Not a column or 
+::register value
+.TE
+.FG "Frame Information Special Values"
+.DE
+
+.P
+The following table shows more general special cell values. 
+These values mean
+that the cell register-number refers to the \fIcfa-register\fP or 
+\fIundefined-value\fP or \fIsame-value\fP
+respectively, rather than referring to a \fIregister in the table\fP.
+The generality arises from making DW_FRAME_CFA_COL3 be
+outside the set of registers and making the cfa rule accessible
+from outside the rule-table.
+.P
+.DS
+.TS
+center box, tab(:);
+lfB lfB lfB
+l c l.
+NAME:value:PURPOSE
+_
+DW_FRAME_UNDEFINED_VAL:1034:means undefined value.
+::Not a column or register value
+DW_FRAME_SAME_VAL:1035:means 'same value' as
+::caller had. Not a column or
+::register value
+DW_FRAME_CFA_COL3:1036:means 'cfa register'is referred to,
+::not a real register, not a column, but the cfa (the cfa
+::does have a value, but in the DWARF3 libdwarf interface
+::it does not have a 'real register number').
+.TE
+.DE
+.\"#if 0
+.\".P
+.\"Since the cie and fde entries are not "organized" by anything
+.\"outside of the .debug_frame section one must scan them all to 
+.\"find all entry addresses and lengths.  Since there is one fde 
+.\"per function this can be a rather long list.
+.\"#endif
+
+.P
+.H 4 "dwarf_get_fde_list()"
+.DS
+\f(CWint dwarf_get_fde_list(
+        Dwarf_Debug dbg,
+        Dwarf_Cie **cie_data,
+        Dwarf_Signed *cie_element_count,
+        Dwarf_Fde **fde_data,
+        Dwarf_Signed *fde_element_count,
+        Dwarf_Error *error);\fP
+.DE
+\f(CWdwarf_get_fde_list()\fP stores a pointer to a list of 
+\f(CWDwarf_Cie\fP descriptors in \f(CW*cie_data\fP, and the 
+count of the number of descriptors in \f(CW*cie_element_count\fP.  
+There is a descriptor for each CIE in the .debug_frame section.  
+Similarly, it stores a pointer to a list of \f(CWDwarf_Fde\fP 
+descriptors in \f(CW*fde_data\fP, and the count of the number 
+of descriptors in \f(CW*fde_element_count\fP.  There is one 
+descriptor per FDE in the .debug_frame section.  
+\f(CWdwarf_get_fde_list()\fP  returns \f(CWDW_DLV_EROR\fP on error.
+It returns \f(CWDW_DLV_NO_ENTRY\fP if it cannot find frame entries.
+It returns \f(CWDW_DLV_OK\fP on a successful return.
+.P
+On successful return, structures pointed to by a
+descriptor should be free'd using \f(CWdwarf_fde_cie_list_dealloc()\fP.
+This dealloc approach is new as of July 15, 2005.
+
+.in +2
+.DS
+\f(CWDwarf_Signed cnt;
+Dwarf_Cie *cie_data;
+Dwarf_Signed cie_count;
+Dwarf_Fde *fde_data;
+Dwarf_Signed fde_count;
+int fres;
+
+fres = dwarf_get_fde_list(dbg,&cie_data,&cie_count,
+                &fde_data,&fde_count,&error);
+if (fres == DW_DLV_OK) {
+        dwarf_fde_cie_list_dealloc(dbg, cie_data, cie_count,
+		fde_data,fde_count);
+}\fP
+.DE
+.in -2
+
+
+
+.P
+The following code is deprecated as of July 15, 2005 as it does not
+free all relevant memory.
+This approach  still works as well as it ever did.
+.in +2
+.DS
+\f(CWDwarf_Signed cnt;
+Dwarf_Cie *cie_data;
+Dwarf_Signed cie_count;
+Dwarf_Fde *fde_data;
+Dwarf_Signed fde_count;
+int fres;
+
+fres = dwarf_get_fde_list(dbg,&cie_data,&cie_count, 
+		&fde_data,&fde_count,&error);
+if (fres == DW_DLV_OK) {
+
+        for (i = 0; i < cie_count; ++i) {
+                /* use cie[i] */
+                dwarf_dealloc(dbg, cie_data[i], DW_DLA_CIE);
+        }
+        for (i = 0; i < fde_count; ++i) {
+                /* use fde[i] */
+                dwarf_dealloc(dbg, fde_data[i], DW_DLA_FDE);
+        }
+        dwarf_dealloc(dbg, cie_data, DW_DLA_LIST);
+        dwarf_dealloc(dbg, fde_data, DW_DLA_LIST);
+}\fP
+.DE
+.in -2
+
+.P
+.H 4 "dwarf_get_fde_list_eh()"
+.DS
+\f(CWint dwarf_get_fde_list_eh(
+        Dwarf_Debug dbg,
+        Dwarf_Cie **cie_data,
+        Dwarf_Signed *cie_element_count,
+        Dwarf_Fde **fde_data,
+        Dwarf_Signed *fde_element_count,
+        Dwarf_Error *error);\fP
+.DE
+\f(CWdwarf_get_fde_list_eh()\fP is identical to
+\f(CWdwarf_get_fde_list()\fP except that
+\f(CWdwarf_get_fde_list_eh()\fP reads the GNU ecgs
+section named .eh_frame (C++ exception handling information).
+
+\f(CWdwarf_get_fde_list_eh()\fP stores a pointer to a list of
+\f(CWDwarf_Cie\fP descriptors in \f(CW*cie_data\fP, and the
+count of the number of descriptors in \f(CW*cie_element_count\fP.
+There is a descriptor for each CIE in the .debug_frame section.
+Similarly, it stores a pointer to a list of \f(CWDwarf_Fde\fP
+descriptors in \f(CW*fde_data\fP, and the count of the number
+of descriptors in \f(CW*fde_element_count\fP.  There is one
+descriptor per FDE in the .debug_frame section.
+\f(CWdwarf_get_fde_list()\fP  returns \f(CWDW_DLV_EROR\fP on error.
+It returns \f(CWDW_DLV_NO_ENTRY\fP if it cannot find 
+exception handling entries.
+It returns \f(CWDW_DLV_OK\fP on a successful return.
+
+.P
+On successful return, structures pointed to by a
+descriptor should be free'd using \f(CWdwarf_fde_cie_list_dealloc()\fP.
+This dealloc approach is new as of July 15, 2005.
+
+.in +2
+.DS
+\f(CWDwarf_Signed cnt;
+Dwarf_Cie *cie_data;
+Dwarf_Signed cie_count;
+Dwarf_Fde *fde_data;
+Dwarf_Signed fde_count;
+int fres;
+
+fres = dwarf_get_fde_list(dbg,&cie_data,&cie_count,
+                &fde_data,&fde_count,&error);
+if (fres == DW_DLV_OK) {
+        dwarf_fde_cie_list_dealloc(dbg, cie_data, cie_count,
+                fde_data,fde_count);
+}\fP
+.DE
+.in -2
+
+
+.P
+.H 4 "dwarf_get_cie_of_fde()"
+.DS
+\f(CWint dwarf_get_cie_of_fde(Dwarf_Fde fde,
+        Dwarf_Cie *cie_returned,
+        Dwarf_Error *error);\fP
+.DE
+\f(CWdwarf_get_cie_of_fde()\fP stores a \f(CWDwarf_Cie\fP
+into the  \f(CWDwarf_Cie\fP that \f(CWcie_returned\fP points at.
+
+If one has called dwarf_get_fde_list and does not wish
+to dwarf_dealloc() all the individual FDEs immediately, one
+must also avoid dwarf_dealloc-ing the CIEs for those FDEs
+not immediately dealloc'd.
+Failing to observe this restriction will cause the  FDE(s) not
+dealloced to become invalid: an FDE contains (hidden in it)
+a CIE pointer which will be be invalid (stale, pointing to freed memory)
+if the CIE is dealloc'd.
+The invalid CIE pointer internal to the FDE cannot be detected
+as invalid by libdwarf.
+If one later passes an FDE with a stale internal CIE pointer
+to one of the routines taking an FDE as input the result will
+be failure of the call (returning DW_DLV_ERROR) at best and
+it is possible a coredump or worse will happpen (eventually).
+
+
+\f(CWdwarf_get_cie_of_fde()\fP returns 
+\f(CWDW_DLV_OK\fP if it is successful (it will be
+unless fde is the NULL pointer).
+It returns \f(CWDW_DLV_ERROR\fP if the fde is invalid (NULL).
+
+.P
+Each \f(CWDwarf_Fde\fP descriptor describes information about the
+frame for a particular subroutine or function.
+
+\f(CWint dwarf_get_fde_for_die\fP is SGI/MIPS specific.
+
+.H 4 "dwarf_get_fde_for_die()"
+.DS
+\f(CWint dwarf_get_fde_for_die(
+        Dwarf_Debug dbg,
+        Dwarf_Die die,
+        Dwarf_Fde *  return_fde,
+        Dwarf_Error *error)\fP
+.DE
+When it succeeds,
+\f(CWdwarf_get_fde_for_die()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_fde\fP
+to
+a \f(CWDwarf_Fde\fP
+descriptor representing frame information for the given \f(CWdie\fP.  It 
+looks for the \f(CWDW_AT_MIPS_fde\fP attribute in the given \f(CWdie\fP.
+If it finds it, is uses the value of the attribute as the offset in 
+the .debug_frame section where the FDE begins.
+If there is no \f(CWDW_AT_MIPS_fde\fP it returns \f(CWDW_DLV_NO_ENTRY\fP.
+If there is an error it returns \f(CWDW_DLV_ERROR\fP.
+
+.H 4 "dwarf_get_fde_range()"
+.DS
+\f(CWint dwarf_get_fde_range(
+        Dwarf_Fde fde,
+        Dwarf_Addr *low_pc,
+        Dwarf_Unsigned *func_length,
+        Dwarf_Ptr *fde_bytes,
+        Dwarf_Unsigned *fde_byte_length,
+        Dwarf_Off *cie_offset,
+        Dwarf_Signed *cie_index,
+        Dwarf_Off *fde_offset,
+        Dwarf_Error *error);\fP
+.DE
+On success,
+\f(CWdwarf_get_fde_range()\fP returns
+\f(CWDW_DLV_OK\fP.
+The location pointed to by \f(CWlow_pc\fP is set to the low pc value for
+this function.  
+The location pointed to by \f(CWfunc_length\fP is 
+set to the length of the function in bytes.  
+This is essentially the
+length of the text section for the function.  
+The location pointed
+to by \f(CWfde_bytes\fP is set to the address where the FDE begins
+in the .debug_frame section.  
+The location pointed to by 
+\f(CWfde_byte_length\fP is set to the length in bytes of the portion
+of .debug_frame for this FDE.  
+This is the same as the value returned
+by \f(CWdwarf_get_fde_range\fP.  
+The location pointed to by 
+\f(CWcie_offset\fP is set to the offset in the .debug_frame section
+of the CIE used by this FDE.  
+The location pointed to by \f(CWcie_index\fP
+is set to the index of the CIE used by this FDE.  
+The index is the 
+index of the CIE in the list pointed to by \f(CWcie_data\fP as set 
+by the function \f(CWdwarf_get_fde_list()\fP.  
+However, if the function
+\f(CWdwarf_get_fde_for_die()\fP was used to obtain the given \f(CWfde\fP, 
+this index may not be correct.   
+The location pointed to by 
+\f(CWfde_offset\fP is set to the offset of the start of this FDE in 
+the .debug_frame section.  
+\f(CWdwarf_get_fde_range()\fP returns \f(CWDW_DLV_ERROR\fP on error.
+
+.H 4 "dwarf_get_cie_info()"
+.DS
+\f(CWint dwarf_get_cie_info(
+        Dwarf_Cie       cie,
+	Dwarf_Unsigned *bytes_in_cie,
+        Dwarf_Small    *version,
+        char          **augmenter,
+        Dwarf_Unsigned *code_alignment_factor,
+        Dwarf_Signed *data_alignment_factor,
+        Dwarf_Half     *return_address_register_rule,
+        Dwarf_Ptr      *initial_instructions,
+        Dwarf_Unsigned *initial_instructions_length,
+        Dwarf_Error    *error);\fP
+.DE
+\f(CWdwarf_get_cie_info()\fP is primarily for Internal-level Interface 
+consumers.  
+If successful,
+it returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*bytes_in_cie\fP to
+the number of bytes in the portion of the
+frames section for the CIE represented by the given \f(CWDwarf_Cie\fP
+descriptor, \f(CWcie\fP.  
+The other fields are directly taken from 
+the cie and returned, via the pointers to the caller.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+
+.H 4 "dwarf_get_fde_instr_bytes()"
+.DS
+\f(CWint dwarf_get_fde_instr_bytes(
+        Dwarf_Fde fde,
+	Dwarf_Ptr *outinstrs,
+	Dwarf_Unsigned *outlen,
+        Dwarf_Error *error);\fP
+.DE
+\f(CWdwarf_get_fde_instr_bytes()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*outinstrs\fP to
+a pointer to a set of bytes which are the
+actual frame instructions for this fde.
+It also sets \f(CW*outlen\fP to the length, in
+bytes, of the frame instructions.
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+The intent is to allow low-level consumers like a dwarf-dumper
+to print the bytes in some fashion.
+The memory pointed to by \f(CWoutinstrs\fP
+must not be changed and there
+is nothing to free.
+
+.H 4 "dwarf_get_fde_info_for_reg()"
+This interface is suitable for DWARF2 but is not
+sufficient for DWARF3.  See \f(CWint dwarf_get_fde_info_for_reg3\fP.
+.DS
+\f(CWint dwarf_get_fde_info_for_reg(
+        Dwarf_Fde fde,
+        Dwarf_Half table_column,
+        Dwarf_Addr pc_requested,
+	Dwarf_Signed *offset_relevant,
+        Dwarf_Signed *register_num,
+        Dwarf_Signed *offset,
+        Dwarf_Addr *row_pc,
+        Dwarf_Error *error);\fP
+.DE
+\f(CWdwarf_get_fde_info_for_reg()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*offset_relevant\fP to
+non-zero if the offset is relevant for the
+row specified by \f(CWpc_requested\fP and column specified by
+\f(CWtable_column\fP, for the FDE specified by \f(CWfde\fP.  
+The
+intent is to return the rule for the given pc value and register.
+The location pointed to by \f(CWregister_num\fP is set to the register
+value for the rule.  
+The location pointed to by \f(CWoffset\fP 
+is set to the offset value for the rule.  
+If offset is not relevant for this rule, \f(CW*offset_relevant\fP is
+set to zero.
+Since more than one pc 
+value will have rows with identical entries, the user may want to
+know the earliest pc value after which the rules for all the columns
+remained unchanged.  
+Recall that in the virtual table that the frame information
+represents there may be one or more table rows with identical data
+(each such table row at a different pc value).
+Given a \f(CWpc_requested\fP which refers to a pc in such a group
+of identical rows, 
+the location pointed to by \f(CWrow_pc\fP is set 
+to the lowest pc value
+within the group of  identical rows.
+The  value put in \f(CW*register_num\fP any of the
+\f(CWDW_FRAME_*\fP table columns values specified in \f(CWlibdwarf.h\fP
+or \f(CWdwarf.h\fP.
+
+\f(CWdwarf_get_fde_info_for_reg\fP returns \f(CWDW_DLV_ERROR\fP if there is an error. 
+
+It is usable with either 
+\f(CWdwarf_get_fde_n()\fP or \f(CWdwarf_get_fde_at_pc()\fP.
+
+.H 4 "dwarf_get_fde_info_for_all_regs()"
+.DS
+\f(CWint dwarf_get_fde_info_for_all_regs(
+        Dwarf_Fde fde,
+        Dwarf_Addr pc_requested,
+	Dwarf_Regtable *reg_table,
+        Dwarf_Addr *row_pc,
+        Dwarf_Error *error);\fP
+.DE
+\f(CWdwarf_get_fde_info_for_all_regs()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*reg_table\fP for the row specified by
+\f(CWpc_requested\fP for the FDE specified by \f(CWfde\fP. 
+.P
+The intent is
+to return the rules for decoding all the registers, given a pc value.
+\f(CWreg_table\fP is an array of rules, one for each register specified in
+\f(CWdwarf.h\fP. The rule for each register contains three items - 
+\f(CWdw_regnum\fP which denotes the register value for that rule,
+\f(CWdw_offset\fP which denotes the offset value for that rule and 
+\f(CWdw_offset_relevant\fP which is set to zero if offset is not relevant 
+for that rule. See \f(CWdwarf_get_fde_info_fo_reg()\fP for a description 
+of \f(CWrow_pc\fP.
+.P
+\f(CWdwarf_get_fde_info_for_all_regs\fP returns \f(CWDW_DLV_ERROR\fP if there is an error. 
+.P
+\f(CWint dwarf_get_fde_info_for_all_regs\fP is SGI/MIPS specific.
+
+
+.H 4 "dwarf_set_frame_rule_table_size()"
+.P
+This allows consumers to set the size of the (internal to libdwarf)
+rule table.  It should be at least as large as the
+number of real registers in the ABI which is to be read in
+for the dwarf_get_fde_info_for_reg3() or dwarf_get_fde_info_for_all_regs3()
+functions to work properly.
+It must be less than the marker values
+DW_FRAME_UNDEFINED_VAL, DW_FRAME_SAME_VAL, DW_FRAME_CFA_COL3.
+.P
+.DS
+\f(CWDwarf_Half
+dwarf_set_frame_rule_table_size(Dwarf_Debug dbg,
+         Dwarf_Half value);\fP
+
+.DE
+\f(CWddwarf_set_frame_rule_table_size()\fP sets the
+value \f(CWvalue\fP as the size of libdwarf-internal
+rules tables  of \f(CWdbg\fP.
+The function returns
+the previous value of the rules table size setting (taken from the 
+\f(CWdbg\fP structure).
+
+.H 4 "dwarf_set_frame_rule_inital_value()"
+This allows consumers to set the initial value
+for rows in the frame tables.  By default it
+is taken from libdwarf.h and is DW_FRAME_REG_INITIAL_VALUE
+(which itself is either DW_FRAME_SAME_VAL or DW_FRAME_UNDEFINED_VAL).
+The MIPS/IRIX default is DW_FRAME_SAME_VAL.
+Comsumer code should set this appropriately and for
+many architectures (but probably not MIPS) DW_FRAME_UNDEFINED_VAL is an
+appropriate setting.
+.DS
+\f(CWDwarf_Half
+dwarf_set_frame_rule_inital_value(Dwarf_Debug dbg,
+         Dwarf_Half value);\fP
+
+.DE
+\f(CWdwarf_set_frame_rule_inital_value()\fP sets the
+value \f(CWvalue\fP as the initial value for this \f(CWdbg\fP
+when initializing rules tables.  The function returns
+the previous value of the initial setting (taken from the 
+\f(CWdbg\fP structure).
+
+
+
+.H 4 "dwarf_get_fde_info_for_reg3()"
+This interface is suitable for DWARF3 and DWARF2.
+It returns the values for a particular real register
+(Not for the CFA register, see dwarf_get_fde_info_for_cfa_reg3()
+below).
+.DS
+\f(CWint dwarf_get_fde_info_for_reg3(
+        Dwarf_Fde fde,
+        Dwarf_Half table_column,
+        Dwarf_Addr pc_requested,
+	Dwarf_Small  *value_type,
+	Dwarf_Signed *offset_relevant,
+        Dwarf_Signed *register_num,
+        Dwarf_Signed *offset_or_block_len,
+	Dwarf_Ptr    *block_ptr,
+        Dwarf_Addr   *row_pc,
+        Dwarf_Error  *error);\fP
+.DE
+\f(CWdwarf_get_fde_info_for_re3()\fP returns
+\f(CWDW_DLV_OK\fP on success. 
+It sets \f(CW*value_type\fP
+to one of  DW_EXPR_OFFSET (0),
+DW_EXPR_VAL_OFFSET(1), DW_EXPR_EXPRESSION(2) or
+DW_EXPR_VAL_EXPRESSION(3).
+On call, \f(CWtable_column\fP must be set to the
+register number of a real register. Not
+the cfa 'register' or DW_FRAME_SAME_VALUE or
+DW_FRAME_UNDEFINED_VALUE.
+
+
+if \f(CW*value_type\fP has the value DW_EXPR_OFFSET (0) then:
+.in +4
+.P
+It sets \f(CW*offset_relevant\fP to
+non-zero if the offset is relevant for the
+row specified by \f(CWpc_requested\fP and column specified by
+\f(CWtable_column\fP or, for the FDE specified by \f(CWfde\fP.  
+In this case  the  \f(CW*register_num\fP will be set
+to DW_FRAME_CFA_COL3.  This is an offset(N) rule
+as specified in the DWARF3/2 documents.
+Adding the value of \f(CW*offset_or_block_len\fP
+to the value of the CFA register gives the address
+of a location holding the previous value of 
+register \f(CWtable_column\fP.
+
+.P
+If offset is not relevant for this rule, \f(CW*offset_relevant\fP is
+set to zero.  \f(CW*register_num\fP will be set
+to the number of the real register holding the value of 
+the \f(CWtable_column\fP register.
+This is the register(R) rule as specifified in DWARF3/2 documents.
+.P
+The
+intent is to return the rule for the given pc value and register.
+The location pointed to by \f(CWregister_num\fP is set to the register
+value for the rule.  
+The location pointed to by \f(CWoffset\fP 
+is set to the offset value for the rule.  
+Since more than one pc 
+value will have rows with identical entries, the user may want to
+know the earliest pc value after which the rules for all the columns
+remained unchanged.  
+Recall that in the virtual table that the frame information
+represents there may be one or more table rows with identical data
+(each such table row at a different pc value).
+Given a \f(CWpc_requested\fP which refers to a pc in such a group
+of identical rows, 
+the location pointed to by \f(CWrow_pc\fP is set 
+to the lowest pc value
+within the group of  identical rows.
+
+.in -4
+
+.P
+If \f(CW*value_type\fP has the value DW_EXPR_VAL_OFFSET (1) then:
+.in +4
+This will be a val_offset(N) rule as specified in the
+DWARF3/2 documents so  \f(CW*offset_relevant\fP will
+be non zero. 
+The calculation  is identical to the  DW_EXPR_OFFSET (0)
+calculation with  \f(CW*offset_relevant\fP non-zero, 
+but the value  resulting is the actual \f(CWtable_column\fP
+value (rather than the address where the value may be found).
+.in -4
+.P
+If \f(CW*value_type\fP has the value DW_EXPR_EXPRESSION (1) then:
+.in +4
+ \f(CW*offset_or_block_len\fP
+is set to the length in bytes of a block of memory
+with a DWARF expression in the block.
+\f(CW*block_ptr\fP is set to point at the block of memory.
+The consumer code should  evaluate the block as
+a DWARF-expression. The result is the address where
+the previous value of the register may be found.
+This is a DWARF3/2 expression(E) rule.
+.in -4
+.P
+If \f(CW*value_type\fP has the value DW_EXPR_VAL_EXPRESSION (1) then:
+.in +4
+The calculation is exactly as for DW_EXPR_EXPRESSION (1)
+but the result of the DWARF-expression evaluation is
+the value of the   \f(CWtable_column\fP (not
+the address of the value).
+This is a DWARF3/2 val_expression(E) rule.
+.in -4
+
+\f(CWdwarf_get_fde_info_for_reg\fP 
+returns \f(CWDW_DLV_ERROR\fP if there is an error and
+if there is an error only the \f(CWerror\fP pointer is set, none
+of the other output arguments are touched.
+
+It is usable with either 
+\f(CWdwarf_get_fde_n()\fP or \f(CWdwarf_get_fde_at_pc()\fP.
+
+
+.H 4 "dwarf_get_fde_info_for_cfa_reg3()"
+.DS
+ \f(CWint dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde,
+      Dwarf_Addr          pc_requested,
+      Dwarf_Small *       value_type,
+      Dwarf_Signed*       offset_relevant,
+      Dwarf_Signed*       register_num,
+      Dwarf_Signed*       offset_or_block_len,
+      Dwarf_Ptr   *       block_ptr ,
+      Dwarf_Addr  *       row_pc_out,
+      Dwarf_Error *       error)\fP
+.DE
+.P
+This is identical to  \f(CWdwarf_get_fde_info_for_reg3()\fP
+except the returned values are for the CFA rule.
+So register number \f(CW*register_num\fP will be set
+to a real register, not 
+DW_FRAME_CFA_COL3, DW_FRAME_SAME_VALUE, or
+DW_FRAME_UNDEFINED_VALUE.
+
+
+
+.H 4 "dwarf_get_fde_info_for_all_regs3()"
+.DS
+\f(CWint dwarf_get_fde_info_for_all_regs3(
+        Dwarf_Fde fde,
+        Dwarf_Addr pc_requested,
+	Dwarf_Regtable3 *reg_table,
+        Dwarf_Addr *row_pc,
+        Dwarf_Error *error)\fP
+.DE
+\f(CWdwarf_get_fde_info_for_all_regs3()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*reg_table\fP 
+for the row specified by
+\f(CWpc_requested\fP for the FDE specified by \f(CWfde\fP. 
+The intent is
+to return the rules for decoding all the registers, given a pc
+value.  
+\f(CWreg_table\fP is an array of rules, the 
+array size specifed by the caller.
+plus a rule for the CFA.
+The rule for the cfa returned in  \f(CW*reg_table\fP
+defines the CFA value at  \f(CWpc_requested\fP
+The rule for each
+register contains  several values that enable
+the consumer to determine the previous value
+of the register (see the earlier documentation of Dwarf_Regtable3).
+\f(CWdwarf_get_fde_info_for_reg3()\fP  and
+the Dwarf_Regtable3 documentation above for a description of
+the values for each row.
+
+\f(CWdwarf_get_fde_info_for_all_regs\fP returns \f(CWDW_DLV_ERROR\fP if there is an error. 
+
+It's up to the caller to allocate space for 
+\f(CW*reg_table\fP and initialize it properly.
+
+
+
+.H 4 "dwarf_get_fde_n()"
+.DS
+\f(CWint   dwarf_get_fde_n(
+        Dwarf_Fde *fde_data,
+        Dwarf_Unsigned fde_index,
+	Dwarf_Fde      *returned_fde
+        Dwarf_Error *error)\fP
+.DE
+\f(CWdwarf_get_fde_n()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CWreturned_fde\fP to
+the \f(CWDwarf_Fde\fP descriptor whose 
+index is \f(CWfde_index\fP in the table of \f(CWDwarf_Fde\fP descriptors
+pointed to by \fPfde_data\fP.  
+The index starts with 0.  
+Returns \f(CWDW_DLV_NO_ENTRY\fP if the index does not 
+exist in the table of \f(CWDwarf_Fde\fP 
+descriptors. 
+Returns \f(CWDW_DLV_ERROR\fP if there is an error.
+This function cannot be used unless
+the block of \f(CWDwarf_Fde\fP descriptors has been created by a call to
+\f(CWdwarf_get_fde_list()\fP.
+
+.H 4 "dwarf_get_fde_at_pc()"
+.DS
+\f(CWint   dwarf_get_fde_at_pc(
+        Dwarf_Fde *fde_data,
+        Dwarf_Addr pc_of_interest,
+        Dwarf_Fde *returned_fde,
+        Dwarf_Addr *lopc,
+        Dwarf_Addr *hipc,
+        Dwarf_Error *error)\fP
+.DE
+\f(CWdwarf_get_fde_at_pc()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CWreturned_fde\fP to
+a \f(CWDwarf_Fde\fP descriptor
+for a function which contains the pc value specified by \f(CWpc_of_interest\fP.
+In addition, it sets the locations pointed to 
+by \f(CWlopc\fP and \f(CWhipc\fP to the low address and the high address 
+covered by this FDE, respectively.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It returns \f(CWDW_DLV_NO_ENTRY\fP 
+if \f(CWpc_of_interest\fP is not in any of the
+FDEs represented by the block of \f(CWDwarf_Fde\fP descriptors pointed
+to by \f(CWfde_data\fP.  
+This function cannot be used unless
+the block of \f(CWDwarf_Fde\fP descriptors has been created by a call to
+\f(CWdwarf_get_fde_list()\fP.
+
+.H 4 "dwarf_expand_frame_instructions()"
+.DS
+\f(CWint dwarf_expand_frame_instructions(
+        Dwarf_Debug dbg,
+        Dwarf_Ptr instruction,
+        Dwarf_Unsigned i_length,
+        Dwarf_Frame_Op **returned_op_list,
+        Dwarf_Signed   * returned_op_count,
+        Dwarf_Error *error);\fP
+.DE
+\f(CWdwarf_expand_frame_instructions()\fP is a High-level interface 
+function which expands a frame instruction byte stream into an 
+array of \f(CWDwarf_Frame_Op\fP structures.  
+To indicate success, it returns \f(CWDW_DLV_OK\fP.
+The address where 
+the byte stream begins is specified by \f(CWinstruction\fP, and
+the length of the byte stream is specified by \f(CWi_length\fP.
+The location pointed to by \f(CWreturned_op_list\fP is set to
+point to a table of 
+\f(CWreturned_op_count\fP
+pointers to \f(CWDwarf_Frame_Op\fP which
+contain the frame instructions in the byte stream.  
+It returns \f(CWDW_DLV_ERROR\fP on error. 
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+After a successful return, the
+array of structures should be freed using
+\f(CWdwarf_dealloc()\fP with the allocation type \f(CWDW_DLA_FRAME_BLOCK\fP
+(when they are no longer of interest).
+
+.in +2
+.DS
+\f(CWDwarf_Signed cnt;
+Dwarf_Frame_Op *frameops;
+Dwarf_Ptr instruction;
+Dwarf_Unsigned len;
+int res;
+
+res = expand_frame_instructions(dbg,instruction,len, &frameops,&cnt, &error);
+if (res == DW_DLV_OK) {
+
+        for (i = 0; i < cnt; ++i) {
+                /* use frameops[i] */
+        }
+        dwarf_dealloc(dbg, frameops, DW_DLA_FRAME_BLOCK);
+}\fP
+.DE
+.in -2
+.H 4 "dwarf_get_fde_exception_info()"
+.DS
+\f(CWint dwarf_get_fde_exception_info(
+    Dwarf_Fde fde,
+    Dwarf_Signed * offset_into_exception_tables,
+    Dwarf_Error * error);
+.DE
+\f(CWdwarf_get_fde_exception_info()\fP is an IRIX specific
+function which returns an exception table signed offset
+thru \f(CWoffset_into_exception_tables\fP.
+The function never returns \f(CWDW_DLV_NO_ENTRY\fP.
+If \f(CWDW_DLV_NO_ENTRY\fP is NULL the function returns 
+\f(CWDW_DLV_ERROR\fP.
+For non-IRIX objects the offset returned will always be zero.
+For non-C++ objects the offset returned will always be zero.
+The meaning of the offset and the content of the tables
+is not defined in this document.
+The applicable CIE augmentation string (see above)
+determines whether the value returned has meaning.
+
+.H 2 "Location Expression Evaluation"
+
+An "interpreter" which evaluates a location expression
+is required in any debugger.  There is no interface defined
+here at this time.  
+
+.P
+One problem with defining an interface is that operations are
+machine dependent: they depend on the interpretation of
+register numbers and the methods of getting values from the
+environment the expression is applied to.
+
+.P
+It would be desirable to specify an interface.
+
+.H 3 "Location List Internal-level Interface"
+
+.H 4 "dwarf_get_loclist_entry()"
+.DS
+\f(CWint dwarf_get_loclist_entry(
+        Dwarf_Debug dbg,
+        Dwarf_Unsigned offset,
+        Dwarf_Addr *hipc_offset,
+        Dwarf_Addr *lopc_offset,
+        Dwarf_Ptr *data,
+        Dwarf_Unsigned *entry_len,
+        Dwarf_Unsigned *next_entry,
+        Dwarf_Error *error)\fP
+.DE
+The function reads 
+a location list entry starting at \f(CWoffset\fP and returns 
+through pointers (when successful)
+the high pc \f(CWhipc_offset\fP, low pc 
+\f(CWlopc_offset\fP, a pointer to the location description data 
+\f(CWdata\fP, the length of the location description data 
+\f(CWentry_len\fP, and the offset of the next location description 
+entry \f(CWnext_entry\fP.  
+\f(CWdwarf_dwarf_get_loclist_entry()\fP returns 
+\f(CWDW_DLV_OK\fP if successful.
+\f(CWDW_DLV_NO_ENTRY\fP is returned when the offset passed
+in is beyond the end of the .debug_loc section (expected if
+you start at offset zero and proceed thru all the entries). 
+\f(CWDW_DLV_ERROR\fP is returned on error. 
+.P
+The \f(CWhipc_offset\fP,
+low pc \f(CWlopc_offset\fP are offsets from the beginning of the
+current procedure, not genuine pc values.
+.in +2
+.DS
+\f(CW
+/* Looping thru the dwarf_loc section finding loclists:
+   an example.  */
+int res;
+Dwarf_Unsigned next_entry;
+Dwarf_unsigned offset=0;
+Dwarf_Addr hipc_off;
+Dwarf_Addr lopc_off;
+Dwarf_Ptr data;
+Dwarf_Unsigned entry_len;
+Dwarf_Unsigned next_entry;
+Dwarf_Error err;
+
+    for(;;) {      
+        res = dwarf_get_loclist_entry(dbg,newoffset,&hipc_off,
+            &lowpc_off, &data, &entry_len,&next_entry,&err);
+        if (res == DW_DLV_OK) {
+            /* A valid entry. */
+            newoffset = next_entry;
+            continue;
+        } else if (res ==DW_DLV_NO_ENTRY) {
+            /* Done! */
+            break;
+        } else {
+            /* Error! */
+            break;
+        }
+         
+
+    }
+}\fP
+.DE
+.in -2
+
+
+.H 2 "Abbreviations access"
+These are Internal-level Interface functions.  
+Debuggers can ignore this.
+
+.H 3 "dwarf_get_abbrev()"
+.DS
+\f(CWint dwarf_get_abbrev(
+        Dwarf_Debug dbg,
+        Dwarf_Unsigned offset,
+        Dwarf_Abbrev   *returned_abbrev,
+        Dwarf_Unsigned *length,
+        Dwarf_Unsigned *attr_count,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_get_abbrev()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*returned_abbrev\fP to
+\f(CWDwarf_Abbrev\fP 
+descriptor for an abbreviation at offset \f(CW*offset\fP in the abbreviations 
+section (i.e .debug_abbrev) on success.  
+The user is responsible for making sure that 
+a valid abbreviation begins at \f(CWoffset\fP in the abbreviations section.  
+The location pointed to by \f(CWlength\fP 
+is set to the length in bytes of the abbreviation in the abbreviations 
+section.  
+The location pointed to by \f(CWattr_count\fP is set to the 
+number of attributes in the abbreviation.  
+An abbreviation entry with a 
+length of 1 is the 0 byte of the last abbreviation entry of a compilation 
+unit.
+\f(CWdwarf_get_abbrev()\fP returns \f(CWDW_DLV_ERROR\fP on error.  
+If the call succeeds, the storage pointed to
+by \f(CW*returned_abbrev\fP
+should be free'd, using \f(CWdwarf_dealloc()\fP with the
+allocation type \f(CWDW_DLA_ABBREV\fP when no longer needed.
+
+
+.H 3 "dwarf_get_abbrev_tag()"
+.DS
+\f(CWint dwarf_get_abbrev_tag(
+        Dwarf_abbrev abbrev,
+	Dwarf_Half  *return_tag,
+        Dwarf_Error *error);\fP
+.DE
+If successful,
+\f(CWdwarf_get_abbrev_tag()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_tag\fP to
+the \fItag\fP of 
+the given abbreviation.
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.H 3 "dwarf_get_abbrev_code()"
+.DS
+\f(CWint dwarf_get_abbrev_code(
+        Dwarf_abbrev     abbrev,
+	Dwarf_Unsigned  *return_code,
+        Dwarf_Error     *error);\fP
+.DE
+If successful,
+\f(CWdwarf_get_abbrev_code()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*return_code\fP to
+the abbreviation code of
+the given abbreviation.
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It never returns \f(CWDW_DLV_NO_ENTRY\fP.
+
+.H 3 "dwarf_get_abbrev_children_flag()"
+.DS
+\f(CWint dwarf_get_abbrev_children_flag(
+        Dwarf_Abbrev abbrev,
+	Dwarf_Signed  *returned_flag,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_get_abbrev_children_flag()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CWreturned_flag\fP to
+\f(CWDW_children_no\fP (if the given abbreviation indicates that 
+a die with that abbreviation has no children) or 
+\f(CWDW_children_yes\fP (if the given abbreviation indicates that 
+a die with that abbreviation has a child).  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+
+.H 3 "dwarf_get_abbrev_entry()"
+.DS
+\f(CWint dwarf_get_abbrev_entry(
+        Dwarf_Abbrev abbrev,
+        Dwarf_Signed index,
+        Dwarf_Half   *attr_num,
+        Dwarf_Signed *form,
+        Dwarf_Off *offset,
+        Dwarf_Error *error)\fP
+
+.DE
+If successful,
+\f(CWdwarf_get_abbrev_entry()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*attr_num\fP to the attribute code of
+the attribute 
+whose index is specified by \f(CWindex\fP in the given abbreviation.  
+The index starts at 0.  
+The location pointed to by \f(CWform\fP is set 
+to the form of the attribute.  
+The location pointed to by \f(CWoffset\fP 
+is set to the byte offset of the attribute in the abbreviations section.  
+It returns \f(CWDW_DLV_NO_ENTRY\fP if the index specified is outside
+the range of attributes in this abbreviation.
+It returns \f(CWDW_DLV_ERROR\fP on error.
+
+.H 2 "String Section Operations"
+The .debug_str section contains only strings.  Debuggers need 
+never use this interface: it is only for debugging problems with 
+the string section itself.  
+
+.H 3 "dwarf_get_str()"
+.DS
+\f(CWint dwarf_get_str(
+        Dwarf_Debug   dbg,
+        Dwarf_Off     offset,
+        char        **string,
+	Dwarf_Signed *returned_str_len,
+        Dwarf_Error  *error)\fP
+.DE
+The function \f(CWdwarf_get_str()\fP returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*returned_str_len\fP to
+the length of 
+the string, not counting the null terminator, that begins at the offset 
+specified by \f(CWoffset\fP in the .debug_str section.  
+The location 
+pointed to by \f(CWstring\fP is set to a pointer to this string.
+The next string in the .debug_str
+section begins at the previous \f(CWoffset\fP + 1 + \f(CW*returned_str_len\fP.
+A zero-length string is NOT the end of the section.
+If there is no .debug_str section, \f(CWDW_DLV_NO_ENTRY\fP is returned.
+If there is an error, \f(CWDW_DLV_ERROR\fP is returned.
+If we are at the end of the section (that is, \f(CWoffset\fP
+is one past the end of the section) \f(CWDW_DLV_NO_ENTRY\fP is returned.
+If the \f(CWoffset\fP is some other too-large value then
+\f(CWDW_DLV_ERROR\fP is returned.
+
+.H 2 "Address Range Operations"
+These functions provide information about address ranges.  Address
+ranges map ranges of pc values to the corresponding compilation-unit
+die that covers the address range.
+
+.H 3 "dwarf_get_aranges()"
+.DS
+\f(CWint dwarf_get_aranges(
+        Dwarf_Debug dbg,
+        Dwarf_Arange **aranges,
+        Dwarf_Signed * returned_arange_count,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_get_aranges()\fP returns 
+\f(CWDW_DLV_OK\fP and sets \f(CW*returned_arange_count\fP to
+the count of the
+number of address ranges in the .debug_aranges section.  
+It sets
+\f(CW*aranges\fP to point to a block of \f(CWDwarf_Arange\fP 
+descriptors, one for each address range.  
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no .debug_aranges
+section.
+
+.in +2
+.DS
+\f(CWDwarf_Signed cnt;
+Dwarf_Arange *arang;
+int res;
+
+res = dwarf_get_aranges(dbg, &arang,&cnt, &error);
+if (res == DW_DLV_OK) {
+
+        for (i = 0; i < cnt; ++i) {
+                /* use arang[i] */
+                dwarf_dealloc(dbg, arang[i], DW_DLA_ARANGE);
+        }
+        dwarf_dealloc(dbg, arang, DW_DLA_LIST);
+}\fP
+.DE
+.in -2
+
+
+.DS
+\f(CWint dwarf_get_arange(
+        Dwarf_Arange *aranges,
+        Dwarf_Unsigned arange_count,
+        Dwarf_Addr address,
+	Dwarf_Arange *returned_arange,
+        Dwarf_Error *error);\fP
+.DE
+The function \f(CWdwarf_get_arange()\fP takes as input a pointer 
+to a block of \f(CWDwarf_Arange\fP pointers, and a count of the
+number of descriptors in the block.  
+It then searches for the
+descriptor that covers the given \f(CWaddress\fP.  
+If it finds
+one, it returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*returned_arange\fP to
+the descriptor. 
+It returns \f(CWDW_DLV_ERROR\fP on error.
+It returns \f(CWDW_DLV_NO_ENTRY\fP if there is no .debug_aranges
+entry covering that address.
+
+
+.H 3 "dwarf_get_cu_die_offset()"
+.DS
+\f(CWint dwarf_get_cu_die_offset(
+        Dwarf_Arange arange,
+        Dwarf_Off   *returned_cu_die_offset,
+        Dwarf_Error *error);\fP
+.DE
+The function \f(CWdwarf_get_cu_die_offset()\fP takes a
+\f(CWDwarf_Arange\fP descriptor as input, and 
+if successful returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*returned_cu_die_offset\fP to
+the offset
+in the .debug_info section of the compilation-unit DIE for the 
+compilation-unit represented by the given address range.
+It returns \f(CWDW_DLV_ERROR\fP on error.
+
+.H 3 "dwarf_get_arange_cu_header_offset()"
+.DS
+\f(CWint dwarf_get_arange_cu_header_offset(
+        Dwarf_Arange arange,
+        Dwarf_Off   *returned_cu_header_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_get_arange_cu_header_offset()\fP takes a
+\f(CWDwarf_Arange\fP descriptor as input, and 
+if successful returns
+\f(CWDW_DLV_OK\fP and sets \f(CW*returned_cu_header_offset\fP to
+the offset
+in the .debug_info section of the compilation-unit header for the 
+compilation-unit represented by the given address range.
+It returns \f(CWDW_DLV_ERROR\fP on error.
+
+This function added Rev 1.45, June, 2001.
+
+This function is declared as 'optional' in libdwarf.h
+on IRIX systems so the _MIPS_SYMBOL_PRESENT
+predicate may be used at run time to determine if the version of
+libdwarf linked into an application has this function.
+
+
+
+.H 3 "dwarf_get_arange_info()"
+.DS
+\f(CWint dwarf_get_arange_info(
+        Dwarf_Arange arange,
+        Dwarf_Addr *start,
+        Dwarf_Unsigned *length,
+        Dwarf_Off *cu_die_offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_get_arange_info()\fP returns
+\f(CWDW_DLV_OK\fP
+and
+stores the starting value of the address range in the location pointed 
+to by \f(CWstart\fP, the length of the address range in the location 
+pointed to by \f(CWlength\fP, and the offset in the .debug_info section 
+of the compilation-unit DIE for the compilation-unit represented by the 
+address range.
+It returns \f(CWDW_DLV_ERROR\fP on error.
+
+.H 2 "General Low Level Operations"
+This function is low-level and intended for use only
+by programs such as dwarf-dumpers.
+
+.H 3 "dwarf_get_address_size()"
+.DS
+\f(CWint dwarf_get_address_size(Dwarf_Debug dbg,
+	Dwarf_Half  *addr_size,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_get_address_size()\fP 
+returns \f(CWDW_DLV_OK\fP on success and sets 
+the \f(CW*addr_size\fP
+to the size in bytes of an address.
+In case of error, it returns \f(CWDW_DLV_ERROR\fP
+and does not set \f(CW*addr_size\fP.
+
+
+.H 2 "Utility Operations"
+These functions aid in the management of errors encountered when using 
+functions in the \fIlibdwarf\fP library and releasing memory allocated 
+as a result of a \fIlibdwarf\fP operation. 
+
+.H 3 "dwarf_errno()"
+.DS
+\f(CWDwarf_Unsigned dwarf_errno(
+        Dwarf_Error error)\fP
+.DE
+The function \f(CWdwarf_errno()\fP returns the error number corresponding 
+to the error specified by \f(CWerror\fP.
+
+.H 3 "dwarf_errmsg()"
+.DS
+\f(CWconst char* dwarf_errmsg(
+        Dwarf_Error error)\fP
+.DE
+The function \f(CWdwarf_errmsg()\fP returns a pointer to a
+null-terminated error message string corresponding to the error specified by 
+\f(CWerror\fP.  
+The string returned by \f(CWdwarf_errmsg()\fP 
+should not be deallocated using \f(CWdwarf_dealloc()\fP.
+
+.P
+The set of errors 
+enumerated in Figure \n(aX below were defined in Dwarf 1.
+These errors are not used by the current implementation
+of Dwarf 2.  
+.DS
+.TS
+center box, tab(:);
+lfB lfB 
+l l.
+SYMBOLIC NAME:DESCRIPTION
+_
+DW_DLE_NE:No error (0)
+DW_DLE_VMM:Version of DWARF information newer than libdwarf
+DW_DLE_MAP:Memory map failure
+DW_DLE_LEE:Propagation of libelf error
+DW_DLE_NDS:No debug section
+DW_DLE_NLS:No line section
+DW_DLE_ID:Requested information not associated with descriptor
+DW_DLE_IOF:I/O failure
+DW_DLE_MAF:Memory allocation failure
+DW_DLE_IA:Invalid argument
+DW_DLE_MDE:Mangled debugging entry
+DW_DLE_MLE:Mangled line number entry
+DW_DLE_FNO:File descriptor does not refer to an open file
+DW_DLE_FNR:File is not a regular file
+DW_DLE_FWA:File is opened with wrong access
+DW_DLE_NOB:File is not an object file
+DW_DLE_MOF:Mangled object file header
+DW_DLE_EOLL:End of location list entries
+DW_DLE_NOLL:No location list section
+DW_DLE_BADOFF:Invalid offset
+DW_DLE_EOS:End of section
+DW_DLE_ATRUNC:Abbreviations section appears truncated
+DW_DLE_BADBITC:Address size passed to dwarf bad
+.TE
+.FG "List of Dwarf Error Codes"
+.DE
+
+The set of errors returned by SGI \f(CWLibdwarf\fP functions
+is listed below.
+Some of the errors are SGI specific.
+
+.DS
+.TS
+center box, tab(:);
+lfB lfB
+l l.
+SYMBOLIC NAME:DESCRIPTION
+_
+DW_DLE_DBG_ALLOC:Could not allocate Dwarf_Debug struct
+DW_DLE_FSTAT_ERROR:Error in fstat()-ing object
+DW_DLE_FSTAT_MODE_ERROR:Error in mode of object file
+DW_DLE_INIT_ACCESS_WRONG:Incorrect access to dwarf_init()
+DW_DLE_ELF_BEGIN_ERROR:Error in elf_begin() on object
+DW_DLE_ELF_GETEHDR_ERROR:Error in elf_getehdr() on object
+DW_DLE_ELF_GETSHDR_ERROR:Error in elf_getshdr() on object
+DW_DLE_ELF_STRPTR_ERROR:Error in elf_strptr() on object
+DW_DLE_DEBUG_INFO_DUPLICATE:Multiple .debug_info sections
+DW_DLE_DEBUG_INFO_NULL:No data in .debug_info section
+DW_DLE_DEBUG_ABBREV_DUPLICATE:Multiple .debug_abbrev sections
+DW_DLE_DEBUG_ABBREV_NULL:No data in .debug_abbrev section
+DW_DLE_DEBUG_ARANGES_DUPLICATE:Multiple .debug_arange sections
+DW_DLE_DEBUG_ARANGES_NULL:No data in .debug_arange section
+DW_DLE_DEBUG_LINE_DUPLICATE:Multiple .debug_line sections
+DW_DLE_DEBUG_LINE_NULL:No data in .debug_line section
+DW_DLE_DEBUG_LOC_DUPLICATE:Multiple .debug_loc sections
+DW_DLE_DEBUG_LOC_NULL:No data in .debug_loc section
+DW_DLE_DEBUG_MACINFO_DUPLICATE:Multiple .debug_macinfo sections
+DW_DLE_DEBUG_MACINFO_NULL:No data in .debug_macinfo section
+DW_DLE_DEBUG_PUBNAMES_DUPLICATE:Multiple .debug_pubnames sections
+DW_DLE_DEBUG_PUBNAMES_NULL:No data in .debug_pubnames section
+DW_DLE_DEBUG_STR_DUPLICATE:Multiple .debug_str sections
+DW_DLE_DEBUG_STR_NULL:No data in .debug_str section
+DW_DLE_CU_LENGTH_ERROR:Length of compilation-unit bad
+DW_DLE_VERSION_STAMP_ERROR:Incorrect Version Stamp
+DW_DLE_ABBREV_OFFSET_ERROR:Offset in .debug_abbrev bad
+DW_DLE_ADDRESS_SIZE_ERROR:Size of addresses in target bad
+DW_DLE_DEBUG_INFO_PTR_NULL:Pointer into .debug_info in DIE null
+DW_DLE_DIE_NULL:Null Dwarf_Die
+DW_DLE_STRING_OFFSET_BAD:Offset in .debug_str bad
+DW_DLE_DEBUG_LINE_LENGTH_BAD:Length of .debug_line segment bad
+DW_DLE_LINE_PROLOG_LENGTH_BAD:Length of .debug_line prolog bad
+DW_DLE_LINE_NUM_OPERANDS_BAD:Number of operands to line instr bad
+DW_DLE_LINE_SET_ADDR_ERROR:Error in DW_LNE_set_address instruction
+DW_DLE_LINE_EXT_OPCODE_BAD:Error in DW_EXTENDED_OPCODE instruction
+DW_DLE_DWARF_LINE_NULL:Null Dwarf_line argument
+DW_DLE_INCL_DIR_NUM_BAD:Error in included directory for given line
+DW_DLE_LINE_FILE_NUM_BAD:File number in .debug_line bad
+DW_DLE_ALLOC_FAIL:Failed to allocate required structs
+DW_DLE_DBG_NULL:Null Dwarf_Debug argument
+DW_DLE_DEBUG_FRAME_LENGTH_BAD:Error in length of frame
+DW_DLE_FRAME_VERSION_BAD:Bad version stamp for frame
+DW_DLE_CIE_RET_ADDR_REG_ERROR:Bad register specified for return address
+DW_DLE_FDE_NULL:Null Dwarf_Fde argument
+DW_DLE_FDE_DBG_NULL:No Dwarf_Debug associated with FDE
+DW_DLE_CIE_NULL:Null Dwarf_Cie argument
+DW_DLE_CIE_DBG_NULL:No Dwarf_Debug associated with CIE
+DW_DLE_FRAME_TABLE_COL_BAD:Bad column in frame table specified
+.TE
+.FG "List of Dwarf 2 Error Codes (continued)"
+.DE
+
+.DS
+.TS
+center box, tab(:);
+lfB lfB
+l l.
+SYMBOLIC NAME:DESCRIPTION
+_
+DW_DLE_PC_NOT_IN_FDE_RANGE:PC requested not in address range of FDE
+DW_DLE_CIE_INSTR_EXEC_ERROR:Error in executing instructions in CIE
+DW_DLE_FRAME_INSTR_EXEC_ERROR:Error in executing instructions in FDE
+DW_DLE_FDE_PTR_NULL:Null Pointer to Dwarf_Fde specified
+DW_DLE_RET_OP_LIST_NULL:No location to store pointer to Dwarf_Frame_Op
+DW_DLE_LINE_CONTEXT_NULL:Dwarf_Line has no context
+DW_DLE_DBG_NO_CU_CONTEXT:dbg has no CU context for dwarf_siblingof()
+DW_DLE_DIE_NO_CU_CONTEXT:Dwarf_Die has no CU context
+DW_DLE_FIRST_DIE_NOT_CU:First DIE in CU not DW_TAG_compilation_unit
+DW_DLE_NEXT_DIE_PTR_NULL:Error in moving to next DIE in .debug_info
+DW_DLE_DEBUG_FRAME_DUPLICATE:Multiple .debug_frame sections
+DW_DLE_DEBUG_FRAME_NULL:No data in .debug_frame section
+DW_DLE_ABBREV_DECODE_ERROR:Error in decoding abbreviation
+DW_DLE_DWARF_ABBREV_NULL:Null Dwarf_Abbrev specified
+DW_DLE_ATTR_NULL:Null Dwarf_Attribute specified
+DW_DLE_DIE_BAD:DIE bad
+DW_DLE_DIE_ABBREV_BAD:No abbreviation found for code in DIE
+DW_DLE_ATTR_FORM_BAD:Inappropriate attribute form for attribute
+DW_DLE_ATTR_NO_CU_CONTEXT:No CU context for Dwarf_Attribute struct
+DW_DLE_ATTR_FORM_SIZE_BAD:Size of block in attribute value bad
+DW_DLE_ATTR_DBG_NULL:No Dwarf_Debug for Dwarf_Attribute struct
+DW_DLE_BAD_REF_FORM:Inappropriate form for reference attribute
+DW_DLE_ATTR_FORM_OFFSET_BAD:Offset reference attribute outside current CU
+DW_DLE_LINE_OFFSET_BAD:Offset of lines for current CU outside .debug_line
+DW_DLE_DEBUG_STR_OFFSET_BAD:Offset into .debug_str past its end
+DW_DLE_STRING_PTR_NULL:Pointer to pointer into .debug_str NULL
+DW_DLE_PUBNAMES_VERSION_ERROR:Version stamp of pubnames incorrect
+DW_DLE_PUBNAMES_LENGTH_BAD:Read pubnames past end of .debug_pubnames
+DW_DLE_GLOBAL_NULL:Null Dwarf_Global specified
+DW_DLE_GLOBAL_CONTEXT_NULL:No context for Dwarf_Global given
+DW_DLE_DIR_INDEX_BAD:Error in directory index read
+DW_DLE_LOC_EXPR_BAD:Bad operator read for location expression
+DW_DLE_DIE_LOC_EXPR_BAD:Expected block value for attribute not found
+DW_DLE_OFFSET_BAD:Offset for next compilation-unit in .debug_info bad
+DW_DLE_MAKE_CU_CONTEXT_FAIL:Could not make CU context
+DW_DLE_ARANGE_OFFSET_BAD:Offset into .debug_info in .debug_aranges bad
+DW_DLE_SEGMENT_SIZE_BAD:Segment size should be 0 for MIPS processors
+DW_DLE_ARANGE_LENGTH_BAD:Length of arange section in .debug_arange bad
+DW_DLE_ARANGE_DECODE_ERROR:Aranges do not end at end of .debug_aranges
+DW_DLE_ARANGES_NULL:NULL pointer to Dwarf_Arange specified
+DW_DLE_ARANGE_NULL:NULL Dwarf_Arange specified
+DW_DLE_NO_FILE_NAME:No file name for Dwarf_Line struct
+DW_DLE_NO_COMP_DIR:No Compilation directory for compilation-unit
+DW_DLE_CU_ADDRESS_SIZE_BAD:CU header address size not match Elf class
+DW_DLE_ELF_GETIDENT_ERROR:Error in elf_getident() on object
+DW_DLE_NO_AT_MIPS_FDE:DIE does not have DW_AT_MIPS_fde attribute
+DW_DLE_NO_CIE_FOR_FDE:No CIE specified for FDE
+DW_DLE_DIE_ABBREV_LIST_NULL:No abbreviation for the code in DIE found
+DW_DLE_DEBUG_FUNCNAMES_DUPLICATE:Multiple .debug_funcnames sections
+DW_DLE_DEBUG_FUNCNAMES_NULL:No data in .debug_funcnames section
+.TE
+.FG "List of Dwarf 2 Error Codes (continued)"
+.DE
+
+.DS
+.TS
+center box, tab(:);
+lfB lfB
+l l.
+SYMBOLIC NAME:DESCRIPTION
+_
+DW_DLE_DEBUG_FUNCNAMES_VERSION_ERROR:Version stamp in .debug_funcnames bad
+DW_DLE_DEBUG_FUNCNAMES_LENGTH_BAD:Length error in reading .debug_funcnames
+DW_DLE_FUNC_NULL:NULL Dwarf_Func specified
+DW_DLE_FUNC_CONTEXT_NULL:No context for Dwarf_Func struct
+DW_DLE_DEBUG_TYPENAMES_DUPLICATE:Multiple .debug_typenames sections
+DW_DLE_DEBUG_TYPENAMES_NULL:No data in .debug_typenames section
+DW_DLE_DEBUG_TYPENAMES_VERSION_ERROR:Version stamp in .debug_typenames bad
+DW_DLE_DEBUG_TYPENAMES_LENGTH_BAD:Length error in reading .debug_typenames
+DW_DLE_TYPE_NULL:NULL Dwarf_Type specified
+DW_DLE_TYPE_CONTEXT_NULL:No context for Dwarf_Type given
+DW_DLE_DEBUG_VARNAMES_DUPLICATE:Multiple .debug_varnames sections
+DW_DLE_DEBUG_VARNAMES_NULL:No data in .debug_varnames section
+DW_DLE_DEBUG_VARNAMES_VERSION_ERROR:Version stamp in .debug_varnames bad
+DW_DLE_DEBUG_VARNAMES_LENGTH_BAD:Length error in reading .debug_varnames
+DW_DLE_VAR_NULL:NULL Dwarf_Var specified
+DW_DLE_VAR_CONTEXT_NULL:No context for Dwarf_Var given
+DW_DLE_DEBUG_WEAKNAMES_DUPLICATE:Multiple .debug_weaknames section
+DW_DLE_DEBUG_WEAKNAMES_NULL:No data in .debug_varnames section
+DW_DLE_DEBUG_WEAKNAMES_VERSION_ERROR:Version stamp in .debug_varnames bad
+DW_DLE_DEBUG_WEAKNAMES_LENGTH_BAD:Length error in reading .debug_weaknames
+DW_DLE_WEAK_NULL:NULL Dwarf_Weak specified
+DW_DLE_WEAK_CONTEXT_NULL:No context for Dwarf_Weak given
+.TE
+.FG "List of Dwarf 2 Error Codes"
+.DE
+
+This list of errors is not necessarily complete;
+additional errors
+might be added when functionality to create debugging information 
+entries are added to \fIlibdwarf\fP and by the implementors of 
+\fIlibdwarf\fP to describe internal errors not addressed by the 
+above list.
+Some of the above errors may be unused.
+Errors may not have the same meaning in different implementations.
+
+.H 3 "dwarf_seterrhand()"
+.DS
+\f(CWDwarf_Handler dwarf_seterrhand(
+        Dwarf_Debug dbg,
+        Dwarf_Handler errhand)\fP
+.DE
+The function \f(CWdwarf_seterrhand()\fP replaces the error handler 
+(see \f(CWdwarf_init()\fP) with \f(CWerrhand\fP.  The old error handler 
+is returned.  This function is currently unimplemented.
+
+.H 3 "dwarf_seterrarg()"
+.DS
+\f(CWDwarf_Ptr dwarf_seterrarg(
+        Dwarf_Debug dbg,
+        Dwarf_Ptr errarg)\fP
+.DE
+The function \f(CWdwarf_seterrarg()\fP replaces the pointer to the 
+error handler communication area (see \f(CWdwarf_init()\fP) with 
+\f(CWerrarg\fP.  A pointer to the old area is returned.  This
+function is currently unimplemented.
+
+.H 3 "dwarf_dealloc()"
+.DS
+\f(CWvoid dwarf_dealloc(
+        Dwarf_Debug dbg,
+        void* space, 
+        Dwarf_Unsigned type)\fP
+.DE
+The function \f(CWdwarf_dealloc\fP frees the dynamic storage pointed
+to by \f(CWspace\fP, and allocated to the given \f(CWDwarf_Debug\fP.
+The argument \f(CWtype\fP is an integer code that specifies the allocation 
+type of the region pointed to by the \f(CWspace\fP.  Refer to section 
+4 for details on \fIlibdwarf\fP memory management.
+
+.SK
+.S
+.TC 1 1 4
+.CS
Binary file tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf2.1.pdf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf2p.1.mm	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,2452 @@
+\." $Revision: 1.12 $
+\." $Date: 2002/01/14 23:40:11 $
+\."
+\."
+\." the following line may be removed if the ff ligature works on your machine
+.lg 0
+\." set up heading formats
+.ds HF 3 3 3 3 3 2 2
+.ds HP +2 +2 +1 +0 +0
+.nr Hs 5
+.nr Hb 5
+\." ==============================================
+\." Put current date in the following at each rev
+.ds vE rev 1.20, 4 Sep 2007
+\." ==============================================
+\." ==============================================
+.ds | |
+.ds ~ ~
+.ds ' '
+.if t .ds Cw \&\f(CW
+.if n .ds Cw \fB
+.de Cf          \" Place every other arg in Cw font, beginning with first
+.if \\n(.$=1 \&\*(Cw\\$1\fP
+.if \\n(.$=2 \&\*(Cw\\$1\fP\\$2
+.if \\n(.$=3 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP
+.if \\n(.$=4 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4
+.if \\n(.$=5 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP
+.if \\n(.$=6 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6
+.if \\n(.$=7 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP
+.if \\n(.$=8 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8
+.if \\n(.$=9 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8\
+*(Cw
+..
+.nr Cl 3
+.SA 1
+.TL
+A Producer Library Interface to DWARF
+.AF ""
+.AU "David Anderson"
+.PF "'\*(vE '- \\\\nP -''"
+.AS 1
+This document describes an interface to a library of functions
+to create DWARF debugging information entries and DWARF line number
+information. It does not make recommendations as to how the functions
+described in this document should be implemented nor does it
+suggest possible optimizations. 
+.P
+The document is oriented to creating DWARF version 2.
+Support for creating DWARF3 is intended but such support
+is not yet fully present.
+.P
+\*(vE 
+.AE
+.MT 4
+.H 1 "INTRODUCTION"
+This document describes an interface to \f(CWlibdwarf\fP, a
+library of functions to provide creation of DWARF debugging information
+records, DWARF line number information, DWARF address range and
+pubnames information, weak names information, and DWARF frame description 
+information.
+
+
+.H 2 "Copyright"
+Copyright 1993-2006 Silicon Graphics, Inc.
+
+Copyright 2007 David Anderson.
+
+Permission is hereby granted to
+copy or republish or use any or all of this document without
+restriction except that when publishing more than a small amount
+of the document
+please acknowledge Silicon Graphics, Inc and David Anderson.
+
+This document is distributed in the hope that it would be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+.H 2 "Purpose and Scope"
+The purpose of this document is to propose a library of functions to 
+create DWARF debugging information.  Reading (consuming) of such records 
+is discussed in a separate document.
+
+The functions in this document have mostly been implemented at 
+Silicon Graphics
+and are being used by the code generator to provide debugging information.
+Some functions (and support for some extensions) were provided
+by Sun Microsystems.
+
+.P
+The focus of this document is the functional interface,
+and as such, implementation and optimization issues are
+intentionally ignored.
+
+.P
+Error handling, error codes, and certain \f(CWLibdwarf\fP codes are discussed
+in the "\fIA Consumer Library Interface to DWARF\fP", which should 
+be read (or at least skimmed) before reading this document.
+.P
+However the general style of functions here 
+in the producer librar is rather C-traditional
+with various types as return values (quite different
+from the consumer library interfaces).   The style
+generally follows the style of the original DWARF1 reader
+proposed as an interface to DWARF.
+When the style of the reader interfaces was changed (1994) in the
+dwarf reader ( See the "Document History"
+section of "A Consumer Library Interface to DWARF")
+the interfaces here were not changed as it seemed like
+too much of a change for the two applications then using
+the interface!  So this interface remains in the traditional C style
+of returning various data types with various (somewhat inconsistent)
+means of indicating failure.
+
+.H 2 "Document History"
+This document originally prominently referenced
+"UNIX International Programming Languages Special Interest Group " 
+(PLSIG).
+Both  UNIX International and the
+affiliated  Programming Languages Special Interest Group
+are defunct
+(UNIX is a registered trademark of UNIX System Laboratories, Inc.
+in the United States and other countries).
+Nothing except the general interface style is actually
+related to anything shown to the PLSIG
+(this document was open sourced with libdwarf in the mid 1990's).
+.P
+See "http://www.dwarfstd.org" for information on current
+DWARF standards and committee activities.
+
+.H 2 "Definitions"
+DWARF debugging information entries (DIEs) are the segments of information 
+placed in the \f(CW.debug_info\fP  and related
+sections by compilers, assemblers, and linkage 
+editors that, in conjunction with line number entries, are necessary for 
+symbolic source-level debugging.  
+Refer to the document 
+"\fIDWARF Debugging Information Format\fP" from UI PLSIG for a more complete 
+description of these entries.
+
+.P
+This document adopts all the terms and definitions in
+"\fIDWARF Debugging Information Format\fP" version 2.
+and the "\fIA Consumer Library Interface to DWARF\fP".
+
+.P
+In addition, this document refers to Elf, the ATT/USL System V
+Release 4 object format.
+This is because the library was first developed for that object
+format.
+Hopefully the functions defined here can easily be
+applied to other object formats.
+
+.H 2 "Overview"
+The remaining sections of this document describe a proposed producer 
+(compiler or assembler) interface to \fILibdwarf\fP, first by describing 
+the purpose of additional types defined by the interface, followed by 
+descriptions of the available operations.  
+This document assumes you 
+are thoroughly familiar with the information contained in the 
+\fIDWARF 
+Debugging Information Format\fP document, and 
+"\fIA Consumer Library Interface to DWARF\fP".
+
+.P
+The interface necessarily knows a little bit about the object format
+(which is assumed to be Elf).  We make an attempt to make this knowledge 
+as limited as possible.  For example, \fILibdwarf\fP does not do the 
+writing of object data to the disk.  The producer program does that.
+
+.H 2 "Revision History"
+.VL 15
+.LI "March 1993"
+Work on dwarf2 sgi producer draft begins
+.LI "March 1999"
+Adding a function to allow any number of trips
+thru the dwarf_get_section_bytes() call.
+.LI "April 10 1999"
+Added support for assembler text output of dwarf
+(as when the output must pass thru an assembler).
+Revamped internals for better performance and
+simpler provision for differences in ABI.
+.LI "Sep 1, 1999"
+Added support for little- and cross- endian
+debug info creation.
+.LI "May 7  2007"
+This library interface now cleans up, deallocating
+all memory it uses (the application simply calls
+dwarf_producer_finish(dbg)).
+.LE
+
+.H 1 "Type Definitions"
+
+.H 2 "General Description"
+The \fIlibdwarf.h\fP 
+header file contains typedefs and preprocessor 
+definitions of types and symbolic names 
+used to reference objects of \fI Libdwarf \fP .  
+The types defined by typedefs contained in \fI libdwarf.h\fP 
+all use the convention of adding \fI Dwarf_ \fP 
+as a prefix to
+indicate that they refer to objects used by Libdwarf.  
+The prefix \fI Dwarf_P_\fP is used for objects 
+referenced by the \fI Libdwarf\fP 
+Producer when there are similar but distinct 
+objects used by the Consumer.
+
+.H 2 "Namespace issues"
+Application programs should avoid creating names
+beginning with 
+\f(CWDwarf_\fP
+\f(CWdwarf_\fP
+or 
+\f(CWDW_\fP
+as these are reserved to dwarf and libdwarf.
+
+.H 1 "libdwarf and Elf and relocations"
+Much of the description below presumes that Elf is the object
+format in use.
+The library is probably usable with other object formats
+that allow arbitrary sections to be created.
+
+.H 2 "binary or assembler output"
+With 
+\f(CWDW_DLC_STREAM_RELOCATIONS\fP 
+(see below)
+it is assumed that the calling app will simply
+write the streams and relocations directly into
+an Elf file, without going thru an assembler.
+
+With 
+\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP 
+the calling app must either 
+A) generate binary relocation streams and write
+the generated debug information streams and
+the relocation streams direct to an elf file
+or
+B) generate assembler output text for an assembler
+to read and produce an object file. 
+
+With case B) the libdwarf-calling application must
+use the relocation information to change
+points of each binary stream into references to 
+symbolic names.  
+It is necessary for the assembler to be
+willing to accept and generate relocations
+for references from arbitrary byte boundaries.
+For example:
+.sp
+.nf
+.in +4
+ .data 0a0bcc    #producing 3 bytes of data.
+ .word mylabel   #producing a reference
+ .word endlabel - startlable #producing absolute length
+.in -4
+.fi
+.sp
+
+
+
+
+.H 2 "libdwarf relationship to Elf"
+When the documentation below refers to 'an elf section number'
+it is really only dependent on getting (via the callback
+function passed by the caller of
+\f(CWdwarf_producer_init()\fP)
+a sequence of integers back (with 1 as the lowest).
+
+When the documentation below refers to 'an Elf symbol index'
+it is really dependent on 
+Elf symbol numbers
+only if
+\f(CWDW_DLC_STREAM_RELOCATIONS\fP 
+are being generated (see below).
+With 
+\f(CWDW_DLC_STREAM_RELOCATIONS\fP 
+the library is generating Elf relocations
+and the section numbers in binary form so
+the section numbers and symbol indices must really 
+be Elf (or elf-like) numbers.
+
+
+With
+\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP 
+the values passed as symbol indexes can be any
+integer set or even pointer set.
+All that libdwarf assumes is that where values
+are unique they get unique values.
+Libdwarf does not generate any kind of symbol table
+from the numbers and does not check their
+uniqueness or lack thereof.
+
+.H 2 "libdwarf and relocations"
+With
+\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP 
+libdwarf creates binary streams of debug information
+and arrays of relocation information describing
+the necessary relocation.
+The Elf section numbers and symbol numbers appear
+nowhere in the binary streams. Such appear
+only in the relocation information and the passed-back
+information from calls requesting the relocation information.
+As a consequence, the 'symbol indices' can be
+any pointer or integer value as the caller must
+arrange that the output deal with relocations.
+
+With 
+\f(CWDW_DLC_STREAM_RELOCATIONS\fP 
+all the relocations are directly created by libdwarf
+as binary streams (libdwarf only creates the streams
+in memory,
+it does not write them to disk).
+
+.H 2 "symbols, addresses, and offsets"
+The following applies to calls that
+pass in symbol indices, addresses, and offsets, such
+as
+\f(CWdwarf_add_AT_targ_address() \fP 
+\f(CWdwarf_add_arange_b()\fP 
+and
+\f(CWdwarf_add_frame_fde_b()\fP.
+
+With 
+\f(CWDW_DLC_STREAM_RELOCATIONS\fP 
+a passed in address is one of:
+a) a section offset and the (non-global) symbol index of
+a section symbol.
+b) A symbol index (global symbol) and a zero offset.
+
+With \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP
+the same approach can be used, or, instead,
+a passed in address may be
+c) a symbol handle and an offset.
+In this case, since it is up to the calling app to
+generate binary relocations (if appropriate)
+or to turn the binary stream into 
+a text stream (for input to an assembler, if appropriate)
+the application has complete control of the interpretation
+of the symbol handles.
+
+
+
+.H 1 "Memory Management"
+
+Several of the functions that comprise the \fILibdwarf\fP 
+producer interface dynamically allocate values and some
+return pointers to those spaces.
+The dynamically allocated spaces 
+can not be reclaimed  (and must
+not be freed)  except by \f(CWdwarf_producer_finish(dbg)\fP.  
+
+All data for a particular \f(CWDwarf_P_Debug\fP descriptor
+is separate from the data for any other 
+\f(CWDwarf_P_Debug\fP descriptor in use in the library-calling
+application.
+
+.H 2 "Read-only Properties"
+All pointers returned by or as a result of a \fILibdwarf\fP call should 
+be assumed to point to read-only memory.  
+Except as defined by this document, the results are undefined for 
+\fILibdwarf\fP clients that attempt to write to a region pointed to by a 
+return value from a \fILibdwarf\fP call.
+
+.H 2 "Storage Deallocation"
+Calling \f(CWdwarf_producer_finish(dbg)\fP frees all the space, and 
+invalidates all pointers returned from \f(CWLibdwarf\fP functions on 
+or descended from \f(CWdbg\fP).
+
+.H 1 "Functional Interface"
+This section describes the functions available in the \fILibdwarf\fP
+library.  Each function description includes its definition, followed 
+by a paragraph describing the function's operation.
+
+.P
+The functions may be categorized into groups: 
+\fIinitialization and termination operations\fP,
+\fIdebugging information entry creation\fP,
+\fIElf section callback function\fP,
+\fIattribute creation\fP,
+\fIexpression creation\fP, 
+\fIline number creation\fP, 
+\fIfast-access (aranges) creation\fP, 
+\fIfast-access (pubnames) creation\fP, 
+\fIfast-access (weak names) creation\fP,
+\fImacro information creation\fP, 
+\fIlow level (.debug_frame) creation\fP, 
+and
+\fIlocation list (.debug_loc) creation\fP. 
+
+.P
+The following sections describe these functions.
+
+.H 2 "Initialization and Termination Operations"
+These functions setup \f(CWLibdwarf\fP to accumulate debugging information
+for an object, usually a compilation-unit, provided by the producer.
+The actual addition of information is done by functions in the other
+sections of this document.  Once all the information has been added,
+functions from this section are used to transform the information to
+appropriate byte streams, and help to write out the byte streams to
+disk.
+
+Typically then, a producer application 
+would create a \f(CWDwarf_P_Debug\fP 
+descriptor to gather debugging information for a particular
+compilation-unit using \f(CWdwarf_producer_init()\fP.  
+The producer application would 
+use this \f(CWDwarf_P_Debug\fP descriptor to accumulate debugging 
+information for this object using functions from other sections of 
+this document.  
+Once all the information had been added, it would 
+call \f(CWdwarf_transform_to_disk_form()\fP to convert the accumulated 
+information into byte streams in accordance with the \f(CWDWARF\fP 
+standard.  
+The application would then repeatedly call 
+\f(CWdwarf_get_section_bytes()\fP 
+for each of the \f(CW.debug_*\fP created.  
+This gives the producer 
+information about the data bytes to be written to disk.  
+At this point, 
+the producer would release all resource used by \f(CWLibdwarf\fP for 
+this object by calling \f(CWdwarf_producer_finish()\fP.
+
+It is also possible to create assembler-input character streams
+from the byte streams created by this library.
+This feature requires slightly different interfaces than
+direct binary output.
+The details are mentioned in the text.
+
+.H 3 "dwarf_producer_init()"
+
+.DS
+\f(CWDwarf_P_Debug dwarf_producer_init(
+        Dwarf_Unsigned flags,
+        Dwarf_Callback_Func func,
+        Dwarf_Handler errhand,
+        Dwarf_Ptr errarg,
+        Dwarf_Error *error) \fP
+.DE
+The function \f(CWdwarf_producer_init() \fP returns a new 
+\f(CWDwarf_P_Debug\fP descriptor that can be used to add \f(CWDwarf\fP 
+information to the object.  
+On error it returns \f(CWDW_DLV_BADADDR\fP.  
+\f(CWflags\fP determine whether the target object is 64-bit or 32-bit.  
+\f(CWfunc\fP is a pointer to a function called-back from \f(CWLibdwarf\fP 
+whenever \f(CWLibdwarf\fP needs to create a new object section (as it will 
+for each .debug_* section and related relocation section).  
+\f(CWerrhand\fP 
+is a pointer to a function that will be used for handling errors detected 
+by \f(CWLibdwarf\fP.  \f(CWerrarg\fP is the default error argument used 
+by the function pointed to by \f(CWerrhand\fP.
+.P
+The \f(CWflags\fP
+values are as follows:
+.in +4
+\f(CWDW_DLC_WRITE\fP 
+is required.
+The values
+\f(CWDW_DLC_READ\fP  
+\f(CWDW_DLC_RDWR\fP
+are not supported by the producer and must not be passed.
+
+If 
+\f(CWDW_DLC_SIZE_64\fP
+is not OR'd into \f(CWflags\fP
+then
+\f(CWDW_DLC_SIZE_32\fP
+is assumed.
+Oring in both is an error.
+
+If
+\f(CWDW_DLC_ISA_IA64\fP
+is not OR'd into \f(CWflags\fP
+then 
+\f(CWDW_DLC_ISA_MIPS\fP
+is assumed.
+Oring in both is an error.
+
+If
+\f(CWDW_DLC_TARGET_BIGENDIAN\fP
+is not OR'd into \f(CWflags\fP
+then 
+endianness the same as the host is assumed.
+
+If
+\f(CWDW_DLC_TARGET_LITTLEENDIAN\fP
+is not OR'd into \f(CWflags\fP
+then 
+endianness the same as the host is assumed.
+
+If both 
+\f(CWDW_DLC_TARGET_LITTLEENDIAN\fP
+and
+\f(CWDW_DLC_TARGET_BIGENDIAN\fP
+are or-d in it is an error.
+
+
+
+Either one of two output forms is specifiable:
+\f(CWDW_DLC_STREAM_RELOCATIONS\fP 
+or
+\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP .
+
+The default is
+\f(CWDW_DLC_STREAM_RELOCATIONS\fP . 
+The
+\f(CWDW_DLC_STREAM_RELOCATIONS\fP
+are relocations in a binary stream (as used
+in a MIPS Elf object).
+
+The
+\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP
+are the same relocations but expressed in an
+array of structures defined by libdwarf,
+which the caller of the relevant function
+(see below) must deal with appropriately.
+This method of expressing relocations allows 
+the producer-application to easily produce
+assembler text output of debugging information.
+
+
+If
+\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP
+is OR'd into \f(CWflags\fP
+then relocations are returned not as streams
+but thru an array of structures.
+
+.in -4
+.P
+The function \f(CWfunc\fP 
+must be provided by the user of this library.
+Its prototype is:
+.DS
+\f(CWtypedef int (*Dwarf_Callback_Func)(
+    char* name,
+    int                 size,
+    Dwarf_Unsigned      type,
+    Dwarf_Unsigned      flags,
+    Dwarf_Unsigned      link,
+    Dwarf_Unsigned      info,
+    int*                sect_name_index,
+    int*                error) \fP
+.DE
+For each section in the object file that \f(CWlibdwarf\fP
+needs to create, it calls this function once, passing in
+the section \f(CWname\fP, the section \f(CWtype\fP,
+the section \f(CWflags\fP, the \f(CWlink\fP field, and
+the \f(CWinfo\fP field.  
+For an Elf object file these values
+should be appropriate Elf section header values.
+For example, for relocation callbacks, the \f(CWlink\fP
+field is supposed to be set (by the app) to the index
+of the symtab section (the link field passed thru the
+callback must be ignored by the app).
+And, for relocation callbacks, the \f(CWinfo\fP field
+is passed as the elf section number of the section
+the relocations apply to.
+
+On success
+the user function should return the Elf section number of the
+newly created Elf section.
+.P
+On success, the function should also set the integer
+pointed to by \f(CWsect_name_index\fP to the
+Elf symbol number assigned in the Elf symbol table of the
+new Elf section.
+This symbol number is needed with relocations
+dependent on the relocation of this new section.
+Because "int *" is not guaranteed to work with elf 'symbols'
+that are really pointers,
+It is better to use the 
+\f(CWdwarf_producer_init_b()\fP
+interface.
+.P
+For example, the \f(CW.debug_line\fP section's third
+data element (in a compilation unit) is the offset from the
+beginning of the \f(CW.debug_info\fP section of the compilation
+unit entry for this \f(CW.debug_line\fP set.
+The relocation entry in \f(CW.rel.debug_line\fP
+for this offset
+must have the relocation symbol index of the 
+symbol \f(CW.debug_info\fP  returned
+by the callback of that section-creation through 
+the pointer \f(CWsect_name_index\fP.
+.P
+On failure, the function should return -1 and set the \f(CWerror\fP
+integer to an error code.
+.P
+Nothing in libdwarf actually depends on the section index
+returned being a real Elf section.
+The Elf section is simply useful for generating relocation
+records.
+Similarly, the Elf symbol table index returned thru 
+the \f(CWsect_name_index\fP must simply be an index
+that can be used in relocations against this section.
+The application will probably want to note the
+values passed to this function in some form, even if
+no Elf file is being produced.
+
+.H 3 "dwarf_producer_init_b()"
+
+.DS
+\f(CWDwarf_P_Debug dwarf_producer_init_b(
+        Dwarf_Unsigned flags,
+        Dwarf_Callback_Func_b func,
+        Dwarf_Handler errhand,
+        Dwarf_Ptr errarg,
+        Dwarf_Error *error) \fP
+.DE
+The function \f(CWdwarf_producer_init_b() \fP 
+is the same as \f(CWdwarf_producer_init() \fP
+except that the callback function uses
+Dwarf_Unsigned rather than int as the
+type of the symbol-index returned to libdwarf
+thru the pointer argument (see below).
+.P
+The \f(CWflags\fP
+values are as follows:
+.in +4
+\f(CWDW_DLC_WRITE\fP 
+is required.
+The values
+\f(CWDW_DLC_READ\fP  
+\f(CWDW_DLC_RDWR\fP
+are not supported by the producer and must not be passed.
+
+If 
+\f(CWDW_DLC_SIZE_64\fP
+is not OR'd into \f(CWflags\fP
+then
+\f(CWDW_DLC_SIZE_32\fP
+is assumed.
+Oring in both is an error.
+
+If
+\f(CWDW_DLC_ISA_IA64\fP
+is not OR'd into \f(CWflags\fP
+then 
+\f(CWDW_DLC_ISA_MIPS\fP
+is assumed.
+Oring in both is an error.
+
+Either one of two output forms are specifiable:
+\f(CWDW_DLC_STREAM_RELOCATIONS\fP
+or
+\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP .
+\f(CWdwarf_producer_init_b() \fP 
+is usable with
+either output form.
+
+Either one of two output forms is specifiable:
+\f(CWDW_DLC_STREAM_RELOCATIONS\fP
+or
+\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP .
+
+The default is
+\f(CWDW_DLC_STREAM_RELOCATIONS\fP .
+The
+\f(CWDW_DLC_STREAM_RELOCATIONS\fP
+are relocations in a binary stream (as used
+in a MIPS Elf object).
+
+\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP
+are OR'd into flags
+to cause 
+the same relocations to be expressed in an
+array of structures defined by libdwarf,
+which the caller of the relevant function
+(see below) must deal with appropriately.
+This method of expressing relocations allows
+the producer-application to easily produce
+assembler text output of debugging information.
+
+.in -4
+.P
+The function \f(CWfunc\fP 
+must be provided by the user of this library.
+Its prototype is:
+.DS
+\f(CWtypedef int (*Dwarf_Callback_Func_b)(
+    char* name,
+    int                 size,
+    Dwarf_Unsigned      type,
+    Dwarf_Unsigned      flags,
+    Dwarf_Unsigned      link,
+    Dwarf_Unsigned      info,
+    Dwarf_Unsigned*     sect_name_index,
+    int*                error) \fP
+.DE
+For each section in the object file that \f(CWlibdwarf\fP
+needs to create, it calls this function once, passing in
+the section \f(CWname\fP, the section \f(CWtype\fP,
+the section \f(CWflags\fP, the \f(CWlink\fP field, and
+the \f(CWinfo\fP field.  For an Elf object file these values
+should be appropriate Elf section header values.
+For example, for relocation callbacks, the \f(CWlink\fP
+field is supposed to be set (by the app) to the index
+of the symtab section (the link field passed thru the
+callback must be ignored by the app).
+And, for relocation callbacks, the \f(CWinfo\fP field
+is passed as the elf section number of the section
+the relocations apply to.
+
+On success
+the user function should return the Elf section number of the
+newly created Elf section.
+.P
+On success, the function should also set the integer
+pointed to by \f(CWsect_name_index\fP to the
+Elf symbol number assigned in the Elf symbol table of the
+new Elf section.
+This symbol number is needed with relocations
+dependent on the relocation of this new section.
+.P
+For example, the \f(CW.debug_line\fP section's third
+data element (in a compilation unit) is the offset from the
+beginning of the \f(CW.debug_info\fP section of the compilation
+unit entry for this \f(CW.debug_line\fP set.
+The relocation entry in \f(CW.rel.debug_line\fP
+for this offset
+must have the relocation symbol index of the 
+symbol \f(CW.debug_info\fP  returned
+by the callback of that section-creation through 
+the pointer \f(CWsect_name_index\fP.
+.P
+On failure, the function should return -1 and set the \f(CWerror\fP
+integer to an error code.
+.P
+Nothing in libdwarf actually depends on the section index
+returned being a real Elf section.
+The Elf section is simply useful for generating relocation
+records.
+Similarly, the Elf symbol table index returned thru 
+the \f(CWsect_name_index\fP must simply be an index
+that can be used in relocations against this section.
+The application will probably want to note the
+values passed to this function in some form, even if
+no Elf file is being produced.
+
+Note that the \f(CWDwarf_Callback_Func_b() \fP form
+passes back the sect_name_index as a Dwarf_Unsigned.
+This is guaranteed large enough to hold a pointer.
+(the other functional interfaces have versions with
+the 'symbol index' as a Dwarf_Unsigned too. See below).
+
+If \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP
+is in use, then the symbol index is simply an arbitrary
+value (from the point of view of libdwarf) so the
+caller can put anything in it:
+a normal elf symbol index,
+a pointer to a struct (with arbitrary contents)
+(the caller must cast to/from Dwarf_Unsigned 
+as appropriate), 
+or some other kind of pointer or value.
+The values show up in the 
+output of \f(CWdwarf_get_relocation_info()\fP
+(described below) and are not emitted anywhere else.
+
+.H 3 "dwarf_transform_to_disk_form()"
+
+.DS
+\f(CWDwarf_Signed dwarf_transform_to_disk_form(
+        Dwarf_P_Debug dbg,
+        Dwarf_Error* error) \fP
+.DE
+The function \f(CWdwarf_transform_to_disk_form() \fP does the actual
+conversion of the \f(CWDwarf\fP information provided so far, to the
+form that is 
+normally written out as \f(CWElf\fP sections.  
+In other words, 
+once all DWARF information has been passed to \f(CWLibdwarf\fP, call 
+\f(CWdwarf_transform_to_disk_form() \fP to transform all the accumulated 
+data into byte streams.  
+This includes turning relocation information 
+into byte streams (and possibly relocation arrays).  
+This function does not write anything to disk.  If 
+successful, it returns a count of the number of \f(CWElf\fP sections 
+ready to be retrieved (and, normally, written to disk).
+In case of error, it returns 
+\f(CWDW_DLV_NOCOUNT\fP.
+
+
+.H 3 "dwarf_get_section_bytes()"
+
+.DS
+\f(CWDwarf_Ptr dwarf_get_section_bytes(
+        Dwarf_P_Debug dbg,
+        Dwarf_Signed dwarf_section,
+        Dwarf_Signed *elf_section_index, 
+        Dwarf_Unsigned *length,
+        Dwarf_Error* error)\fP
+.DE
+The function \f(CWdwarf_get_section_bytes() \fP must be called repetitively, 
+with the index \f(CWdwarf_section\fP starting at 0 and continuing for the 
+number of sections 
+returned by \f(CWdwarf_transform_to_disk_form() \fP.
+It returns \f(CWNULL\fP to indicate that there are no more sections of 
+\f(CWDwarf\fP information.  
+For each non-NULL return, the return value
+points to \f(CW*length\fP bytes of data that are normally
+added to the output 
+object in \f(CWElf\fP section \f(CW*elf_section\fP by the producer application.
+It is illegal to call these in any order other than 0 thru N-1 where
+N is the number of dwarf sections
+returned by \f(CWdwarf_transform_to_disk_form() \fP.
+The \f(CWdwarf_section\fP
+number is actually ignored: the data is returned as if the
+caller passed in the correct dwarf_section numbers in the
+required sequence.
+The \f(CWerror\fP argument is not used.
+.P
+There is no requirement that the section bytes actually 
+be written to an elf file.
+For example, consider the .debug_info section and its
+relocation section (the call back function would resulted in
+assigning 'section' numbers and the link field to tie these
+together (.rel.debug_info would have a link to .debug_info).
+One could examine the relocations, split the .debug_info
+data at relocation boundaries, emit byte streams (in hex)
+as assembler output, and at each relocation point,
+emit an assembler directive with a symbol name for the assembler.
+Examining the relocations is awkward though. 
+It is much better to use \f(CWdwarf_get_section_relocation_info() \fP
+.P
+
+The memory space of the section byte stream is freed
+by the \f(CWdwarf_producer_finish() \fP call
+(or would be if the \f(CWdwarf_producer_finish() \fP
+was actually correct), along
+with all the other space in use with that Dwarf_P_Debug.
+
+.H 3 "dwarf_get_relocation_info_count()"
+.DS
+\f(CWint  dwarf_get_relocation_info_count(
+        Dwarf_P_Debug dbg,
+        Dwarf_Unsigned *count_of_relocation_sections ,
+	int            *drd_buffer_version,
+        Dwarf_Error* error)\fP
+.DE
+The function \f(CWdwarf_get_relocation_info() \fP
+returns, thru  the pointer \f(CWcount_of_relocation_sections\fP, the
+number of times that \f(CWdwarf_get_relocation_info() \fP
+should be called.
+
+The function \f(CWdwarf_get_relocation_info() \fP
+returns DW_DLV_OK if the call was successful (the 
+\f(CWcount_of_relocation_sections\fP is therefore meaningful,
+though \f(CWcount_of_relocation_sections\fP
+could be zero).
+
+\f(CW*drd_buffer_version\fP
+is the value 2.
+If the structure pointed to by
+the \f(CW*reldata_buffer\fP
+changes this number will change.
+The application should verify that the number is
+the version it understands (that it matches
+the value of DWARF_DRD_BUFFER_VERSION (from libdwarf.h)).
+The value 1 version was never used in production 
+MIPS libdwarf (version 1 did exist in source).
+
+It returns DW_DLV_NO_ENTRY if 
+\f(CWcount_of_relocation_sections\fP is not meaningful
+because \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP was not
+passed in the 
+\f(CWdwarf_producer_init() \fP
+(or
+\f(CWdwarf_producer_init_b() \fP ) call.
+
+It returns DW_DLV_ERROR if there was an error,
+in which case
+\f(CWcount_of_relocation_sections\fP is not meaningful.
+
+.H 3 "dwarf_get_relocation_info()"
+.DS
+\f(CWint dwarf_get_relocation_info(
+        Dwarf_P_Debug dbg,
+        Dwarf_Signed *elf_section_index, 
+	Dwarf_Signed *elf_section_index_link, 
+        Dwarf_Unsigned *relocation_buffer_count,
+	Dwarf_Relocation_Data *reldata_buffer,
+        Dwarf_Error* error)\fP
+.DE
+
+The function \f(CWdwarf_get_relocation_info() \fP 
+should normally be called repetitively, 
+for the number of relocation sections that 
+\f(CWdwarf_get_relocation_info_count() \fP
+indicated exist.
+
+It returns \f(CWDW_DLV_OK\fP to indicate that 
+valid values are returned thru the pointer arguments.
+The \f(CWerror\fP argument is not set.
+
+It returns DW_DLV_NO_ENTRY if there are no entries
+(the count of relocation arrays is zero.).
+The \f(CWerror\fP argument is not set.
+
+It returns \f(CWDW_DLV_ERROR\fP if there is an error.
+Calling \f(CWdwarf_get_relocation_info() \fP
+more than the number of times indicated by
+\f(CWdwarf_get_relocation_info_count() \fP
+(without an intervening call to
+\f(CWdwarf_reset_section_bytes() \fP )
+results in a return of \f(CWDW_DLV_ERROR\fP once past
+the valid count.
+The \f(CWerror\fP argument is set to indicate the error.
+
+Now consider the returned-thru-pointer values for
+\f(CWDW_DLV_OK\fP .
+
+\f(CW*elf_section_index\fP
+is the 'elf section index' of the section implied by
+this group of relocations.
+
+
+\f(CW*elf_section_index_link\fP
+is the section index of the section that these
+relocations apply to.
+
+\f(CW*relocation_buffer_count\fP
+is the number of array entries of relocation information
+in the array pointed to by
+\f(CW*reldata_buffer\fP .
+
+
+\f(CW*reldata_buffer\fP
+points to an array of 'struct Dwarf_Relocation_Data_s'
+structures.
+
+The version 2 array information is as follows:
+
+.nf
+enum Dwarf_Rel_Type {dwarf_drt_none,
+                dwarf_drt_data_reloc,
+                dwarf_drt_segment_rel,
+                dwarf_drt_first_of_length_pair,
+                dwarf_drt_second_of_length_pair
+};
+typedef struct Dwarf_Relocation_Data_s  * Dwarf_Relocation_Data;
+struct Dwarf_Relocation_Data_s {
+        unsigned char        drd_type;   /* contains Dwarf_Rel_Type */
+	unsigned char        drd_length; /* typically 4 or 8 */
+        Dwarf_Unsigned       drd_offset; /* where the data to reloc is */
+        Dwarf_Unsigned       drd_symbol_index;
+};
+
+.fi
+
+The \f(CWDwarf_Rel_Type\fP enum is encoded (via casts if necessary)
+into the single unsigned char \f(CWdrd_type\fP field to control
+the space used for this information (keep the space to 1 byte).
+
+The unsigned char \f(CWdrd_length\fP field
+holds the size in bytes of the field to be relocated.
+So for elf32 object formats with 32 bit apps, \f(CWdrd_length\fP
+will be 4.  For objects with MIPS -64 contents,
+\f(CWdrd_length\fP will be 8.  
+For some dwarf 64 bit environments, such as ia64, \f(CWdrd_length\fP
+is 4 for some relocations (file offsets, for example) 
+and 8 for others (run time
+addresses, for example).
+
+If \f(CWdrd_type\fP is \f(CWdwarf_drt_none\fP, this is an unused slot
+and it should be ignored.
+
+If \f(CWdrd_type\fP is \f(CWdwarf_drt_data_reloc\fP 
+this is an ordinary relocation.
+The relocation type means either
+(R_MIPS_64) or (R_MIPS_32) (or the like for
+the particular ABI.
+f(CWdrd_length\fP gives the length of the field to be relocated.
+\f(CWdrd_offset\fP is an offset (of the
+value to be relocated) in
+the section this relocation stuff is linked to.
+\f(CWdrd_symbol_index\fP is the symbol index (if elf symbol
+indices were provided) or the handle to arbitrary
+information (if that is what the caller passed in 
+to the relocation-creating dwarf calls) of the symbol
+that the relocation is relative to.
+
+
+When \f(CWdrd_type\fP is \f(CWdwarf_drt_first_of_length_pair\fP
+the next data record will be \f(CWdrt_second_of_length_pair\fP
+and the \f(CWdrd_offset\fP of the two data records will match.
+The relevant 'offset' in the section this reloc applies to
+should contain a symbolic pair like
+.nf
+.in +4
+ .word    second_symbol - first_symbol
+.in -4
+.fi
+to generate a length.
+\f(CWdrd_length\fP gives the length of the field to be relocated.
+
+\f(CWdrt_segment_rel\fP means (R_MIPS_SCN_DISP)
+is the real relocation (R_MIPS_SCN_DISP applies to
+exception tables and this part may need further work).
+\f(CWdrd_length\fP gives the length of the field to be relocated.
+
+.P
+The memory space of the section byte stream is freed
+by the \f(CWdwarf_producer_finish() \fP call
+(or would be if the \f(CWdwarf_producer_finish() \fP
+was actually correct), along
+with all the other space in use with that Dwarf_P_Debug.
+
+.H 3 "dwarf_reset_section_bytes()"
+
+.DS
+\f(CWvoid dwarf_reset_section_bytes(
+        Dwarf_P_Debug dbg
+        ) \fP
+.DE
+The function \f(CWdwarf_reset_section_bytes() \fP 
+is used to reset the internal information so that
+\f(CWdwarf_get_section_bytes() \fP will begin (on the next
+call) at the initial dwarf section again.
+It also resets so that calls to 
+\f(CWdwarf_get_relocation_info() \fP
+will begin again at the initial array of relocation information.
+
+Some dwarf producers need to be able to run thru
+the \f(CWdwarf_get_section_bytes()\fP
+and/or
+the \f(CWdwarf_get_relocation_info()\fP
+calls more than once and this call makes additional 
+passes possible.
+The set of Dwarf_Ptr values returned is identical to the
+set returned by the first pass.
+It is acceptable to call this before finishing a pass
+of \f(CWdwarf_get_section_bytes()\fP
+or
+\f(CWdwarf_get_relocation_info()\fP
+calls.
+No errors are possible as this just resets some
+internal pointers.
+It is unwise to call this before
+\f(CWdwarf_transform_to_disk_form() \fP has been called.
+.P
+
+.H 3 "dwarf_producer_finish()"
+.DS
+\f(CWDwarf_Unsigned dwarf_producer_finish(
+        Dwarf_P_Debug dbg,
+        Dwarf_Error* error) \fP
+.DE
+The function \f(CWdwarf_producer_finish() \fP should be called after all 
+the bytes of data have been copied somewhere
+(normally the bytes are written to disk).  
+It frees all dynamic space 
+allocated for \f(CWdbg\fP, include space for the structure pointed to by
+\f(CWdbg\fP.  
+This should not be called till the data have been 
+copied or written 
+to disk or are no longer of interest.  
+It returns non-zero if successful, and \f(CWDW_DLV_NOCOUNT\fP 
+if there is an error.
+
+.H 2 "Debugging Information Entry Creation"
+The functions in this section add new \f(CWDIE\fPs to the object,
+and also the relationships among the \f(CWDIE\fP to be specified
+by linking them up as parents, children, left or right siblings
+of each other.  
+In addition, there is a function that marks the
+root of the graph thus created.
+
+.H 3 "dwarf_add_die_to_debug()"
+.DS
+\f(CWDwarf_Unsigned dwarf_add_die_to_debug(
+        Dwarf_P_Debug dbg,
+        Dwarf_P_Die first_die,
+        Dwarf_Error *error) \fP
+.DE
+The function \f(CWdwarf_add_die_to_debug() \fP indicates to \f(CWLibdwarf\fP
+the root \f(CWDIE\fP of the \f(CWDIE\fP graph that has been built so 
+far.  
+It is intended to mark the compilation-unit \f(CWDIE\fP for the 
+object represented by \f(CWdbg\fP.  
+The root \f(CWDIE\fP is specified 
+by \f(CWfirst_die\fP.
+
+It returns \f(CW0\fP on success, and \f(CWDW_DLV_NOCOUNT\fP on error.
+
+.H 3 "dwarf_new_die()"
+.DS
+\f(CWDwarf_P_Die dwarf_new_die(
+        Dwarf_P_Debug dbg, 
+        Dwarf_Tag new_tag,
+        Dwarf_P_Die parent,
+        Dwarf_P_Die child,
+        Dwarf_P_Die left_sibling, 
+        Dwarf_P_Die right_sibling,
+        Dwarf_Error *error) \fP
+.DE
+The function \f(CWdwarf_new_die() \fP creates a new \f(CWDIE\fP with
+its parent, child, left sibling, and right sibling \f(CWDIE\fPs
+specified by \f(CWparent\fP, \f(CWchild\fP, \f(CWleft_sibling\fP,
+and \f(CWright_sibling\fP, respectively.  
+There is no requirement
+that all of these \f(CWDIE\fPs be specified, i.e. any of these
+descriptors may be \f(CWNULL\fP.  
+If none is specified, this will
+be an isolated \f(CWDIE\fP.  
+A \f(CWDIE\fP is 
+transformed to disk form by \f(CWdwarf_transform_to_disk_form() \fP 
+only if there is a path from
+the \f(CWDIE\fP specified by \f(CWdwarf_add_die_to_debug\fP to it.
+This function returns \f(CWDW_DLV_BADADDR\fP on error.
+
+\f(CWnew_tag\fP is the tag which is given to the new \f(CWDIE\fP.
+\f(CWparent\fP, \f(CWchild\fP, \f(CWleft_sibling\fP, and
+\f(CWright_sibling\fP are pointers to establish links to existing 
+\f(CWDIE\fPs.  Only one of \f(CWparent\fP, \f(CWchild\fP, 
+\f(CWleft_sibling\fP, and \f(CWright_sibling\fP may be non-NULL.
+If \f(CWparent\fP (\f(CWchild\fP) is given, the \f(CWDIE\fP is 
+linked into the list after (before) the \f(CWDIE\fP pointed to.  
+If \f(CWleft_sibling\fP (\f(CWright_sibling\fP) is given, the 
+\f(CWDIE\fP is linked into the list after (before) the \f(CWDIE\fP 
+pointed to.
+
+To add attributes to the new \f(CWDIE\fP, use the \f(CWAttribute Creation\fP 
+functions defined in the next section.
+
+.H 3 "dwarf_die_link()"
+.DS
+\f(CWDwarf_P_Die dwarf_die_link(
+        Dwarf_P_Die die, 
+        Dwarf_P_Die parent,
+        Dwarf_P_Die child,
+        Dwarf_P_Die left-sibling, 
+        Dwarf_P_Die right_sibling,
+        Dwarf_Error *error) \fP
+.DE
+The function \f(CWdwarf_die_link() \fP links an existing \f(CWDIE\fP
+described by the given \f(CWdie\fP to other existing \f(CWDIE\fPs.
+The given \f(CWdie\fP can be linked to a parent \f(CWDIE\fP, a child
+\f(CWDIE\fP, a left sibling \f(CWDIE\fP, or a right sibling \f(CWDIE\fP
+by specifying non-NULL \f(CWparent\fP, \f(CWchild\fP, \f(CWleft_sibling\fP,
+and \f(CWright_sibling\fP \f(CWDwarf_P_Die\fP descriptors.  
+It returns
+the given \f(CWDwarf_P_Die\fP descriptor, \f(CWdie\fP, on success,
+and \f(CWDW_DLV_BADADDR\fP on error.
+
+Only one of \f(CWparent\fP, \f(CWchild\fP, \f(CWleft_sibling\fP,
+and \f(CWright_sibling\fP may be non-NULL.  
+If \f(CWparent\fP
+(\f(CWchild\fP) is given, the \f(CWDIE\fP is linked into the list 
+after (before) the \f(CWDIE\fP pointed to.  
+If \f(CWleft_sibling\fP
+(\f(CWright_sibling\fP) is given, the \f(CWDIE\fP is linked into 
+the list after (before) the \f(CWDIE\fP pointed to.  
+Non-NULL links
+overwrite the corresponding links the given \f(CWdie\fP may have
+had before the call to \f(CWdwarf_die_link() \fP.
+
+.H 2 "Attribute Creation"
+The functions in this section add attributes to a \f(CWDIE\fP.
+These functions return a \f(CWDwarf_P_Attribute\fP descriptor 
+that represents the attribute added to the given \f(CWDIE\fP.  
+In most cases the return value is only useful to determine if 
+an error occurred.
+
+Some of the attributes have values that are relocatable.  
+They
+need a symbol with respect to which the linker will perform
+relocation.  
+This symbol is specified by means of an index into
+the Elf symbol table for the object
+(of course, the symbol index can be more general than an index).
+
+.H 3 "dwarf_add_AT_location_expr()"
+.DS
+\f(CWDwarf_P_Attribute dwarf_add_AT_location_expr(
+        Dwarf_P_Debug dbg,
+        Dwarf_P_Die ownerdie,
+        Dwarf_Half attr,
+        Dwarf_P_Expr loc_expr,
+        Dwarf_Error *error) \fP
+.DE
+The function \f(CWdwarf_add_AT_location_expr() \fP adds the attribute
+specified by \f(CWattr\fP to the \f(CWDIE\fP descriptor given by
+\f(CWownerdie\fP.  The attribute should be one that has a location
+expression as its value.  The location expression that is the value
+is represented by the \f(CWDwarf_P_Expr\fP descriptor \f(CWloc_expr\fP.
+It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute
+given, on success.  On error it returns \f(CWDW_DLV_BADADDR\fP.
+
+.H 3 "dwarf_add_AT_name()"
+.DS
+\f(CWDwarf_P_Attribute dwarf_add_AT_name(
+        Dwarf_P_Die ownerdie, 
+        char *name,
+        Dwarf_Error *error) \fP
+.DE
+The function \f(CWdwarf_add_AT_name() \fP adds the string specified
+by \f(CWname\fP as the value of the \f(CWDW_AT_name\fP attribute
+for the given \f(CWDIE\fP, \f(CWownerdie\fP.  It returns the 
+\f(CWDwarf_P_attribute\fP descriptor for the \f(CWDW_AT_name\fP 
+attribute on success.  On error, it returns \f(CWDW_DLV_BADADDR\fP.
+
+.H 3 "dwarf_add_AT_comp_dir()"
+.DS
+\f(CWDwarf_P_Attribute dwarf_add_AT_comp_dir(
+        Dwarf_P_Die ownerdie,
+        char *current_working_directory,
+        Dwarf_Error *error) \fP
+.DE
+The function \f(CWdwarf_add_AT_comp_dir() \fP adds the string given by
+\f(CWcurrent_working_directory\fP as the value of the \f(CWDW_AT_comp_dir\fP
+attribute for the \f(CWDIE\fP described by the given \f(CWownerdie\fP.  
+It returns the \f(CWDwarf_P_Attribute\fP for this attribute on success.
+On error, it returns \f(CWDW_DLV_BADADDR\fP.
+
+.H 3 "dwarf_add_AT_producer()"
+.DS
+\f(CWDwarf_P_Attribute dwarf_add_AT_producer(
+        Dwarf_P_Die ownerdie,
+        char *producer_string,
+        Dwarf_Error *error) \fP
+.DE
+The function \f(CWdwarf_add_AT_producer() \fP adds the string given by
+\f(CWproducer_string\fP as the value of the \f(CWDW_AT_producer\fP
+attribute for the \f(CWDIE\fP given by \f(CWownerdie\fP.  It returns
+the \f(CWDwarf_P_Attribute\fP descriptor representing this attribute
+on success.  On error, it returns \f(CWDW_DLV_BADADDR\fP.
+
+.H 3 "dwarf_add_AT_const_value_signedint()"
+.DS
+\f(CWDwarf_P_Attribute dwarf_add_AT_const_value_signedint(
+        Dwarf_P_Die ownerdie,
+        Dwarf_Signed signed_value,
+        Dwarf_Error *error) \fP
+.DE
+The function \f(CWdwarf_add_AT_const_value_signedint() \fP adds the
+given \f(CWDwarf_Signed\fP value \f(CWsigned_value\fP as the value
+of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP
+described by the given \f(CWownerdie\fP.  It returns the 
+\f(CWDwarf_P_Attribute\fP descriptor for this attribute on success.  
+On error, it returns \f(CWDW_DLV_BADADDR\fP.
+
+.H 3 "dwarf_add_AT_const_value_unsignedint()"
+.DS
+\f(CWDwarf_P_Attribute dwarf_add_AT_const_value_unsignedint(
+        Dwarf_P_Die ownerdie,
+        Dwarf_Unsigned unsigned_value,
+        Dwarf_Error *error) \fP
+.DE
+The function \f(CWdwarf_add_AT_const_value_unsignedint() \fP adds the
+given \f(CWDwarf_Unsigned\fP value \f(CWunsigned_value\fP as the value
+of the \f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described 
+by the given \f(CWownerdie\fP.  It returns the \f(CWDwarf_P_Attribute\fP
+descriptor for this attribute on success.  On error, it returns
+\f(CWDW_DLV_BADADDR\fP.
+
+.H 3 "dwarf_add_AT_const_value_string()"
+.DS
+\f(CWDwarf_P_Attribute dwarf_add_AT_const_value_string(
+        Dwarf_P_Die ownerdie,
+        char *string_value,
+        Dwarf_Error *error) \fP
+.DE
+The function \f(CWdwarf_add_AT_const_value_string() \fP adds the 
+string value given by \f(CWstring_value\fP as the value of the 
+\f(CWDW_AT_const_value\fP attribute for the \f(CWDIE\fP described 
+by the given \f(CWownerdie\fP.  It returns the \f(CWDwarf_P_Attribute\fP
+descriptor for this attribute on success.  On error, it returns
+\f(CWDW_DLV_BADADDR\fP.
+
+.H 3 "dwarf_add_AT_targ_address()"
+.DS
+\f(CWDwarf_P_Attribute dwarf_add_AT_targ_address(
+        Dwarf_P_Debug dbg,
+        Dwarf_P_Die ownerdie,
+        Dwarf_Half attr,
+        Dwarf_Unsigned pc_value,
+        Dwarf_Signed sym_index,
+        Dwarf_Error *error) \fP
+.DE
+The function \f(CWdwarf_add_AT_targ_address() \fP adds an attribute that
+belongs to the "address" class to the die specified by \f(CWownerdie\fP.  
+The attribute is specified by \f(CWattr\fP, and the object that the 
+\f(CWDIE\fP belongs to is specified by \f(CWdbg\fP.  The relocatable 
+address that is the value of the attribute is specified by \f(CWpc_value\fP. 
+The symbol to be used for relocation is specified by the \f(CWsym_index\fP,
+which is the index of the symbol in the Elf symbol table.
+
+It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute
+on success, and \f(CWDW_DLV_BADADDR\fP on error.
+
+
+.H 3 "dwarf_add_AT_targ_address_b()"
+.DS
+\f(CWDwarf_P_Attribute dwarf_add_AT_targ_address_b(
+        Dwarf_P_Debug dbg,
+        Dwarf_P_Die ownerdie,
+        Dwarf_Half attr,
+        Dwarf_Unsigned pc_value,
+        Dwarf_Unsigned sym_index,
+        Dwarf_Error *error) \fP
+.DE
+The function \f(CWdwarf_add_AT_targ_address_b() \fP 
+is identical to \f(CWdwarf_add_AT_targ_address_b() \fP
+except that \f(CWsym_index() \fP is guaranteed to 
+be large enough that it can contain a pointer to
+arbitrary data (so the caller can pass in a real elf
+symbol index, an arbitrary number, or a pointer
+to arbitrary data).  
+The ability to pass in a pointer thru \f(CWsym_index() \fP
+is only usable with 
+\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP.
+
+The \f(CWpc_value\fP
+is put into the section stream output and
+the \f(CWsym_index\fP is applied to the relocation
+information.
+
+Do not use this function for attr \f(CWDW_AT_high_pc\fP
+if the value to be recorded is an offset (not a pc)
+[ use \f(CWdwarf_add_AT_unsigned_const()\fP  (for example)
+instead].
+
+.H 3 "dwarf_add_AT_dataref()"
+.DS
+\f(CWDwarf_P_Attribute dwarf_add_AT_dataref(
+        Dwarf_P_Debug dbg,
+        Dwarf_P_Die ownerdie,
+        Dwarf_Half attr,
+        Dwarf_Unsigned pc_value,
+        Dwarf_Unsigned sym_index,
+        Dwarf_Error *error) \fP
+.DE
+This is very similar to \f(CWdwarf_add_AT_targ_address_b() \fP
+but results in a different FORM (results in DW_FORM_data4
+or DW_FORM_data8).
+
+Useful for adding relocatable addresses in location lists.
+
+\f(CWsym_index() \fP is guaranteed to
+be large enough that it can contain a pointer to
+arbitrary data (so the caller can pass in a real elf
+symbol index, an arbitrary number, or a pointer
+to arbitrary data).
+The ability to pass in a pointer thru \f(CWsym_index() \fP
+is only usable with
+\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP.
+
+The \f(CWpc_value\fP
+is put into the section stream output and
+the \f(CWsym_index\fP is applied to the relocation
+information.
+
+Do not use this function for \f(CWDW_AT_high_pc\fP, use
+\f(CWdwarf_add_AT_unsigned_const()\fP  [ (for example)
+if the value to be recorded is
+an offset of \f(CWDW_AT_low_pc\fP]
+or \f(CWdwarf_add_AT_targ_address_b()\fP [ if the value
+to be recorded is an address].
+
+.H 3 "dwarf_add_AT_ref_address()"
+.DS
+\f(CWDwarf_P_Attribute dwarf_add_AT_ref_address(
+        Dwarf_P_Debug dbg,
+        Dwarf_P_Die ownerdie,
+        Dwarf_Half attr,
+        Dwarf_Unsigned pc_value,
+        Dwarf_Unsigned sym_index,
+        Dwarf_Error *error) \fP
+.DE
+
+This is very similar to \f(CWdwarf_add_AT_targ_address_b() \fP
+but results in a different FORM (results in \f(CWDW_FORM_ref_addr\fP
+being generated).
+
+Useful for  \f(CWDW_AT_type\fP and \f(CWDW_AT_import\fP attributes.
+
+\f(CWsym_index() \fP is guaranteed to
+be large enough that it can contain a pointer to
+arbitrary data (so the caller can pass in a real elf
+symbol index, an arbitrary number, or a pointer
+to arbitrary data).
+The ability to pass in a pointer thru \f(CWsym_index() \fP
+is only usable with
+\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP.
+
+The \f(CWpc_value\fP
+is put into the section stream output and
+the \f(CWsym_index\fP is applied to the relocation
+information.
+
+Do not use this function for \f(CWDW_AT_high_pc\fP.
+
+
+.H 3 "dwarf_add_AT_unsigned_const()"
+.DS
+\f(CWDwarf_P_Attribute dwarf_add_AT_unsigned_const(
+        Dwarf_P_Debug dbg,
+        Dwarf_P_Die ownerdie,
+        Dwarf_Half attr,
+        Dwarf_Unsigned value,
+        Dwarf_Error *error) \fP
+.DE
+The function \f(CWdwarf_add_AT_unsigned_const() \fP adds an attribute
+with a \f(CWDwarf_Unsigned\fP value belonging to the "constant" class, 
+to the \f(CWDIE\fP specified by \f(CWownerdie\fP.  The object that
+the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP.  The attribute
+is specified by \f(CWattr\fP, and its value is specified by \f(CWvalue\fP.
+
+It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute
+on success, and \f(CWDW_DLV_BADADDR\fP on error.
+
+.H 3 "dwarf_add_AT_signed_const()"
+.DS
+\f(CWDwarf_P_Attribute dwarf_add_AT_signed_const(
+        Dwarf_P_Debug dbg,
+        Dwarf_P_Die ownerdie,
+        Dwarf_Half attr,
+        Dwarf_Signed value,
+        Dwarf_Error *error) \fP
+.DE
+The function \f(CWdwarf_add_AT_signed_const() \fP adds an attribute
+with a \f(CWDwarf_Signed\fP value belonging to the "constant" class,
+to the \f(CWDIE\fP specified by \f(CWownerdie\fP.  The object that
+the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP.  The attribute
+is specified by \f(CWattr\fP, and its value is specified by \f(CWvalue\fP.
+
+It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute
+on success, and \f(CWDW_DLV_BADADDR\fP on error.
+
+.H 3 "dwarf_add_AT_reference()"
+.DS
+\f(CWDwarf_P_Attribute dwarf_add_AT_reference(
+        Dwarf_P_Debug dbg,
+        Dwarf_P_Die ownerdie,
+        Dwarf_Half attr,
+        Dwarf_P_Die otherdie,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_add_AT_reference()\fP adds an attribute
+with a value that is a reference to another \f(CWDIE\fP in the
+same compilation-unit to the \f(CWDIE\fP specified by \f(CWownerdie\fP.  
+The object that the \f(CWDIE\fP belongs to is specified by \f(CWdbg\fP.  
+The attribute is specified by \f(CWattr\fP, and the other \f(CWDIE\fP
+being referred to is specified by \f(CWotherdie\fP.
+
+This cannot generate DW_FORM_ref_addr references to
+\f(CWDIE\fPs in other compilation units.
+
+It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute
+on success, and \f(CWDW_DLV_BADADDR\fP on error.
+
+.H 3 "dwarf_add_AT_flag()"
+.DS
+\f(CWDwarf_P_Attribute dwarf_add_AT_flag(
+        Dwarf_P_Debug dbg,
+        Dwarf_P_Die ownerdie,
+        Dwarf_Half attr,
+        Dwarf_Small flag,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_add_AT_flag()\fP adds an attribute with 
+a \f(CWDwarf_Small\fP value belonging to the "flag" class, to the 
+\f(CWDIE\fP specified by \f(CWownerdie\fP.  The object that the 
+\f(CWDIE\fP belongs to is specified by \f(CWdbg\fP.  The attribute
+is specified by \f(CWattr\fP, and its value is specified by \f(CWflag\fP.
+
+It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute
+on success, and \f(CWDW_DLV_BADADDR\fP on error.
+
+.H 3 "dwarf_add_AT_string()"
+.DS
+\f(CWDwarf_P_Attribute dwarf_add_AT_string(
+        Dwarf_P_Debug dbg,
+        Dwarf_P_Die ownerdie,
+        Dwarf_Half attr,
+        char *string,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_add_AT_string()\fP adds an attribute with a 
+value that is a character string to the \f(CWDIE\fP specified by 
+\f(CWownerdie\fP.  The object that the \f(CWDIE\fP belongs to is 
+specified by \f(CWdbg\fP.  The attribute is specified by \f(CWattr\fP, 
+and its value is pointed to by \f(CWstring\fP.
+
+It returns the \f(CWDwarf_P_Attribute\fP descriptor for the attribute
+on success, and \f(CWDW_DLV_BADADDR\fP on error.
+
+.H 2 "Expression Creation"
+The following functions are used to convert location expressions into
+blocks so that attributes with values that are location expressions
+can store their values as a \f(CWDW_FORM_blockn\fP value.  This is for 
+both .debug_info and .debug_loc expression blocks.
+
+To create an expression, first call \f(CWdwarf_new_expr()\fP to get 
+a \f(CWDwarf_P_Expr\fP descriptor that can be used to build up the
+block containing the location expression.  Then insert the parts of 
+the expression in prefix order (exactly the order they would be 
+interpreted in in an expression interpreter).  The bytes of the 
+expression are then built-up as specified by the user.
+
+.H 3 "dwarf_new_expr()"
+.DS
+\f(CWDwarf_Expr dwarf_new_expr(
+        Dwarf_P_Debug dbg,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_new_expr()\fP creates a new expression area 
+in which a location expression stream can be created.  It returns
+a \f(CWDwarf_P_Expr\fP descriptor that can be used to add operators
+to build up a location expression.  It returns \f(CWNULL\fP on error.
+
+.H 3 "dwarf_add_expr_gen()"
+.DS
+\f(CWDwarf_Unsigned dwarf_add_expr_gen(
+        Dwarf_P_Expr expr,
+        Dwarf_Small opcode, 
+        Dwarf_Unsigned val1,
+        Dwarf_Unsigned val2,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_add_expr_gen()\fP takes an operator specified
+by \f(CWopcode\fP, along with up to 2 operands specified by \f(CWval1\fP,
+and \f(CWval2\fP, converts it into the \f(CWDwarf\fP representation and 
+appends the bytes to the byte stream being assembled for the location
+expression represented by \f(CWexpr\fP.  The first operand, if present,
+to \f(CWopcode\fP is in \f(CWval1\fP, and the second operand, if present,
+is in \f(CWval2\fP.  Both the operands may actually be signed or unsigned
+depending on \f(CWopcode\fP.  It returns the number of bytes in the byte
+stream for \f(CWexpr\fP currently generated, i.e. after the addition of
+\f(CWopcode\fP.  It returns \f(CWDW_DLV_NOCOUNT\fP on error.
+
+The function \f(CWdwarf_add_expr_gen()\fP works for all opcodes except
+those that have a target address as an operand.  This is because it does
+not set up a relocation record that is needed when target addresses are
+involved.
+
+.H 3 "dwarf_add_expr_addr()"
+.DS
+\f(CWDwarf_Unsigned dwarf_add_expr_addr(
+        Dwarf_P_Expr expr,
+        Dwarf_Unsigned address,
+        Dwarf_Signed sym_index,
+        Dwarf_Error *error)\fP 
+.DE
+The function \f(CWdwarf_add_expr_addr()\fP is used to add the
+\f(CWDW_OP_addr\fP opcode to the location expression represented
+by the given \f(CWDwarf_P_Expr\fP descriptor, \f(CWexpr\fP.  The
+value of the relocatable address is given by \f(CWaddress\fP.  
+The symbol to be used for relocation is given by \f(CWsym_index\fP,
+which is the index of the symbol in the Elf symbol table.  It returns 
+the number of bytes in the byte stream for \f(CWexpr\fP currently 
+generated, i.e. after the addition of the \f(CWDW_OP_addr\fP operator.  
+It returns \f(CWDW_DLV_NOCOUNT\fP on error.
+
+.H 3 "dwarf_add_expr_addr_b()"
+.DS
+\f(CWDwarf_Unsigned dwarf_add_expr_addr_b(
+        Dwarf_P_Expr expr,
+        Dwarf_Unsigned address,
+        Dwarf_Unsigned sym_index,
+        Dwarf_Error *error)\fP 
+.DE
+The function \f(CWdwarf_add_expr_addr_f()\fP is
+identical to \f(CWdwarf_add_expr_addr()\fP
+except that \f(CWsym_index() \fP is guaranteed to
+be large enough that it can contain a pointer to
+arbitrary data (so the caller can pass in a real elf
+symbol index, an arbitrary number, or a pointer
+to arbitrary data).
+The ability to pass in a pointer thru \f(CWsym_index() \fP
+is only usable with
+\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP.
+
+
+
+.H 3 "dwarf_expr_current_offset()"
+.DS
+\f(CWDwarf_Unsigned dwarf_expr_current_offset(
+        Dwarf_P_Expr expr, 
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_expr_current_offset()\fP returns the number
+of bytes currently in the byte stream for the location expression
+represented by the given \fCW(Dwarf_P_Expr\fP descriptor, \f(CWexpr\fP.
+It returns \f(CWDW_DLV_NOCOUNT\fP on error.
+
+.H 3 "dwarf_expr_into_block()"
+.DS
+\f(CWDwarf_Addr dwarf_expr_into_block(
+        Dwarf_P_Expr expr,
+        Dwarf_Unsigned *length,
+        Dwarf_Error *error)\fP 
+.DE
+The function \f(CWdwarf_expr_into_block()\fP returns the address
+of the start of the byte stream generated for the location expression
+represented by the given \f(CWDwarf_P_Expr\fP descriptor, \f(CWexpr\fP.
+The length of the byte stream is returned in the location pointed to
+by \f(CWlength\fP.  It returns \f(CWDW_DLV_BADADDR\fP on error.
+
+.H 2 "Line Number Operations"
+These are operations on the .debug_line section.  
+They provide 
+information about instructions in the program and the source 
+lines the instruction come from.  
+Typically, code is generated 
+in contiguous blocks, which may then be relocated as contiguous 
+blocks.  
+To make the provision of relocation information more 
+efficient, the information is recorded in such a manner that only
+the address of the start of the block needs to be relocated.  
+This is done by providing the address of the first instruction 
+in a block using the function \f(CWdwarf_lne_set_address()\fP.  
+Information about the instructions in the block are then added 
+using the function \f(CWdwarf_add_line_entry()\fP, which specifies
+offsets from the address of the first instruction.  
+The end of 
+a contiguous block is indicated by calling the function 
+\f(CWdwarf_lne_end_sequence()\fP.
+.P
+Line number operations do not support
+\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP.
+
+.H 3 "dwarf_add_line_entry()"
+.DS
+\f(CWDwarf_Unsigned dwarf_add_line_entry(
+        Dwarf_P_Debug dbg,
+        Dwarf_Unsigned file_index, 
+        Dwarf_Addr code_offset,
+        Dwarf_Unsigned lineno, 
+        Dwarf_Signed column_number,
+        Dwarf_Bool is_source_stmt_begin, 
+        Dwarf_Bool is_basic_block_begin,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_add_line_entry()\fP adds an entry to the
+section containing information about source lines.  
+It specifies
+in \f(CWcode_offset\fP, the offset from the address set using
+\f(CWdwarfdwarf_lne_set_address()\fP, of the address of the first
+instruction in a contiguous block.  
+The source file that gave rise
+to the instruction is specified by \f(CWfile_index\fP, the source
+line number is specified by \f(CWlineno\fP, and the source column 
+number is specified by \f(CWcolumn_number\fP
+(column numbers begin at 1)
+(if the source column is unknown, specify 0).  
+\f(CWfile_index\fP 
+is the index of the source file in a list of source files which is 
+built up using the function \f(CWdwarf_add_file_decl()\fP. 
+
+\f(CWis_source_stmt_begin\fP is a boolean flag that is true only if 
+the instruction at \f(CWcode_address\fP is the first instruction in 
+the sequence generated for the source line at \f(CWlineno\fP.  Similarly,
+\f(CWis_basic_block_begin\fP is a boolean flag that is true only if
+the instruction at \f(CWcode_address\fP is the first instruction of
+a basic block.
+
+It returns \f(CW0\fP on success, and \f(CWDW_DLV_NOCOUNT\fP on error.
+
+.H 3 "dwarf_lne_set_address()"
+.DS
+\f(CWDwarf_Unsigned dwarf_lne_set_address(
+        Dwarf_P_Debug dbg,
+        Dwarf_Addr offs,
+        Dwarf_Unsigned symidx,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_lne_set_address()\fP sets the target address
+at which a contiguous block of instructions begin.  Information about
+the instructions in the block is added to .debug_line using calls to
+\f(CWdwarfdwarf_add_line_entry()\fP which specifies the offset of each
+instruction in the block relative to the start of the block.  This is 
+done so that a single relocation record can be used to obtain the final
+target address of every instruction in the block.
+
+The relocatable address of the start of the block of instructions is
+specified by \f(CWoffs\fP.  The symbol used to relocate the address 
+is given by \f(CWsymidx\fP, which is normally the index of the symbol in the
+Elf symbol table. 
+
+It returns \f(CW0\fP on success, and \f(CWDW_DLV_NOCOUNT\fP on error.
+
+.H 3 "dwarf_lne_end_sequence()"
+.DS
+\f(CWDwarf_Unsigned dwarf_lne_end_sequence(
+        Dwarf_P_Debug dbg,
+	Dwarf_Addr    address;
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_lne_end_sequence()\fP indicates the end of a
+contiguous block of instructions.  
+\f(CWaddress()\fP 
+should be just higher than the end of the last address in the 
+sequence of instructions.
+block of instructions, a call to \f(CWdwarf_lne_set_address()\fP will 
+have to be made to set the address of the start of the target address
+of the block, followed by calls to \f(CWdwarf_add_line_entry()\fP for
+each of the instructions in the block.
+
+It returns \f(CW0\fP on success, and \f(CWDW_DLV_NOCOUNT\fP on error.
+
+.H 3 "dwarf_add_directory_decl()"
+.DS
+\f(CWDwarf_Unsigned dwarf_add_directory_decl(
+        Dwarf_P_Debug dbg,
+        char *name,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_add_directory_decl()\fP adds the string 
+specified by \f(CWname\fP to the list of include directories in 
+the statement program prologue of the .debug_line section.  
+The
+string should therefore name a directory from which source files
+have been used to create the present object.
+
+It returns the index of the string just added, in the list of include 
+directories for the object.  
+This index is then used to refer to this 
+string.  
+It returns \f(CWDW_DLV_NOCOUNT\fP on error.
+
+.H 3 "dwarf_add_file_decl()"
+.DS
+\f(CWDwarf_Unsigned dwarf_add_file_decl(
+        Dwarf_P_Debug dbg,
+        char *name,
+        Dwarf_Unsigned dir_idx,
+        Dwarf_Unsigned time_mod,
+        Dwarf_Unsigned length,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_add_file_decl()\fP adds the name of a source
+file that contributed to the present object.  
+The name of the file is
+specified by \f(CWname\fP (which must not be the empty string
+or a null pointer, it must point to 
+a string with length greater than 0).  
+In case the name is not a fully-qualified
+pathname, it is prefixed with the name of the directory specified by
+\f(CWdir_idx\fP.  
+\f(CWdir_idx\fP is the index of the directory to be
+prefixed in the list builtup using \f(CWdwarf_add_directory_decl()\fP.
+
+\f(CWtime_mod\fP gives the time at which the file was last modified,
+and \f(CWlength\fP gives the length of the file in bytes.
+
+It returns the index of the source file in the list built up so far
+using this function, on success.  This index can then be used to 
+refer to this source file in calls to \f(CWdwarf_add_line_entry()\fP.
+On error, it returns \f(CWDW_DLV_NOCOUNT\fP.
+
+.H 2 "Fast Access (aranges) Operations"
+These functions operate on the .debug_aranges section.  
+
+.H 3 "dwarf_add_arange()"
+.DS
+\f(CWDwarf_Unsigned dwarf_add_arange(
+        Dwarf_P_Debug dbg,
+        Dwarf_Addr begin_address,
+        Dwarf_Unsigned length,
+        Dwarf_Signed symbol_index,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_add_arange()\fP adds another address range 
+to be added to the section 
+containing address range information, .debug_aranges.  
+The relocatable start address of the range is 
+specified by \f(CWbegin_address\fP, and the length of the address 
+range is specified by \f(CWlength\fP.  
+The relocatable symbol to be 
+used to relocate the start of the address range is specified by 
+\f(CWsymbol_index\fP, which is normally 
+the index of the symbol in the Elf
+symbol table.
+
+It returns a non-zero value on success, and \f(CW0\fP on error.
+
+.H 3 "dwarf_add_arange_b()"
+.DS
+\f(CWDwarf_Unsigned dwarf_add_arange_b(
+        Dwarf_P_Debug dbg,
+        Dwarf_Addr begin_address,
+        Dwarf_Unsigned length,
+        Dwarf_Unsigned symbol_index,
+	Dwarf_Unsigned end_symbol_index,
+	Dwarf_Addr     offset_from_end_symbol,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_add_arange_b()\fP adds another address range
+to be added to the section containing 
+address range information, .debug_aranges.  
+
+If
+\f(CWend_symbol_index is not zero\fP
+we are using two symbols to create a length
+(must be \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP to be useful)
+.sp
+.in +2
+\f(CWbegin_address\fP
+is the offset from the symbol specified by
+\f(CWsymbol_index\fP .
+\f(CWoffset_from_end_symbol\fP
+is the offset from the symbol specified by
+\f(CWend_symbol_index\fP.
+\f(CWlength\fP is ignored.
+This begin-end pair will be show up in the
+relocation array returned by
+\f(CWdwarf_get_relocation_info() \fP
+as a
+\f(CWdwarf_drt_first_of_length_pair\fP
+and
+\f(CWdwarf_drt_second_of_length_pair\fP
+pair of relocation records.
+The consuming application will turn that pair into
+something conceptually identical to
+.sp
+.nf
+.in +4
+ .word end_symbol + offset_from_end - \\
+   ( start_symbol + begin_address)
+.in -4
+.fi
+.sp
+The reason offsets are allowed on the begin and end symbols
+is to allow the caller to re-use existing labels
+when the labels are available
+and the corresponding offset is known  
+(economizing on the number of labels in use).
+The  'offset_from_end - begin_address'
+will actually be in the binary stream, not the relocation
+record, so the app processing the relocation array
+must read that stream value into (for example)
+net_offset and actually emit something like
+.sp
+.nf
+.in +4
+ .word end_symbol - start_symbol + net_offset
+.in -4
+.fi
+.sp
+.in -2
+
+If
+\f(CWend_symbol_index\fP is zero
+we must be given a length
+(either
+\f(CWDW_DLC_STREAM_RELOCATIONS\fP
+or
+\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP
+):
+.sp
+.in +2
+The relocatable start address of the range is
+specified by \f(CWbegin_address\fP, and the length of the address
+range is specified by \f(CWlength\fP.  
+The relocatable symbol to be
+used to relocate the start of the address range is specified by
+\f(CWsymbol_index\fP, which is normally
+the index of the symbol in the Elf
+symbol table.
+The 
+\f(CWoffset_from_end_symbol\fP
+is ignored.
+.in -2
+
+
+It returns a non-zero value on success, and \f(CW0\fP on error.
+
+
+.H 2 "Fast Access (pubnames) Operations"
+These functions operate on the .debug_pubnames section.
+.sp
+.H 3 "dwarf_add_pubname()"
+.DS
+\f(CWDwarf_Unsigned dwarf_add_pubname(
+        Dwarf_P_Debug dbg,
+        Dwarf_P_Die die,
+        char *pubname_name,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_add_pubname()\fP adds the pubname specified
+by \f(CWpubname_name\fP to the section containing pubnames, i.e.
+  .debug_pubnames.  The \f(CWDIE\fP that represents the function
+being named is specified by \f(CWdie\fP.  
+
+It returns a non-zero value on success, and \f(CW0\fP on error.
+
+.H 2 "Fast Access (weak names) Operations"
+These functions operate on the .debug_weaknames section.
+
+.H 3 "dwarf_add_weakname()"
+.DS
+\f(CWDwarf_Unsigned dwarf_add_weakname(
+        Dwarf_P_Debug dbg,
+        Dwarf_P_Die die,
+        char *weak_name,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_add_weakname()\fP adds the weak name specified
+by \f(CWweak_name\fP to the section containing weak names, i.e.  
+ .debug_weaknames.  The \f(CWDIE\fP that represents the function
+being named is specified by \f(CWdie\fP.  
+
+It returns a non-zero value on success, and \f(CW0\fP on error.
+
+.H 2 "Static Function Names Operations"
+The .debug_funcnames section contains the names of static function 
+names defined in the object, and also the offsets of the \f(CWDIE\fPs
+that represent the definitions of the functions in the .debug_info 
+section.
+
+.H 3 "dwarf_add_funcname()"
+.DS
+\f(CWDwarf_Unsigned dwarf_add_funcname(
+        Dwarf_P_Debug dbg,
+        Dwarf_P_Die die,
+        char *func_name,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_add_funcname()\fP adds the name of a static
+function specified by \f(CWfunc_name\fP to the section containing the
+names of static functions defined in the object represented by \f(CWdbg\fP.
+The \f(CWDIE\fP that represents the definition of the function is
+specified by \f(CWdie\fP.
+
+It returns a non-zero value on success, and \f(CW0\fP on error.
+
+.H 2 "File-scope User-defined Type Names Operations"
+The .debug_typenames section contains the names of file-scope
+user-defined types in the given object, and also the offsets 
+of the \f(CWDIE\fPs that represent the definitions of the types 
+in the .debug_info section.
+
+.H 3 "dwarf_add_typename()"
+.DS
+\f(CWDwarf_Unsigned dwarf_add_typename(
+        Dwarf_P_Debug dbg,
+        Dwarf_P_Die die,
+        char *type_name,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_add_typename()\fP adds the name of a file-scope
+user-defined type specified by \f(CWtype_name\fP to the section that 
+contains the names of file-scope user-defined type.  The object that 
+this section belongs to is specified by \f(CWdbg\fP.  The \f(CWDIE\fP 
+that represents the definition of the type is specified by \f(CWdie\fP.
+
+It returns a non-zero value on success, and \f(CW0\fP on error.
+
+.H 2 "File-scope Static Variable Names Operations"
+The .debug_varnames section contains the names of file-scope static
+variables in the given object, and also the offsets of the \f(CWDIE\fPs
+that represent the definition of the variables in the .debug_info
+section.
+
+.H 3 "dwarf_add_varname()"
+.DS
+\f(CWDwarf_Unsigned dwarf_add_varname(
+        Dwarf_P_Debug dbg,
+        Dwarf_P_Die die,
+        char *var_name,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_add_varname()\fP adds the name of a file-scope
+static variable specified by \f(CWvar_name\fP to the section that 
+contains the names of file-scope static variables defined by the 
+object represented by \f(CWdbg\fP.  The \f(CWDIE\fP that represents
+the definition of the static variable is specified by \f(CWdie\fP.
+
+It returns a non-zero value on success, and \f(CW0\fP on error.
+
+.H 2 "Macro Information Creation"
+All strings passed in by the caller are copied by these
+functions, so the space in which the caller provides the strings
+may be ephemeral (on the stack, or immediately reused or whatever)
+without this causing any difficulty.
+
+.H 3 "dwarf_def_macro()"
+.DS
+\f(CWint dwarf_def_macro(Dwarf_P_Debug dbg,
+	Dwarf_Unsigned lineno,
+	char *name
+	char *value,
+        Dwarf_Error *error);\fP
+.DE
+Adds a macro definition.
+The \f(CWname\fP argument should include the parentheses
+and parameter names if this is a function-like macro.
+Neither string should contain extraneous whitespace.
+\f(CWdwarf_def_macro()\fP adds the mandated space after the
+name and before the value  in the
+output DWARF section(but does not change the
+strings pointed to by the arguments).
+If this is a definition before any files are read,
+\f(CWlineno\fP should be 0.
+Returns \f(CWDW_DLV_ERROR\fP
+and sets \f(CWerror\fP
+if there is an error.
+Returns \f(CWDW_DLV_OK\fP if the call was successful.
+
+
+.H 3 "dwarf_undef_macro()"
+.DS
+\f(CWint dwarf_undef_macro(Dwarf_P_Debug dbg,
+	Dwarf_Unsigned lineno,
+	char *name,
+        Dwarf_Error *error);\fP
+.DE
+Adds a macro un-definition note.
+If this is a definition before any files are read,
+\f(CWlineno\fP should be 0.
+Returns \f(CWDW_DLV_ERROR\fP
+and sets \f(CWerror\fP
+if there is an error.
+Returns \f(CWDW_DLV_OK\fP if the call was successful.
+
+
+.H 3 "dwarf_start_macro_file()"
+.DS
+\f(CWint dwarf_start_macro_file(Dwarf_P_Debug dbg,
+	Dwarf_Unsigned lineno,
+        Dwarf_Unsigned fileindex,
+        Dwarf_Error *error);\fP
+.DE
+\f(CWfileindex\fP is an index in the .debug_line header: 
+the index of
+the file name.
+See the function \f(CWdwarf_add_file_decl()\fP.
+The \f(CWlineno\fP should be 0 if this file is
+the file of the compilation unit source itself
+(which, of course, is not a #include in any
+file).
+Returns \f(CWDW_DLV_ERROR\fP
+and sets \f(CWerror\fP
+if there is an error.
+Returns \f(CWDW_DLV_OK\fP if the call was successful.
+
+
+.H 3 "dwarf_end_macro_file()"
+.DS
+\f(CWint dwarf_end_macro_file(Dwarf_P_Debug dbg,
+        Dwarf_Error *error);\fP
+.DE
+Returns \f(CWDW_DLV_ERROR\fP
+and sets \f(CWerror\fP
+if there is an error.
+Returns \f(CWDW_DLV_OK\fP if the call was successful.
+
+.H 3 "dwarf_vendor_ext()"
+.DS
+\f(CWint dwarf_vendor_ext(Dwarf_P_Debug dbg,
+    Dwarf_Unsigned constant,
+    char *         string,
+    Dwarf_Error*   error); \fP
+.DE
+The meaning of the \f(CWconstant\fP and the\f(CWstring\fP
+in the macro info section
+are undefined by DWARF itself, but the string must be
+an ordinary null terminated string.
+This call is not an extension to DWARF. 
+It simply enables storing
+macro information as specified in the DWARF document.
+Returns \f(CWDW_DLV_ERROR\fP
+and sets \f(CWerror\fP
+if there is an error.
+Returns \f(CWDW_DLV_OK\fP if the call was successful.
+
+
+.H 2 "Low Level (.debug_frame) operations"
+These functions operate on the .debug_frame section.  Refer to 
+\f(CWlibdwarf.h\fP for the register names and register assignment 
+mapping.  Both of these are necessarily machine dependent.
+
+.H 3 "dwarf_new_fde()"
+.DS
+\f(CWDwarf_P_Fde dwarf_new_fde(
+        Dwarf_P_Debug dbg, 
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_new_fde()\fP returns a new \f(CWDwarf_P_Fde\fP
+descriptor that should be used to build a complete \f(CWFDE\fP.  
+Subsequent calls to routines that build up the \f(CWFDE\fP should use
+the same \f(CWDwarf_P_Fde\fP descriptor.
+
+It returns a valid \f(CWDwarf_P_Fde\fP descriptor on success, and
+\f(CWDW_DLV_BADADDR\fP on error.
+
+.H 3 "dwarf_add_frame_cie()"
+.DS
+\f(CWDwarf_Unsigned dwarf_add_frame_cie(
+        Dwarf_P_Debug dbg,
+        char *augmenter, 
+        Dwarf_Small code_align,
+        Dwarf_Small data_align, 
+        Dwarf_Small ret_addr_reg, 
+        Dwarf_Ptr init_bytes, 
+        Dwarf_Unsigned init_bytes_len,
+        Dwarf_Error *error);\fP
+.DE
+The function 
+\f(CWdwarf_add_frame_cie()\fP 
+creates a \f(CWCIE\fP,
+and returns an index to it, that should be used to refer to this
+\f(CWCIE\fP.  
+\f(CWCIE\fPs are used by \f(CWFDE\fPs to setup
+initial values for frames.  
+The augmentation string for the \f(CWCIE\fP
+is specified by \f(CWaugmenter\fP.  
+The code alignment factor,
+data alignment factor, and the return address register for the
+\f(CWCIE\fP are specified by \f(CWcode_align\fP, \f(CWdata_align\fP,
+and \f(CWret_addr_reg\fP respectively.  
+\f(CWinit_bytes\fP points
+to the bytes that represent the instructions for the \f(CWCIE\fP
+being created, and \f(CWinit_bytes_len\fP specifies the number
+of bytes of instructions.
+
+There is no convenient way to generate the  \f(CWinit_bytes\fP
+stream. 
+One just
+has to calculate it by hand or separately
+generate something with the 
+correct sequence and use dwarfdump -v and elfdump -h  and some
+kind of hex dumper to see the bytes.
+This is a serious inconvenience! 
+
+It returns an index to the \f(CWCIE\fP just created on success.
+On error it returns \f(CWDW_DLV_NOCOUNT\fP.
+
+.H 3 "dwarf_add_frame_fde()"
+.DS
+\f(CWDwarf_Unsigned dwarf_add_frame_fde(
+        Dwarf_P_Debug dbg,
+        Dwarf_P_Fde fde,
+        Dwarf_P_Die die,
+        Dwarf_Unsigned cie,
+        Dwarf_Addr virt_addr,
+        Dwarf_Unsigned  code_len,
+        Dwarf_Unsigned sym_idx,
+        Dwarf_Error* error)\fP
+.DE
+The function \f(CWdwarf_add_frame_fde()\fP adds the \f(CWFDE\fP
+specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the
+object represented by the given \f(CWdbg\fP.  
+\f(CWdie\fP specifies
+the \f(CWDIE\fP that represents the function whose frame information
+is specified by the given \f(CWfde\fP.  
+\f(CWcie\fP specifies the
+index of the \f(CWCIE\fP that should be used to setup the initial
+conditions for the given frame.  
+
+
+It returns an index to the given \f(CWfde\fP.
+
+
+.H 3 "dwarf_add_frame_fde_b()"
+.DS
+\f(CWDwarf_Unsigned dwarf_add_frame_fde_b(
+        Dwarf_P_Debug dbg,
+        Dwarf_P_Fde fde,
+        Dwarf_P_Die die,
+        Dwarf_Unsigned cie,
+        Dwarf_Addr virt_addr,
+        Dwarf_Unsigned  code_len,
+        Dwarf_Unsigned sym_idx,
+	Dwarf_Unsigned sym_idx_of_end,
+	Dwarf_Addr     offset_from_end_sym,
+        Dwarf_Error* error)\fP
+.DE
+This function is like 
+\f(CWdwarf_add_frame_fde()\fP 
+except that 
+\f(CWdwarf_add_frame_fde_b()\fP 
+has new arguments to allow use
+with
+\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP.
+
+The function \f(CWdwarf_add_frame_fde_b()\fP 
+adds the 
+\f(CWFDE\fP
+specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the
+object represented by the given \f(CWdbg\fP.  
+\f(CWdie\fP specifies
+the \f(CWDIE\fP that represents the function whose frame information
+is specified by the given \f(CWfde\fP.  
+\f(CWcie\fP specifies the
+index of the \f(CWCIE\fP that should be used to setup the initial
+conditions for the given frame.  
+\f(CWvirt_addr\fP represents the
+relocatable address at which the code for the given function begins,
+and \f(CWsym_idx\fP gives the index of the relocatable symbol to
+be used to relocate this address (\f(CWvirt_addr\fP that is).
+\f(CWcode_len\fP specifies the size in bytes of the machine instructions
+for the given function.
+
+If \f(CWsym_idx_of_end\fP is zero 
+(may  be 
+\f(CWDW_DLC_STREAM_RELOCATIONS\fP 
+or
+\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP 
+):
+.sp
+.in +2
+\f(CWvirt_addr\fP represents the
+relocatable address at which the code for the given function begins,
+and \f(CWsym_idx\fP gives the index of the relocatable symbol to
+be used to relocate this address (\f(CWvirt_addr\fP that is).
+\f(CWcode_len\fP 
+specifies the size in bytes of the machine instructions
+for the given function.
+\f(CWsym_idx_of_end\fP
+and
+\f(CWoffset_from_end_sym\fP
+are unused.
+.in -2
+.sp
+
+
+If \f(CWsym_idx_of_end\fP is non-zero 
+(must be \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP to be useful):
+.sp
+.in +2
+\f(CWvirt_addr\fP
+is the offset from the symbol specified by
+\f(CWsym_idx\fP .
+\f(CWoffset_from_end_sym\fP
+is the offset from the symbol specified by
+\f(CWsym_idx_of_end\fP.
+\f(CWcode_len\fP is ignored.
+This begin-end pair will be show up in the
+relocation array returned by
+\f(CWdwarf_get_relocation_info() \fP
+as a
+\f(CWdwarf_drt_first_of_length_pair\fP
+and
+\f(CWdwarf_drt_second_of_length_pair\fP
+pair of relocation records.
+The consuming application will turn that pair into
+something conceptually identical to
+.sp
+.nf
+.in +4
+ .word end_symbol + begin - \\
+   ( start_symbol + offset_from_end)
+.in -4
+.fi
+.sp
+The reason offsets are allowed on the begin and end symbols
+is to allow the caller to re-use existing labels
+when the labels are available
+and the corresponding offset is known
+(economizing on the number of labels in use).
+The  'offset_from_end - begin_address'
+will actually be in the binary stream, not the relocation
+record, so the app processing the relocation array
+must read that stream value into (for example)
+net_offset and actually emit something like
+.sp
+.nf
+.in +4
+ .word end_symbol - start_symbol + net_offset
+.in -4
+.fi
+.sp
+.in -2
+
+It returns an index to the given \f(CWfde\fP.
+
+On error, it returns \f(CWDW_DLV_NOCOUNT\fP.
+
+.H 3 "dwarf_add_frame_info_b()"
+.DS
+\f(CWDwarf_Unsigned dwarf_add_frame_info_b(
+        Dwarf_P_Debug   dbg,
+        Dwarf_P_Fde     fde,
+        Dwarf_P_Die     die,
+        Dwarf_Unsigned  cie,
+        Dwarf_Addr      virt_addr,
+        Dwarf_Unsigned  code_len,
+        Dwarf_Unsigned  sym_idx,
+	Dwarf_Unsigned  end_symbol_index,
+        Dwarf_Addr      offset_from_end_symbol,
+	Dwarf_Signed    offset_into_exception_tables,
+	Dwarf_Unsigned  exception_table_symbol,
+        Dwarf_Error*    error)\fP
+.DE
+The function \f(CWdwarf_add_frame_fde()\fP adds the \f(CWFDE\fP
+specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the
+object represented by the given \f(CWdbg\fP.  
+\f(CWdie\fP specifies
+the \f(CWDIE\fP that represents the function whose frame information
+is specified by the given \f(CWfde\fP.  
+\f(CWcie\fP specifies the
+index of the \f(CWCIE\fP that should be used to setup the initial
+conditions for the given frame.  
+\f(CWoffset_into_exception_tables\fP specifies the
+offset into \f(CW.MIPS.eh_region\fP elf section where the exception tables 
+for this function begins. 
+\f(CWexception_table_symbol\fP  gives the index of 
+the relocatable symbol to be used to relocate this offset.
+
+
+If
+\f(CWend_symbol_index is not zero\fP
+we are using two symbols to create a length
+(must be \f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP to be useful)
+.sp
+.in +2
+\f(CWvirt_addr\fP
+is the offset from the symbol specified by
+\f(CWsym_idx\fP .
+\f(CWoffset_from_end_symbol\fP
+is the offset from the symbol specified by
+\f(CWend_symbol_index\fP.
+\f(CWcode_len\fP is ignored.
+This begin-end pair will be show up in the
+relocation array returned by
+\f(CWdwarf_get_relocation_info() \fP
+as a
+\f(CWdwarf_drt_first_of_length_pair\fP
+and
+\f(CWdwarf_drt_second_of_length_pair\fP
+pair of relocation records.
+The consuming application will turn that pair into
+something conceptually identical to
+.sp
+.nf
+.in +4
+ .word end_symbol + offset_from_end_symbol - \\
+   ( start_symbol + virt_addr)
+.in -4
+.fi
+.sp
+The reason offsets are allowed on the begin and end symbols
+is to allow the caller to re-use existing labels
+when the labels are available
+and the corresponding offset is known  
+(economizing on the number of labels in use).
+The  'offset_from_end - begin_address'
+will actually be in the binary stream, not the relocation
+record, so the app processing the relocation array
+must read that stream value into (for example)
+net_offset and actually emit something like
+.sp
+.nf
+.in +4
+ .word end_symbol - start_symbol + net_offset
+.in -4
+.fi
+.sp
+.in -2
+
+If
+\f(CWend_symbol_index\fP is zero
+we must be given a code_len value
+(either
+\f(CWDW_DLC_STREAM_RELOCATIONS\fP
+or
+\f(CWDW_DLC_SYMBOLIC_RELOCATIONS\fP
+):
+.sp
+.in +2
+The relocatable start address of the range is
+specified by \f(CWvirt_addr\fP, and the length of the address
+range is specified by \f(CWcode_len\fP.  
+The relocatable symbol to be
+used to relocate the start of the address range is specified by
+\f(CWsymbol_index\fP, which is normally
+the index of the symbol in the Elf
+symbol table.
+The 
+\f(CWoffset_from_end_symbol\fP
+is ignored.
+.in -2
+
+
+It returns an index to the given \f(CWfde\fP.
+
+On error, it returns \f(CWDW_DLV_NOCOUNT\fP.
+
+
+.H 3 "dwarf_add_frame_info()"
+
+.DS
+\f(CWDwarf_Unsigned dwarf_add_frame_info(
+        Dwarf_P_Debug dbg,
+        Dwarf_P_Fde fde,
+        Dwarf_P_Die die,
+        Dwarf_Unsigned cie,
+        Dwarf_Addr virt_addr,
+        Dwarf_Unsigned  code_len,
+        Dwarf_Unsigned sym_idx,
+	Dwarf_Signed offset_into_exception_tables,
+	Dwarf_Unsigned exception_table_symbol,
+        Dwarf_Error* error)\fP
+.DE
+The function \f(CWdwarf_add_frame_fde()\fP adds the \f(CWFDE\fP
+specified by \f(CWfde\fP to the list of \f(CWFDE\fPs for the
+object represented by the given \f(CWdbg\fP.  \f(CWdie\fP specifies
+the \f(CWDIE\fP that represents the function whose frame information
+is specified by the given \f(CWfde\fP.  \f(CWcie\fP specifies the
+index of the \f(CWCIE\fP that should be used to setup the initial
+conditions for the given frame.  \f(CWvirt_addr\fP represents the
+relocatable address at which the code for the given function begins,
+and \f(CWsym_idx\fP gives the index of the relocatable symbol to
+be used to relocate this address (\f(CWvirt_addr\fP that is).
+\f(CWcode_len\fP specifies the size in bytes of the machine instructions
+for the given function. \f(CWoffset_into_exception_tables\fP specifies the
+offset into \f(CW.MIPS.eh_region\fP elf section where the exception tables 
+for this function begins. \f(CWexception_table_symbol\fP  gives the index of 
+the relocatable symbol to be used to relocate this offset.
+
+It returns an index to the given \f(CWfde\fP.
+
+.H 3 "dwarf_fde_cfa_offset()"
+.DS
+\f(CWDwarf_P_Fde dwarf_fde_cfa_offset(
+        Dwarf_P_Fde fde,
+        Dwarf_Unsigned reg,
+        Dwarf_Signed offset,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_fde_cfa_offset()\fP appends a \f(CWDW_CFA_offset\fP
+operation to the \f(CWFDE\fP, specified by \f(CWfde\fP,  being constructed.  
+The first operand of the \f(CWDW_CFA_offset\fP operation is specified by 
+\f(CWreg\P.  The register specified should not exceed 6 bits.  The second 
+operand of the \f(CWDW_CFA_offset\fP operation is specified by \f(CWoffset\fP.
+
+It returns the given \f(CWfde\fP on success.
+
+It returns \f(CWDW_DLV_BADADDR\fP on error.
+
+.H 3 "dwarf_add_fde_inst()"
+.DS
+\f(CWDwarf_P_Fde dwarf_add_fde_inst(
+        Dwarf_P_Fde fde,
+        Dwarf_Small op,
+        Dwarf_Unsigned val1,
+        Dwarf_Unsigned val2,
+        Dwarf_Error *error)\fP
+.DE
+The function \f(CWdwarf_add_fde_inst()\fP adds the operation specified
+by \f(CWop\fP to the \f(CWFDE\fP specified by \f(CWfde\fP.  Upto two
+operands can be specified in \f(CWval1\fP, and \f(CWval2\fP.  Based on
+the operand specified \f(CWLibdwarf\fP decides how many operands are
+meaningful for the operand.  It also converts the operands to the 
+appropriate datatypes (they are passed to \f(CWdwarf_add_fde_inst\fP
+as \f(CWDwarf_Unsigned\fP).
+
+It returns the given \f(CWfde\fP on success, and \f(CWDW_DLV_BADADDR\fP
+on error.
+
+.S
+.TC 1 1 4
+.CS
Binary file tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf2p.1.pdf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarfdefs.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,91 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+/* libdwarfdefs.h
+*/
+
+#ifndef LIBDWARFDEFS_H
+#define LIBDWARFDEFS_H
+
+/* We want __uint32_t and __uint64_t and __int32_t __int64_t
+   properly defined but not duplicated, since duplicate typedefs
+   are not legal C.
+*/
+/*
+ HAVE___UINT32_T
+ HAVE___UINT64_T will be set by configure if
+ our 4 types are predefined in compiler
+*/
+
+
+#if (!defined(HAVE___UINT32_T)) && defined(HAVE___UINT32_T_IN_SGIDEFS_H)
+#include <sgidefs.h>		/* sgidefs.h defines them */
+#define HAVE___UINT32_T 1
+#endif
+
+#if (!defined(HAVE___UINT64_T)) && defined(HAVE___UINT64_T_IN_SGIDEFS_H)
+#include <sgidefs.h>		/* sgidefs.h defines them */
+#define HAVE___UINT64_T 1
+#endif
+
+
+#if (!defined(HAVE___UINT32_T)) &&   \
+	defined(HAVE_SYS_TYPES_H) &&   \
+	defined(HAVE___UINT32_T_IN_SYS_TYPES_H)
+#  include <sys/types.h>
+#define HAVE___UINT32_T 1
+#endif
+
+#if (!defined(HAVE___UINT64_T)) &&   \
+	defined(HAVE_SYS_TYPES_H) &&   \
+	defined(HAVE___UINT64_T_IN_SYS_TYPES_H)
+#  include <sys/types.h>
+#define HAVE___UINT64_T 1
+#endif
+
+#ifndef HAVE___UINT32_T
+typedef int __int32_t;
+typedef unsigned __uint32_t;
+#define HAVE___UINT32_T 1
+#endif
+
+#ifndef HAVE___UINT64_T
+typedef long long __int64_t;
+typedef unsigned long long __uint64_t;
+#define HAVE___UINT64_T 1
+#endif
+
+#endif /* LIBDWARFDEFS_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/malloc_check.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,339 @@
+/*
+
+  Copyright (C) 2005 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+/* malloc_check.c For checking dealloc completeness. 
+
+   This code is as simple as possible and works ok for
+   reasonable size allocation counts.
+
+   It treats allocation as global, and so will not
+   work very well if an application opens more than one
+   Dwarf_Debug.
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>		/* for exit() and various malloc
+				   prototypes */
+#include "config.h"
+#include "dwarf_incl.h"
+#include "malloc_check.h"
+#ifdef  WANT_LIBBDWARF_MALLOC_CHECK
+
+/* To turn off printing every entry, just change the define
+   to set PRINT_MALLOC_DETAILS 0.
+*/
+#define PRINT_MALLOC_DETAILS 0
+
+#define MC_TYPE_UNKNOWN 0
+#define MC_TYPE_ALLOC 1
+#define MC_TYPE_DEALLOC 2
+
+struct mc_data_s {
+    struct mc_data_s *mc_prev;
+    unsigned long mc_address;	/* Assumes this is large enough to hold 
+				   a pointer! */
+
+    long mc_alloc_number;	/* Assigned in order by when record
+				   created. */
+    unsigned char mc_alloc_code;	/* Allocation code, libdwarf. */
+    unsigned char mc_type;
+    unsigned char mc_dealloc_noted;	/* Used on an ALLOC node. */
+    unsigned char mc_dealloc_noted_count;	/* Used on an ALLOC
+						   node. */
+};
+
+/* 
+   
+   
+*/
+#define HASH_TABLE_SIZE 10501
+static struct mc_data_s *mc_data_hash[HASH_TABLE_SIZE];
+static long mc_data_list_size = 0;
+
+static char *alloc_type_name[MAX_DW_DLA + 1] = {
+    "",
+    "DW_DLA_STRING",
+    "DW_DLA_LOC",
+    "DW_DLA_LOCDESC",
+    "DW_DLA_ELLIST",
+    "DW_DLA_BOUNDS",
+    "DW_DLA_BLOCK",
+    "DW_DLA_DEBUG",
+    "DW_DLA_DIE",
+    "DW_DLA_LINE",
+    "DW_DLA_ATTR",
+    "DW_DLA_TYPE",
+    "DW_DLA_SUBSCR",
+    "DW_DLA_GLOBAL",
+    "DW_DLA_ERROR",
+    "DW_DLA_LIST",
+    "DW_DLA_LINEBUF",
+    "DW_DLA_ARANGE",
+    "DW_DLA_ABBREV",
+    "DW_DLA_FRAME_OP",
+    "DW_DLA_CIE",
+    "DW_DLA_FDE",
+    "DW_DLA_LOC_BLOCK",
+    "DW_DLA_FRAME_BLOCK",
+    "DW_DLA_FUNC",
+    "DW_DLA_TYPENAME",
+    "DW_DLA_VAR",
+    "DW_DLA_WEAK",
+    "DW_DLA_ADDR",
+    "DW_DLA_ABBREV_LIST",
+    "DW_DLA_CHAIN",
+    "DW_DLA_CU_CONTEXT",
+    "DW_DLA_FRAME",
+    "DW_DLA_GLOBAL_CONTEXT",
+    "DW_DLA_FILE_ENTRY",
+    "DW_DLA_LINE_CONTEXT",
+    "DW_DLA_LOC_CHAIN",
+    "DW_DLA_HASH_TABLE",
+    "DW_DLA_FUNC_CONTEXT",
+    "DW_DLA_TYPENAME_CONTEXT",
+    "DW_DLA_VAR_CONTEXT",
+    "DW_DLA_WEAK_CONTEXT",
+    "DW_DLA_PUBTYPES_CONTEXT"
+	/* Don't forget to expand this list if the list of codes
+	   expands. */
+};
+
+static unsigned
+hash_address(unsigned long addr)
+{
+    unsigned long a = addr >> 2;
+
+    return a % HASH_TABLE_SIZE;
+}
+
+#if PRINT_MALLOC_DETAILS
+static void
+print_alloc_dealloc_detail(unsigned long addr,
+			   int code, char *whichisit)
+{
+    fprintf(stderr,
+	    "%s  addr 0x%lx code %d (%s) entry %ld\n",
+	    whichisit, addr, code, alloc_type_name[code],
+	    mc_data_list_size);
+}
+#else
+#define  print_alloc_dealloc_detail(a,b,c)	/* nothing */
+#endif
+
+/* Create a zeroed struct or die. */
+static void *
+newone(void)
+{
+    struct mc_data_s *newd = malloc(sizeof(struct mc_data_s));
+
+    if (newd == 0) {
+	fprintf(stderr, "out of memory , # %ld\n", mc_data_list_size);
+	exit(1);
+    }
+    memset(newd, 0, sizeof(struct mc_data_s));
+    return newd;
+}
+
+/* Notify checker that get_alloc has allocated user data. */
+void
+dwarf_malloc_check_alloc_data(void *addr_in, unsigned char code)
+{
+    struct mc_data_s *newd = newone();
+    unsigned long addr = (unsigned long) addr_in;
+    struct mc_data_s **base = &mc_data_hash[hash_address(addr)];
+
+    print_alloc_dealloc_detail(addr, code, "alloc   ");
+    newd->mc_address = addr;
+    newd->mc_alloc_code = code;
+    newd->mc_type = MC_TYPE_ALLOC;
+    newd->mc_alloc_number = mc_data_list_size;
+    newd->mc_prev = *base;
+    *base = newd;
+    newd->mc_alloc_number = mc_data_list_size;
+    mc_data_list_size += 1;
+}
+
+static void
+print_entry(char *msg, struct mc_data_s *data)
+{
+    fprintf(stderr,
+	    "%s: 0x%08lx code %2d (%s) type %s dealloc noted %u ct %u\n",
+	    msg,
+	    (long) data->mc_address,
+	    data->mc_alloc_code,
+	    alloc_type_name[data->mc_alloc_code],
+	    (data->mc_type == MC_TYPE_ALLOC) ? "alloc  " :
+	    (data->mc_type == MC_TYPE_DEALLOC) ? "dealloc" : "unknown",
+	    (unsigned) data->mc_dealloc_noted,
+	    (unsigned) data->mc_dealloc_noted_count);
+}
+
+/* newd is a 'dealloc'.
+*/
+static long
+balanced_by_alloc_p(struct mc_data_s *newd,
+		    long *addr_match_num,
+		    struct mc_data_s **addr_match,
+		    struct mc_data_s *base)
+{
+    struct mc_data_s *cur = base;
+
+    for (; cur; cur = cur->mc_prev) {
+	if (cur->mc_address == newd->mc_address) {
+	    if (cur->mc_type == MC_TYPE_ALLOC) {
+		if (cur->mc_alloc_code == newd->mc_alloc_code) {
+		    *addr_match = cur;
+		    *addr_match_num = cur->mc_alloc_number;
+		    return cur->mc_alloc_number;
+		} else {
+		    /* code mismatch */
+		    *addr_match = cur;
+		    *addr_match_num = cur->mc_alloc_number;
+		    return -1;
+		}
+	    } else {
+		/* Unbalanced new/del */
+		*addr_match = cur;
+		*addr_match_num = cur->mc_alloc_number;
+		return -1;
+	    }
+	}
+    }
+    return -1;
+}
+
+/*  A dealloc is to take place. Ensure it balances an alloc.
+*/
+void
+dwarf_malloc_check_dealloc_data(void *addr_in, unsigned char code)
+{
+    struct mc_data_s *newd = newone();
+    long prev;
+    long addr_match_num = -1;
+    struct mc_data_s *addr_match = 0;
+    unsigned long addr = (unsigned long) addr_in;
+    struct mc_data_s **base = &mc_data_hash[hash_address(addr)];
+
+
+    print_alloc_dealloc_detail(addr, code, "dealloc ");
+    newd->mc_address = (unsigned long) addr;
+    newd->mc_alloc_code = code;
+    newd->mc_type = MC_TYPE_DEALLOC;
+    newd->mc_prev = *base;
+    prev =
+	balanced_by_alloc_p(newd, &addr_match_num, &addr_match, *base);
+    if (prev < 0) {
+	fprintf(stderr,
+		"Unbalanced dealloc at index %ld\n", mc_data_list_size);
+	print_entry("new", newd);
+	fprintf(stderr, "addr-match_num? %ld\n", addr_match_num);
+	if (addr_match) {
+	    print_entry("prev entry", addr_match);
+	    if (addr_match->mc_dealloc_noted > 1) {
+		fprintf(stderr, "Above is Duplicate dealloc!\n");
+	    }
+	}
+	abort();
+	exit(3);
+    }
+    addr_match->mc_dealloc_noted = 1;
+    addr_match->mc_dealloc_noted_count += 1;
+    if (addr_match->mc_dealloc_noted_count > 1) {
+	fprintf(stderr, "Double dealloc entry %ld\n", addr_match_num);
+	print_entry("new dealloc entry", newd);
+	print_entry("bad alloc entry", addr_match);
+    }
+    *base = newd;
+    mc_data_list_size += 1;
+}
+
+/* Final check for leaks.
+*/
+void
+dwarf_malloc_check_complete(char *msg)
+{
+    long i = 0;
+    long total = mc_data_list_size;
+    long hash_slots_used = 0;
+    long max_chain_length = 0;
+
+    fprintf(stderr, "Run complete, %s. %ld entries\n", msg, total);
+    for (; i < HASH_TABLE_SIZE; ++i) {
+	struct mc_data_s *cur = mc_data_hash[i];
+	long cur_chain_length = 0;
+
+	if (cur == 0)
+	    continue;
+	++hash_slots_used;
+	for (; cur; cur = cur->mc_prev) {
+	    ++cur_chain_length;
+	    if (cur->mc_type == MC_TYPE_ALLOC) {
+		if (cur->mc_dealloc_noted) {
+		    if (cur->mc_dealloc_noted > 1) {
+			fprintf(stderr,
+				" Duplicate dealloc! entry %ld\n",
+				cur->mc_alloc_number);
+			print_entry("duplicate dealloc", cur);
+
+		    }
+		    continue;
+		} else {
+		    fprintf(stderr, "malloc no dealloc, entry %ld\n",
+			    cur->mc_alloc_number);
+		    print_entry("dangle", cur);
+		}
+	    } else {
+		/* mc_type is MC_TYPE_DEALLOC, already checked */
+
+	    }
+	}
+	if (cur_chain_length > max_chain_length) {
+	    max_chain_length = cur_chain_length;
+	}
+    }
+    fprintf(stderr, "mc hash table slots=%ld, "
+	    "used=%ld,  maxchain=%ld\n",
+	    (long) HASH_TABLE_SIZE, hash_slots_used, max_chain_length);
+    return;
+}
+
+#else
+
+static void nothing(){}
+
+#endif /* WANT_LIBBDWARF_MALLOC_CHECK */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/malloc_check.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,62 @@
+/*
+
+  Copyright (C) 2005 Silicon Graphics, Inc.  All Rights Reserved.
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement
+  or the like.  Any license provided herein, whether implied or
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with
+  other software, or any other product whatsoever.
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+/* malloc_check.h */
+
+/* A simple libdwarf-aware malloc checker. 
+   define WANT_LIBBDWARF_MALLOC_CHECK and rebuild libdwarf
+   do make a checking-for-alloc-mistakes libdwarf.
+   NOT  recommended for production use.
+
+   When defined, also add malloc_check.c to the list of
+   files in Makefile.
+*/
+
+#undef WANT_LIBBDWARF_MALLOC_CHECK 
+/*#define WANT_LIBBDWARF_MALLOC_CHECK  1 */
+
+#ifdef WANT_LIBBDWARF_MALLOC_CHECK
+
+void dwarf_malloc_check_alloc_data(void * addr,unsigned char code);
+void dwarf_malloc_check_dealloc_data(void * addr,unsigned char code);
+void dwarf_malloc_check_complete(char *wheremsg); /* called at exit of app */
+
+#else /* !WANT_LIBBDWARF_MALLOC_CHECK */
+
+#define dwarf_malloc_check_alloc_data(a,b)  /* nothing */
+#define dwarf_malloc_check_dealloc_data(a,b)  /* nothing */
+#define dwarf_malloc_check_complete(a) /* nothing */
+
+#endif /* WANT_LIBBDWARF_MALLOC_CHECK */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/mips_extensions.mm	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1266 @@
+\."
+\." the following line may be removed if the ff ligature works on your machine
+.lg 0
+\." set up heading formats
+.ds HF 3 3 3 3 3 2 2
+.ds HP +2 +2 +1 +0 +0
+.nr Hs 5
+.nr Hb 5
+\." ==============================================
+\." Put current date in the following at each rev
+.ds vE rev 1.18, 31 March 2005
+\." ==============================================
+\." ==============================================
+.ds | |
+.ds ~ ~
+.ds ' '
+.if t .ds Cw \&\f(CW
+.if n .ds Cw \fB
+.de Cf          \" Place every other arg in Cw font, beginning with first
+.if \\n(.$=1 \&\*(Cw\\$1\fP
+.if \\n(.$=2 \&\*(Cw\\$1\fP\\$2
+.if \\n(.$=3 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP
+.if \\n(.$=4 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4
+.if \\n(.$=5 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP
+.if \\n(.$=6 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6
+.if \\n(.$=7 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP
+.if \\n(.$=8 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8
+.if \\n(.$=9 \&\*(Cw\\$1\fP\\$2\*(Cw\\$3\fP\\$4\*(Cw\\$5\fP\\$6\*(Cw\\$7\fP\\$8\
+*(Cw
+..
+.nr Cl 4
+.SA 1
+.TL
+MIPS Extensions to DWARF Version 2.0
+.AF ""
+.AU "Silicon Graphics Computer Systems"
+.PF "'\*(vE'- \\\\nP -''"
+.AS 1
+This document describes the MIPS/Silicon Graphics extensions 
+to the "DWARF Information Format" (version 2.0.0 dated July 27, 1993).
+DWARF3 draft 8 (or draft 9) is out as of 2005, and
+is mentioned below where applicable.
+MIPS/IRIX compilers emit DWARF2 (with extensions).
+.P
+Rather than alter the base documents to describe the extensions
+we provide this separate document.
+.P
+The extensions documented here are subject to change.
+.P
+It also describes known bugs resulting in incorrect dwarf usage.
+.P
+\*(vE
+
+.AE
+.MT 4
+
+.H 1 "INTRODUCTION"
+.P
+This 
+document describes MIPS extensions 
+to the DWARF debugging information format.  
+The extensions documented here are subject to change at
+any time.
+.H 1 "64 BIT DWARF"
+.P
+The DWARF2 spec has no provision for 64 bit offsets.
+SGI-IRIX/MIPS Elf64 objects contain DWARF 2 with all offsets
+(and addresses) as 64bit values.  
+This non-standard extension was adopted in 1992.
+Nothing in the dwarf itself identifies the dwarf as 64bit.
+This extension 64bit-offset dwarf cannot be mixed with 32bit-offset dwarf
+in a single object or executable, and SGI-IRIX/MIPS compilers
+and tools do not mix the sizes.
+.P
+In 2001 DWARF3 adopted a very different 64bit-offset
+format which can be mixed usefully with 32bit-offset DWARF2 or DWARF3.
+It is not very likely SGI-IRIX/MIPS compilers will switch to the 
+now-standard
+DWARF3 64bit-offset scheme, but such a switch is theoretically
+possible and would be a good idea.
+.P
+SGI-IRIX/MIPS Elf32 objects
+contain DWARF2 with all offsets (and addresses) 32 bits.
+.H 1 "How much symbol information is emitted"
+The following standard DWARF V2 sections may be emitted:
+.AL
+.LI 
+Section .debug_abbrev
+contains
+abbreviations supporting the .debug_info section.
+.LI
+Section .debug_info
+contains
+Debug Information Entries (DIEs).
+.LI 
+Section .debug_frame
+contains
+stack frame descriptions.
+.LI 
+Section .debug_line
+contains
+line number information.
+.LI 
+Section .debug_aranges
+contains
+address range descriptions.
+.LI 
+Section .debug_pubnames
+contains
+names of global functions and data.
+.P
+The following
+are MIPS extensions.
+Theses were created to allow debuggers to
+know names without having to look at
+the .debug_info section.
+.LI 
+Section .debug_weaknames
+is a MIPS extension
+containing .debug_pubnames-like entries describing weak
+symbols.
+.LI 
+Section .debug_funcnames
+is a MIPS extension
+containing .debug_pubnames-like entries describing file-static
+functions (C static functions).
+The gcc extension of nested subprograms (like Pascal)
+adds non-global non-static functions.  These should be treated like
+static functions and gcc should add such to this section
+so that IRIX libexc(3C) will work correctly.
+Similarly, Ada functions which are non-global should be here too
+so that libexc(3C) can work.
+Putting it another way, every function (other than inline code)
+belongs either in .debug_pubnames or in .debug_funcnames
+or else libexc(3C) cannot find the function name.
+.LI 
+Section .debug_varnames
+is a MIPS extension
+containing .debug_pubnames-like entries describing file-static
+data symbols (C static variables).
+.LI 
+Section .debug_typenames
+is a MIPS extension
+containing .debug_pubnames-like entries describing file-level
+types.
+.P
+The following are not currently emitted.
+.LI 
+Section .debug_macinfo
+Macro information is not currently emitted.
+.LI 
+Section .debug_loc
+Location lists are not currently emitted.
+.LI
+Section .debug_str
+The string section is not currently emitted.
+.LE
+.H 2 "Overview of information emitted"
+We emit debug information in 3 flavors.
+We mention C here.
+The situation is essentially identical for f77, f90, and C++.
+.AL
+.LI 
+"default C"
+We emit line information and DIEs for each subprogram.
+But no local symbols and no type information.
+Frame information is output.
+The DW_AT_producer string has the optimization level: for example
+"-O2".
+We put so much in the DW_AT_producer that the string
+is a significant user of space in .debug_info --
+this is perhaps a poor use of space.
+When optimizing the IRIX CC/cc option -DEBUG:optimize_space
+eliminates such wasted space.
+Debuggers only currently use the lack of -g
+of DW_AT_producer
+as a hint as to how a 'step' command should be interpreted, and
+the rest of the string is not used for anything (unless
+a human looks at it for some reason), so if space-on-disk
+is an issue, it is quite appropriate to use -DEBUG:optimize_space
+and save disk space.
+Every function definition (not inline instances though) is mentioned
+in either .debug_pubnames or .debug_funcnames.
+This is crucial to allow libexc(3C) stack-traceback to work and
+show function names (for all languages).
+.LI 
+"C with full symbols"
+All possible info is emitted.
+DW_AT_producer string has all options that might be of interest,
+which includes -D's, -U's, and the -g option.
+These options look like they came from the command line.
+We put so much in the DW_AT_producer that the string
+is a significant user of space in .debug_info.
+this is perhaps a poor use of space.
+Debuggers only currently use the -g
+of DW_AT_producer
+as a hint as to how a 'step' command should be interpreted, and
+the rest of the string is not used for anything (unless
+a human looks at it for some reason).
+Every function definition (not inline instances though) is mentioned
+in either .debug_pubnames or .debug_funcnames.
+This is crucial to allow libexc(3C) stack-traceback to work and
+show function names (for all languages).
+.LI 
+"Assembler (-g, non -g are the same)"
+Frame information is output.
+No type information is emitted, but DIEs are prepared
+for globals.
+.LE
+.H 2 "Detecting 'full symbols' (-g)"
+The debugger depends on the existence of
+the DW_AT_producer string to determine if the
+compilation unit has full symbols or not.
+It looks for -g or -g[123] and accepts these as
+full symbols but an absent -g or a present -g0 
+is taken to mean that only basic symbols are defined and there
+are no local symbols and no type information.
+.P
+In various contexts the debugger will think the program  is
+stripped or 'was not compiled with -g' unless the -g
+is in the DW_AT_producer string.
+.H 2 "DWARF and strip(1)"
+The DWARF section ".debug_frame" is marked SHF_MIPS_NOSTRIP
+and is not stripped by the strip(1) program.
+This is because the section is needed for doing
+stack back traces (essential for C++
+and Ada exception handling).
+.P
+All .debug_* sections are marked with elf type
+SHT_MIPS_DWARF.
+Applications needing to access the various DWARF sections
+must use the section name to discriminate between them. 
+
+.H 2 "Evaluating location expressions"
+When the debugger evaluates location expressions, it does so
+in 2 stages. In stage one it simply looks for the trivial
+location expressions and treats those as special cases.
+.P
+If the location expression is not trivial, it enters stage two.
+In this case it uses a stack to evaluate the expression.
+.P
+If the application is a 32-bit application, it does the operations
+on 32-bit values (address size values).  Even though registers
+can be 64 bits in a 32-bit program all evaluations are done in 
+32-bit quantities, so an attempt to calculate a 32-bit quantity
+by taking the difference of 2 64-bit register values will not
+work.  The notion is that the stack machine is, by the dwarf
+definition, working in address size units.
+.P
+These values are then expanded to 64-bit values (addresses or
+offsets).   This extension does not involve sign-extension.
+.P
+If the application is a 64-bit application, then the stack
+values are all 64 bits and all operations are done on 64 bits.
+.H 3 "The fbreg location op"
+Compilers shipped with IRIX 6.0 and 6.1
+do not emit the fbreg location expression
+and never emit the DW_AT_frame_base attribute that it
+depends on. 
+However, this changes
+with release 6.2 and these are now emitted routinely.
+
+.H 1 "Frame Information"
+.H 2 "Initial Instructions"
+The DWARF V2 spec 
+provides for "initial instructions" in each CIE (page 61,
+section 6.4.1).
+However, it does not say whether there are default
+values for each column (register).
+.P
+Rather than force every CIE to have a long list
+of bytes to initialize all 32 integer registers,
+we define that the default values of all registers
+(as returned by libdwarf in the frame interface)
+are 'same value'.
+This is a good choice for many non-register-windows
+implementations.
+.H 2 "Augmentation string in debug_frame"
+The augmentation string we use in shipped compilers (up thru
+irix6.2) is the empty string.
+IRIX6.2 and later has an augmentation string 
+the empty string ("")
+or "z" or "mti v1" 
+where the "v1" is a version number (version 1).
+.P
+We do not believe that "mti v1" was emitted  as the
+augmentation string in any shipped compiler.
+.P
+.H 3 "CIE processing based on augmentation string:"
+If the augmentation string begins with 'z', then it is followed
+immediately by a unsigned_leb_128 number giving the code alignment factor.
+Next is a signed_leb_128 number giving the data alignment factor.
+Next is a unsigned byte giving the number of the return address register.
+Next is an unsigned_leb_128 number giving the length of the 'augmentation'
+fields  (the length of augmentation bytes, not
+including the unsigned_leb_128 length itself).
+As of release 6.2, the length of the CIE augmentation fields is 0.
+What this means is that it is possible to add new
+augmentations, z1, z2, etc and yet an old consumer to
+understand the entire CIE as it can bypass the
+augmentation it does not understand because the
+length of the augmentation fields is present.
+Presuming of course that all augmentation fields are
+simply additional information, 
+not some 'changing of the meaning of 
+an existing field'.
+Currently there is no CIE data in the augmentation for things
+beginning with 'z'.
+.P
+If the augmentation string is "mti v1" or "" then it is followed
+immediately by a unsigned_leb_128 number giving the code alignment factor.
+Next is a signed_leb_128 number giving the data alignment factor.
+Next is a unsigned byte giving the number of the return address register.
+.P
+If the augmentation string is something else, then the
+code alignment factor is assumed to be 4 and the data alignment
+factor is assumed to be -1 and the return
+address register is assumed to be 31. Arbitrarily.
+The library (libdwarf) assumes it does not understand the rest of the CIE.
+.P
+.H 3 "FDE processing based on augmentation"
+If the CIE augmentation string 
+for an fde begins with 'z'
+then the next FDE field after the address_range field
+is an 
+unsigned_leb_128 number giving the length of the 'augmentation'
+fields, and those fields follow immediately.
+
+.H 4 "FDE augmentation fields"
+.P
+If the CIE augmentation string is "mti v1" or ""
+then the FDE is exactly as described in the Dwarf Document section 6.4.1.
+.P
+Else, if the CIE augmentation string begins with "z"
+then the next field after the FDE augmentation length field
+is a Dwarf_Sword size offset into
+exception tables.
+If the CIE augmentation string does not begin with "z"
+(and is neither "mti v1" nor "")
+the FDE augmentation fields are skipped (not understood).
+Note that libdwarf actually (as of MIPSpro7.3 and earlier)
+only tests that the initial character of the augmentation
+string is 'z', and ignores the rest of the string, if any.
+So in reality the test is for a _prefix_ of 'z'.
+.P
+If the CIE augmentation string neither starts with 'z' nor is ""
+nor is "mti v1" then libdwarf (incorrectly) assumes that the
+table defining instructions start next.  
+Processing (in libdwarf) will be incorrect.
+.H 2 "Stack Pointer recovery from debug_frame"
+There is no identifiable means in
+DWARF2 to say that the stack register is
+recovered by any particular operation.
+A 'register rule' works if the caller's
+stack pointer was copied to another
+register.
+An 'offset(N)' rule works if the caller's
+stack pointer was stored on the stack.
+However if the stack pointer is
+some register value plus/minus some offset,
+there is no means to say this in an FDE.
+For MIPS/IRIX, the recovered stack pointer
+of the next frame up the stack (towards main())
+is simply the CFA value of the current
+frame, and the CFA value is
+precisely a register (value of a register)
+or a register plus offset (value of a register
+plus offset).  This is a software convention.
+.H 1 "egcs dwarf extensions (egcs-1.1.2 extensions)"
+This and following egcs sections describe
+the extensions currently shown in egcs dwarf2.
+Note that egcs has chosen to adopt tag and
+attribute naming as if their choices were
+standard dwarf, not as if they were extensions.
+However, they are properly numbered as extensions.
+
+.H 2 "DW_TAG_format_label             0x4101" 
+For FORTRAN 77, Fortran 90.
+Details of use not defined in egcs source, so
+unclear if used.
+.H 2 "DW_TAG_function_template        0x4102"
+For C++.
+Details of use not defined in egcs source, so
+unclear if used.
+.H 2 "DW_TAG_class_template           0x4103" 
+For C++.
+Details of use not defined in egcs source, so
+unclear if used.
+.H 2 "DW_AT_sf_names                          0x2101"
+Apparently only output in DWARF1, not DWARF2.
+.H 2 "DW_AT_src_info                          0x2102"
+Apparently only output in DWARF1, not DWARF2.
+.H 2 "DW_AT_mac_info                          0x2103"
+Apparently only output in DWARF1, not DWARF2.
+.H 2 "DW_AT_src_coords                        0x2104"
+Apparently only output in DWARF1, not DWARF2.
+.H 2 "DW_AT_body_begin                        0x2105"
+Apparently only output in DWARF1, not DWARF2.
+.H 2 "DW_AT_body_end                          0x2106"
+Apparently only output in DWARF1, not DWARF2.
+
+.H 1 "egcs .eh_frame (non-sgi) (egcs-1.1.2 extensions)"
+egcs-1.1.2 (and earlier egcs)
+emits by default a section named .eh_frame 
+for ia32 (and possibly other platforms) which
+is nearly identical to .debug_frame in format and content.
+This section is used for helping handle C++ exceptions.
+.P
+Because after linking there are sometimes zero-ed out bytes
+at the end of the eh_frame section, the reader code in
+dwarf_frame.c considers a zero cie/fde length as an indication
+that it is the end of the section.
+.P
+.H 2 "CIE_id 0"
+The section is an ALLOCATED section in an executable, and
+is therefore mapped into memory at run time.
+The CIE_pointer (aka CIE_id, section 6.4.1
+of the DWARF2 document) is the field that 
+distinguishes a CIE from an FDE.
+The designers of the egcs .eh_frame section
+decided to make the CIE_id
+be 0 as the CIE_pointer definition is
+.in +2
+the number of bytes from the CIE-pointer in the FDE back to the
+applicable CIE.
+.in -2
+In a dwarf .debug_frame section, the CIE_pointer is the
+offset in .debug_frame of the CIE for this fde, and
+since an offset can be zero of some CIE, the CIE_id
+cannot be 0, but must be all 1 bits .
+Note that the dwarf2.0 spec does specify the value of CIE_id
+as 0xffffffff
+(see section 7.23 of v2.0.0),
+though earlier versions of this extensions document
+incorrectly said it was not specified in the dwarf
+document.
+.H 2 "augmentation eh"
+The augmentation string in each CIE is "eh"
+which, with its following NUL character, aligns
+the following word to a 32bit boundary.
+Following the augmentation string is a 32bit
+word with the address of the __EXCEPTION_TABLE__,
+part of the exception handling data for egcs.
+.H 2 "DW_CFA_GNU_window_save   0x2d"
+This is effectively a flag for architectures with
+register windows, and tells the unwinder code that
+it must look to a previous frame for the
+correct register window set.
+As of this writing, egcs  gcc/frame.c
+indicates this is for SPARC register windows.
+.H 2 "DW_CFA_GNU_args_size     0x2e"
+DW_CFA_GNU_args_size has a single uleb128 argument
+which is the size, in bytes, of the function's stack
+at that point in the function.
+.H 2 "__EXCEPTION_TABLE__"
+A series of 3 32bit word entries by default:
+0 word: low pc address
+1 word: high pc address
+2 word: pointer to exception handler code
+The end of the table is 
+signaled by 2 words  of -1 (not 3 words!).
+.H 1 "Interpretations of the DWARF V2 spec"
+.H 2 "template TAG spellings"
+The DWARF V2 spec spells two attributes in two ways.
+DW_TAG_template_type_param 
+(listed in Figure 1, page 7)
+is spelled DW_TAG_template_type_parameter
+in the body of the document (section 3.3.7, page 28).
+We have adopted the spelling 
+DW_TAG_template_type_param.
+.P
+DW_TAG_template_value_param
+(listed in Figure 1, page 7)
+is spelled DW_TAG_template_value_parameter
+in the body of the document (section 3.3.7, page 28).
+We have adopted the spelling 
+DW_TAG_template_value_parameter.
+.P
+We recognize that the choices adopted are neither consistently
+the longer nor the shorter name.
+This inconsistency was an accident.
+.H 2 DW_FORM_ref_addr confusing
+Section 7.5.4, Attribute Encodings, describes
+DW_FORM_ref_addr.
+The description says the reference is the size of an address
+on the target architecture.
+This is surely a mistake, because on a 16bit-pointer-architecture
+it would mean that the reference could not exceed
+16 bits, which makes only
+a limited amount of  sense as the reference is from one
+part of the dwarf to another, and could (in theory)
+be *on the disk* and not limited to what fits in memory.
+Since MIPS is 32 bit pointers (at the smallest) 
+the restriction is not a problem for MIPS/SGI.
+The 32bit pointer ABIs are limited to 32 bit section sizes
+anyway (as a result of implementation details).
+And the 64bit pointer ABIs currently have the same limit
+as a result of how the compilers and tools are built
+(this has not proven to be a limit in practice, so far).
+.P
+This has been clarified in the DWARF3 spec and the IRIX use
+of DW_FORM_ref_addr being an offset is correct.
+.H 2 "Section .debug_macinfo in a debugger"
+It seems quite difficult, in general, to
+tie specific text(code) addresses to points in the
+stream of macro information for a particular compilation unit.
+So it's been difficult to see how to design a consumer
+interface to libdwarf for macro information.
+.P
+The best (simple to implement, easy for a debugger user to
+understand) candidate seems to be that
+the debugger asks for macros of a given name in a compilation
+unit, and the debugger responds with *all* the macros of that name.
+.H 3 "only a single choice exists"
+If there is exactly one, that is usable in expressions, if the
+debugger is able to evaluate such.
+.H 3 "multiple macros with same name".
+If there are multiple macros with the same name
+in a compilation unit, 
+the debugger (and the debugger user and the application
+programmer) have
+a problem: confusion is quite possible.
+If the macros are simple the
+debugger  user can simply substitute by hand in an expression.
+If the macros are complicated hand substitution will be
+impractical, and the debugger will have to identify the
+choices and let the debugger user choose an interpretation.
+.H 2 "Section 6.1.2 Lookup by address problem"
+Each entry is a beginning-address followed by a length.
+And the distinguished entry 0,0 is used to denote
+the end of a range of entries.
+.P
+This means that one must be careful not to emit a zero length,
+as in a .o (object file) the beginning address of
+a normal entry might be 0 (it is a section offset after all),
+and the resulting 0,0 would be taken as end-of-range, not
+as a valid entry.
+A dwarf dumper would have trouble with such data
+in an object file.
+.P
+In an a.out or shared object (dynamic shared object, DSO)
+no text will be at address zero so in such this problem does
+not arise.
+.H 2 "Section 5.10 Subrange Type Entries problem"
+It is specified that  DW_AT_upper_bound (and lower bound)
+must be signed entries if there is no object type
+info to specify the bound type (Sec 5.10, end of section). 
+One cannot tell (with some
+dwarf constant types) what the signedness is from the
+form itself (like DW_FORM_data1), so it is necessary
+to determine the object and type according to the rules 
+in 5.10 and then if all that fails, the type is signed.
+It's a bit complicated and earlier versions of  mips_extensions
+incorrectly said signedness was not defined.
+.H 2 "Section 5.5.6 Class Template Instantiations problem"
+Lots of room for implementor to canonicalize
+template declarations.  Ie various folks won't agree.
+This is not serious since a given compiler
+will be consistent with itself and  debuggers
+will have to cope!
+.H 2 "Section 2.4.3.4  # 11. operator spelling"  
+DW_OP_add should be DW_OP_plus (page 14)
+(this mistake just one place on the page).
+.H 2 "No clear specification of C++ static funcs"
+There is no clear way to tell if a C++ member function
+is a static member or a non-static member function.
+(dwarf2read.c in gdb 4.18, for example, has this observation)
+.H 2 "Misspelling of DW_AT_const_value"
+Twice in appendix 1, DW_AT_const_value is misspelled
+as DW_AT_constant_value.
+.H 2 "Mistake in Atribute Encodings"
+Section 7.5.4, "Attribute Encodings"
+has a brief discussion of "constant"
+which says there are 6 forms of constants.
+It is incorrect in that it fails to mention (or count)
+the block forms, which are clearly allowed by
+section 4.1 "Data Object Entries" (see entry number 9 in
+the numbered list, on constants).
+.H 2 "DW_OP_bregx"
+The description of DW_OP_bregx in 2.4.3.2 (Register Based
+Addressing) is slightly misleading, in that it
+lists the offset first.
+As section 7.7.1 (Location Expression)
+makes clear, in the encoding the register number
+comes first.
+.H 1 "MIPS attributes"
+.H 2 "DW_AT_MIPS_fde"
+This extension to Dwarf appears only on subprogram TAGs and has as
+its value the offset, in the .debug_frame section, of the fde which
+describes the frame of this function.  It is an optimization of
+sorts to have this present.
+
+.H 2 "DW_CFA_MIPS_advance_loc8 0x1d"
+This obvious extension to dwarf line tables enables encoding of 8 byte
+advance_loc values (for cases when such must be relocatable, 
+and thus must be full length).  Applicable only to 64-bit objects.
+
+.H 2 "DW_TAG_MIPS_loop        0x4081"
+For future use. Not currently emitted.
+Places to be emitted and attributes that this might own
+not finalized.
+
+.H 2 "DW_AT_MIPS_loop_begin   0x2002"
+For future use. Not currently emitted.
+Attribute form and content not finalized.
+
+.H 2 "DW_AT_MIPS_tail_loop_begin  0x2003"
+For future use. Not currently emitted.
+Attribute form and content not finalized.
+
+.H 2 "DW_AT_MIPS_epilog_begin     0x2004"
+For future use. Not currently emitted.
+Attribute form and content not finalized.
+
+.H 2 "DW_AT_MIPS_loop_unroll_factor  0x2005"
+For future use. Not currently emitted.
+Attribute form and content not finalized.
+
+.H 2 "DW_AT_MIPS_software_pipeline_depth   0x2006"
+For future use. Not currently emitted.
+Attribute form and content not finalized.
+.H 2 "DW_AT_MIPS_linkage_name                 0x2007"
+The rules for mangling C++ names are not part of the
+C++ standard and are different for different versions
+of C++.  With this extension, the compiler emits
+both the DW_AT_name for things with mangled names 
+(recall that DW_AT_name is NOT the mangled form)
+and also emits DW_AT_MIPS_linkage_name whose value
+is the mangled name.
+.P
+This makes looking for the mangled name in other linker
+information straightforward.
+It also is passed (by the debugger) to the
+libmangle routines to generate names to present to the
+debugger user.
+.H 2 "DW_AT_MIPS_stride            0x2008"
+F90 allows assumed shape arguments and pointers to describe
+non-contiguous memory. A (runtime) descriptor contains address,
+bounds and stride information - rank and element size is known
+during compilation. The extent in each dimension is given by the
+bounds in a DW_TAG_subrange_type, but the stride cannot be
+represented in conventional dwarf. DW_AT_MIPS_stride was added as
+an attribute of a DW_TAG_subrange_type to describe the
+location of the stride.
+Used in the MIPSpro 7.2 (7.2.1 etc) compilers.
+.P
+If the stride is constant (ie: can be inferred from the type in the
+usual manner) DW_AT_MIPS_stride is absent. 
+.P
+If DW_AT_MIPS_stride is present, the attribute contains a reference
+to a DIE which describes the location holding the stride, and the
+DW_AT_stride_size field of DW_TAG_array_type is ignored if
+present.  The value of the stride is the number of 
+4 byte words between
+elements along that axis.
+.P
+This applies to 
+.nf
+a) Intrinsic types whose size is greater 
+   or equal to 4bytes ie: real*4,integer*8 
+   complex etc, but not character types.
+
+b) Derived types (ie: structs) of any size, 
+   unless all components are of type character.
+.fi
+
+.H 2 "DW_AT_MIPS_abstract_name              0x2009"
+This attribute only appears in a DA_TAG_inlined_subroutine DIE.
+The value of this attribute is a string.
+When IPA inlines a routine and the abstract origin is
+in another compilation unit, there is a problem with putting
+in a reference, since the ordering and timing of the 
+creation of references is unpredicatable with reference to
+the DIE and compilation unit the reference refers to. 
+.P
+Since there may be NO ordering of the compilation units that
+allows a correct reference to be done without some kind of patching,
+and since even getting the information from one place to another
+is a problem, the compiler simply passes the problem on to the debugger.
+.P
+The debugger must match the DW_AT_MIPS_abstract_name 
+in the concrete
+inlined instance DIE 
+with the  DW_AT_MIPS_abstract_name
+in the abstract inlined subroutine DIE.
+.P
+A dwarf-consumer-centric view of this  and other inline
+issues could be expressed as follows:
+.nf
+If DW_TAG_subprogram
+  If has DW_AT_inline is abstract instance root
+  If has DW_AT_abstract_origin, is out-of-line instance
+    of function (need abstract origin for some data)
+    (abstract root in same CU (conceptually anywhere
+    a ref can reach, but reaching outside of CU is
+    a problem for ipa: see DW_AT_MIPS_abstract_name))
+  If has DW_AT_MIPS_abstract_name is abstract instance
+    root( must have DW_AT_inline) and this name is used to
+    match with the abstract root
+
+If DW_TAG_inline_subroutine
+  Is concrete inlined subprogram instance.
+  If has DW_AT_abstract_origin, it is a CU-local inline.
+  If it has DW_AT_MIPS_abstract_name it is an
+    inline whose abstract root is in another file (CU).
+.fi
+
+.H 2 "DW_AT_MIPS_clone_origin               0x200a"
+This attribute appears only in a cloned subroutine.
+The procedure is cloned from the same compilation unit.
+The value of this attribute is a reference to 
+the original routine in this compilation unit.
+.P
+The 'original' routine means the routine which has all the
+original code.  The cloned routines will always have
+been 'specialized' by IPA.   
+A routine with DW_AT_MIPS_clone_origin
+will also have the DW_CC_nocall value of the DW_AT_calling_convention
+attribute.
+
+.H 2 "DW_AT_MIPS_has_inlines               0x200b"
+This attribute  may appear in a DW_TAG_subprogram DIE.
+If present and it has the value True, then the subprogram
+has inlined functions somewhere in the body.
+.P
+By default, at startup, the debugger may not look for 
+inlined functions in scopes inside the outer function.
+.P
+This is a hint to the debugger to look for the inlined functions
+so the debugger can set breakpoints on these in case the user
+requests 'stop in foo' and foo is inlined.
+.H 2 "DW_AT_MIPS_stride_byte                  0x200c"
+Created for f90 pointer and assumed shape
+arrays.
+Used in the MIPSpro 7.2 (7.2.1 etc) compilers.
+A variant of DW_AT_MIPS_stride. 
+This stride is interpreted as a byte count. 
+Used for integer*1 and character arrays
+and arrays of derived type
+whose components are all character.
+.H 2 "DW_AT_MIPS_stride_elem                  0x200d"
+Created for f90 pointer and assumed shape
+arrays.
+Used in the MIPSpro 7.2 (7.2.1 etc) compilers.
+A variant of DW_AT_MIPS_stride. 
+This stride is interpreted as a byte-pair (2 byte) count. 
+Used for integer*2 arrays.
+.H 2 "DW_AT_MIPS_ptr_dopetype                 0x200e"
+See following.
+.H 2 "DW_AT_MIPS_allocatable_dopetype         0x200f"
+See following.
+.H 2 "DW_AT_MIPS_assumed_shape_dopetype       0x2010"
+DW_AT_MIPS_assumed_shape_dopetype, DW_AT_MIPS_allocatable_dopetype,
+and DW_AT_MIPS_ptr_dopetype have an attribute value
+which is a reference to a Fortran 90 Dope Vector.
+These attributes are introduced in MIPSpro7.3.
+They only apply to f90 arrays (where they are
+needed to describe arrays never properly described
+before in debug information).
+C, C++, f77, and most f90 arrays continue to be described
+in standard dwarf.
+.P
+The distinction between these three attributes is the f90 syntax
+distinction: keywords 'pointer' and 'allocatable' with the absence
+of these keywords on an assumed shape array being the third case.
+.P
+A "Dope Vector" is a struct (C struct) which describes
+a dynamically-allocatable array.
+In objects with full debugging the C struct will be
+in the dwarf information (of the f90 object, represented like C).
+A debugger will use the link to find the main struct DopeVector
+and will use that information to decode the dope vector.
+At the outer allocatable/assumed-shape/pointer
+the DW_AT_location points at the dope vector (so debugger
+calculations use that as a base).
+.H 2 "Overview of debugger use of dope vectors"
+Fundamentally, we build two distinct
+representations of the arrays and pointers.
+One, in dwarf, represents the statically-representable
+information (the types and
+variable/type-names, without type size information).
+The other, using dope vectors in memory, represents
+the run-time data of sizes.
+A debugger must process the two representations
+in parallel (and merge them) to deal with  user expressions in
+a debugger.
+.H 2 "Example f90 code for use in explanation"
+[Note
+We want dwarf output with *exactly* 
+this little (arbitrary) example.
+Not yet available.
+end Note]
+Consider the following code.
+.nf
+       type array_ptr
+	  real   :: myvar
+          real, dimension (:), pointer :: ap
+       end type array_ptr
+
+       type (array_ptr), allocatable, dimension (:) :: arrays
+
+       allocate (arrays(20))
+       do i = 1,20
+          allocate (arrays(i)%ap(i))
+       end do
+.fi
+arrays is an allocatable array (1 dimension) whose size is
+not known at compile time (it has
+a Dope Vector).  At run time, the
+allocate statement creats 20 array_ptr dope vectors
+and marks the base arrays dopevector as allocated.
+The myvar variable is just there to add complexity to
+the example :-)
+.nf
+In the loop, arrays(1)%ap(1) 
+    is allocated as a single element array of reals.
+In the loop, arrays(2)%ap(2) 
+    is allocated as an array of two reals.
+...
+In the loop, arrays(20)%ap(20) 
+    is allocated as an array of twenty reals.
+.fi
+.H 2 "the problem with standard dwarf and this example"
+.sp
+In dwarf, there is no way to find the array bounds of arrays(3)%ap,
+for example, (which are 1:3 in f90 syntax)
+since any location expression in an ap array lower bound
+attribute cannot involve the 3 (the 3 is known at debug time and
+does not appear in the running binary, so no way for the
+location expression to get to it).
+And of course the 3 must actually index across the array of
+dope vectors in 'arrays' in our implementation, but that is less of
+a problem than the problem with the '3'.
+.sp
+Plus dwarf has no way to find the 'allocated' flag in the
+dope vector (so the debugger can know when the allocate is done
+for a particular arrays(j)%ap).
+.sp
+Consequently, the calculation of array bounds and indices
+for these dynamically created f90 arrays
+is now pushed of into the debugger, which must know the
+field names and usages of the dope vector C structure and
+use the field offsets etc to find data arrays.
+C, C++, f77, and most f90 arrays continue to be described
+in standard dwarf.
+At the outer allocatable/assumed-shape/pointer
+the DW_AT_location points at the dope vector (so debugger
+calculations use that as a base).
+.P
+It would have been nice to design a dwarf extension
+to handle the above problems, but
+the methods considered to date were not
+any more consistent with standard dwarf than
+this dope vector centric approach: essentially just
+as much work in the debugger appeared necessary either way.
+A better (more dwarf-ish) 
+design would be welcome information.
+
+.H 2 "A simplified sketch of the dwarf information"
+[Note:
+Needs to be written.
+end Note]
+
+.H 2 "A simplified sketch of the dope vector information"
+[Note:
+This one is simplified.
+Details left out that should be here. Amplify.
+end Note]
+This is an overly simplified version of a dope vector,
+presented as an initial hint.
+Full details presented later.
+.nf
+struct simplified{
+  void *base; // pointer to the data this describes
+  long  el_len;
+  int   assoc:1
+  int   ptr_alloc:1
+  int   num_dims:3;
+  struct dims_s {
+    long lb;
+    long ext;
+    long str_m;
+  } dims[7];
+};
+.fi
+Only 'num_dims' elements of dims[] are actually used.
+
+.H 2 "The dwarf information"
+
+Here is dwarf information from the compiler for
+the example above, as printed by dwarfdump(1)
+.nf
+[Note:
+The following may not be the test.
+Having field names with '.' in the name is 
+not such a good idea, as it conflicts with the
+use of '.' in dbx extended naming.
+Something else, like _$, would be much easier
+to work with in dbx (customers won't care about this,
+for the most part, 
+but folks working on dbx will, and in those
+rare circumstances when a customer cares,
+the '.' will be a real problem in dbx.).
+Note that to print something about .base., in dbx one
+would have to do
+	whatis `.base.`
+where that is the grave accent, or back-quote I am using.
+With extended naming one do
+	whatis `.dope.`.`.base.`
+which is hard to type and hard to read.
+end Note]
+
+<2><  388>      DW_TAG_array_type
+                DW_AT_name                  .base.
+                DW_AT_type                  <815>
+                DW_AT_declaration           yes(1)
+<3><  401>      DW_TAG_subrange_type
+                DW_AT_lower_bound           0
+                DW_AT_upper_bound           0
+<2><  405>      DW_TAG_pointer_type
+                DW_AT_type                  <388>
+                DW_AT_byte_size             4
+                DW_AT_address_class         0
+<2><  412>      DW_TAG_structure_type
+                DW_AT_name                  .flds.
+                DW_AT_byte_size             28
+<3><  421>      DW_TAG_member
+                DW_AT_name                  el_len
+                DW_AT_type                  <815>
+                DW_AT_data_member_location  DW_OP_consts 0
+<3><  436>      DW_TAG_member
+                DW_AT_name                  assoc
+                DW_AT_type                  <841>
+                DW_AT_byte_size             0
+                DW_AT_bit_offset            0
+                DW_AT_bit_size              1
+                DW_AT_data_member_location  DW_OP_consts 4
+<3><  453>      DW_TAG_member
+                DW_AT_name                  ptr_alloc
+                DW_AT_type                  <841>
+                DW_AT_byte_size             0
+                DW_AT_bit_offset            1
+                DW_AT_bit_size              1
+                DW_AT_data_member_location  DW_OP_consts 4
+<3><  474>      DW_TAG_member
+                DW_AT_name                  p_or_a
+                DW_AT_type                  <841>
+                DW_AT_byte_size             0
+                DW_AT_bit_offset            2
+                DW_AT_bit_size              2
+                DW_AT_data_member_location  DW_OP_consts 4
+<3><  492>      DW_TAG_member
+                DW_AT_name                  a_contig
+                DW_AT_type                  <841>
+                DW_AT_byte_size             0
+                DW_AT_bit_offset            4
+                DW_AT_bit_size              1
+                DW_AT_data_member_location  DW_OP_consts 4
+<3><  532>      DW_TAG_member
+                DW_AT_name                  num_dims
+                DW_AT_type                  <841>
+                DW_AT_byte_size             0
+                DW_AT_bit_offset            29
+                DW_AT_bit_size              3
+                DW_AT_data_member_location  DW_OP_consts 8
+<3><  572>      DW_TAG_member
+                DW_AT_name                  type_code
+                DW_AT_type                  <841>
+                DW_AT_byte_size             0
+                DW_AT_bit_offset            0
+                DW_AT_bit_size              32
+                DW_AT_data_member_location  DW_OP_consts 16
+<3><  593>      DW_TAG_member
+                DW_AT_name                  orig_base
+                DW_AT_type                  <841>
+                DW_AT_data_member_location  DW_OP_consts 20
+<3><  611>      DW_TAG_member
+                DW_AT_name                  orig_size
+                DW_AT_type                  <815>
+                DW_AT_data_member_location  DW_OP_consts 24
+<2><  630>      DW_TAG_structure_type
+                DW_AT_name                  .dope_bnd.
+                DW_AT_byte_size             12
+<3><  643>      DW_TAG_member
+                DW_AT_name                  lb
+                DW_AT_type                  <815>
+                DW_AT_data_member_location  DW_OP_consts 0
+<3><  654>      DW_TAG_member
+                DW_AT_name                  ext
+                DW_AT_type                  <815>
+                DW_AT_data_member_location  DW_OP_consts 4
+<3><  666>      DW_TAG_member
+                DW_AT_name                  str_m
+                DW_AT_type                  <815>
+                DW_AT_data_member_location  DW_OP_consts 8
+<2><  681>      DW_TAG_array_type
+                DW_AT_name                  .dims.
+                DW_AT_type                  <630>
+                DW_AT_declaration           yes(1)
+<3><  694>      DW_TAG_subrange_type
+                DW_AT_lower_bound           0
+                DW_AT_upper_bound           0
+<2><  698>      DW_TAG_structure_type
+                DW_AT_name                  .dope.
+                DW_AT_byte_size             44
+<3><  707>      DW_TAG_member
+                DW_AT_name                  base
+                DW_AT_type                  <405>
+                DW_AT_data_member_location  DW_OP_consts 0
+<3><  720>      DW_TAG_member
+                DW_AT_name                  .flds
+                DW_AT_type                  <412>
+                DW_AT_data_member_location  DW_OP_consts 4
+<3><  734>      DW_TAG_member
+                DW_AT_name                  .dims.
+                DW_AT_type                  <681>
+                DW_AT_data_member_location  DW_OP_consts 32
+<2><  750>      DW_TAG_variable
+                DW_AT_type                  <815>
+                DW_AT_location              DW_OP_fbreg -32
+                DW_AT_artificial            yes(1)
+<2><  759>      DW_TAG_variable
+                DW_AT_type                  <815>
+                DW_AT_location              DW_OP_fbreg -28
+                DW_AT_artificial            yes(1)
+<2><  768>      DW_TAG_variable
+                DW_AT_type                  <815>
+                DW_AT_location              DW_OP_fbreg -24
+                DW_AT_artificial            yes(1)
+<2><  777>      DW_TAG_array_type
+                DW_AT_type                  <815>
+                DW_AT_declaration           yes(1)
+<3><  783>      DW_TAG_subrange_type
+                DW_AT_lower_bound           <750>
+                DW_AT_count                 <759>
+                DW_AT_MIPS_stride           <768>
+<2><  797>      DW_TAG_variable
+                DW_AT_decl_file             1
+                DW_AT_decl_line             1
+                DW_AT_name                  ARRAY
+                DW_AT_type                  <698>
+                DW_AT_location              DW_OP_fbreg -64 DW_OP_deref
+<1><  815>      DW_TAG_base_type
+                DW_AT_name                  INTEGER_4
+                DW_AT_encoding              DW_ATE_signed
+                DW_AT_byte_size             4
+<1><  828>      DW_TAG_base_type
+                DW_AT_name                  INTEGER_8
+                DW_AT_encoding              DW_ATE_signed
+                DW_AT_byte_size             8
+<1><  841>      DW_TAG_base_type
+                DW_AT_name                  INTEGER*4
+                DW_AT_encoding              DW_ATE_unsigned
+                DW_AT_byte_size             4
+<1><  854>      DW_TAG_base_type
+                DW_AT_name                  INTEGER*8
+                DW_AT_encoding              DW_ATE_unsigned
+                DW_AT_byte_size             8
+
+.fi
+.H 2 "The dope vector structure details"
+A dope vector is the following C struct, "dopevec.h".
+Not all the fields are of use to a debugger.
+It may be that not all fields will show up
+in the f90 dwarf (since not all are of interest to debuggers).
+.nf
+[Note:
+Need details on the use of each field.
+And need to know which are really 32 bits and which
+are 32 or 64.
+end Note]
+The following
+struct 
+is a representation of all the dope vector fields.
+It suppresses irrelevant detail and may not
+exactly match the layout in memory (a debugger must
+examine the dwarf to find the fields, not
+compile this structure into the debugger!).
+.nf
+struct .dope. {
+ void *base;   // pointer to data
+ struct .flds. {
+  long el_len; // length of element in bytes?
+  unsigned int assoc:1;     //means?
+  unsigned int ptr_alloc:1;     //means?
+  unsigned int p_or_a:2;    //means?
+  unsigned int a_contig:1;  // means?
+  unsigned int num_dims: 3; // 0 thru 7
+  unsigned int type_code:32; //values?
+  unsigned int orig_base; //void *? means?
+  long         orig_size; // means?
+ } .flds;
+ 
+ struct .dope_bnd. {
+   long lb   ; // lower bound 
+   long ext  ;  // means?
+   long str_m; // means?
+ } .dims[7];
+}
+.fi
+
+.H 2 "DW_AT_MIPS_assumed_size       0x2011"
+This flag was invented to deal with f90 arrays.
+For example:
+
+.nf
+      pointer (rptr, axx(1))
+      pointer (iptr, ita(*))
+      rptr = malloc (100*8)
+      iptr = malloc (100*4)
+.fi
+
+This flag attribute has the value 'yes' (true, on) if and only if
+the size is unbounded, as iptr is.
+Both may show an explicit upper bound of 1 in the dwarf,
+but this flag notifies the debugger that there is explicitly
+no user-provided size.
+
+So if a user asks for a printout of  the rptr allocated
+array, the default will be of a single entry (as
+there is a user slice bound in the source).
+In contrast, there is no explicit upper bound on the iptr
+(ita) array so the default slice will use the current bound
+(a value calculated from the malloc size, see the dope vector).
+
+Given explicit requests, more of rptr(axx) can me shown
+than the default.
+
+.H 1 "Line information and Source Position"
+DWARF does not define the meaning of the term 'source statement'.
+Nor does it define any way to find the first user-written
+executable code in a function.
+.P
+It does define that a source statement  has a file name,
+a line number, and a column position (see Sec 6.2, Line Number
+Information of the Dwarf Version 2 document).
+We will call those 3 source coordinates a 'source position'
+in this document.  We'll try not to accidentally call the
+source position a 'line number' since that is ambiguous
+as to what it means.
+
+.H 2 "Definition of Statement"
+.P
+A function prolog is a statement.
+.P
+A C, C++, Pascal, or Fortran statement is a statement.
+.P
+Each initialized local variable in C,C++ is a statement
+in that its initialization generates a source position.
+This means that
+	x =3, y=4;
+is two statements.
+.P
+For C, C++:
+The 3 parts a,b,c in for(a;b;c) {d;} are individual statements.
+The condition portion of a while() and do {} while() is
+a statement.  (of course d; can be any number of statements)
+.P
+For Fortran, the controlling expression of a DO loop is a statement.
+Is a 'continue' statement in Fortran a DWARF statement?
+.P
+Each function return, whether user coded or generated by the
+compiler, is a statement.  This is so one can step over (in
+a debugger) the final user-coded statement 
+(exclusive of the return statement if any) in a function
+wile not leaving the function scope.
+.P
+
+.H 2 "Finding The First User Code in a Function"
+
+.nf
+Consider:
+int func(int a)
+{                    /* source position 1 */
+	float b = a; /* source position 2 */
+	int x;       
+	x = b + 2;   /* source position 3 */
+}                    /* source position 4 */
+.fi
+.P
+The DIE for a function gives the address range of the function,
+including function prolog(s) and epilog(s)
+.P
+Since there is no scope block for the outer user scope of a
+function (and thus no beginning address range for the outer
+user scope:  the DWARF committee explicitly rejected the idea
+of having a user scope block)
+it is necessary to use the source position information to find
+the first user-executable statement.
+.P
+This means that the user code for a function must be presumed
+to begin at the code location of the second source position in
+the function address range.
+.P
+If a function has exactly one source position, the function
+presumably consists solely of a return.
+.P
+If a function has exactly two source positions, the function
+may consist of a function prolog and a return or a single user
+statement and a return (there may be no prolog code needed in a
+leaf function).  In this case, there is no way to be sure which
+is the first source position of user code, so the rule is to
+presume that the first address is user code.
+.P
+If a function consists of 3 or more source positions, one
+should assume that the first source position is function prolog and
+the second is the first user executable code.
+
+.H 2 "Using debug_frame Information to find first user statement"
+In addition to the line information, the debug_frame information
+can be
+useful in determining the first user source line.
+.P
+Given that a function has more than 1 source position,
+Find the code location of the second source position, then
+examine the debug_frame information to determine if the Canonical
+Frame Address (cfa) is updated before the second source position
+code location.
+If the cfa is updated, then one can be pretty sure that the
+code for the first source position is function prolog code.
+.P
+Similarly, if the cfa is restored in the code for
+a source position, the source position is likely to
+represent a function exit block.
+
+.H 2 "Debugger Use Of Source Position"
+Command line debuggers, such as dbx and gdb, will ordinarily
+want to consider multiple statements on one line to be a single
+statement: doing otherwise is distressing to users since it
+causes a 'step' command to appear to have no effect.
+.P
+An exception for command line debuggers is in determining the
+first user statement: as detailed above, there one wants to
+consider the full  source position and will want to consider
+the function return a separate statement.  It is difficult to
+make the function return a separate statement 'step' reliably
+however if a function is coded all on one line or if the last
+line of user code before the return  is on the same line as the
+return.
+.P
+A graphical debugger has none of these problems if it simply
+highlights the portion of the line being executed.  In that
+case, stepping will appear natural even stepping within a
+line.
+.H 1 "Known Bugs"
+Up through at least MIPSpro7.2.1
+the compiler has been emitting form DW_FORM_DATA1,2, or 4
+for DW_AT_const_value in DW_TAG_enumerator.
+And dwarfdump and debuggers have read this with dwarf_formudata()
+or form_sdata() and gotten some values incorrect.
+For example, a value of 128 was printed by debuggers as a negative value.
+Since dwarfdump and the compilers were not written to use the
+value the same way, their output differed.
+For negative enumerator values the compiler has been emitting 32bit values
+in a DW_FORM_DATA4.
+The compiler should probably be emitting a DW_FORM_sdata for
+enumerator values.
+And consumers of enumerator values should then call form_sdata().
+However, right now, debuggers should call form_udata() and only if
+it fails, call form_sdata().
+Anything else will break backward compatibility with
+the objects produced earlier.
+.SK
+.S
+.TC 1 1 4
+.CS
Binary file tools/elf4rom/libs/dwarf-20071209/libdwarf/mips_extensions.pdf has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_alloc.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,187 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002,2007 Sun Microsystems, Inc. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "pro_incl.h"
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif /* HAVE_STDLIB_H */
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#include <malloc.h>
+
+/*
+ When each block is allocated, there is a two-word structure
+ allocated at the beginning so the block can go on a list.
+ The address returned is the address *after* the two pointers
+ at the start.  But this allows us to be given a pointer to
+ a generic block, and go backwards to find the list-node.  Then
+ we can remove this block from it's list without the need to search
+ through a linked list in order to remove the node.  It also allows
+ us to 'delete' a memory block without needing the dbg structure.
+ We still need the dbg structure on allocation so that we know which
+ linked list to add the block to.
+
+ Only the allocation of the dbg structure itself cannot use _dwarf_p_get_alloc.
+ That structure should be set up by hand, and the two list pointers
+ should be initialized to point at the node itself.  That initializes
+ the doubly linked list.
+*/
+
+#define LIST_TO_BLOCK(lst) ((void*) (((char *)lst) + sizeof(memory_list_t)))
+#define BLOCK_TO_LIST(blk) ((memory_list_t*) (((char*)blk) - sizeof(memory_list_t)))
+
+
+/*
+  dbg should be NULL only when allocating dbg itself.  In that
+  case we initialize it to an empty circular doubly-linked list.
+*/
+
+Dwarf_Ptr
+_dwarf_p_get_alloc(Dwarf_P_Debug dbg, Dwarf_Unsigned size)
+{
+    void *sp;
+    memory_list_t *lp = NULL;
+    memory_list_t *dbglp = NULL;
+    memory_list_t *nextblock = NULL;
+
+    /* alloc control struct and data block together for performance reasons */
+    lp = (memory_list_t *) malloc(size + sizeof(memory_list_t));
+    if (lp == NULL) {
+	/* should throw an error */
+	return NULL;
+    }
+    
+    /* point to 'size' bytes just beyond lp struct */
+    sp = LIST_TO_BLOCK(lp);
+    memset(sp, 0, size);
+
+    if (dbg == NULL) {
+	lp->next = lp->prev = lp;
+    } else {
+	/* I always have to draw a picture to understand this part. */
+
+	dbglp = BLOCK_TO_LIST(dbg);
+	nextblock = dbglp->next;
+	
+	/* Insert between dbglp and nextblock */
+	dbglp->next = lp;
+	lp->prev = dbglp;
+	lp->next = nextblock;
+	nextblock->prev = lp;
+    }
+
+    return sp;
+}
+
+/*
+  This routine is only here in case a caller of an older version of the
+  library is calling this for some reason.
+  We will clean up any stray blocks when the session is closed.
+  No need to remove this block.  In theory the user might be depending on the fact
+  that we used to just 'free' this.  In theory they might also be
+  passing a block that they got from libdwarf.  So we don't know if we
+  should try to remove this block from our global list.  Safest just to
+  do nothing at this point.
+
+  !!!
+  This function is deprecated!  Don't call it inside libdwarf or outside of it.
+  !!!
+*/
+       
+void
+dwarf_p_dealloc(Dwarf_Small * ptr)
+{
+    return;
+}
+
+/*
+  The dbg structure is not needed here anymore.
+*/
+
+void
+_dwarf_p_dealloc(Dwarf_P_Debug dbg, Dwarf_Small * ptr) /* ARGSUSED */
+{
+  memory_list_t *lp;
+  lp = BLOCK_TO_LIST(ptr);
+
+  /*
+    Remove from a doubly linked, circular list.
+    Read carefully, use a white board if necessary.
+    If this is an empty list, the following statements are no-ops, and
+    will write to the same memory location they read from.
+    This should only happen when we deallocate the dbg structure itself.
+  */
+  
+  lp->prev->next = lp->next;
+  lp->next->prev = lp->prev;
+
+  free((void*)lp);
+}
+
+
+/*
+  This routine deallocates all the nodes on the dbg list,
+  and then deallocates the dbg structure itself.
+*/
+
+void
+_dwarf_p_dealloc_all(Dwarf_P_Debug dbg)
+{
+    memory_list_t *dbglp;
+
+    if (dbg == NULL) {
+	/* should throw an error */
+	return;
+    }
+    
+    dbglp = BLOCK_TO_LIST(dbg);
+    while (dbglp->next != dbglp) {
+        _dwarf_p_dealloc(dbg, LIST_TO_BLOCK(dbglp->next));
+    }
+    if (dbglp->next != dbglp ||
+	dbglp->prev != dbglp) {
+
+	/* should throw error */
+	/* For some reason we couldn't free all the blocks? */
+	return;
+    }
+    _dwarf_p_dealloc(NULL, (void*)dbg);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_alloc.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,42 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+Dwarf_Ptr _dwarf_p_get_alloc(Dwarf_P_Debug, Dwarf_Unsigned);
+
+void _dwarf_p_dealloc(Dwarf_P_Debug dbg, Dwarf_Small * ptr);
+
+void _dwarf_p_dealloc_all(Dwarf_P_Debug dbg);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_arange.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,337 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_ELFACCESS_H
+#include <elfaccess.h>
+#endif
+#include "pro_incl.h"
+#include "pro_arange.h"
+#include "pro_section.h"
+#include "pro_reloc.h"
+
+
+
+/*
+    This function adds another address range 
+    to the list of address ranges for the
+    given Dwarf_P_Debug.  It returns 0 on error,
+    and 1 otherwise.
+*/
+Dwarf_Unsigned
+dwarf_add_arange(Dwarf_P_Debug dbg,
+		 Dwarf_Addr begin_address,
+		 Dwarf_Unsigned length,
+		 Dwarf_Signed symbol_index, Dwarf_Error * error)
+{
+    return dwarf_add_arange_b(dbg, begin_address, length, symbol_index,
+			      /* end_symbol_index */ 0,
+			      /* offset_from_end_sym */ 0,
+			      error);
+}
+
+/*
+    This function adds another address range 
+    to the list of address ranges for the
+    given Dwarf_P_Debug.  It returns 0 on error,
+    and 1 otherwise.
+*/
+Dwarf_Unsigned
+dwarf_add_arange_b(Dwarf_P_Debug dbg,
+		   Dwarf_Addr begin_address,
+		   Dwarf_Unsigned length,
+		   Dwarf_Unsigned symbol_index,
+		   Dwarf_Unsigned end_symbol_index,
+		   Dwarf_Addr offset_from_end_sym, Dwarf_Error * error)
+{
+    Dwarf_P_Arange arange;
+
+    if (dbg == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+	return (0);
+    }
+
+    arange = (Dwarf_P_Arange)
+	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Arange_s));
+    if (arange == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (0);
+    }
+
+    arange->ag_begin_address = begin_address;
+    arange->ag_length = length;
+    arange->ag_symbol_index = symbol_index;
+    arange->ag_end_symbol_index = end_symbol_index;
+    arange->ag_end_symbol_offset = offset_from_end_sym;
+
+    if (dbg->de_arange == NULL)
+	dbg->de_arange = dbg->de_last_arange = arange;
+    else {
+	dbg->de_last_arange->ag_next = arange;
+	dbg->de_last_arange = arange;
+    }
+    dbg->de_arange_count++;
+
+    return (1);
+}
+
+
+int
+_dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg, Dwarf_Error * error)
+{
+    /* Total num of bytes in .debug_aranges section. */
+    Dwarf_Unsigned arange_num_bytes;
+
+    /* 
+       Adjustment to align the start of the actual address ranges on a
+       boundary aligned with twice the address size. */
+    Dwarf_Small remainder;
+
+    /* Total number of bytes excluding the length field. */
+    Dwarf_Unsigned adjusted_length;
+
+    /* Points to first byte of .debug_aranges buffer. */
+    Dwarf_Small *arange;
+
+    /* Fills in the .debug_aranges buffer. */
+    Dwarf_Small *arange_ptr;
+
+    /* Scans the list of address ranges provided by user. */
+    Dwarf_P_Arange given_arange;
+
+    /* Used to fill in 0. */
+    const Dwarf_Signed big_zero = 0;
+
+    int extension_word_size = dbg->de_64bit_extension ? 4 : 0;
+    int uword_size = dbg->de_offset_size;
+    int upointer_size = dbg->de_pointer_size;
+    int res;
+
+
+    /* ***** BEGIN CODE ***** */
+
+    /* Size of the .debug_aranges section header. */
+    arange_num_bytes = extension_word_size + uword_size +	/* Size 
+								   of
+								   length 
+								   field. 
+								 */
+	sizeof(Dwarf_Half) +	/* Size of version field. */
+	uword_size +		/* Size of .debug_info offset. */
+	sizeof(Dwarf_Small) +	/* Size of address size field. */
+	sizeof(Dwarf_Small);	/* Size of segment size field. */
+
+    /* 
+       Adjust the size so that the set of aranges begins on a boundary
+       that aligned with twice the address size.  This is a Libdwarf
+       requirement. */
+    remainder = arange_num_bytes % (2 * upointer_size);
+    if (remainder != 0)
+	arange_num_bytes += (2 * upointer_size) - remainder;
+
+
+    /* Add the bytes for the actual address ranges. */
+    arange_num_bytes += upointer_size * 2 * (dbg->de_arange_count + 1);
+
+    GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_ARANGES],
+	      arange, (unsigned long) arange_num_bytes, error);
+    arange_ptr = arange;
+    if (arange == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (0);
+    }
+    if (extension_word_size) {
+	Dwarf_Word x = DISTINGUISHED_VALUE;
+
+	WRITE_UNALIGNED(dbg, (void *) arange_ptr,
+			(const void *) &x,
+			sizeof(x), extension_word_size);
+	arange_ptr += extension_word_size;
+    }
+
+    /* Write the total length of .debug_aranges section. */
+    adjusted_length = arange_num_bytes - uword_size
+	- extension_word_size;
+    {
+	Dwarf_Unsigned du = adjusted_length;
+
+	WRITE_UNALIGNED(dbg, (void *) arange_ptr,
+			(const void *) &du, sizeof(du), uword_size);
+	arange_ptr += uword_size;
+    }
+
+    /* Write the version as 2 bytes. */
+    {
+	Dwarf_Half verstamp = CURRENT_VERSION_STAMP;
+
+	WRITE_UNALIGNED(dbg, (void *) arange_ptr,
+			(const void *) &verstamp,
+			sizeof(verstamp), sizeof(Dwarf_Half));
+	arange_ptr += sizeof(Dwarf_Half);
+    }
+
+
+    /* Write the .debug_info offset.  This is always 0. */
+    WRITE_UNALIGNED(dbg, (void *) arange_ptr,
+		    (const void *) &big_zero,
+		    sizeof(big_zero), uword_size);
+    arange_ptr += uword_size;
+
+    {
+	unsigned long count = dbg->de_arange_count + 1;
+	int res;
+
+	if (dbg->de_reloc_pair) {
+	    count = (3 * dbg->de_arange_count) + 1;
+	}
+	/* the following is a small optimization: not needed for
+	   correctness */
+	res = _dwarf_pro_pre_alloc_n_reloc_slots(dbg,
+						 DEBUG_ARANGES, count);
+	if (res != DW_DLV_OK) {
+	    {
+		_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+		return (0);
+	    }
+	}
+    }
+
+    /* reloc for .debug_info */
+    res = dbg->de_reloc_name(dbg,
+			     DEBUG_ARANGES,
+			     extension_word_size +
+			     uword_size + sizeof(Dwarf_Half),
+			     dbg->de_sect_name_idx[DEBUG_INFO],
+			     dwarf_drt_data_reloc, uword_size);
+
+    /* Write the size of addresses. */
+    *arange_ptr = dbg->de_pointer_size;
+    arange_ptr++;
+
+    /* 
+       Write the size of segment addresses. This is zero for MIPS
+       architectures. */
+    *arange_ptr = 0;
+    arange_ptr++;
+
+    /* 
+       Skip over the padding to align the start of the actual address
+       ranges to twice the address size. */
+    if (remainder != 0)
+	arange_ptr += (2 * upointer_size) - remainder;
+
+
+
+
+
+    /* The arange address, length are pointer-size fields of the target 
+       machine. */
+    for (given_arange = dbg->de_arange; given_arange != NULL;
+	 given_arange = given_arange->ag_next) {
+
+	/* Write relocation record for beginning of address range. */
+	res = dbg->de_reloc_name(dbg, DEBUG_ARANGES, arange_ptr - arange,	/* r_offset 
+										 */
+				 (long) given_arange->ag_symbol_index,
+				 dwarf_drt_data_reloc, upointer_size);
+	if (res != DW_DLV_OK) {
+	    {
+		_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+		return (0);
+	    }
+	}
+
+	/* Copy beginning address of range. */
+	WRITE_UNALIGNED(dbg, (void *) arange_ptr,
+			(const void *) &given_arange->ag_begin_address,
+			sizeof(given_arange->ag_begin_address),
+			upointer_size);
+	arange_ptr += upointer_size;
+
+	if (dbg->de_reloc_pair &&
+	    given_arange->ag_end_symbol_index != 0 &&
+	    given_arange->ag_length == 0) {
+	    /* symbolic reloc, need reloc for length What if we really
+	       know the length? If so, should use the other part of
+	       'if'. */
+	    Dwarf_Unsigned val;
+
+	    res = dbg->de_reloc_pair(dbg, DEBUG_ARANGES, arange_ptr - arange,	/* r_offset 
+										 */
+				     given_arange->ag_symbol_index,
+				     given_arange->ag_end_symbol_index,
+				     dwarf_drt_first_of_length_pair,
+				     upointer_size);
+	    if (res != DW_DLV_OK) {
+		{
+		    _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+		    return (0);
+		}
+	    }
+
+	    /* arrange pre-calc so assem text can do .word end - begin
+	       + val (gets val from stream) */
+	    val = given_arange->ag_end_symbol_offset -
+		given_arange->ag_begin_address;
+	    WRITE_UNALIGNED(dbg, (void *) arange_ptr,
+			    (const void *) &val,
+			    sizeof(val), upointer_size);
+	    arange_ptr += upointer_size;
+
+	} else {
+	    /* plain old length to copy, no relocation at all */
+	    WRITE_UNALIGNED(dbg, (void *) arange_ptr,
+			    (const void *) &given_arange->ag_length,
+			    sizeof(given_arange->ag_length),
+			    upointer_size);
+	    arange_ptr += upointer_size;
+	}
+    }
+
+    WRITE_UNALIGNED(dbg, (void *) arange_ptr,
+		    (const void *) &big_zero,
+		    sizeof(big_zero), upointer_size);
+
+    arange_ptr += upointer_size;
+    WRITE_UNALIGNED(dbg, (void *) arange_ptr,
+		    (const void *) &big_zero,
+		    sizeof(big_zero), upointer_size);
+    return (int) dbg->de_n_debug_sect;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_arange.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,62 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+/*
+	If ag_end_symbol_index is zero, 
+	ag_length must be known and non-zero.
+
+
+	Deals with length being known costant or fr
+	assembler output, not known.
+
+*/
+
+struct Dwarf_P_Arange_s {
+    Dwarf_Addr ag_begin_address;	/* known address or for
+					   symbolic assem output,
+					   offset of symbol */
+    Dwarf_Addr ag_length;	/* zero or address or offset */
+    Dwarf_Unsigned ag_symbol_index;
+
+    Dwarf_P_Arange ag_next;
+
+    Dwarf_Unsigned ag_end_symbol_index;	/* zero or index/id of end
+					   symbol */
+    Dwarf_Addr ag_end_symbol_offset;	/* known address or for
+					   symbolic assem output,
+					   offset of end symbol */
+
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_die.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,435 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#include <stdio.h>
+#include <string.h>
+#include "pro_incl.h"
+#include "pro_die.h"
+
+#ifndef R_MIPS_NONE
+#define R_MIPS_NONE 0
+#endif
+
+/* adds an attribute to a die */
+void _dwarf_pro_add_at_to_die(Dwarf_P_Die die, Dwarf_P_Attribute attr);
+
+/*----------------------------------------------------------------------------
+	This function creates a new die. 
+	tag: tag of the new die to be created
+	parent,child,left,right: specify neighbors of the new die. Only
+	    one of these may be non-null
+-----------------------------------------------------------------------------*/
+Dwarf_P_Die
+dwarf_new_die(Dwarf_P_Debug dbg,
+	      Dwarf_Tag tag,
+	      Dwarf_P_Die parent,
+	      Dwarf_P_Die child,
+	      Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error)
+{
+    Dwarf_P_Die new_die, ret_die;
+
+    new_die = (Dwarf_P_Die)
+	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Die_s));
+    if (new_die == NULL) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_ALLOC,
+			  (Dwarf_P_Die) DW_DLV_BADADDR);
+    }
+    new_die->di_parent = NULL;
+    new_die->di_left = NULL;
+    new_die->di_right = NULL;
+    new_die->di_child = NULL;
+    new_die->di_tag = tag;
+    new_die->di_dbg = dbg;
+    new_die->di_marker = 0;
+    ret_die = 
+        dwarf_die_link(new_die, parent, child, left, right, error);
+    return ret_die;
+}
+
+/*----------------------------------------------------------------------------
+	This function links up a die to specified neighbors
+	parent,child,left,right: specify neighbors of the new die. Only
+	    one of these may be non-null
+-----------------------------------------------------------------------------*/
+Dwarf_P_Die
+dwarf_die_link(Dwarf_P_Die new_die,
+	       Dwarf_P_Die parent,
+	       Dwarf_P_Die child,
+	       Dwarf_P_Die left, Dwarf_P_Die right, Dwarf_Error * error)
+{
+    int n_nulls;		/* to count # of non null neighbors */
+    Dwarf_P_Die orig;
+
+    n_nulls = 0;
+    if (parent != NULL) {
+        n_nulls++;
+        if (new_die->di_parent != NULL) {
+              DWARF_P_DBG_ERROR(NULL, DW_DLE_LINK_LOOP,
+                    (Dwarf_P_Die) DW_DLV_BADADDR);
+        }
+        new_die->di_parent = parent;
+        if (parent->di_child) {	/* got to traverse the child's siblings 
+				 */
+            Dwarf_P_Die curdie;
+
+            curdie = parent->di_child;
+            orig = curdie;
+            while (curdie->di_right) {
+                curdie = curdie->di_right;
+                if (curdie == orig || curdie == curdie->di_right) {
+                    DWARF_P_DBG_ERROR(NULL, DW_DLE_LINK_LOOP,
+                       (Dwarf_P_Die) DW_DLV_BADADDR);
+                }
+            }
+            curdie->di_right = new_die;	/* attach to sibling list */
+            new_die->di_left = curdie;	/* back pointer */
+	} else
+	    parent->di_child = new_die;
+    }
+    if (child != NULL) {
+        n_nulls++;
+        new_die->di_child = child;
+        if (child->di_parent) {
+	    DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS,
+			      (Dwarf_P_Die) DW_DLV_BADADDR);
+        } else {
+	    child->di_parent = new_die;
+        }
+    }
+    if (left != NULL) {
+	n_nulls++;
+	new_die->di_left = left;
+	if (left->di_right)	/* there's already a right sibl, lets
+				   insert */
+	    new_die->di_right = left->di_right;
+	left->di_right = new_die;
+	/* add parent pointer */
+	if (new_die->di_parent) {
+	    DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS,
+			      (Dwarf_P_Die) DW_DLV_BADADDR);
+	} else
+	    new_die->di_parent = left->di_parent;
+    }
+    if (right != NULL) {
+	n_nulls++;
+	new_die->di_right = right;
+	if (right->di_left)	/* left sibl exists, try inserting */
+	    new_die->di_left = right->di_left;
+	right->di_left = new_die;
+	if (new_die->di_parent) {
+	    DWARF_P_DBG_ERROR(NULL, DW_DLE_PARENT_EXISTS,
+			      (Dwarf_P_Die) DW_DLV_BADADDR);
+	} else
+	    new_die->di_parent = right->di_parent;
+    }
+    if (n_nulls > 1) {		/* multiple neighbors, error */
+	DWARF_P_DBG_ERROR(NULL, DW_DLE_EXTRA_NEIGHBORS,
+			  (Dwarf_P_Die) DW_DLV_BADADDR);
+    }
+    return new_die;
+
+}
+
+Dwarf_Unsigned
+dwarf_add_die_marker(Dwarf_P_Debug dbg,
+		     Dwarf_P_Die die,
+		     Dwarf_Unsigned marker,
+		     Dwarf_Error * error)
+{
+    if (die == NULL) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT);
+    }
+    die->di_marker = marker;
+    return 0;
+}
+
+		     
+Dwarf_Unsigned
+dwarf_get_die_marker(Dwarf_P_Debug dbg,
+		     Dwarf_P_Die die,
+		     Dwarf_Unsigned * marker,
+		     Dwarf_Error * error)
+{
+    if (die == NULL) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT);
+    }
+    *marker = die->di_marker;
+    return 0;
+}
+
+		     
+		     
+
+/*----------------------------------------------------------------------------
+	This function adds a die to dbg struct. It should be called using 
+	the root of all the dies.
+-----------------------------------------------------------------------------*/
+Dwarf_Unsigned
+dwarf_add_die_to_debug(Dwarf_P_Debug dbg,
+		       Dwarf_P_Die first_die, Dwarf_Error * error)
+{
+    if (first_die == NULL) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_DIE_NULL, DW_DLV_NOCOUNT);
+    }
+    if (first_die->di_tag != DW_TAG_compile_unit) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_TAG, DW_DLV_NOCOUNT);
+    }
+    dbg->de_dies = first_die;
+    return 0;
+}
+
+int
+_dwarf_pro_add_AT_stmt_list(Dwarf_P_Debug dbg,
+			    Dwarf_P_Die first_die, Dwarf_Error * error)
+{
+    Dwarf_P_Attribute new_attr;
+    int uwordb_size = dbg->de_offset_size;
+
+    /* Add AT_stmt_list attribute */
+    new_attr = (Dwarf_P_Attribute)
+	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
+    if (new_attr == NULL) {
+	DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, DW_DLV_NOCOUNT);
+    }
+
+    new_attr->ar_attribute = DW_AT_stmt_list;
+    new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form;
+    new_attr->ar_rel_type = dbg->de_offset_reloc;
+
+    new_attr->ar_nbytes = uwordb_size;
+    new_attr->ar_next = NULL;
+    new_attr->ar_reloc_len = uwordb_size;
+    new_attr->ar_data = (char *)
+	_dwarf_p_get_alloc(dbg, uwordb_size);
+    if (new_attr->ar_data == NULL) {
+	DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT);
+    }
+    {
+	Dwarf_Unsigned du = 0;
+
+	WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data,
+			(const void *) &du, sizeof(du), uwordb_size);
+    }
+
+    _dwarf_pro_add_at_to_die(first_die, new_attr);
+    return 0;
+}
+
+/*-----------------------------------------------------------------------------
+	Add AT_name attribute to die
+------------------------------------------------------------------------------*/
+Dwarf_P_Attribute
+dwarf_add_AT_name(Dwarf_P_Die die, char *name, Dwarf_Error * error)
+{
+    Dwarf_P_Attribute new_attr;
+
+    if (die == NULL) {
+	DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL,
+			  (Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+    new_attr = (Dwarf_P_Attribute)
+	_dwarf_p_get_alloc(die->di_dbg,sizeof(struct Dwarf_P_Attribute_s));
+    if (new_attr == NULL) {
+	DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC,
+			  (Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    /* fill in the information */
+    new_attr->ar_attribute = DW_AT_name;
+    /* assume that form is string, no debug_str yet */
+    new_attr->ar_attribute_form = DW_FORM_string;
+    new_attr->ar_nbytes = strlen(name) + 1;
+    new_attr->ar_next = NULL;
+    new_attr->ar_reloc_len = 0;
+    new_attr->ar_data = (char *)
+	_dwarf_p_get_alloc(die->di_dbg, strlen(name)+1);
+    if (new_attr->ar_data == NULL) {
+	DWARF_P_DBG_ERROR(NULL, DW_DLE_STRING_ALLOC,
+			  (Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+    strcpy(new_attr->ar_data, name);
+
+    new_attr->ar_rel_type = R_MIPS_NONE;
+
+    /* add attribute to the die */
+    _dwarf_pro_add_at_to_die(die, new_attr);
+    return new_attr;
+}
+
+
+/*-----------------------------------------------------------------------------
+	Add AT_comp_dir attribute to die
+------------------------------------------------------------------------------*/
+Dwarf_P_Attribute
+dwarf_add_AT_comp_dir(Dwarf_P_Die ownerdie,
+		      char *current_working_directory,
+		      Dwarf_Error * error)
+{
+    Dwarf_P_Attribute new_attr;
+
+    if (ownerdie == NULL) {
+	DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL,
+			  (Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+    new_attr = (Dwarf_P_Attribute)
+	_dwarf_p_get_alloc(ownerdie->di_dbg,sizeof(struct Dwarf_P_Attribute_s));
+    if (new_attr == NULL) {
+	DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC,
+			  (Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    /* fill in the information */
+    new_attr->ar_attribute = DW_AT_comp_dir;
+    /* assume that form is string, no debug_str yet */
+    new_attr->ar_attribute_form = DW_FORM_string;
+    new_attr->ar_nbytes = strlen(current_working_directory) + 1;
+    new_attr->ar_next = NULL;
+    new_attr->ar_reloc_len = 0;
+    new_attr->ar_data = (char *)
+	_dwarf_p_get_alloc(ownerdie->di_dbg, strlen(current_working_directory)+1);
+    if (new_attr->ar_data == NULL) {
+	DWARF_P_DBG_ERROR(NULL, DW_DLE_STRING_ALLOC,
+			  (Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+    strcpy(new_attr->ar_data, current_working_directory);
+
+    new_attr->ar_rel_type = R_MIPS_NONE;
+
+    /* add attribute to the die */
+    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
+    return new_attr;
+}
+
+int
+_dwarf_pro_add_AT_fde(Dwarf_P_Debug dbg,
+		      Dwarf_P_Die die,
+		      Dwarf_Unsigned offset, Dwarf_Error * error)
+{
+    Dwarf_P_Attribute new_attr;
+    int uwordb_size = dbg->de_offset_size;
+
+    if (die == NULL) {
+	DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, -1);
+    }
+    new_attr = (Dwarf_P_Attribute)
+	_dwarf_p_get_alloc(dbg,sizeof(struct Dwarf_P_Attribute_s));
+    if (new_attr == NULL) {
+	DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, -1);
+    }
+
+    /* fill in the information */
+    new_attr->ar_attribute = DW_AT_MIPS_fde;
+    new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form;;
+    new_attr->ar_rel_type = dbg->de_offset_reloc;
+    new_attr->ar_nbytes = uwordb_size;
+    new_attr->ar_next = NULL;
+    new_attr->ar_reloc_len = uwordb_size;
+    new_attr->ar_data = (char *)
+	_dwarf_p_get_alloc(dbg, uwordb_size);
+    if (new_attr->ar_data == NULL) {
+	DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT);
+    }
+    {
+	Dwarf_Unsigned du = offset;
+
+	WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data,
+			(const void *) &du, sizeof(du), uwordb_size);
+    }
+
+    _dwarf_pro_add_at_to_die(die, new_attr);
+
+    return 0;
+}
+
+int
+_dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg,
+			     Dwarf_P_Die die,
+			     Dwarf_Unsigned offset, Dwarf_Error * error)
+{
+    Dwarf_P_Attribute new_attr;
+    int uwordb_size = dbg->de_offset_size;
+
+    if (die == NULL) {
+	DWARF_P_DBG_ERROR(NULL, DW_DLE_DIE_NULL, -1);
+    }
+    new_attr = (Dwarf_P_Attribute)
+        _dwarf_p_get_alloc(dbg,sizeof(struct Dwarf_P_Attribute_s));
+    if (new_attr == NULL) {
+	DWARF_P_DBG_ERROR(NULL, DW_DLE_ATTR_ALLOC, -1);
+    }
+
+    /* fill in the information */
+    new_attr->ar_attribute = DW_AT_macro_info;
+    new_attr->ar_attribute_form = dbg->de_ar_data_attribute_form;
+    new_attr->ar_rel_type = dbg->de_offset_reloc;
+
+    new_attr->ar_nbytes = uwordb_size;
+    new_attr->ar_next = NULL;
+    new_attr->ar_reloc_len = uwordb_size;
+    new_attr->ar_data = (char *)
+        _dwarf_p_get_alloc(dbg, uwordb_size);
+    if (new_attr->ar_data == NULL) {
+	DWARF_P_DBG_ERROR(NULL, DW_DLE_ADDR_ALLOC, DW_DLV_NOCOUNT);
+    }
+    {
+	Dwarf_Unsigned du = offset;
+
+	WRITE_UNALIGNED(dbg, (void *) new_attr->ar_data,
+			(const void *) &du, sizeof(du), uwordb_size);
+    }
+
+    _dwarf_pro_add_at_to_die(die, new_attr);
+
+    return 0;
+}
+
+
+void
+_dwarf_pro_add_at_to_die(Dwarf_P_Die die, Dwarf_P_Attribute attr)
+{
+    if (die->di_last_attr) {
+	die->di_last_attr->ar_next = attr;
+	die->di_last_attr = attr;
+	die->di_n_attr++;
+    } else {
+	die->di_n_attr = 1;
+	die->di_attrs = die->di_last_attr = attr;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_die.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,68 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+
+/* 
+	This struct holds the abbreviation table, before they are written 
+	on disk. Holds a linked list of abbreviations, each consisting of
+	a bitmap for attributes and a bitmap for forms
+*/
+typedef struct Dwarf_P_Abbrev_s *Dwarf_P_Abbrev;
+
+struct Dwarf_P_Abbrev_s {
+    Dwarf_Unsigned abb_idx;	/* index of abbreviation */
+    Dwarf_Tag abb_tag;		/* tag of die */
+    Dwarf_Ubyte abb_children;	/* if children are present */
+    Dwarf_ufixed *abb_attrs;	/* holds names of attrs */
+    Dwarf_ufixed *abb_forms;	/* forms of attributes */
+    int abb_n_attr;		/* num of attrs = # of forms */
+    Dwarf_P_Abbrev abb_next;
+};
+
+/* used in pro_section.c */
+
+int _dwarf_pro_add_AT_fde(Dwarf_P_Debug dbg, Dwarf_P_Die die,
+			  Dwarf_Unsigned offset, Dwarf_Error * error);
+
+int _dwarf_pro_add_AT_stmt_list(Dwarf_P_Debug dbg,
+				Dwarf_P_Die first_die,
+				Dwarf_Error * error);
+
+int _dwarf_pro_add_AT_macro_info(Dwarf_P_Debug dbg,
+				 Dwarf_P_Die first_die,
+				 Dwarf_Unsigned offset,
+				 Dwarf_Error * error);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_encode_nm.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,123 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#include <string.h>
+#include "pro_incl.h"
+
+#define MORE_BYTES      0x80
+#define DATA_MASK       0x7f
+#define DIGIT_WIDTH     7
+#define SIGN_BIT        0x40
+
+
+/*-------------------------------------------------------------
+	Encode val as a leb128. This encodes it as an unsigned 
+	number.
+---------------------------------------------------------------*/
+/* return DW_DLV_ERROR or DW_DLV_OK.
+** space to write leb number is provided by caller, with caller
+** passing length.
+** number of bytes used returned thru nbytes arg
+*/
+int
+_dwarf_pro_encode_leb128_nm(Dwarf_Unsigned val, int *nbytes,
+			    char *space, int splen)
+{
+    char *a;
+    char *end = space + splen;
+
+    a = space;
+    do {
+	unsigned char uc;
+
+	if (a >= end) {
+	    return DW_DLV_ERROR;
+	}
+	uc = val & DATA_MASK;
+	val >>= DIGIT_WIDTH;
+	if (val != 0) {
+	    uc |= MORE_BYTES;
+	}
+	*a = uc;
+	a++;
+    } while (val);
+    *nbytes = a - space;
+    return DW_DLV_OK;
+}
+
+/* return DW_DLV_ERROR or DW_DLV_OK.
+** space to write leb number is provided by caller, with caller
+** passing length.
+** number of bytes used returned thru nbytes arg
+** encodes a signed number.
+*/
+int
+_dwarf_pro_encode_signed_leb128_nm(Dwarf_Signed value, int *nbytes,
+				   char *space, int splen)
+{
+    char *str;
+    Dwarf_Signed sign = -(value < 0);
+    int more = 1;
+    char *end = space + splen;
+
+    str = space;
+
+    do {
+	unsigned char byte = value & DATA_MASK;
+
+	value >>= DIGIT_WIDTH;
+
+	if (str >= end) {
+	    return DW_DLV_ERROR;
+	}
+	/* 
+	 * Remaining chunks would just contain the sign bit, and this chunk
+	 * has already captured at least one sign bit.
+	 */
+	if (value == sign && ((byte & SIGN_BIT) == (sign & SIGN_BIT))) {
+	    more = 0;
+	} else {
+	    byte |= MORE_BYTES;
+	}
+	*str = byte;
+	str++;
+    } while (more);
+    *nbytes = str - space;
+    return DW_DLV_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_encode_nm.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,48 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+/*  Bytes needed to encode a number.
+    Not a tight bound, just a reasonable bound.
+*/
+#define ENCODE_SPACE_NEEDED   (2*sizeof(Dwarf_Unsigned))
+
+
+int _dwarf_pro_encode_leb128_nm(Dwarf_Unsigned val, int *nbytes,
+				char *space, int splen);
+
+int _dwarf_pro_encode_signed_leb128_nm(Dwarf_Signed value, int *nbytes,
+				       char *space, int splen);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_error.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,97 @@
+/*
+
+  Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#ifdef HAVE_ELF_H
+#include <elf.h>
+#endif
+
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include "pro_incl.h"
+
+extern char *_dwarf_errmsgs[];
+
+/* 
+    This function performs error handling as described in the 
+    libdwarf consumer document section 3.  Dbg is the Dwarf_P_debug
+    structure being processed.  Error is a pointer to the pointer
+    to the error descriptor that will be returned.  Errval is an
+    error code listed in dwarf_error.h.
+*/
+void
+_dwarf_p_error(Dwarf_P_Debug dbg,
+	       Dwarf_Error * error, Dwarf_Word errval)
+{
+    Dwarf_Error errptr;
+
+    /* Allow NULL dbg on entry, since sometimes that can happen and we
+       want to report the upper-level error, not this one. */
+    if ((Dwarf_Sword) errval < 0)
+	printf("ERROR VALUE: %ld - %s\n",
+	       (long) errval, _dwarf_errmsgs[-errval - 1]);
+    if (error != NULL) {
+	errptr = (Dwarf_Error)
+	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_Error_s));
+	if (errptr == NULL) {
+	    fprintf(stderr,
+		    "Could not allocate Dwarf_Error structure\n");
+	    abort();
+	}
+	errptr->er_errval = (Dwarf_Sword) errval;
+	*error = errptr;
+	return;
+    }
+
+    if (dbg != NULL && dbg->de_errhand != NULL) {
+	errptr = (Dwarf_Error)
+	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_Error_s));
+	if (errptr == NULL) {
+	    fprintf(stderr,
+		    "Could not allocate Dwarf_Error structure\n");
+	    abort();
+	}
+	errptr->er_errval = (Dwarf_Sword) errval;
+	dbg->de_errhand(errptr, dbg->de_errarg);
+	return;
+    }
+
+    abort();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_error.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,52 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+
+/* Handle error passing in the name of the Dwarf_P_Debug
+   User must supply {} around the macro.
+   Putting the {} here leads to macro uses that don't look like C.
+   The error argument to dwarf_error is hard coded here as 'error'
+*/
+#define DWARF_P_DBG_ERROR(dbg,errval,retval) \
+     _dwarf_p_error(dbg,error,errval); return(retval);
+
+struct Dwarf_Error_s {
+    Dwarf_Sword er_errval;
+};
+
+void _dwarf_p_error(Dwarf_P_Debug dbg, Dwarf_Error * error,
+		    Dwarf_Word errval);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_expr.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,596 @@
+/*
+
+  Copyright (C) 2000,2004,2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#include <stdio.h>
+#include <string.h>
+#include "pro_incl.h"
+#include "pro_expr.h"
+
+/*
+    This function creates a new expression 
+    struct that can be used to build up a
+    location expression.
+*/
+Dwarf_P_Expr
+dwarf_new_expr(Dwarf_P_Debug dbg, Dwarf_Error * error)
+{
+    Dwarf_P_Expr ret_expr;
+
+    if (dbg == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+	return (NULL);
+    }
+
+    ret_expr = (Dwarf_P_Expr)
+	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Expr_s));
+    if (ret_expr == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (NULL);
+    }
+
+    ret_expr->ex_dbg = dbg;
+
+    return (ret_expr);
+}
+
+
+Dwarf_Unsigned
+dwarf_add_expr_gen(Dwarf_P_Expr expr,
+		   Dwarf_Small opcode,
+		   Dwarf_Unsigned val1,
+		   Dwarf_Unsigned val2, Dwarf_Error * error)
+{
+    char encode_buffer[2 * ENCODE_SPACE_NEEDED];	/* 2* since
+							   used to
+							   concatenate
+							   2 leb's
+							   below */
+    char encode_buffer2[ENCODE_SPACE_NEEDED];
+    int res;
+    Dwarf_P_Debug dbg = expr->ex_dbg;
+
+    /* 
+       Give the buffer where the operands are first going to be
+       assembled the largest alignment. */
+    Dwarf_Unsigned operand_buffer[10];
+
+    /* 
+       Size of the byte stream buffer that needs to be memcpy-ed. */
+    int operand_size;
+
+    /* 
+       Points to the byte stream for the first operand, and finally to
+       the buffer that is memcp-ed into the Dwarf_P_Expr_s struct. */
+    Dwarf_Small *operand;
+
+    /* Size of the byte stream for second operand. */
+    int operand2_size;
+
+    /* Points to next byte to be written in Dwarf_P_Expr_s struct. */
+    Dwarf_Small *next_byte_ptr;
+
+    /* Offset past the last byte written into Dwarf_P_Expr_s. */
+    int next_byte_offset;
+
+    /* ***** BEGIN CODE ***** */
+
+    if (expr == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
+	return (DW_DLV_NOCOUNT);
+    }
+
+    if (expr->ex_dbg == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_NOCOUNT);
+    }
+
+    operand = NULL;
+    operand_size = 0;
+
+    switch (opcode) {
+    case DW_OP_reg0:
+    case DW_OP_reg1:
+    case DW_OP_reg2:
+    case DW_OP_reg3:
+    case DW_OP_reg4:
+    case DW_OP_reg5:
+    case DW_OP_reg6:
+    case DW_OP_reg7:
+    case DW_OP_reg8:
+    case DW_OP_reg9:
+    case DW_OP_reg10:
+    case DW_OP_reg11:
+    case DW_OP_reg12:
+    case DW_OP_reg13:
+    case DW_OP_reg14:
+    case DW_OP_reg15:
+    case DW_OP_reg16:
+    case DW_OP_reg17:
+    case DW_OP_reg18:
+    case DW_OP_reg19:
+    case DW_OP_reg20:
+    case DW_OP_reg21:
+    case DW_OP_reg22:
+    case DW_OP_reg23:
+    case DW_OP_reg24:
+    case DW_OP_reg25:
+    case DW_OP_reg26:
+    case DW_OP_reg27:
+    case DW_OP_reg28:
+    case DW_OP_reg29:
+    case DW_OP_reg30:
+    case DW_OP_reg31:
+	break;
+
+    case DW_OP_breg0:
+    case DW_OP_breg1:
+    case DW_OP_breg2:
+    case DW_OP_breg3:
+    case DW_OP_breg4:
+    case DW_OP_breg5:
+    case DW_OP_breg6:
+    case DW_OP_breg7:
+    case DW_OP_breg8:
+    case DW_OP_breg9:
+    case DW_OP_breg10:
+    case DW_OP_breg11:
+    case DW_OP_breg12:
+    case DW_OP_breg13:
+    case DW_OP_breg14:
+    case DW_OP_breg15:
+    case DW_OP_breg16:
+    case DW_OP_breg17:
+    case DW_OP_breg18:
+    case DW_OP_breg19:
+    case DW_OP_breg20:
+    case DW_OP_breg21:
+    case DW_OP_breg22:
+    case DW_OP_breg23:
+    case DW_OP_breg24:
+    case DW_OP_breg25:
+    case DW_OP_breg26:
+    case DW_OP_breg27:
+    case DW_OP_breg28:
+    case DW_OP_breg29:
+    case DW_OP_breg30:
+    case DW_OP_breg31:
+	res = _dwarf_pro_encode_signed_leb128_nm(val1,
+						 &operand_size,
+						 encode_buffer,
+						 sizeof(encode_buffer));
+	if (res != DW_DLV_OK) {
+	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+	    return (DW_DLV_NOCOUNT);
+	}
+	operand = (Dwarf_Small *) encode_buffer;
+	break;
+
+    case DW_OP_regx:
+	res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
+					  encode_buffer,
+					  sizeof(encode_buffer));
+	if (res != DW_DLV_OK) {
+	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+	    return (DW_DLV_NOCOUNT);
+	}
+	operand = (Dwarf_Small *) encode_buffer;
+	break;
+
+    case DW_OP_lit0:
+    case DW_OP_lit1:
+    case DW_OP_lit2:
+    case DW_OP_lit3:
+    case DW_OP_lit4:
+    case DW_OP_lit5:
+    case DW_OP_lit6:
+    case DW_OP_lit7:
+    case DW_OP_lit8:
+    case DW_OP_lit9:
+    case DW_OP_lit10:
+    case DW_OP_lit11:
+    case DW_OP_lit12:
+    case DW_OP_lit13:
+    case DW_OP_lit14:
+    case DW_OP_lit15:
+    case DW_OP_lit16:
+    case DW_OP_lit17:
+    case DW_OP_lit18:
+    case DW_OP_lit19:
+    case DW_OP_lit20:
+    case DW_OP_lit21:
+    case DW_OP_lit22:
+    case DW_OP_lit23:
+    case DW_OP_lit24:
+    case DW_OP_lit25:
+    case DW_OP_lit26:
+    case DW_OP_lit27:
+    case DW_OP_lit28:
+    case DW_OP_lit29:
+    case DW_OP_lit30:
+    case DW_OP_lit31:
+	break;
+
+    case DW_OP_addr:
+	_dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
+	return (DW_DLV_NOCOUNT);
+
+    case DW_OP_const1u:
+    case DW_OP_const1s:
+	operand = (Dwarf_Small *) & operand_buffer[0];
+	WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 1);
+	operand_size = 1;
+	break;
+
+    case DW_OP_const2u:
+    case DW_OP_const2s:
+	operand = (Dwarf_Small *) & operand_buffer[0];
+	WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2);
+	operand_size = 2;
+	break;
+
+    case DW_OP_const4u:
+    case DW_OP_const4s:
+	operand = (Dwarf_Small *) & operand_buffer[0];
+	WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 4);
+	operand_size = 4;
+	break;
+
+    case DW_OP_const8u:
+    case DW_OP_const8s:
+	operand = (Dwarf_Small *) & operand_buffer[0];
+	WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 8);
+	operand_size = 8;
+	break;
+
+    case DW_OP_constu:
+	res = _dwarf_pro_encode_leb128_nm(val1,
+					  &operand_size,
+					  encode_buffer,
+					  sizeof(encode_buffer));
+	if (res != DW_DLV_OK) {
+	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+	    return (DW_DLV_NOCOUNT);
+	}
+	operand = (Dwarf_Small *) encode_buffer;
+	break;
+
+    case DW_OP_consts:
+	res = _dwarf_pro_encode_signed_leb128_nm(val1,
+						 &operand_size,
+						 encode_buffer,
+						 sizeof(encode_buffer));
+	if (res != DW_DLV_OK) {
+	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+	    return (DW_DLV_NOCOUNT);
+	}
+	operand = (Dwarf_Small *) encode_buffer;
+	break;
+
+    case DW_OP_fbreg:
+	res = _dwarf_pro_encode_signed_leb128_nm(val1,
+						 &operand_size,
+						 encode_buffer,
+						 sizeof(encode_buffer));
+	if (res != DW_DLV_OK) {
+	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+	    return (DW_DLV_NOCOUNT);
+	}
+	operand = (Dwarf_Small *) encode_buffer;
+	break;
+
+    case DW_OP_bregx:
+	res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
+					  encode_buffer,
+					  sizeof(encode_buffer));
+	if (res != DW_DLV_OK) {
+	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+	    return (DW_DLV_NOCOUNT);
+	}
+	operand = (Dwarf_Small *) encode_buffer;
+	/* put this one directly into 'operand' at tail of prev value */
+	res = _dwarf_pro_encode_signed_leb128_nm(val2, &operand2_size,
+						 ((char *) operand) +
+						 operand_size,
+						 sizeof
+						 (encode_buffer2));
+	if (res != DW_DLV_OK) {
+	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+	    return (DW_DLV_NOCOUNT);
+	}
+	operand_size += operand2_size;
+
+    case DW_OP_dup:
+    case DW_OP_drop:
+	break;
+
+    case DW_OP_pick:
+	operand = (Dwarf_Small *) & operand_buffer[0];
+	WRITE_UNALIGNED(dbg, operand, (const void *) &val1,
+			sizeof(val1), 1);
+	operand_size = 1;
+	break;
+
+    case DW_OP_over:
+    case DW_OP_swap:
+    case DW_OP_rot:
+    case DW_OP_deref:
+    case DW_OP_xderef:
+	break;
+
+    case DW_OP_deref_size:
+    case DW_OP_xderef_size:
+	operand = (Dwarf_Small *) & operand_buffer[0];
+	WRITE_UNALIGNED(dbg, operand, (const void *) &val1,
+			sizeof(val1), 1);
+	operand_size = 1;
+	break;
+
+    case DW_OP_abs:
+    case DW_OP_and:
+    case DW_OP_div:
+    case DW_OP_minus:
+    case DW_OP_mod:
+    case DW_OP_mul:
+    case DW_OP_neg:
+    case DW_OP_not:
+    case DW_OP_or:
+    case DW_OP_plus:
+	break;
+
+    case DW_OP_plus_uconst:
+	res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
+					  encode_buffer,
+					  sizeof(encode_buffer));
+	if (res != DW_DLV_OK) {
+	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+	    return (DW_DLV_NOCOUNT);
+	}
+	operand = (Dwarf_Small *) encode_buffer;
+	break;
+
+    case DW_OP_shl:
+    case DW_OP_shr:
+    case DW_OP_shra:
+    case DW_OP_xor:
+	break;
+
+    case DW_OP_le:
+    case DW_OP_ge:
+    case DW_OP_eq:
+    case DW_OP_lt:
+    case DW_OP_gt:
+    case DW_OP_ne:
+	break;
+
+    case DW_OP_skip:
+    case DW_OP_bra:
+	/* FIX: unhandled! OP_bra, OP_skip! */
+	_dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
+	return (DW_DLV_NOCOUNT);
+
+    case DW_OP_piece:
+	res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
+					  encode_buffer,
+					  sizeof(encode_buffer));
+	if (res != DW_DLV_OK) {
+	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+	    return (DW_DLV_NOCOUNT);
+	}
+	operand = (Dwarf_Small *) encode_buffer;
+	break;
+
+    case DW_OP_nop:
+	break;
+    case DW_OP_push_object_address:	/* DWARF3 */
+	break;
+    case DW_OP_call2:		/* DWARF3 */
+	operand = (Dwarf_Small *) & operand_buffer[0];
+	WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 2);
+	operand_size = 2;
+	break;
+
+    case DW_OP_call4:		/* DWARF3 */
+	operand = (Dwarf_Small *) & operand_buffer[0];
+	WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1), 4);
+	operand_size = 4;
+	break;
+
+    case DW_OP_call_ref:	/* DWARF3 */
+	operand = (Dwarf_Small *) & operand_buffer[0];
+	WRITE_UNALIGNED(dbg, operand, &val1, sizeof(val1),
+			dbg->de_offset_size);
+	operand_size = dbg->de_offset_size;
+	break;
+    case DW_OP_form_tls_address:	/* DWARF3f */
+	break;
+    case DW_OP_call_frame_cfa:	/* DWARF3f */
+	break;
+    case DW_OP_bit_piece:	/* DWARF3f */
+	res = _dwarf_pro_encode_leb128_nm(val1, &operand_size,
+					  encode_buffer,
+					  sizeof(encode_buffer));
+	if (res != DW_DLV_OK) {
+	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+	    return (DW_DLV_NOCOUNT);
+	}
+	operand = (Dwarf_Small *) encode_buffer;
+	/* put this one directly into 'operand' at tail of prev value */
+	res = _dwarf_pro_encode_leb128_nm(val2, &operand2_size,
+					  ((char *) operand) +
+					  operand_size,
+					  sizeof(encode_buffer2));
+	if (res != DW_DLV_OK) {
+	    _dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+	    return (DW_DLV_NOCOUNT);
+	}
+	operand_size += operand2_size;
+
+
+    default:
+	_dwarf_p_error(expr->ex_dbg, error, DW_DLE_BAD_EXPR_OPCODE);
+	return (DW_DLV_NOCOUNT);
+    }
+
+    next_byte_offset = expr->ex_next_byte_offset + operand_size + 1;
+
+    if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) {
+	_dwarf_p_error(expr->ex_dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+	return (DW_DLV_NOCOUNT);
+    }
+
+    next_byte_ptr =
+	&(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset;
+
+    *next_byte_ptr = opcode;
+    next_byte_ptr++;
+    memcpy(next_byte_ptr, operand, operand_size);
+
+    expr->ex_next_byte_offset = next_byte_offset;
+    return (next_byte_offset);
+}
+
+Dwarf_Unsigned
+dwarf_add_expr_addr_b(Dwarf_P_Expr expr,
+		      Dwarf_Unsigned addr,
+		      Dwarf_Unsigned sym_index, Dwarf_Error * error)
+{
+    Dwarf_P_Debug dbg;
+    Dwarf_Small *next_byte_ptr;
+    Dwarf_Unsigned next_byte_offset;
+    int upointer_size;
+
+    if (expr == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
+	return (DW_DLV_NOCOUNT);
+    }
+
+    dbg = expr->ex_dbg;
+    if (dbg == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_NOCOUNT);
+    }
+
+    upointer_size = dbg->de_pointer_size;
+    next_byte_offset = expr->ex_next_byte_offset + upointer_size + 1;
+    if (next_byte_offset > MAXIMUM_LOC_EXPR_LENGTH) {
+	_dwarf_p_error(dbg, error, DW_DLE_EXPR_LENGTH_BAD);
+	return (DW_DLV_NOCOUNT);
+    }
+
+    next_byte_ptr =
+	&(expr->ex_byte_stream[0]) + expr->ex_next_byte_offset;
+
+    *next_byte_ptr = DW_OP_addr;
+    next_byte_ptr++;
+    WRITE_UNALIGNED(dbg, next_byte_ptr, (const void *) &addr,
+		    sizeof(addr), upointer_size);
+
+    if (expr->ex_reloc_offset != 0) {
+	_dwarf_p_error(dbg, error, DW_DLE_MULTIPLE_RELOC_IN_EXPR);
+	return (DW_DLV_NOCOUNT);
+    }
+
+    expr->ex_reloc_sym_index = sym_index;
+    expr->ex_reloc_offset = expr->ex_next_byte_offset + 1;
+
+    expr->ex_next_byte_offset = next_byte_offset;
+    return (next_byte_offset);
+}
+
+Dwarf_Unsigned
+dwarf_add_expr_addr(Dwarf_P_Expr expr,
+		    Dwarf_Unsigned addr,
+		    Dwarf_Signed sym_index, Dwarf_Error * error)
+{
+    return
+	dwarf_add_expr_addr_b(expr, addr, (Dwarf_Unsigned) sym_index,
+			      error);
+}
+
+
+Dwarf_Unsigned
+dwarf_expr_current_offset(Dwarf_P_Expr expr, Dwarf_Error * error)
+{
+    if (expr == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
+	return (DW_DLV_NOCOUNT);
+    }
+
+    if (expr->ex_dbg == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_NOCOUNT);
+    }
+
+    return (expr->ex_next_byte_offset);
+}
+
+void
+dwarf_expr_reset(Dwarf_P_Expr expr, Dwarf_Error * error)
+{
+   if (expr == NULL) {
+      _dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
+      return;
+   }
+   expr->ex_next_byte_offset=0;
+}
+
+
+Dwarf_Addr
+dwarf_expr_into_block(Dwarf_P_Expr expr,
+		      Dwarf_Unsigned * length, Dwarf_Error * error)
+{
+    if (expr == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_EXPR_NULL);
+	return (DW_DLV_BADADDR);
+    }
+
+    if (expr->ex_dbg == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_BADADDR);
+    }
+
+    if (length != NULL)
+	*length = expr->ex_next_byte_offset;
+    /* The following cast from pointer to integer is ok as long as
+       Dwarf_Addr is at least as large as a pointer. Which is a
+       requirement of libdwarf so must be satisfied (some compilers
+       emit a warning about the following line). */
+    return ((Dwarf_Addr) & (expr->ex_byte_stream[0]));
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_expr.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,45 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+#define	MAXIMUM_LOC_EXPR_LENGTH		20
+
+struct Dwarf_P_Expr_s {
+    Dwarf_Small ex_byte_stream[MAXIMUM_LOC_EXPR_LENGTH];
+    Dwarf_P_Debug ex_dbg;
+    Dwarf_Unsigned ex_next_byte_offset;
+    Dwarf_Unsigned ex_reloc_sym_index;
+    Dwarf_Unsigned ex_reloc_offset;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_finish.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,57 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#include "pro_incl.h"
+
+/*---------------------------------------------------------------
+	This routine deallocates all memory, and does some 
+	finishing up
+-----------------------------------------------------------------*/
+ /*ARGSUSED*/ Dwarf_Unsigned
+dwarf_producer_finish(Dwarf_P_Debug dbg, Dwarf_Error * error)
+{
+    if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_NOCOUNT);
+    }
+
+    /* this frees all blocks, then frees dbg. */
+    _dwarf_p_dealloc_all(dbg);
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_forms.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1164 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+  Portions Copyright 2007 David Anderson. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include "pro_incl.h"
+#include "pro_expr.h"
+
+#ifndef R_MIPS_NONE
+#define R_MIPS_NONE 0
+#endif
+
+
+    /* Indicates no relocation needed. */
+#define NO_ELF_SYM_INDEX	0
+
+
+/* adds an attribute to a die */
+extern void _dwarf_pro_add_at_to_die(Dwarf_P_Die die,
+				     Dwarf_P_Attribute attr);
+
+/*
+    This function adds an attribute whose value is
+    a target address to the given die.  The attribute
+    is given the name provided by attr.  The address
+    is given in pc_value.
+*/
+
+static Dwarf_P_Attribute
+local_add_AT_address(Dwarf_P_Debug dbg,
+		     Dwarf_P_Die ownerdie,
+		     Dwarf_Half attr,
+		     Dwarf_Signed form,
+		     Dwarf_Unsigned pc_value,
+		     Dwarf_Unsigned sym_index,
+		     Dwarf_Error * error);
+     
+/* old interface */
+Dwarf_P_Attribute
+dwarf_add_AT_targ_address(Dwarf_P_Debug dbg,
+			  Dwarf_P_Die ownerdie,
+			  Dwarf_Half attr,
+			  Dwarf_Unsigned pc_value,
+			  Dwarf_Signed sym_index, Dwarf_Error * error)
+{
+    return 
+	dwarf_add_AT_targ_address_b(dbg,
+				    ownerdie, 
+				    attr,
+				    pc_value, 
+				    (Dwarf_Unsigned) sym_index, error);
+}
+
+/* New interface, replacing dwarf_add_AT_targ_address. 
+   Essentially just makes sym_index a Dwarf_Unsigned
+   so for symbolic relocations it can be a full address.
+*/
+Dwarf_P_Attribute
+dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg,
+			    Dwarf_P_Die ownerdie,
+			    Dwarf_Half attr,
+			    Dwarf_Unsigned pc_value,
+			    Dwarf_Unsigned sym_index,
+			    Dwarf_Error * error)
+{
+    switch (attr) {
+    case DW_AT_low_pc:
+    case DW_AT_high_pc:
+
+    /* added to support location lists */
+    /* no way to check that this is a loclist-style address though */
+    case DW_AT_location:
+    case DW_AT_string_length:
+    case DW_AT_return_addr:
+    case DW_AT_frame_base:
+    case DW_AT_segment:
+    case DW_AT_static_link:
+    case DW_AT_use_location:
+    case DW_AT_vtable_elem_location:
+	
+	break;
+
+    default: 
+	if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
+	    _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
+	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+	}
+	break;
+    }
+    
+    return local_add_AT_address(dbg, ownerdie, attr, DW_FORM_addr,
+				pc_value, sym_index, error);
+}
+
+Dwarf_P_Attribute
+dwarf_add_AT_ref_address(Dwarf_P_Debug dbg,
+			 Dwarf_P_Die ownerdie,
+			 Dwarf_Half attr,
+			 Dwarf_Unsigned pc_value,
+			 Dwarf_Unsigned sym_index,
+			 Dwarf_Error * error)
+{
+    switch (attr) {
+    case DW_AT_type:
+    case DW_AT_import:
+	break;
+
+    default: 
+	if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
+	    _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
+	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+	}
+	break;
+    }
+    
+    return local_add_AT_address(dbg, ownerdie, attr, DW_FORM_ref_addr,
+				pc_value, sym_index, error);    
+}
+
+
+/* Make sure attribute types are checked before entering here. */
+static Dwarf_P_Attribute
+local_add_AT_address(Dwarf_P_Debug dbg,
+		     Dwarf_P_Die ownerdie,
+		     Dwarf_Half attr,
+		     Dwarf_Signed form,
+		     Dwarf_Unsigned pc_value,
+		     Dwarf_Unsigned sym_index,
+		     Dwarf_Error * error)
+{
+    Dwarf_P_Attribute new_attr;
+    int upointer_size = dbg->de_pointer_size;
+
+    if (dbg == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    if (ownerdie == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    /* attribute types have already been checked */
+    /* switch (attr) { ... } */
+
+    new_attr = (Dwarf_P_Attribute)
+	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
+    if (new_attr == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    new_attr->ar_attribute = attr;
+    new_attr->ar_attribute_form = form;
+    new_attr->ar_nbytes = upointer_size;
+    new_attr->ar_rel_symidx = sym_index;
+    new_attr->ar_reloc_len = upointer_size;
+    new_attr->ar_next = 0;
+    if (sym_index != NO_ELF_SYM_INDEX)
+	new_attr->ar_rel_type = dbg->de_ptr_reloc;
+    else
+	new_attr->ar_rel_type = R_MIPS_NONE;
+
+    new_attr->ar_data = (char *)
+	_dwarf_p_get_alloc(dbg, upointer_size);
+    if (new_attr->ar_data == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+    WRITE_UNALIGNED(dbg, new_attr->ar_data,
+		    (const void *) &pc_value,
+		    sizeof(pc_value), upointer_size);
+
+    /* add attribute to the die */
+    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
+    return new_attr;
+}
+
+/*
+ * Functions to compress and uncompress data from normal
+ * arrays of integral types into arrays of LEB128 numbers.
+ * Extend these functions as needed to handle wider input
+ * variety.  Return values should be freed with _dwarf_p_dealloc
+ * after they aren't needed any more.
+ */
+
+/* return value points to an array of LEB number */
+
+void *
+dwarf_compress_integer_block(
+    Dwarf_P_Debug    dbg,
+    Dwarf_Bool       unit_is_signed,
+    Dwarf_Small      unit_length_in_bits,
+    void*            input_block,
+    Dwarf_Unsigned   input_length_in_units,
+    Dwarf_Unsigned*  output_length_in_bytes_ptr,
+    Dwarf_Error*     error
+)
+{
+    Dwarf_Unsigned output_length_in_bytes;
+    char * output_block;
+    char encode_buffer[ENCODE_SPACE_NEEDED];
+    int unit_length;
+    int i;
+    char * ptr;
+    int remain;
+    int result;
+
+    if (dbg == NULL) {
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return((void *)DW_DLV_BADADDR);
+    }
+    
+    if (unit_is_signed == false ||
+	unit_length_in_bits != 32 ||
+	input_block == NULL ||
+	input_length_in_units == 0 ||
+	output_length_in_bytes_ptr == NULL) {
+	
+	_dwarf_p_error(NULL, error, DW_DLE_BADBITC);
+	return ((void *) DW_DLV_BADADDR);
+    }
+
+    /* At this point we assume the format is: signed 32 bit */
+
+    /* first compress everything to find the total size. */
+
+    output_length_in_bytes = 0;
+    for (i=0; i<input_length_in_units; i++) {
+	int unit_encoded_size;
+	Dwarf_sfixed unit; /* this is fixed at signed-32-bits */
+	
+	unit = ((Dwarf_sfixed*)input_block)[i];
+	
+	result = _dwarf_pro_encode_signed_leb128_nm(unit, &unit_encoded_size,
+					     encode_buffer,sizeof(encode_buffer));
+	if (result !=  DW_DLV_OK) {
+	    _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	    return((Dwarf_P_Attribute)DW_DLV_BADADDR);
+	}
+	output_length_in_bytes += unit_encoded_size;
+    }
+
+    
+    /* then alloc */
+
+    output_block = (void *)
+        _dwarf_p_get_alloc(dbg, output_length_in_bytes);
+    if (output_block == NULL) {
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return((void*)DW_DLV_BADADDR);
+    }
+    
+    /* then compress again and copy into new buffer */
+
+    ptr = output_block;
+    remain = output_length_in_bytes;
+    for (i=0; i<input_length_in_units; i++) {
+	int unit_encoded_size;
+	Dwarf_sfixed unit; /* this is fixed at signed-32-bits */
+	
+	unit = ((Dwarf_sfixed*)input_block)[i];
+	
+	result = _dwarf_pro_encode_signed_leb128_nm(unit, &unit_encoded_size,
+					     ptr, remain);
+	if (result !=  DW_DLV_OK) {
+	    _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	    return((Dwarf_P_Attribute)DW_DLV_BADADDR);
+	}
+	remain -= unit_encoded_size;
+	ptr += unit_encoded_size;
+    }
+
+    if (remain != 0) {
+	_dwarf_p_dealloc(dbg, (unsigned char *)output_block);
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return((Dwarf_P_Attribute)DW_DLV_BADADDR);
+    }
+
+    *output_length_in_bytes_ptr = output_length_in_bytes;
+    return (void*) output_block;
+
+}
+
+void
+dwarf_dealloc_compressed_block(Dwarf_P_Debug dbg, void * space)
+{
+    _dwarf_p_dealloc(dbg, space);
+}
+
+/* This is very similar to targ_address but results in a different FORM */
+/* dbg->de_ar_data_attribute_form is data4 or data8
+   and dwarf4 changes the definition for such on DW_AT_high_pc.
+   DWARF 3: the FORM here has no defined meaning for dwarf3.
+   DWARF 4: the FORM here means that for DW_AT_high_pc the value
+            is not a high address but is instead an offset
+            from a (separate) DW_AT_low_pc. 
+   The intent for DWARF4 is that this is not a relocated
+   address at all.  Instead a simple offset.
+   But this should NOT be called for a simple non-relocated offset.
+   So do not call this with an attr of DW_AT_high_pc.
+   Use dwarf_add_AT_unsigned_const() (for example) instead of
+   dwarf_add_AT_dataref when the value is a simple offset .
+*/
+Dwarf_P_Attribute
+dwarf_add_AT_dataref(
+    Dwarf_P_Debug dbg,
+    Dwarf_P_Die ownerdie,
+    Dwarf_Half attr,
+    Dwarf_Unsigned pc_value,
+    Dwarf_Unsigned sym_index,
+    Dwarf_Error * error)
+{
+    /* TODO: Add checking here */
+    return local_add_AT_address(dbg, ownerdie, attr,
+				dbg->de_ar_data_attribute_form,
+				pc_value,
+				sym_index,
+				error);
+}
+
+
+
+Dwarf_P_Attribute 
+dwarf_add_AT_block(
+    Dwarf_P_Debug	dbg,
+    Dwarf_P_Die 	ownerdie,
+    Dwarf_Half		attr,
+    Dwarf_Small         *block_data,
+    Dwarf_Unsigned      block_size,
+    Dwarf_Error 	*error
+)
+{
+    Dwarf_P_Attribute 	new_attr;
+    int result;
+    char encode_buffer[ENCODE_SPACE_NEEDED];
+    int len_size;
+    char * attrdata;
+
+    if (dbg == NULL) {
+        _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
+    }
+
+    if (ownerdie == NULL) {
+        _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
+        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
+    }
+
+    /* I don't mess with block1, block2, block4, not worth the effort */
+
+    /* So, encode the length into LEB128 */
+    result = _dwarf_pro_encode_leb128_nm(block_size, &len_size,
+					 encode_buffer,sizeof(encode_buffer));
+    if (result !=  DW_DLV_OK) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return((Dwarf_P_Attribute)DW_DLV_BADADDR);
+    }
+
+    /* Allocate the new attribute */
+    new_attr = (Dwarf_P_Attribute)
+        _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
+    if (new_attr == NULL) {
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
+    }
+
+    /* Fill in the attribute */
+    new_attr->ar_attribute = attr;
+    new_attr->ar_attribute_form = DW_FORM_block;
+    new_attr->ar_nbytes = len_size + block_size;
+    new_attr->ar_next = 0;
+
+    new_attr->ar_data = attrdata = (char *)
+        _dwarf_p_get_alloc(dbg, len_size + block_size);
+    if (new_attr->ar_data == NULL) {
+	/* free the block we got earlier */
+	_dwarf_p_dealloc(dbg, (unsigned char *) new_attr);
+        _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+        return((Dwarf_P_Attribute)DW_DLV_BADADDR);
+    }
+
+    /* write length and data to attribute data buffer */
+    memcpy(attrdata, encode_buffer, len_size);
+    attrdata += len_size;
+    memcpy(attrdata, block_data, block_size);
+    
+    /* add attribute to the die */
+    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
+
+    return new_attr;
+}
+
+
+/*
+    This function adds attributes whose value
+    is an unsigned constant.  It determines the 
+    size of the value field from the value of 
+    the constant.
+*/
+Dwarf_P_Attribute
+dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg,
+			    Dwarf_P_Die ownerdie,
+			    Dwarf_Half attr,
+			    Dwarf_Unsigned value, Dwarf_Error * error)
+{
+    Dwarf_P_Attribute new_attr;
+    Dwarf_Half attr_form;
+    Dwarf_Small size;
+
+    if (dbg == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    if (ownerdie == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    switch (attr) {
+    case DW_AT_ordering:
+    case DW_AT_byte_size:
+    case DW_AT_bit_offset:
+    case DW_AT_bit_size:
+    case DW_AT_inline:
+    case DW_AT_language:
+    case DW_AT_visibility:
+    case DW_AT_virtuality:
+    case DW_AT_accessibility:
+    case DW_AT_address_class:
+    case DW_AT_calling_convention:
+    case DW_AT_encoding:
+    case DW_AT_identifier_case:
+    case DW_AT_MIPS_loop_unroll_factor:
+    case DW_AT_MIPS_software_pipeline_depth:
+	break;
+
+    case DW_AT_decl_column:
+    case DW_AT_decl_file:
+    case DW_AT_decl_line:
+    case DW_AT_const_value:
+    case DW_AT_start_scope:
+    case DW_AT_stride_size:
+    case DW_AT_count:
+    case DW_AT_associated:
+    case DW_AT_allocated:
+    case DW_AT_upper_bound:
+    case DW_AT_lower_bound:
+	break;
+
+        default: {
+	         if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
+	             _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
+	             return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+	       }
+	       break;
+	    }
+        }
+
+    /* 
+       Compute the number of bytes needed to hold constant. */
+    if (value <= UCHAR_MAX) {
+	attr_form = DW_FORM_data1;
+	size = 1;
+    } else if (value <= USHRT_MAX) {
+	attr_form = DW_FORM_data2;
+	size = 2;
+    } else if (value <= UINT_MAX) {
+	attr_form = DW_FORM_data4;
+	size = 4;
+    } else {
+	attr_form = DW_FORM_data8;
+	size = 8;
+    }
+
+    new_attr = (Dwarf_P_Attribute)
+	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
+    if (new_attr == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    new_attr->ar_attribute = attr;
+    new_attr->ar_attribute_form = attr_form;
+    new_attr->ar_rel_type = R_MIPS_NONE;
+    new_attr->ar_reloc_len = 0;	/* irrelevant: unused with R_MIPS_NONE */
+    new_attr->ar_nbytes = size;
+    new_attr->ar_next = 0;
+
+    new_attr->ar_data = (char *)
+	_dwarf_p_get_alloc(dbg, size);
+    if (new_attr->ar_data == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+    WRITE_UNALIGNED(dbg, new_attr->ar_data,
+		    (const void *) &value, sizeof(value), size);
+
+    /* add attribute to the die */
+    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
+    return new_attr;
+}
+
+
+/*
+    This function adds attributes whose value
+    is an signed constant.  It determines the 
+    size of the value field from the value of 
+    the constant.
+*/
+Dwarf_P_Attribute
+dwarf_add_AT_signed_const(Dwarf_P_Debug dbg,
+			  Dwarf_P_Die ownerdie,
+			  Dwarf_Half attr,
+			  Dwarf_Signed value, Dwarf_Error * error)
+{
+    Dwarf_P_Attribute new_attr;
+    Dwarf_Half attr_form;
+    Dwarf_Small size;
+
+    if (dbg == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    if (ownerdie == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    switch (attr) {
+    case DW_AT_upper_bound:
+    case DW_AT_lower_bound:
+    case DW_AT_const_value:
+        break;
+
+    default:{ 
+	        if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
+	             _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
+	             return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+	        }
+	}
+	break;
+    }
+
+    /* 
+       Compute the number of bytes needed to hold constant. */
+    if (value >= SCHAR_MIN && value <= SCHAR_MAX) {
+	attr_form = DW_FORM_data1;
+	size = 1;
+    } else if (value >= SHRT_MIN && value <= SHRT_MAX) {
+	attr_form = DW_FORM_data2;
+	size = 2;
+    } else if (value >= INT_MIN && value <= INT_MAX) {
+	attr_form = DW_FORM_data4;
+	size = 4;
+    } else {
+	attr_form = DW_FORM_data8;
+	size = 8;
+    }
+
+    new_attr = (Dwarf_P_Attribute)
+	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
+    if (new_attr == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    new_attr->ar_attribute = attr;
+    new_attr->ar_attribute_form = attr_form;
+    new_attr->ar_rel_type = R_MIPS_NONE;
+    new_attr->ar_reloc_len = 0;	/* irrelevant: unused with R_MIPS_NONE */
+    new_attr->ar_nbytes = size;
+    new_attr->ar_next = 0;
+
+    new_attr->ar_data = (char *)
+	_dwarf_p_get_alloc(dbg, size);
+    if (new_attr->ar_data == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+    WRITE_UNALIGNED(dbg, new_attr->ar_data,
+		    (const void *) &value, sizeof(value), size);
+
+    /* add attribute to the die */
+    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
+    return new_attr;
+}
+
+
+/*
+    This function adds attributes whose value
+    is a location expression.
+*/
+Dwarf_P_Attribute
+dwarf_add_AT_location_expr(Dwarf_P_Debug dbg,
+			   Dwarf_P_Die ownerdie,
+			   Dwarf_Half attr,
+			   Dwarf_P_Expr loc_expr, Dwarf_Error * error)
+{
+    char encode_buffer[ENCODE_SPACE_NEEDED];
+    int res;
+    Dwarf_P_Attribute new_attr;
+    Dwarf_Half attr_form;
+    char *len_str = 0;
+    int len_size;
+    int block_size;
+    char *block_dest_ptr;
+    int do_len_as_int = 0;
+
+    if (dbg == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    if (ownerdie == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    if (loc_expr == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_EXPR_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    if (loc_expr->ex_dbg != dbg) {
+	_dwarf_p_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+    block_size = loc_expr->ex_next_byte_offset;
+
+    switch (attr) {
+    case DW_AT_location:
+    case DW_AT_string_length:
+    case DW_AT_const_value:
+    case DW_AT_use_location:
+    case DW_AT_return_addr:
+    case DW_AT_data_member_location:
+    case DW_AT_frame_base:
+    case DW_AT_static_link:
+    case DW_AT_vtable_elem_location:
+	case DW_AT_lower_bound:
+	case DW_AT_upper_bound:
+	case DW_AT_count:
+	case DW_AT_associated:
+	case DW_AT_allocated:
+	break;
+
+        default:
+	    if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
+	    _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
+	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+	}
+	    break;
+    }
+
+    /* 
+       Compute the number of bytes needed to hold constant. */
+    if (block_size <= UCHAR_MAX) {
+	attr_form = DW_FORM_block1;
+	len_size = 1;
+	do_len_as_int = 1;
+    } else if (block_size <= USHRT_MAX) {
+	attr_form = DW_FORM_block2;
+	len_size = 2;
+	do_len_as_int = 1;
+    } else if (block_size <= UINT_MAX) {
+	attr_form = DW_FORM_block4;
+	len_size = 4;
+	do_len_as_int = 1;
+    } else {
+	attr_form = DW_FORM_block;
+	res = _dwarf_pro_encode_leb128_nm(block_size, &len_size,
+					  encode_buffer,
+					  sizeof(encode_buffer));
+	if (res != DW_DLV_OK) {
+	    _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+	}
+	len_str = (char *) encode_buffer;
+    }
+
+    new_attr = (Dwarf_P_Attribute)
+	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
+    if (new_attr == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    new_attr->ar_attribute = attr;
+    new_attr->ar_attribute_form = attr_form;
+    new_attr->ar_reloc_len = dbg->de_pointer_size;
+    if (loc_expr->ex_reloc_sym_index != NO_ELF_SYM_INDEX) {
+	new_attr->ar_rel_type = dbg->de_ptr_reloc;
+    } else {
+	new_attr->ar_rel_type = R_MIPS_NONE;
+    }
+    new_attr->ar_rel_symidx = loc_expr->ex_reloc_sym_index;
+    new_attr->ar_rel_offset =
+	(Dwarf_Word) loc_expr->ex_reloc_offset + len_size;
+
+    new_attr->ar_nbytes = block_size + len_size;
+
+    new_attr->ar_next = 0;
+    new_attr->ar_data = block_dest_ptr =
+	(char *) _dwarf_p_get_alloc(dbg, block_size + len_size);
+    if (new_attr->ar_data == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    if (do_len_as_int) {
+	WRITE_UNALIGNED(dbg, block_dest_ptr, (const void *) &block_size,
+			sizeof(block_size), len_size);
+    } else {
+	/* Is uleb number form, DW_FORM_block. See above. */
+	memcpy(block_dest_ptr, len_str, len_size);
+    }
+    block_dest_ptr += len_size;
+    memcpy(block_dest_ptr, &(loc_expr->ex_byte_stream[0]), block_size);
+
+    /* add attribute to the die */
+    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
+    return new_attr;
+}
+
+
+/*
+    This function adds attributes of reference class.
+    The references here are local CU references, 
+    not DW_FORM_ref_addr.
+    The offset field is 4 bytes for 32-bit objects,
+    and 8-bytes for 64-bit objects.  Otherdie is the
+    that is referenced by ownerdie.
+
+    For reference attributes, the ar_data and ar_nbytes
+    are not needed.  Instead, the ar_ref_die points to
+    the other die, and its di_offset value is used as
+    the reference value.
+*/
+Dwarf_P_Attribute
+dwarf_add_AT_reference(Dwarf_P_Debug dbg,
+		       Dwarf_P_Die ownerdie,
+		       Dwarf_Half attr,
+		       Dwarf_P_Die otherdie, Dwarf_Error * error)
+{
+    Dwarf_P_Attribute new_attr;
+
+    if (dbg == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    if (ownerdie == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    if (otherdie == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    switch (attr) {
+    case DW_AT_specification:
+    case DW_AT_discr:
+    case DW_AT_common_reference:
+    case DW_AT_import:
+    case DW_AT_containing_type:
+    case DW_AT_default_value:
+    case DW_AT_abstract_origin:
+    case DW_AT_friend:
+    case DW_AT_priority:
+    case DW_AT_type:
+    case DW_AT_lower_bound:
+    case DW_AT_upper_bound:
+    case DW_AT_count:
+    case DW_AT_associated:
+    case DW_AT_allocated:
+    case DW_AT_sibling:
+    case DW_AT_namelist_item:
+	break;
+
+    default:
+	if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
+	    _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
+	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+	}
+	break;
+    }
+
+    new_attr = (Dwarf_P_Attribute)
+	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
+    if (new_attr == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    new_attr->ar_attribute = attr;
+    new_attr->ar_attribute_form = dbg->de_ar_ref_attr_form;
+    new_attr->ar_nbytes = dbg->de_offset_size;
+    new_attr->ar_reloc_len = dbg->de_offset_size;
+    new_attr->ar_ref_die = otherdie;
+    new_attr->ar_rel_type = R_MIPS_NONE;
+    new_attr->ar_next = 0;
+
+    /* add attribute to the die */
+    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
+    return new_attr;
+}
+
+
+/*
+    This function adds attributes of the flag class.
+*/
+Dwarf_P_Attribute
+dwarf_add_AT_flag(Dwarf_P_Debug dbg,
+		  Dwarf_P_Die ownerdie,
+		  Dwarf_Half attr,
+		  Dwarf_Small flag, Dwarf_Error * error)
+{
+    Dwarf_P_Attribute new_attr;
+
+    if (dbg == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    if (ownerdie == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+#if 0    
+    switch (attr) {
+    case DW_AT_is_optional:
+    case DW_AT_artificial:
+    case DW_AT_declaration:
+    case DW_AT_external:
+    case DW_AT_prototyped:
+    case DW_AT_variable_parameter:
+	break;
+
+        default:
+	    if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
+	    _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
+	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+	}
+    	    break;
+    }
+#endif    
+
+    new_attr = (Dwarf_P_Attribute)
+	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
+    if (new_attr == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    new_attr->ar_attribute = attr;
+    new_attr->ar_attribute_form = DW_FORM_flag;
+    new_attr->ar_nbytes = 1;
+    new_attr->ar_reloc_len = 0;	/* not used */
+    new_attr->ar_rel_type = R_MIPS_NONE;
+    new_attr->ar_next = 0;
+
+    new_attr->ar_data = (char *)
+	_dwarf_p_get_alloc(dbg, 1);
+    if (new_attr->ar_data == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+    memcpy(new_attr->ar_data, &flag, 1);
+
+    /* add attribute to the die */
+    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
+    return new_attr;
+}
+
+
+/*
+    This function adds values of attributes
+    belonging to the string class.
+*/
+Dwarf_P_Attribute
+dwarf_add_AT_string(Dwarf_P_Debug dbg,
+		    Dwarf_P_Die ownerdie,
+		    Dwarf_Half attr, char *string, Dwarf_Error * error)
+{
+    Dwarf_P_Attribute new_attr;
+
+    if (dbg == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    if (ownerdie == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_DIE_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    new_attr = (Dwarf_P_Attribute)
+	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s));
+    if (new_attr == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    switch (attr) {
+    case DW_AT_name:
+    case DW_AT_comp_dir:
+    case DW_AT_const_value:
+    case DW_AT_producer:
+	break;
+
+	default:
+	    if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) {
+	    _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD);
+	    return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+	}
+	    break;
+    }
+
+    new_attr->ar_attribute = attr;
+    new_attr->ar_attribute_form = DW_FORM_string;
+    new_attr->ar_nbytes = strlen(string) + 1;
+    new_attr->ar_next = 0;
+
+    new_attr->ar_data =
+	(char *) _dwarf_p_get_alloc(dbg, strlen(string)+1);
+    if (new_attr->ar_data == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    strcpy(new_attr->ar_data, string);
+    new_attr->ar_rel_type = R_MIPS_NONE;
+    new_attr->ar_reloc_len = 0;	/* unused for R_MIPS_NONE */
+
+    /* add attribute to the die */
+    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
+    return new_attr;
+}
+
+
+Dwarf_P_Attribute
+dwarf_add_AT_const_value_string(Dwarf_P_Die ownerdie,
+				char *string_value, Dwarf_Error * error)
+{
+    Dwarf_P_Attribute new_attr;
+
+    if (ownerdie == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    new_attr = (Dwarf_P_Attribute)
+        _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
+    if (new_attr == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    new_attr->ar_attribute = DW_AT_const_value;
+    new_attr->ar_attribute_form = DW_FORM_string;
+    new_attr->ar_nbytes = strlen(string_value) + 1;
+    new_attr->ar_next = 0;
+
+    new_attr->ar_data =
+	(char *) _dwarf_p_get_alloc(ownerdie->di_dbg, strlen(string_value)+1);
+    if (new_attr->ar_data == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    strcpy(new_attr->ar_data, string_value);
+    new_attr->ar_rel_type = R_MIPS_NONE;
+    new_attr->ar_reloc_len = 0;	/* unused for R_MIPS_NONE */
+
+    /* add attribute to the die */
+    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
+    return new_attr;
+}
+
+
+Dwarf_P_Attribute
+dwarf_add_AT_producer(Dwarf_P_Die ownerdie,
+		      char *producer_string, Dwarf_Error * error)
+{
+    Dwarf_P_Attribute new_attr;
+
+    if (ownerdie == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    new_attr = (Dwarf_P_Attribute)
+        _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
+    if (new_attr == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    new_attr->ar_attribute = DW_AT_producer;
+    new_attr->ar_attribute_form = DW_FORM_string;
+    new_attr->ar_nbytes = strlen(producer_string) + 1;
+    new_attr->ar_next = 0;
+
+    new_attr->ar_data =
+	(char *) _dwarf_p_get_alloc(ownerdie->di_dbg, strlen(producer_string)+1);
+    if (new_attr->ar_data == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    strcpy(new_attr->ar_data, producer_string);
+    new_attr->ar_rel_type = R_MIPS_NONE;
+    new_attr->ar_reloc_len = 0;	/* unused for R_MIPS_NONE */
+
+    /* add attribute to the die */
+    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
+    return new_attr;
+}
+
+
+Dwarf_P_Attribute
+dwarf_add_AT_const_value_signedint(Dwarf_P_Die ownerdie,
+				   Dwarf_Signed signed_value,
+				   Dwarf_Error * error)
+{
+    Dwarf_P_Attribute new_attr;
+    int leb_size;
+    char encode_buffer[ENCODE_SPACE_NEEDED];
+    int res;
+
+    if (ownerdie == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    new_attr = (Dwarf_P_Attribute)
+        _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
+    if (new_attr == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    new_attr->ar_attribute = DW_AT_const_value;
+    new_attr->ar_attribute_form = DW_FORM_sdata;
+    new_attr->ar_rel_type = R_MIPS_NONE;
+    new_attr->ar_reloc_len = 0;	/* unused for R_MIPS_NONE */
+    new_attr->ar_next = 0;
+
+    res = _dwarf_pro_encode_signed_leb128_nm(signed_value, &leb_size,
+					     encode_buffer,
+					     sizeof(encode_buffer));
+    if (res != DW_DLV_OK) {
+	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+    new_attr->ar_data = (char *)
+        _dwarf_p_get_alloc(ownerdie->di_dbg, leb_size);
+    if (new_attr->ar_data == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+    memcpy(new_attr->ar_data, encode_buffer, leb_size);
+    new_attr->ar_nbytes = leb_size;
+
+    /* add attribute to the die */
+    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
+    return new_attr;
+}
+
+
+Dwarf_P_Attribute
+dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die ownerdie,
+				     Dwarf_Unsigned unsigned_value,
+				     Dwarf_Error * error)
+{
+    Dwarf_P_Attribute new_attr;
+    int leb_size;
+    char encode_buffer[ENCODE_SPACE_NEEDED];
+    int res;
+
+    if (ownerdie == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    new_attr = (Dwarf_P_Attribute)
+        _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s));
+    if (new_attr == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+
+    new_attr->ar_attribute = DW_AT_const_value;
+    new_attr->ar_attribute_form = DW_FORM_udata;
+    new_attr->ar_rel_type = R_MIPS_NONE;
+    new_attr->ar_reloc_len = 0;	/* unused for R_MIPS_NONE */
+    new_attr->ar_next = 0;
+
+    res = _dwarf_pro_encode_leb128_nm(unsigned_value, &leb_size,
+				      encode_buffer,
+				      sizeof(encode_buffer));
+    if (res != DW_DLV_OK) {
+	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+    new_attr->ar_data = (char *)
+	_dwarf_p_get_alloc(ownerdie->di_dbg, leb_size);
+    if (new_attr->ar_data == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL);
+	return ((Dwarf_P_Attribute) DW_DLV_BADADDR);
+    }
+    memcpy(new_attr->ar_data, encode_buffer, leb_size);
+    new_attr->ar_nbytes = leb_size;
+
+    /* add attribute to the die */
+    _dwarf_pro_add_at_to_die(ownerdie, new_attr);
+    return new_attr;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_frame.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,560 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include "pro_incl.h"
+#include "pro_frame.h"
+
+static void _dwarf_pro_add_to_fde(Dwarf_P_Fde fde,
+				  Dwarf_P_Frame_Pgm inst);
+
+/*-------------------------------------------------------------------------
+	This functions adds a cie struct to the debug pointer. Its in the
+	form of a linked list.
+	augmenter: string reps augmentation (implementation defined)
+	code_align: alignment of code
+	data_align: alignment of data
+	init_bytes: byts having initial instructions
+	init_n_bytes: number of bytes of initial instructions
+--------------------------------------------------------------------------*/
+Dwarf_Unsigned
+dwarf_add_frame_cie(Dwarf_P_Debug dbg,
+		    char *augmenter,
+		    Dwarf_Small code_align,
+		    Dwarf_Small data_align,
+		    Dwarf_Small return_reg,
+		    Dwarf_Ptr init_bytes,
+		    Dwarf_Unsigned init_n_bytes, Dwarf_Error * error)
+{
+    Dwarf_P_Cie curcie;
+
+    if (dbg->de_frame_cies == NULL) {
+	dbg->de_frame_cies = (Dwarf_P_Cie)
+	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s));
+	if (dbg->de_frame_cies == NULL) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT);
+	}
+	curcie = dbg->de_frame_cies;
+	dbg->de_n_cie = 1;
+	dbg->de_last_cie = curcie;
+    } else {
+	curcie = dbg->de_last_cie;
+	curcie->cie_next = (Dwarf_P_Cie)
+	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s));
+	if (curcie->cie_next == NULL) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT);
+	}
+	curcie = curcie->cie_next;
+	dbg->de_n_cie++;
+	dbg->de_last_cie = curcie;
+    }
+    curcie->cie_version = DW_CIE_VERSION;
+    curcie->cie_aug = augmenter;
+    curcie->cie_code_align = code_align;
+    curcie->cie_data_align = data_align;
+    curcie->cie_ret_reg = return_reg;
+    curcie->cie_inst = (char *) init_bytes;
+    curcie->cie_inst_bytes = (long) init_n_bytes;
+    curcie->cie_next = NULL;
+    return dbg->de_n_cie;
+}
+
+
+/*-------------------------------------------------------------------------
+	This functions adds a fde struct to the debug pointer. Its in the
+	form of a linked list.
+	die: subprogram/function die corresponding to this fde
+	cie: cie referred to by this fde, obtained from call to 
+	    add_frame_cie() routine.
+	virt_addr: beginning address
+	code_len: length of code reps by the fde
+--------------------------------------------------------------------------*/
+ /*ARGSUSED*/			/* pretend all args used */
+    Dwarf_Unsigned
+dwarf_add_frame_fde(Dwarf_P_Debug dbg,
+		    Dwarf_P_Fde fde,
+		    Dwarf_P_Die die,
+		    Dwarf_Unsigned cie,
+		    Dwarf_Unsigned virt_addr,
+		    Dwarf_Unsigned code_len,
+		    Dwarf_Unsigned symidx, Dwarf_Error * error)
+{
+    return dwarf_add_frame_fde_b(dbg, fde, die, cie, virt_addr,
+				 code_len, symidx, 0, 0, error);
+}
+
+/*ARGSUSED10*/
+Dwarf_Unsigned
+dwarf_add_frame_fde_b(Dwarf_P_Debug dbg,
+		      Dwarf_P_Fde fde,
+		      Dwarf_P_Die die,
+		      Dwarf_Unsigned cie,
+		      Dwarf_Unsigned virt_addr,
+		      Dwarf_Unsigned code_len,
+		      Dwarf_Unsigned symidx,
+		      Dwarf_Unsigned symidx_of_end,
+		      Dwarf_Addr offset_from_end_sym,
+		      Dwarf_Error * error)
+{
+    Dwarf_P_Fde curfde;
+
+    fde->fde_die = die;
+    fde->fde_cie = (long) cie;
+    fde->fde_initloc = virt_addr;
+    fde->fde_r_symidx = symidx;
+    fde->fde_addr_range = code_len;
+    fde->fde_offset_into_exception_tables = DW_DLX_NO_EH_OFFSET;
+    fde->fde_exception_table_symbol = 0;
+    fde->fde_end_symbol_offset = offset_from_end_sym;
+    fde->fde_end_symbol = symidx_of_end;
+    fde->fde_dbg = dbg;
+
+    curfde = dbg->de_last_fde;
+    if (curfde == NULL) {
+	dbg->de_frame_fdes = fde;
+	dbg->de_last_fde = fde;
+	dbg->de_n_fde = 1;
+    } else {
+	curfde->fde_next = fde;
+	dbg->de_last_fde = fde;
+	dbg->de_n_fde++;
+    }
+    return dbg->de_n_fde;
+}
+
+/*-------------------------------------------------------------------------
+	This functions adds information to an fde. The fde is
+	linked into the linked list of fde's maintained in the Dwarf_P_Debug
+	structure.
+	dbg: The debug descriptor.
+	fde: The fde to be added.
+	die: subprogram/function die corresponding to this fde
+	cie: cie referred to by this fde, obtained from call to 
+	    add_frame_cie() routine.
+	virt_addr: beginning address
+	code_len: length of code reps by the fde
+	symidx: The symbol id of the symbol wrt to which relocation needs
+		to be performed for 'virt_addr'.
+	offset_into_exception_tables: The start of exception tables for
+		this function (indicated as an offset into the exception
+		tables). A value of -1 indicates that there is no exception
+		table entries associated with this function.
+	exception_table_symbol: The symbol id of the section for exception
+		tables wrt to which the offset_into_exception_tables will
+		be relocated.
+--------------------------------------------------------------------------*/
+Dwarf_Unsigned
+dwarf_add_frame_info(Dwarf_P_Debug dbg,
+		     Dwarf_P_Fde fde,
+		     Dwarf_P_Die die,
+		     Dwarf_Unsigned cie,
+		     Dwarf_Unsigned virt_addr,
+		     Dwarf_Unsigned code_len,
+		     Dwarf_Unsigned symidx,
+		     Dwarf_Signed offset_into_exception_tables,
+		     Dwarf_Unsigned exception_table_symbol,
+		     Dwarf_Error * error)
+{
+
+    return dwarf_add_frame_info_b(dbg, fde, die, cie, virt_addr,
+				  code_len, symidx,
+				  /* end_symbol */ 0,
+				  /* offset_from_end */ 0,
+				  offset_into_exception_tables,
+				  exception_table_symbol, error);
+
+}
+
+ /*ARGSUSED*/			/* pretend all args used */
+    Dwarf_Unsigned
+dwarf_add_frame_info_b(Dwarf_P_Debug dbg,
+		       Dwarf_P_Fde fde,
+		       Dwarf_P_Die die,
+		       Dwarf_Unsigned cie,
+		       Dwarf_Unsigned virt_addr,
+		       Dwarf_Unsigned code_len,
+		       Dwarf_Unsigned symidx,
+		       Dwarf_Unsigned end_symidx,
+		       Dwarf_Unsigned offset_from_end_symbol,
+		       Dwarf_Signed offset_into_exception_tables,
+		       Dwarf_Unsigned exception_table_symbol,
+		       Dwarf_Error * error)
+{
+    Dwarf_P_Fde curfde;
+
+    fde->fde_die = die;
+    fde->fde_cie = (long) cie;
+    fde->fde_initloc = virt_addr;
+    fde->fde_r_symidx = symidx;
+    fde->fde_addr_range = code_len;
+    fde->fde_offset_into_exception_tables =
+	offset_into_exception_tables;
+    fde->fde_exception_table_symbol = exception_table_symbol;
+    fde->fde_end_symbol_offset = offset_from_end_symbol;
+    fde->fde_end_symbol = end_symidx;
+    fde->fde_dbg = dbg;
+
+    curfde = dbg->de_last_fde;
+    if (curfde == NULL) {
+	dbg->de_frame_fdes = fde;
+	dbg->de_last_fde = fde;
+	dbg->de_n_fde = 1;
+    } else {
+	curfde->fde_next = fde;
+	dbg->de_last_fde = fde;
+	dbg->de_n_fde++;
+    }
+    return dbg->de_n_fde;
+}
+
+
+/*-------------------------------------------------------------------
+	Create a new fde 
+---------------------------------------------------------------------*/
+Dwarf_P_Fde
+dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error * error)
+{
+    Dwarf_P_Fde fde;
+
+    fde = (Dwarf_P_Fde)
+	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Fde_s));
+    if (fde == NULL) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_FDE_ALLOC,
+			  (Dwarf_P_Fde) DW_DLV_BADADDR);
+    }
+    fde->fde_next = NULL;
+    fde->fde_inst = NULL;
+    fde->fde_n_inst = 0;
+    fde->fde_n_bytes = 0;
+    fde->fde_last_inst = NULL;
+    fde->fde_uwordb_size = dbg->de_offset_size;
+    return fde;
+}
+
+/*------------------------------------------------------------------------
+	Add cfe_offset instruction to fde
+-------------------------------------------------------------------------*/
+Dwarf_P_Fde
+dwarf_fde_cfa_offset(Dwarf_P_Fde fde,
+		     Dwarf_Unsigned reg,
+		     Dwarf_Signed offset, Dwarf_Error * error)
+{
+    Dwarf_Ubyte opc, regno;
+    char *ptr;
+    Dwarf_P_Frame_Pgm curinst;
+    int nbytes;
+    int res;
+    char buff1[ENCODE_SPACE_NEEDED];
+    Dwarf_P_Debug dbg = fde->fde_dbg;
+
+    curinst = (Dwarf_P_Frame_Pgm)
+	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s));
+    if (curinst == NULL) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_FPGM_ALLOC,
+			  (Dwarf_P_Fde) DW_DLV_BADADDR);
+    }
+    opc = DW_CFA_offset;
+    regno = reg;
+    if (regno & 0xc0) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_REGNO_OVFL,
+			  (Dwarf_P_Fde) DW_DLV_BADADDR);
+    }
+    opc = opc | regno;		/* lower 6 bits are register number */
+    curinst->dfp_opcode = opc;
+    res = _dwarf_pro_encode_leb128_nm(offset, &nbytes,
+				      buff1, sizeof(buff1));
+    if (res != DW_DLV_OK) {
+	_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+	return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+    }
+    ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
+    if (ptr == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+	return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+    }
+    memcpy(ptr, buff1, nbytes);
+
+    curinst->dfp_args = ptr;
+    curinst->dfp_nbytes = nbytes;
+    curinst->dfp_next = NULL;
+
+    _dwarf_pro_add_to_fde(fde, curinst);
+    return fde;
+}
+
+/*
+    Generic routine to add opcode to fde instructions. val1 and
+    val2 are parameters whose interpretation depends on the 'op'.
+
+    This does not work properly for  DW_DLC_SYMBOLIC_RELOCATIONS
+    for DW_CFA_set_loc or DW_DVA_advance_loc* 'op', as
+    these ops normally are addresses or (DW_CFA_set_loc) 
+    or code lengths (DW_DVA_advance_loc*) and such must be
+    represented with relocations and symbol indices for
+    DW_DLC_SYMBOLIC_RELOCATIONS.
+
+    This does not treat all DW_CFA instructions and
+    currently excludes DWARF3 additions.
+
+*/
+Dwarf_P_Fde
+dwarf_add_fde_inst(Dwarf_P_Fde fde,
+		   Dwarf_Small op,
+		   Dwarf_Unsigned val1,
+		   Dwarf_Unsigned val2, Dwarf_Error * error)
+{
+    Dwarf_P_Frame_Pgm curinst;
+    int nbytes, nbytes1, nbytes2;
+    Dwarf_Ubyte db;
+    Dwarf_Half dh;
+    Dwarf_Word dw;
+    Dwarf_Unsigned du;
+    char *ptr;
+    int res;
+    char buff1[ENCODE_SPACE_NEEDED];
+    char buff2[ENCODE_SPACE_NEEDED];
+    Dwarf_P_Debug dbg = fde->fde_dbg;
+
+
+    nbytes = 0;
+    ptr = NULL;
+    curinst = (Dwarf_P_Frame_Pgm)
+	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s));
+    if (curinst == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_FPGM_ALLOC);
+	return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+    }
+
+    switch (op) {
+
+    case DW_CFA_advance_loc:
+	if (val1 <= 0x3f) {
+	    db = val1;
+	    op |= db;
+	}
+	/* test not portable FIX */
+	else if (val1 <= UCHAR_MAX) {
+	    op = DW_CFA_advance_loc1;
+	    db = val1;
+	    ptr = (char *) _dwarf_p_get_alloc(dbg, 1);
+	    if (ptr == NULL) {
+		_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+	    }
+	    memcpy((void *) ptr, (const void *) &db, 1);
+	    nbytes = 1;
+	}
+	/* test not portable FIX */
+	else if (val1 <= USHRT_MAX) {
+	    op = DW_CFA_advance_loc2;
+	    dh = val1;
+	    ptr = (char *) _dwarf_p_get_alloc(dbg, 2);
+	    if (ptr == NULL) {
+		_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+	    }
+	    memcpy((void *) ptr, (const void *) &dh, 2);
+	    nbytes = 2;
+	}
+	/* test not portable FIX */
+	else if (val1 <= ULONG_MAX) {
+	    op = DW_CFA_advance_loc4;
+	    dw = (Dwarf_Word) val1;
+	    ptr = (char *) _dwarf_p_get_alloc(dbg, 4);
+	    if (ptr == NULL) {
+		_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+	    }
+	    memcpy((void *) ptr, (const void *) &dw, 4);
+	    nbytes = 4;
+	} else {
+	    op = DW_CFA_MIPS_advance_loc8;
+	    du = val1;
+	    ptr =
+		(char *) _dwarf_p_get_alloc(dbg,
+					    sizeof(Dwarf_Unsigned));
+	    if (ptr == NULL) {
+		_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+	    }
+	    memcpy((void *) ptr, (const void *) &du, 8);
+	    nbytes = 8;
+	}
+	break;
+
+    case DW_CFA_offset:
+	if (val1 <= MAX_6_BIT_VALUE) {
+	    db = val1;
+	    op |= db;
+	    res = _dwarf_pro_encode_leb128_nm(val2, &nbytes,
+					      buff1, sizeof(buff1));
+	    if (res != DW_DLV_OK) {
+		_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+	    }
+	    ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
+	    if (ptr == NULL) {
+		_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+	    }
+	    memcpy(ptr, buff1, nbytes);
+
+	} else {
+	    op = DW_CFA_offset_extended;
+
+	    res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1,
+					      buff1, sizeof(buff1));
+	    if (res != DW_DLV_OK) {
+		_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+	    }
+	    res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2,
+					      buff2, sizeof(buff2));
+	    if (res != DW_DLV_OK) {
+		_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+	    }
+	    ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes1 + nbytes2);
+	    if (ptr == NULL) {
+		_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+	    }
+	    memcpy(ptr, buff1, nbytes1);
+	    memcpy(ptr + nbytes1, buff2, nbytes2);
+	    nbytes = nbytes1 + nbytes2;
+	}
+	break;
+
+    case DW_CFA_undefined:
+    case DW_CFA_same_value:
+	res = _dwarf_pro_encode_leb128_nm(val1, &nbytes,
+					  buff1, sizeof(buff1));
+	if (res != DW_DLV_OK) {
+	    _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+	}
+	ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
+	if (ptr == NULL) {
+	    _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+	}
+	memcpy(ptr, buff1, nbytes);
+	break;
+
+    case DW_CFA_register:
+    case DW_CFA_def_cfa:
+	res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1,
+					  buff1, sizeof(buff1));
+	if (res != DW_DLV_OK) {
+	    _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+	}
+
+	res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2,
+					  buff2, sizeof(buff2));
+	if (res != DW_DLV_OK) {
+	    _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+	}
+
+	ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes1 + nbytes2);
+	if (ptr == NULL) {
+	    _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+	}
+	memcpy(ptr, buff1, nbytes1);
+	memcpy(ptr + nbytes1, buff2, nbytes2);
+	nbytes = nbytes1 + nbytes2;
+	break;
+
+    case DW_CFA_def_cfa_register:
+    case DW_CFA_def_cfa_offset:
+	res = _dwarf_pro_encode_leb128_nm(val1, &nbytes,
+					  buff1, sizeof(buff1));
+	if (res != DW_DLV_OK) {
+	    _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+	}
+	ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
+	if (ptr == NULL) {
+	    _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
+	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
+	}
+	memcpy(ptr, buff1, nbytes);
+	break;
+
+    default:
+	/* This is wrong. We are just ignoring
+           instructions we don't yet handle. FIXME. */
+	break;
+    }
+
+    curinst->dfp_opcode = op;
+    curinst->dfp_args = ptr;
+    curinst->dfp_nbytes = nbytes;
+    curinst->dfp_next = NULL;
+
+    _dwarf_pro_add_to_fde(fde, curinst);
+    return fde;
+}
+
+
+/*------------------------------------------------------------------------
+	instructions are added to fde in the form of a linked
+	list. This function manages the linked list
+-------------------------------------------------------------------------*/
+void
+_dwarf_pro_add_to_fde(Dwarf_P_Fde fde, Dwarf_P_Frame_Pgm curinst)
+{
+    if (fde->fde_last_inst) {
+	fde->fde_last_inst->dfp_next = curinst;
+	fde->fde_last_inst = curinst;
+	fde->fde_n_inst++;
+	fde->fde_n_bytes +=
+	    (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte));
+    } else {
+	fde->fde_last_inst = curinst;
+	fde->fde_inst = curinst;
+	fde->fde_n_inst = 1;
+	fde->fde_n_bytes =
+	    (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_frame.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,127 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+/*
+    Largest register value that can be coded into
+    the opcode since there are only 6 bits in the
+    register field.
+*/
+#define MAX_6_BIT_VALUE		0x3f
+
+/*
+	This struct holds debug_frame instructions
+*/
+typedef struct Dwarf_P_Frame_Pgm_s *Dwarf_P_Frame_Pgm;
+
+struct Dwarf_P_Frame_Pgm_s {
+    Dwarf_Ubyte dfp_opcode;	/* opcode - includes reg # */
+    char *dfp_args;		/* operands */
+    int dfp_nbytes;		/* number of bytes in args */
+#if 0
+    Dwarf_Unsigned dfp_sym_index;	/* 0 unless reloc needed */
+#endif
+    Dwarf_P_Frame_Pgm dfp_next;
+};
+
+
+/*
+	This struct has cie related information. Used to gather data 
+	from user program, and later to transform to disk form
+*/
+struct Dwarf_P_Cie_s {
+    Dwarf_Ubyte cie_version;
+    char *cie_aug;		/* augmentation */
+    Dwarf_Ubyte cie_code_align;	/* alignment of code */
+    Dwarf_Sbyte cie_data_align;
+    Dwarf_Ubyte cie_ret_reg;	/* return register # */
+    char *cie_inst;		/* initial instruction */
+    long cie_inst_bytes;
+    /* no of init_inst */
+    Dwarf_P_Cie cie_next;
+};
+
+
+/* producer fields */
+struct Dwarf_P_Fde_s {
+    Dwarf_Unsigned fde_unused1;
+
+    /* function/subr die for this fde */
+    Dwarf_P_Die fde_die;
+
+    /* index to asso. cie */
+    Dwarf_Word fde_cie;
+
+    /* Address of first location of the code this frame applies to If
+       fde_end_symbol non-zero, this represents the offset from the
+       symbol indicated by fde_r_symidx */
+    Dwarf_Addr fde_initloc;
+
+    /* Relocation symbol for address of the code this frame applies to. 
+     */
+    Dwarf_Unsigned fde_r_symidx;
+
+    /* Bytes of instr for this fde, if known */
+    Dwarf_Unsigned fde_addr_range;
+
+    /* linked list of instructions we will put in fde. */
+    Dwarf_P_Frame_Pgm fde_inst;
+
+    /* number of instructions in fde */
+    long fde_n_inst;
+
+    /* number of bytes of inst in fde */
+    long fde_n_bytes;
+
+    /* offset into exception table for this function. */
+    Dwarf_Signed fde_offset_into_exception_tables;
+
+    /* The symbol for the exception table elf section. */
+    Dwarf_Unsigned fde_exception_table_symbol;
+
+    /* pointer to last inst */
+    Dwarf_P_Frame_Pgm fde_last_inst;
+
+    Dwarf_P_Fde fde_next;
+
+    /* The symbol and offset of the end symbol. When fde_end_symbol is
+       non-zero we must represent the */
+    Dwarf_Addr fde_end_symbol_offset;
+    Dwarf_Unsigned fde_end_symbol;
+
+    int fde_uwordb_size;
+    Dwarf_P_Debug fde_dbg;
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_funcs.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,62 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_ELFACCESS_H
+#include <elfaccess.h>
+#endif
+#include "pro_incl.h"
+#include "pro_section.h"
+
+/*
+    This function adds another function name to the 
+    list of function names for the given Dwarf_P_Debug.  
+    It returns 0 on error, and 1 otherwise.
+*/
+Dwarf_Unsigned
+dwarf_add_funcname(Dwarf_P_Debug dbg,
+		   Dwarf_P_Die die,
+		   char *function_name, Dwarf_Error * error)
+{
+    return
+	_dwarf_add_simple_name_entry(dbg, die, function_name,
+				     dwarf_snk_funcname, error);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_incl.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,92 @@
+/*
+
+  Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+#ifdef HAVE_ELF_H
+#include <elf.h>
+#elif defined(HAVE_LIBELF_H) 
+/* On one platform without elf.h this gets Elf32_Rel 
+   type defined (a required type). */
+#include <libelf.h>
+#endif
+
+#if defined(sun)
+#include <sys/elf_SPARC.h>
+#include <sys/elf_386.h>
+#endif
+
+/* The target address is given: the place in the source integer
+   is to be determined.
+*/
+#ifdef WORDS_BIGENDIAN
+#define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \
+    { \
+      dbg->de_copy_word(dest, \
+                        ((char *)source) +srclength-len_out,  \
+			len_out) ; \
+    }
+
+
+#else /* LITTLE ENDIAN */
+
+#define WRITE_UNALIGNED(dbg,dest,source, srclength,len_out) \
+    { \
+      dbg->de_copy_word( (dest) , \
+                        ((char *)source) ,  \
+			len_out) ; \
+    }
+#endif
+
+
+#if defined(sparc) && defined(sun)
+#define REL32 Elf32_Rela
+#define REL64 Elf64_Rela
+#define REL_SEC_PREFIX ".rela"
+#else
+#define REL32 Elf32_Rel
+#define REL64 Elf64_Rel
+#define REL_SEC_PREFIX ".rel"
+#endif
+
+
+#include "libdwarf.h"
+
+#include "dwarf.h"
+#include "pro_opaque.h"
+#include "pro_error.h"
+#include "pro_util.h"
+#include "pro_encode_nm.h"
+#include "pro_alloc.h"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_init.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,251 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#include <stdio.h>
+#include <string.h>
+#include "pro_incl.h"
+#include "pro_section.h"	/* for MAGIC_SECT_NO */
+#include "pro_reloc_symbolic.h"
+#include "pro_reloc_stream.h"
+
+
+static void common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags);
+
+void *_dwarf_memcpy_swap_bytes(void *s1, const void *s2, size_t len);
+
+/*--------------------------------------------------------------------
+	This function sets up a new dwarf producing region. 
+	flags: Indicates type of access method, one of DW_DLC* macros
+	func(): Used to create a new object file, a call back function
+	errhand(): Error Handler provided by user
+	errarg: Argument to errhand()
+	error: returned error value
+--------------------------------------------------------------------*/
+    /* We want the following to have an elf section number that matches 
+       'nothing' */
+static struct Dwarf_P_Section_Data_s init_sect = {
+    MAGIC_SECT_NO, 0, 0, 0, 0
+};
+
+Dwarf_P_Debug
+dwarf_producer_init_b(Dwarf_Unsigned flags,
+		      Dwarf_Callback_Func_b func,
+		      Dwarf_Handler errhand,
+		      Dwarf_Ptr errarg, Dwarf_Error * error)
+{
+    Dwarf_P_Debug dbg;
+    dbg = (Dwarf_P_Debug) _dwarf_p_get_alloc(NULL,
+					     sizeof(struct
+						    Dwarf_P_Debug_s));
+    if (dbg == NULL) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC,
+			  (Dwarf_P_Debug) DW_DLV_BADADDR);
+    }
+    memset((void *) dbg, 0, sizeof(struct Dwarf_P_Debug_s));
+    /* For the time being */
+    if (func == NULL) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC,
+			  (Dwarf_P_Debug) DW_DLV_BADADDR);
+    }
+    dbg->de_func_b = func;
+    dbg->de_errhand = errhand;
+    dbg->de_errarg = errarg;
+    common_init(dbg, flags);
+    return dbg;
+
+}
+
+Dwarf_P_Debug
+dwarf_producer_init(Dwarf_Unsigned flags,
+		    Dwarf_Callback_Func func,
+		    Dwarf_Handler errhand,
+		    Dwarf_Ptr errarg, Dwarf_Error * error)
+{
+
+    Dwarf_P_Debug dbg;
+
+
+
+    dbg = (Dwarf_P_Debug) _dwarf_p_get_alloc(NULL,
+					     sizeof(struct
+						    Dwarf_P_Debug_s));
+    if (dbg == NULL) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC,
+			  (Dwarf_P_Debug) DW_DLV_BADADDR);
+    }
+    memset((void *) dbg, 0, sizeof(struct Dwarf_P_Debug_s));
+    /* For the time being */
+    if (func == NULL) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_NO_CALLBACK_FUNC,
+			  (Dwarf_P_Debug) DW_DLV_BADADDR);
+    }
+    dbg->de_func = func;
+    dbg->de_errhand = errhand;
+    dbg->de_errarg = errarg;
+    common_init(dbg, flags);
+    return dbg;
+}
+static void
+common_init(Dwarf_P_Debug dbg, Dwarf_Unsigned flags)
+{
+    unsigned int k;
+
+
+    dbg->de_version_magic_number = PRO_VERSION_MAGIC;
+    dbg->de_n_debug_sect = 0;
+    dbg->de_debug_sects = &init_sect;
+    dbg->de_current_active_section = &init_sect;
+    dbg->de_flags = flags;
+
+    /* Now, with flags set, can use 64bit tests */
+
+
+
+#if  defined(HAVE_DWARF2_99_EXTENSION)
+    /* Revised 64 bit output, using distingushed values. Per 1999
+       dwarf2 revision This produces 64bit extension with ia64 objects.
+
+       Some might want library run time selection of offset size. Not
+       provided here at present. */
+    dbg->de_64bit_extension = (IS_64BIT(dbg) ? 1 : 0);
+    dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4);
+    dbg->de_offset_size = (IS_64BIT(dbg) ? 8 : 4);
+    dbg->de_ptr_reloc =
+	IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg);
+    /* Non-MIPS, dwarf lengths and offsets are 32 bits even for 64bit
+       pointer environments. */
+    /* Get_REL??_isa here supports 64bit-offset dwarf. For 64bit, we
+       emit the extension bytes. */
+
+    dbg->de_offset_reloc = IS_64BIT(dbg) ? Get_REL64_isa(dbg)
+	: Get_REL32_isa(dbg);
+#elif defined(HAVE_OLD_DWARF2_32BIT_OFFSET)
+    /* This is cygnus 32bit offset, as specified in pure dwarf2 v2.0.0 */
+    dbg->de_64bit_extension = 0;
+    dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4);
+    dbg->de_offset_size = (IS_64BIT(dbg) ? 4 : 4);
+    dbg->de_ptr_reloc =
+	IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg);
+    /* non-MIPS, dwarf lengths and offsets are 32 bits even for 64bit
+       pointer environments. */
+    /* Get_REL32_isa here supports 64-bit-pointer dwarf with pure
+       dwarf2 v2.0.0 32bit offsets, as emitted by cygnus tools. And
+       pure 32 bit offset dwarf for 32bit pointer apps. */
+
+    dbg->de_offset_reloc = Get_REL32_isa(dbg);
+#else
+    /* MIPS-SGI 32 or 64, where offsets and lengths are both 64 bit for 
+       64bit pointer objects and both 32 bit for 32bit pointer objects. 
+       And a dwarf-reader must check elf info to tell which applies. */
+    dbg->de_64bit_extension = 0;
+    dbg->de_pointer_size = (IS_64BIT(dbg) ? 8 : 4);
+    dbg->de_offset_size = (IS_64BIT(dbg) ? 8 : 4);
+    dbg->de_ptr_reloc =
+	IS_64BIT(dbg) ? Get_REL64_isa(dbg) : Get_REL32_isa(dbg);
+    dbg->de_offset_reloc = dbg->de_ptr_reloc;
+#endif
+    dbg->de_exc_reloc = Get_REL_SEGREL_isa(dbg);
+
+    dbg->de_is_64bit = IS_64BIT(dbg);
+
+
+    if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) {
+	dbg->de_relocation_record_size =
+	    sizeof(struct Dwarf_Relocation_Data_s);
+    } else {
+	
+#if HAVE_ELF64_GETEHDR
+	dbg->de_relocation_record_size =
+	    IS_64BIT(dbg)? sizeof(REL64) : sizeof(REL32);
+#else
+	dbg->de_relocation_record_size = sizeof(REL32);
+#endif
+
+    }
+
+    if (dbg->de_offset_size == 8) {
+	dbg->de_ar_data_attribute_form = DW_FORM_data8;
+	dbg->de_ar_ref_attr_form = DW_FORM_ref8;
+    } else {
+	dbg->de_ar_data_attribute_form = DW_FORM_data4;
+	dbg->de_ar_ref_attr_form = DW_FORM_ref4;
+    }
+
+    if (flags & DW_DLC_SYMBOLIC_RELOCATIONS) {
+	dbg->de_reloc_name = _dwarf_pro_reloc_name_symbolic;
+	dbg->de_reloc_pair = _dwarf_pro_reloc_length_symbolic;
+	dbg->de_transform_relocs_to_disk =
+	    _dwarf_symbolic_relocs_to_disk;
+    } else {
+	if (IS_64BIT(dbg)) {
+	    dbg->de_reloc_name = _dwarf_pro_reloc_name_stream64;
+	} else {
+	    dbg->de_reloc_name = _dwarf_pro_reloc_name_stream32;
+	}
+	dbg->de_reloc_pair = 0;
+	dbg->de_transform_relocs_to_disk = _dwarf_stream_relocs_to_disk;
+    }
+    for (k = 0; k < NUM_DEBUG_SECTIONS; ++k) {
+
+	Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[k];
+
+	prel->pr_slots_per_block_to_alloc = DEFAULT_SLOTS_PER_BLOCK;
+    }
+    /* First assume host, target same endianness */
+    dbg->de_same_endian = 1;
+    dbg->de_copy_word = memcpy;
+#ifdef WORDS_BIGENDIAN
+    /* host is big endian, so what endian is target? */
+    if (flags & DW_DLC_TARGET_LITTLEENDIAN) {
+	dbg->de_same_endian = 0;
+	dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
+    }
+#else /* little endian */
+    /* host is little endian, so what endian is target? */
+    if (flags & DW_DLC_TARGET_BIGENDIAN) {
+	dbg->de_same_endian = 0;
+	dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
+    }
+#endif /* !WORDS_BIGENDIAN */
+
+
+    return;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_line.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,300 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_ELF_H
+#include <elf.h>
+#endif
+#include "pro_incl.h"
+#include "pro_line.h"
+
+Dwarf_Unsigned _dwarf_pro_add_line_entry(Dwarf_P_Debug,
+					 Dwarf_Unsigned file_index,
+					 Dwarf_Addr code_address,
+					 Dwarf_Unsigned symidx,
+					 Dwarf_Unsigned line_no,
+					 Dwarf_Signed col_no,
+					 Dwarf_Bool is_stmt_begin,
+					 Dwarf_Bool is_bb_begin,
+					 Dwarf_Ubyte opc,
+					 Dwarf_Error * error);
+
+/*-------------------------------------------------------------------------
+	Add a entry to the line information section
+	file_index: index of file in file entries, obtained from
+	add_file_entry() call. 
+	
+	This function actually calls _dwarf_pro_add_line_entry(), with
+	an extra parameter, the opcode. Done so that interface calls
+	dwarf_lne_set_address() and dwarf_lne_end_sequence() can use
+	this internal routine.
+---------------------------------------------------------------------------*/
+Dwarf_Unsigned
+dwarf_add_line_entry(Dwarf_P_Debug dbg,
+		     Dwarf_Unsigned file_index,
+		     Dwarf_Addr code_address,
+		     Dwarf_Unsigned line_no,
+		     Dwarf_Signed col_no,
+		     Dwarf_Bool is_stmt_begin,
+		     Dwarf_Bool is_bb_begin, Dwarf_Error * error)
+{
+    Dwarf_Unsigned retval;
+
+    retval = _dwarf_pro_add_line_entry(dbg, file_index, code_address, 0,
+				       line_no, col_no, is_stmt_begin,
+				       is_bb_begin, 0, error);
+    return retval;
+}
+
+/*------------------------------------------------------------------------
+	Ask to emit DW_LNE_set_address opcode explicitly. Used by be
+	to emit start of a new .text section, or to force a relocated
+	address into debug line information entry.
+-------------------------------------------------------------------------*/
+Dwarf_Unsigned
+dwarf_lne_set_address(Dwarf_P_Debug dbg,
+		      Dwarf_Addr offs,
+		      Dwarf_Unsigned symidx, Dwarf_Error * error)
+{
+    Dwarf_Ubyte opc;
+    Dwarf_Unsigned retval;
+
+    opc = DW_LNE_set_address;
+    retval =
+	_dwarf_pro_add_line_entry(dbg, 0, offs, symidx, 0, 0, 0, 0, opc,
+				  error);
+    return retval;
+}
+
+/*------------------------------------------------------------------------
+	Ask to emit end_seqence opcode. Used normally at the end of a 
+	compilation unit. Can also be used in the middle if there
+	are gaps in the region described by the code address. 
+-------------------------------------------------------------------------*/
+Dwarf_Unsigned
+dwarf_lne_end_sequence(Dwarf_P_Debug dbg,
+		       Dwarf_Addr end_address, Dwarf_Error * error)
+{
+    Dwarf_Ubyte opc;
+    Dwarf_Unsigned retval;
+
+    opc = DW_LNE_end_sequence;
+    retval =
+	_dwarf_pro_add_line_entry(dbg, 0, end_address, 0, 0, 0, 0, 0,
+				  opc, error);
+    return retval;
+}
+
+/*----------------------------------------------------------------------------
+	Add an entry in the internal list of lines mantained by producer. 
+	Opc indicates if an opcode needs to be generated, rather than just
+	an entry in the matrix. During opcodes generation time, these 
+	opcodes will be used.
+-----------------------------------------------------------------------------*/
+Dwarf_Unsigned
+_dwarf_pro_add_line_entry(Dwarf_P_Debug dbg,
+			  Dwarf_Unsigned file_index,
+			  Dwarf_Addr code_address,
+			  Dwarf_Unsigned symidx,
+			  Dwarf_Unsigned line_no,
+			  Dwarf_Signed col_no,
+			  Dwarf_Bool is_stmt_begin,
+			  Dwarf_Bool is_bb_begin,
+			  Dwarf_Ubyte opc, Dwarf_Error * error)
+{
+    if (dbg->de_lines == NULL) {
+	dbg->de_lines = (Dwarf_P_Line)
+	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
+	if (dbg->de_lines == NULL) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_NOCOUNT);
+	}
+	dbg->de_last_line = dbg->de_lines;
+	_dwarf_pro_reg_init(dbg->de_lines);
+
+    } else {
+	dbg->de_last_line->dpl_next = (Dwarf_P_Line)
+	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
+	if (dbg->de_last_line->dpl_next == NULL) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, DW_DLV_NOCOUNT);
+	}
+	dbg->de_last_line = dbg->de_last_line->dpl_next;
+	_dwarf_pro_reg_init(dbg->de_last_line);
+    }
+    dbg->de_last_line->dpl_address = code_address;
+    dbg->de_last_line->dpl_file = (unsigned long) file_index;
+    dbg->de_last_line->dpl_line = (unsigned long) line_no;
+    dbg->de_last_line->dpl_column = (unsigned long) col_no;
+    dbg->de_last_line->dpl_is_stmt = is_stmt_begin;
+    dbg->de_last_line->dpl_basic_block = is_bb_begin;
+    dbg->de_last_line->dpl_opc = opc;
+    dbg->de_last_line->dpl_r_symidx = symidx;
+
+    return (0);
+}
+
+/*-----------------------------------------------------------------------
+	Add a directory declaration to the debug_line section. Stored
+	in linked list.
+------------------------------------------------------------------------*/
+Dwarf_Unsigned
+dwarf_add_directory_decl(Dwarf_P_Debug dbg,
+			 char *name, Dwarf_Error * error)
+{
+    if (dbg->de_inc_dirs == NULL) {
+	dbg->de_inc_dirs = (Dwarf_P_Inc_Dir)
+	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Inc_Dir_s));
+	if (dbg->de_inc_dirs == NULL) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_NOCOUNT);
+	}
+	dbg->de_last_inc_dir = dbg->de_inc_dirs;
+	dbg->de_n_inc_dirs = 1;
+    } else {
+	dbg->de_last_inc_dir->did_next = (Dwarf_P_Inc_Dir)
+	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Inc_Dir_s));
+	if (dbg->de_last_inc_dir->did_next == NULL) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_INCDIR_ALLOC, DW_DLV_NOCOUNT);
+	}
+	dbg->de_last_inc_dir = dbg->de_last_inc_dir->did_next;
+	dbg->de_n_inc_dirs++;
+    }
+    dbg->de_last_inc_dir->did_name =
+	(char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1);
+    if (dbg->de_last_inc_dir->did_name == NULL) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_STRING_ALLOC, DW_DLV_NOCOUNT);
+    }
+    strcpy(dbg->de_last_inc_dir->did_name, name);
+    dbg->de_last_inc_dir->did_next = NULL;
+
+    return dbg->de_n_inc_dirs;
+}
+
+/*-----------------------------------------------------------------------
+	Add a file entry declaration to the debug_line section. Stored
+	in linked list. The data is immediately encodes as leb128
+	and stored in Dwarf_P_F_Entry_s struct.
+------------------------------------------------------------------------*/
+Dwarf_Unsigned
+dwarf_add_file_decl(Dwarf_P_Debug dbg,
+		    char *name,
+		    Dwarf_Unsigned dir_idx,
+		    Dwarf_Unsigned time_mod,
+		    Dwarf_Unsigned length, Dwarf_Error * error)
+{
+    Dwarf_P_F_Entry cur;
+    char *ptr;
+    int nbytes_idx, nbytes_time, nbytes_len;
+    char buffidx[ENCODE_SPACE_NEEDED];
+    char bufftime[ENCODE_SPACE_NEEDED];
+    char bufflen[ENCODE_SPACE_NEEDED];
+    int res;
+
+    if (dbg->de_file_entries == NULL) {
+	dbg->de_file_entries = (Dwarf_P_F_Entry)
+	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s));
+	if (dbg->de_file_entries == NULL) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC,
+			      DW_DLV_NOCOUNT);
+	}
+	cur = dbg->de_file_entries;
+	dbg->de_last_file_entry = cur;
+	dbg->de_n_file_entries = 1;
+    } else {
+	cur = dbg->de_last_file_entry;
+	cur->dfe_next = (Dwarf_P_F_Entry)
+	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_F_Entry_s));
+	if (cur->dfe_next == NULL) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_FILE_ENTRY_ALLOC,
+			      DW_DLV_NOCOUNT);
+	}
+	cur = cur->dfe_next;
+	dbg->de_last_file_entry = cur;
+	dbg->de_n_file_entries++;
+    }
+    cur->dfe_name = (char *) _dwarf_p_get_alloc(dbg, strlen(name) + 1);
+    if (cur->dfe_name == NULL) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
+    }
+    strcpy((char *) cur->dfe_name, name);
+    res = _dwarf_pro_encode_leb128_nm(dir_idx, &nbytes_idx,
+				      buffidx, sizeof(buffidx));
+    if (res != DW_DLV_OK) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
+    }
+    res = _dwarf_pro_encode_leb128_nm(time_mod, &nbytes_time,
+				      bufftime, sizeof(bufftime));
+    if (res != DW_DLV_OK) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
+    }
+    res = _dwarf_pro_encode_leb128_nm(length, &nbytes_len,
+				      bufflen, sizeof(bufflen));
+    cur->dfe_args = (char *)
+	_dwarf_p_get_alloc(dbg, nbytes_idx + nbytes_time + nbytes_len);
+    if (cur->dfe_args == NULL) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_ALLOC_FAIL, DW_DLV_NOCOUNT);
+    }
+    ptr = cur->dfe_args;
+    memcpy((void *) ptr, buffidx, nbytes_idx);
+    ptr += nbytes_idx;
+    memcpy((void *) ptr, bufftime, nbytes_time);
+    ptr += nbytes_time;
+    memcpy((void *) ptr, bufflen, nbytes_len);
+    ptr += nbytes_len;
+    cur->dfe_nbytes = nbytes_idx + nbytes_time + nbytes_len;
+    cur->dfe_next = NULL;
+
+    return dbg->de_n_file_entries;
+}
+
+
+/*---------------------------------------------------------------------
+	Initialize a row of the matrix for line numbers, meaning 
+	initialize the struct corresponding to it
+----------------------------------------------------------------------*/
+void
+_dwarf_pro_reg_init(Dwarf_P_Line cur_line)
+{
+    cur_line->dpl_address = 0;
+    cur_line->dpl_file = 1;
+    cur_line->dpl_line = 1;
+    cur_line->dpl_column = 0;
+    cur_line->dpl_is_stmt = DEFAULT_IS_STMT;
+    cur_line->dpl_basic_block = false;
+    cur_line->dpl_next = NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_line.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,116 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#define VERSION				2
+#ifdef __i386
+#define MIN_INST_LENGTH			1
+#else
+#define MIN_INST_LENGTH			4
+#endif
+#define DEFAULT_IS_STMT			false
+			/* line base and range are temporarily defines.
+			   They need to be calculated later */
+#define LINE_BASE			-1
+#define LINE_RANGE			4
+
+#define OPCODE_BASE			10
+#define MAX_OPCODE			255
+
+
+/*
+	This struct is used to hold entries in the include directories
+	part of statement prologue.
+*/
+struct Dwarf_P_Inc_Dir_s {
+    char *did_name;		/* name of directory */
+    Dwarf_P_Inc_Dir did_next;
+};
+
+
+/*
+	This struct holds file entries for the statement prologue. 
+	Defined in pro_line.h
+*/
+struct Dwarf_P_F_Entry_s {
+    char *dfe_name;
+    char *dfe_args;		/* has dir index, time of modification,
+				   length in bytes. Encodes as leb128 */
+    int dfe_nbytes;		/* number of bytes in args */
+    Dwarf_P_F_Entry dfe_next;
+};
+
+
+/*
+	Struct holding line number information for each of the producer 
+	line entries 
+*/
+struct Dwarf_P_Line_s {
+    /* code address */
+    Dwarf_Addr dpl_address;
+
+    /* file index, index into file entry */
+    Dwarf_Word dpl_file;
+
+    /* line number */
+    Dwarf_Word dpl_line;
+
+    /* column number */
+    Dwarf_Word dpl_column;
+
+    /* whether its a beginning of a stmt */
+    Dwarf_Ubyte dpl_is_stmt;
+
+    /* whether its a beginning of basic blk */
+    Dwarf_Ubyte dpl_basic_block;
+
+    /* used to store opcodes set_address, and end_seq */
+    Dwarf_Ubyte dpl_opc;
+
+    /* 
+       Used only for relocations.  Has index of symbol relative to
+       which relocation has to be done (the S part in S + A) */
+    Dwarf_Unsigned dpl_r_symidx;
+
+    Dwarf_P_Line dpl_next;
+};
+
+/* 
+	to initialize state machine registers, definition in 
+	pro_line.c
+*/
+void _dwarf_pro_reg_init(Dwarf_P_Line);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_macinfo.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,472 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#include <stdio.h>
+#include <string.h>
+#include "pro_incl.h"
+#include "pro_section.h"
+#include "pro_macinfo.h"
+
+/*
+	I don't much like the error strings this generates, since
+	like the rest of libdwarf they are simple strings with
+	no useful numbers in them. But that's not something I can
+	fix without more work than I have time for
+	right now.  davea Nov 94.
+*/
+
+/* these are gross overestimates of the number of
+** bytes needed to store a number in LEB form.
+** Just estimates, and since blocks are reasonable size,
+** the end-block waste is small.
+** Of course the waste is NOT present on disk.
+*/
+
+#define COMMAND_LEN ENCODE_SPACE_NEEDED
+#define LINE_LEN    ENCODE_SPACE_NEEDED
+#define BASE_MACINFO_MALLOC_LEN 2048
+
+static int
+libdwarf_compose_begin(Dwarf_P_Debug dbg, int code,
+		       size_t maxlen, int *compose_error_type)
+{
+    unsigned char *nextchar;
+    struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo;
+
+    if (curblk == 0) {
+	struct dw_macinfo_block_s *newb;
+	size_t len;
+
+	/* initial allocation */
+	size_t blen = BASE_MACINFO_MALLOC_LEN;
+
+	if (blen < maxlen) {
+	    blen = 2 * maxlen;
+	}
+	len = sizeof(struct dw_macinfo_block_s) + blen;
+	newb =
+	    (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len);
+	if (!newb) {
+	    *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL;
+	    return DW_DLV_ERROR;
+	}
+	newb->mb_data =
+	    (char *) newb + sizeof(struct dw_macinfo_block_s);
+	newb->mb_avail_len = blen;
+	newb->mb_used_len = 0;
+	newb->mb_macinfo_data_space_len = blen;
+	dbg->de_first_macinfo = newb;
+	dbg->de_current_macinfo = newb;
+	curblk = newb;
+    } else if (curblk->mb_avail_len < maxlen) {
+	struct dw_macinfo_block_s *newb;
+	size_t len;
+
+	/* no space left in block: allocate a new block */
+	size_t blen =
+	    dbg->de_current_macinfo->mb_macinfo_data_space_len * 2;
+	if (blen < maxlen) {
+	    blen = 2 * maxlen;
+	}
+	len = sizeof(struct dw_macinfo_block_s) + blen;
+	newb =
+	    (struct dw_macinfo_block_s *) _dwarf_p_get_alloc(dbg, len);
+	if (!newb) {
+	    *compose_error_type = DW_DLE_MACINFO_MALLOC_FAIL;
+	    return DW_DLV_ERROR;
+	}
+	newb->mb_data =
+	    (char *) newb + sizeof(struct dw_macinfo_block_s);
+	newb->mb_avail_len = blen;
+	newb->mb_used_len = 0;
+	newb->mb_macinfo_data_space_len = blen;
+	dbg->de_first_macinfo->mb_next = newb;
+	dbg->de_current_macinfo = newb;
+	curblk = newb;
+    }
+    /* now curblk has enough room */
+    dbg->de_compose_avail = curblk->mb_avail_len;
+    dbg->de_compose_used_len = curblk->mb_used_len;
+    nextchar =
+	(unsigned char *) (curblk->mb_data + dbg->de_compose_used_len);
+    *nextchar = code;
+    dbg->de_compose_avail--;
+    ++dbg->de_compose_used_len;
+    return DW_DLV_OK;
+}
+
+
+
+static void
+libdwarf_compose_add_string(Dwarf_P_Debug dbg, char *string, size_t len)
+{
+    struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo;
+    unsigned char *nextchar;
+
+    nextchar =
+	(unsigned char *) (curblk->mb_data + dbg->de_compose_used_len);
+
+    len += 1;			/* count the null terminator */
+
+    memcpy(nextchar, string, len);
+    dbg->de_compose_avail -= len;
+    dbg->de_compose_used_len += len;
+    return;
+
+}
+static int
+libdwarf_compose_add_line(Dwarf_P_Debug dbg,
+			  Dwarf_Unsigned line, int *compose_error_type)
+{
+    struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo;
+    unsigned char *nextchar;
+    int res;
+    int nbytes;
+
+    nextchar =
+	(unsigned char *) (curblk->mb_data + dbg->de_compose_used_len);
+
+    /* Put the created leb number directly into the macro buffer If
+       dbg->de_compose_avail is > INT_MAX this will not work as the
+       'int' will look negative to _dwarf_pro_encode_leb128_nm! */
+
+    res = _dwarf_pro_encode_leb128_nm(line, &nbytes,
+				      (char *) nextchar,
+				      (int) dbg->de_compose_avail);
+    if (res != DW_DLV_OK) {
+	*compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE;
+	return DW_DLV_ERROR;
+    }
+
+    dbg->de_compose_avail -= nbytes;
+    dbg->de_compose_used_len += nbytes;
+    return DW_DLV_OK;
+}
+
+/*
+   This function actually 'commits' the space used by the
+   preceeding calls.
+*/
+static int
+libdwarf_compose_complete(Dwarf_P_Debug dbg, int *compose_error_type)
+{
+    struct dw_macinfo_block_s *curblk = dbg->de_current_macinfo;
+
+    if (dbg->de_compose_used_len > curblk->mb_macinfo_data_space_len) {
+	*compose_error_type = DW_DLE_MACINFO_INTERNAL_ERROR_SPACE;
+	return DW_DLV_ERROR;
+    }
+    curblk->mb_avail_len = dbg->de_compose_avail;
+    curblk->mb_used_len = dbg->de_compose_used_len;
+    return DW_DLV_OK;
+}
+
+
+
+int
+dwarf_def_macro(Dwarf_P_Debug dbg,
+		Dwarf_Unsigned line,
+		char *macname, char *macvalue, Dwarf_Error * error)
+{
+    size_t len;
+    size_t len2;
+    size_t length_est;
+    int res;
+    int compose_error_type;
+
+    if (dbg == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+    if (macname == 0) {
+	_dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
+	return (DW_DLV_ERROR);
+    }
+    len = strlen(macname) + 1;
+    if (len == 0) {
+	_dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
+	return (DW_DLV_ERROR);
+    }
+    if (macvalue) {
+	len2 = strlen(macvalue) + 1;
+    } else {
+	len2 = 0;
+    }
+    length_est = COMMAND_LEN + LINE_LEN + len + len2 + 1;	/* 1
+								   for
+								   space 
+								   character 
+								   we
+								   add */
+    res = libdwarf_compose_begin(dbg, DW_MACINFO_define, length_est,
+				 &compose_error_type);
+    if (res != DW_DLV_OK) {
+	_dwarf_p_error(NULL, error, compose_error_type);
+	return (DW_DLV_ERROR);
+    }
+    res = libdwarf_compose_add_line(dbg, line, &compose_error_type);
+    if (res != DW_DLV_OK) {
+	_dwarf_p_error(NULL, error, compose_error_type);
+	return (DW_DLV_ERROR);
+    }
+    libdwarf_compose_add_string(dbg, macname, len);
+    libdwarf_compose_add_string(dbg, " ", 1);
+    if (macvalue) {
+	libdwarf_compose_add_string(dbg, " ", 1);
+	libdwarf_compose_add_string(dbg, macvalue, len2);
+    }
+    res = libdwarf_compose_complete(dbg, &compose_error_type);
+    if (res != DW_DLV_OK) {
+	_dwarf_p_error(NULL, error, compose_error_type);
+	return (DW_DLV_ERROR);
+    }
+    return DW_DLV_OK;
+}
+
+int
+dwarf_undef_macro(Dwarf_P_Debug dbg,
+		  Dwarf_Unsigned line,
+		  char *macname, Dwarf_Error * error)
+{
+
+    size_t len;
+    size_t length_est;
+    int res;
+    int compose_error_type;
+
+    if (dbg == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+    if (macname == 0) {
+	_dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
+	return (DW_DLV_ERROR);
+    }
+    len = strlen(macname) + 1;
+    if (len == 0) {
+	_dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
+	return (DW_DLV_ERROR);
+    }
+    length_est = COMMAND_LEN + LINE_LEN + len;
+    res = libdwarf_compose_begin(dbg, DW_MACINFO_undef, length_est,
+				 &compose_error_type);
+    if (res != DW_DLV_OK) {
+	_dwarf_p_error(NULL, error, compose_error_type);
+	return (DW_DLV_ERROR);
+    }
+    res = libdwarf_compose_add_line(dbg, line, &compose_error_type);
+    if (res != DW_DLV_OK) {
+	_dwarf_p_error(NULL, error, compose_error_type);
+	return (DW_DLV_ERROR);
+    }
+    libdwarf_compose_add_string(dbg, macname, len);
+    res = libdwarf_compose_complete(dbg, &compose_error_type);
+    if (res != DW_DLV_OK) {
+	_dwarf_p_error(NULL, error, compose_error_type);
+	return (DW_DLV_ERROR);
+    }
+    return DW_DLV_OK;
+}
+
+int
+dwarf_start_macro_file(Dwarf_P_Debug dbg,
+		       Dwarf_Unsigned fileindex,
+		       Dwarf_Unsigned linenumber, Dwarf_Error * error)
+{
+    size_t length_est;
+    int res;
+    int compose_error_type;
+
+    if (dbg == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+    length_est = COMMAND_LEN + LINE_LEN + LINE_LEN;
+    res = libdwarf_compose_begin(dbg, DW_MACINFO_start_file, length_est,
+				 &compose_error_type);
+    if (res != DW_DLV_OK) {
+	_dwarf_p_error(NULL, error, compose_error_type);
+	return (DW_DLV_ERROR);
+    }
+    res = libdwarf_compose_add_line(dbg, fileindex,
+				    &compose_error_type);
+    if (res != DW_DLV_OK) {
+	_dwarf_p_error(NULL, error, compose_error_type);
+	return (DW_DLV_ERROR);
+    }
+    res = libdwarf_compose_add_line(dbg, linenumber,
+				    &compose_error_type);
+    if (res != DW_DLV_OK) {
+	_dwarf_p_error(NULL, error, compose_error_type);
+	return (DW_DLV_ERROR);
+    }
+    return DW_DLV_OK;
+}
+
+int
+dwarf_end_macro_file(Dwarf_P_Debug dbg, Dwarf_Error * error)
+{
+    size_t length_est;
+    int res;
+    int compose_error_type;
+
+    if (dbg == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+    length_est = COMMAND_LEN;
+    res = libdwarf_compose_begin(dbg, DW_MACINFO_end_file, length_est,
+				 &compose_error_type);
+    if (res != DW_DLV_OK) {
+	_dwarf_p_error(NULL, error, compose_error_type);
+	return (DW_DLV_ERROR);
+    }
+    res = libdwarf_compose_complete(dbg, &compose_error_type);
+    if (res != DW_DLV_OK) {
+	_dwarf_p_error(NULL, error, compose_error_type);
+	return (DW_DLV_ERROR);
+    }
+    return DW_DLV_OK;
+}
+
+int
+dwarf_vendor_ext(Dwarf_P_Debug dbg,
+		 Dwarf_Unsigned constant,
+		 char *string, Dwarf_Error * error)
+{
+    size_t len;
+    size_t length_est;
+    int res;
+    int compose_error_type;
+
+    if (dbg == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+	return (DW_DLV_ERROR);
+    }
+    if (string == 0) {
+	_dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_NULL);
+	return (DW_DLV_ERROR);
+    }
+    len = strlen(string) + 1;
+    if (len == 0) {
+	_dwarf_p_error(NULL, error, DW_DLE_MACINFO_STRING_EMPTY);
+	return (DW_DLV_ERROR);
+    }
+    length_est = COMMAND_LEN + LINE_LEN + len;
+    res = libdwarf_compose_begin(dbg, DW_MACINFO_vendor_ext, length_est,
+				 &compose_error_type);
+    if (res != DW_DLV_OK) {
+	_dwarf_p_error(NULL, error, compose_error_type);
+	return (DW_DLV_ERROR);
+    }
+    res = libdwarf_compose_add_line(dbg, constant, &compose_error_type);
+    if (res != DW_DLV_OK) {
+	_dwarf_p_error(NULL, error, compose_error_type);
+	return (DW_DLV_ERROR);
+    }
+    libdwarf_compose_add_string(dbg, string, len);
+    libdwarf_compose_complete(dbg, &compose_error_type);
+    if (res != DW_DLV_OK) {
+	_dwarf_p_error(NULL, error, compose_error_type);
+	return (DW_DLV_ERROR);
+    }
+    return DW_DLV_OK;
+}
+
+
+
+int
+_dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg,
+					Dwarf_Error * error)
+{
+    /* Total num of bytes in .debug_macinfo section. */
+    Dwarf_Unsigned mac_num_bytes;
+
+    /* Points to first byte of .debug_macinfo buffer. */
+    Dwarf_Small *macinfo;
+
+    /* Fills in the .debug_macinfo buffer. */
+    Dwarf_Small *macinfo_ptr;
+
+
+    /* Used to scan the section data buffers. */
+    struct dw_macinfo_block_s *m_prev;
+    struct dw_macinfo_block_s *m_sect;
+
+
+    /* Get the size of the debug_macinfo data */
+    mac_num_bytes = 0;
+    for (m_sect = dbg->de_first_macinfo; m_sect != NULL;
+	 m_sect = m_sect->mb_next) {
+	mac_num_bytes += m_sect->mb_used_len;
+    }
+    /* Tthe final entry has a type code of 0 to indicate It is final
+       for this CU Takes just 1 byte. */
+    mac_num_bytes += 1;
+
+    GET_CHUNK(dbg, dbg->de_elf_sects[DEBUG_MACINFO],
+	      macinfo, (unsigned long) mac_num_bytes, error);
+    if (macinfo == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (0);
+    }
+
+    macinfo_ptr = macinfo;
+    m_prev = 0;
+    for (m_sect = dbg->de_first_macinfo; m_sect != NULL;
+	 m_sect = m_sect->mb_next) {
+	memcpy(macinfo_ptr, m_sect->mb_data, m_sect->mb_used_len);
+	macinfo_ptr += m_sect->mb_used_len;
+	if (m_prev) {
+	    _dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev);
+	    m_prev = 0;
+	}
+	m_prev = m_sect;
+    }
+    *macinfo_ptr = 0;		/* the type code of 0 as last entry */
+    if (m_prev) {
+	_dwarf_p_dealloc(dbg, (Dwarf_Small *) m_prev);
+	m_prev = 0;
+    }
+
+    dbg->de_first_macinfo = NULL;
+    dbg->de_current_macinfo = NULL;
+
+    return (int) dbg->de_n_debug_sect;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_macinfo.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,40 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+
+int _dwarf_pro_transform_macro_info_to_disk(Dwarf_P_Debug dbg,
+					    Dwarf_Error * error);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_opaque.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,514 @@
+/*
+
+  Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+#include <stddef.h>
+
+/* 
+    Sgidefs included to define __uint32_t, 
+    a guaranteed 4-byte quantity.            
+*/
+#include "libdwarfdefs.h"
+
+#define true                    1
+#define false                   0
+
+/* to identify a cie */
+#define DW_CIE_ID 		~(0x0)
+#define DW_CIE_VERSION		1
+
+/*Dwarf_Word  is unsigned word usable for index, count in memory */
+/*Dwarf_Sword is   signed word usable for index, count in memory */
+/* The are 32 or 64 bits depending if 64 bit longs or not, which
+** fits the  ILP32 and LP64 models
+** These work equally well with ILP64.
+*/
+
+typedef unsigned long Dwarf_Word;
+typedef long Dwarf_Sword;
+
+
+typedef signed char Dwarf_Sbyte;
+typedef unsigned char Dwarf_Ubyte;
+typedef signed short Dwarf_Shalf;
+
+/*
+	On any change that makes libdwarf producer
+	incompatible, increment this number.
+	1->2->3 ...
+
+*/
+#define  PRO_VERSION_MAGIC 0xdead1
+
+
+/* these 2 are fixed sizes which must not vary with the
+** ILP32/LP64 model. These two stay at 32 bit.
+*/
+typedef __uint32_t Dwarf_ufixed;
+typedef __int32_t Dwarf_sfixed;
+
+/* 
+	producer:
+	This struct is used to hold information about all
+	debug* sections. On creating a new section, section
+	names and indices are added to this struct
+	definition in pro_section.h
+*/
+typedef struct Dwarf_P_Section_Data_s *Dwarf_P_Section_Data;
+
+/*
+	producer:
+	This struct is used to hold entries in the include directories
+	part of statement prologue. Definition in pro_line.h
+*/
+typedef struct Dwarf_P_Inc_Dir_s *Dwarf_P_Inc_Dir;
+
+/*
+	producer:
+	This struct holds file entries for the statement prologue. 
+	Defined in pro_line.h
+*/
+typedef struct Dwarf_P_F_Entry_s *Dwarf_P_F_Entry;
+
+/*
+	producer:
+	This struct holds information for each cie. Defn in pro_frame.h
+*/
+typedef struct Dwarf_P_Cie_s *Dwarf_P_Cie;
+
+/*
+	producer:
+	Struct to hold line number information, different from 
+	Dwarf_Line opaque type.
+*/
+typedef struct Dwarf_P_Line_s *Dwarf_P_Line;
+
+/*
+	producer:
+	Struct to hold information about address ranges.
+*/
+typedef struct Dwarf_P_Simple_nameentry_s *Dwarf_P_Simple_nameentry;
+typedef struct Dwarf_P_Simple_name_header_s *Dwarf_P_Simple_name_header;
+typedef struct Dwarf_P_Arange_s *Dwarf_P_Arange;
+typedef struct Dwarf_P_Per_Reloc_Sect_s *Dwarf_P_Per_Reloc_Sect;
+typedef struct Dwarf_P_Per_Sect_String_Attrs_s *Dwarf_P_Per_Sect_String_Attrs;
+
+/* Defined to get at the elf section numbers and section name
+   indices in symtab for the dwarf sections
+   Must match .rel.* names in _dwarf_rel_section_names
+   exactly.
+*/
+#define         DEBUG_INFO      0
+#define         DEBUG_LINE      1
+#define         DEBUG_ABBREV    2
+#define         DEBUG_FRAME     3
+#define         DEBUG_ARANGES   4
+#define         DEBUG_PUBNAMES  5
+#define         DEBUG_STR       6
+#define         DEBUG_FUNCNAMES 7
+#define         DEBUG_TYPENAMES 8
+#define         DEBUG_VARNAMES  9
+#define         DEBUG_WEAKNAMES 10
+#define         DEBUG_MACINFO   11
+#define         DEBUG_LOC   12
+
+    /* number of debug_* sections not including the relocations */
+#define         NUM_DEBUG_SECTIONS      DEBUG_LOC + 1
+
+
+struct Dwarf_P_Die_s {
+    Dwarf_Unsigned di_offset;	/* offset in debug info */
+    char *di_abbrev;		/* abbreviation */
+    Dwarf_Word di_abbrev_nbytes;	/* # of bytes in abbrev */
+    Dwarf_Tag di_tag;
+    Dwarf_P_Die di_parent;	/* parent of current die */
+    Dwarf_P_Die di_child;	/* first child */
+    Dwarf_P_Die di_left;	/* left sibling */
+    Dwarf_P_Die di_right;	/* right sibling */
+    Dwarf_P_Attribute di_attrs;	/* list of attributes */
+    Dwarf_P_Attribute di_last_attr;	/* last attribute */
+    int di_n_attr;		/* number of attributes */
+    Dwarf_P_Debug di_dbg;	/* For memory management */
+    Dwarf_Unsigned di_marker;   /* used to attach symbols to dies */
+};
+
+
+/* producer fields */
+struct Dwarf_P_Attribute_s {
+    Dwarf_Half ar_attribute;	/* Attribute Value. */
+    Dwarf_Half ar_attribute_form;	/* Attribute Form. */
+    Dwarf_P_Die ar_ref_die;	/* die pointer if form ref */
+    char *ar_data;		/* data, format given by form */
+    Dwarf_Unsigned ar_nbytes;	/* no. of bytes of data */
+    Dwarf_Unsigned ar_rel_symidx;	/* when attribute has a
+					   relocatable value, holds
+					   index of symbol in SYMTAB */
+    Dwarf_Ubyte ar_rel_type;	/* relocation type */
+    Dwarf_Word ar_rel_offset;	/* Offset of relocation within block */
+    char ar_reloc_len;		/* Number of bytes that relocation
+				   applies to. 4 or 8. Unused and may
+				   be 0 if if ar_rel_type is
+				   R_MIPS_NONE */
+    Dwarf_P_Attribute ar_next;
+};
+
+/* A block of .debug_macinfo data: this forms a series of blocks.
+** Each macinfo input is compressed immediately and put into
+** the current block if room, else a newblock allocated.
+** The space allocation is such that the block and the macinfo
+** data are one malloc block: free with a pointer to this and the
+** mb_data is freed automatically.
+** Like the struct hack, but legal ANSI C.
+*/
+struct dw_macinfo_block_s {
+    struct dw_macinfo_block_s *mb_next;
+    unsigned long mb_avail_len;
+    unsigned long mb_used_len;
+    unsigned long mb_macinfo_data_space_len;
+    char *mb_data;		/* original malloc ptr. */
+};
+
+/* dwarf_sn_kind is for the array of similarly-treated
+   name -> cu ties
+*/
+enum dwarf_sn_kind { dwarf_snk_pubname, dwarf_snk_funcname,
+    dwarf_snk_weakname, dwarf_snk_typename,
+    dwarf_snk_varname,
+    dwarf_snk_entrycount	/* this one must be last */
+};
+
+
+
+/* The calls to add a varname etc use a list of
+   these as the list.
+*/
+struct Dwarf_P_Simple_nameentry_s {
+    Dwarf_P_Die sne_die;
+    char *sne_name;
+    int sne_name_len;
+    Dwarf_P_Simple_nameentry sne_next;
+};
+
+/* An array of these, each of which heads a list
+   of Dwarf_P_Simple_nameentry
+*/
+struct Dwarf_P_Simple_name_header_s {
+    Dwarf_P_Simple_nameentry sn_head;
+    Dwarf_P_Simple_nameentry sn_tail;
+    Dwarf_Signed sn_count;
+
+    /* length that will be generated, not counting fixed header or
+       trailer */
+    Dwarf_Signed sn_net_len;
+};
+typedef int (*_dwarf_pro_reloc_name_func_ptr) (Dwarf_P_Debug dbg, int sec_index, Dwarf_Unsigned offset,	/* r_offset 
+													 */
+					       Dwarf_Unsigned symidx,
+					       enum Dwarf_Rel_Type type,
+					       int reltarget_length);
+
+typedef int (*_dwarf_pro_reloc_length_func_ptr) (Dwarf_P_Debug dbg, int sec_index, Dwarf_Unsigned offset,	/* r_offset 
+														 */
+						 Dwarf_Unsigned
+						 start_symidx,
+						 Dwarf_Unsigned
+						 end_symidx,
+						 enum Dwarf_Rel_Type
+						 type,
+						 int reltarget_length);
+typedef int (*_dwarf_pro_transform_relocs_func_ptr) (Dwarf_P_Debug dbg,
+						     Dwarf_Signed *
+						     new_sec_count);
+
+/*
+	Each slot in a block of slots could be:
+	a binary stream relocation entry (32 or 64bit relocation data)
+        a SYMBOLIC relocation entry.
+	During creation sometimes we create multiple chained blocks,
+	but sometimes we create a single long block.
+        Before returning reloc data to caller, 
+        we switch to a single, long-enough,
+	block.
+
+	We make counters here Dwarf_Unsigned so that we
+	get sufficient alignment. Since we use space after
+	the struct (at malloc time) for user data which
+        must have Dwarf_Unsigned alignment, this
+	struct must have that alignment too.
+
+*/
+struct Dwarf_P_Relocation_Block_s {
+    Dwarf_Unsigned rb_slots_in_block;	/* slots in block, as created */
+    Dwarf_Unsigned rb_next_slot_to_use;	/* counter, start at 0. */
+    struct Dwarf_P_Relocation_Block_s *rb_next;
+    char *rb_where_to_add_next;	/* pointer to next slot (might be past
+				   end, depending on
+				   rb_next_slot_to_use) */
+    char *rb_data;		/* data area */
+};
+
+/* One of these per potential relocation section 
+   So one per actual dwarf section.
+   Left zeroed when not used (some sections have
+   no relocations).
+*/
+struct Dwarf_P_Per_Reloc_Sect_s {
+
+
+    unsigned long pr_reloc_total_count;	/* total number of entries
+					   across all blocks */
+
+    unsigned long pr_slots_per_block_to_alloc;	/* at Block alloc, this 
+						   is the default
+						   number of slots to
+						   use */
+
+    int pr_sect_num_of_reloc_sect;	/* sect number returned by
+					   de_func() or de_func_b()
+					   call, this is the sect
+					   number of the relocation
+					   section. */
+
+
+    /* singly-linked list. add at and ('last') with count of blocks */
+    struct Dwarf_P_Relocation_Block_s *pr_first_block;
+    struct Dwarf_P_Relocation_Block_s *pr_last_block;
+    unsigned long pr_block_count;
+};
+
+#define DEFAULT_SLOTS_PER_BLOCK 3
+
+typedef struct memory_list_s {
+  struct memory_list_s *prev;
+  struct memory_list_s *next;
+} memory_list_t;
+
+
+struct Dwarf_P_Per_Sect_String_Attrs_s {
+    int sect_sa_section_number;
+    unsigned sect_sa_n_alloc;
+    unsigned sect_sa_n_used;
+    Dwarf_P_String_Attr sect_sa_list;
+};
+
+/* Fields used by producer */
+struct Dwarf_P_Debug_s {
+    /* used to catch dso passing dbg to another DSO with incompatible
+       version of libdwarf See PRO_VERSION_MAGIC */
+    int de_version_magic_number;
+
+    Dwarf_Unsigned de_access;
+    Dwarf_Handler de_errhand;
+    Dwarf_Ptr de_errarg;
+
+    /* 
+       Call back function, used to create .debug* sections. Provided
+       by user. Only of these used per dbg. */
+    Dwarf_Callback_Func de_func;
+    Dwarf_Callback_Func_b de_func_b;
+
+    /* Flags from producer_init call */
+    Dwarf_Unsigned de_flags;
+
+    /* This holds information on debug section stream output, including
+       the stream data */
+    Dwarf_P_Section_Data de_debug_sects;
+
+    /* Pointer to the 'current active' section */
+    Dwarf_P_Section_Data de_current_active_section;
+
+    /* Number of debug data streams globs. */
+    Dwarf_Word de_n_debug_sect;
+
+    /* File entry information, null terminated singly-linked list */
+    Dwarf_P_F_Entry de_file_entries;
+    Dwarf_P_F_Entry de_last_file_entry;
+    Dwarf_Unsigned de_n_file_entries;
+
+    /* Has the directories used to search for source files */
+    Dwarf_P_Inc_Dir de_inc_dirs;
+    Dwarf_P_Inc_Dir de_last_inc_dir;
+    Dwarf_Unsigned de_n_inc_dirs;
+
+    /* Has all the line number info for the stmt program */
+    Dwarf_P_Line de_lines;
+    Dwarf_P_Line de_last_line;
+
+    /* List of cie's for the debug unit */
+    Dwarf_P_Cie de_frame_cies;
+    Dwarf_P_Cie de_last_cie;
+    Dwarf_Unsigned de_n_cie;
+
+    /* Singly-linked list of fde's for the debug unit */
+    Dwarf_P_Fde de_frame_fdes;
+    Dwarf_P_Fde de_last_fde;
+    Dwarf_Unsigned de_n_fde;
+
+    /* First die, leads to all others */
+    Dwarf_P_Die de_dies;
+
+    /* Pointer to list of strings */
+    char *de_strings;
+
+    /* Pointer to chain of aranges */
+    Dwarf_P_Arange de_arange;
+    Dwarf_P_Arange de_last_arange;
+    Dwarf_Sword de_arange_count;
+
+    /* macinfo controls. */
+    /* first points to beginning of the list during creation */
+    struct dw_macinfo_block_s *de_first_macinfo;
+
+    /* current points to the current, unfilled, block */
+    struct dw_macinfo_block_s *de_current_macinfo;
+
+
+    /* Pointer to the first section, to support reset_section_bytes */
+    Dwarf_P_Section_Data de_first_debug_sect;
+
+    /* handles pubnames, weaknames, etc. See dwarf_sn_kind in
+       pro_opaque.h */
+    struct Dwarf_P_Simple_name_header_s
+      de_simple_name_headers[dwarf_snk_entrycount];
+
+    /* relocation data. not all sections will actally have relocation
+       info, of course */
+    struct Dwarf_P_Per_Reloc_Sect_s de_reloc_sect[NUM_DEBUG_SECTIONS];
+    int de_reloc_next_to_return;	/* iterator on reloc sections
+					   (SYMBOLIC output) */
+
+    /* used in remembering sections */
+    int de_elf_sects[NUM_DEBUG_SECTIONS];	/* 
+						   elf sect number of
+						   the section itself,
+						   DEBUG_LINE for
+						   example */
+
+    Dwarf_Unsigned de_sect_name_idx[NUM_DEBUG_SECTIONS];	/* section 
+								   name 
+								   index 
+								   or
+								   handle 
+								   for
+								   the
+								   name 
+								   of
+								   the
+								   symbol 
+								   for
+								   DEBUG_LINE 
+								   for
+								   example 
+								 */
+
+
+
+    int de_offset_reloc;	/* offset reloc type, R_MIPS_32 for
+				   example. Specific to the ABI being
+				   produced. Relocates offset size
+				   field */
+    int de_exc_reloc;		/* reloc type specific to exception
+				   table relocs. */
+    int de_ptr_reloc;		/* standard reloc type, R_MIPS_32 for
+				   example. Specific to the ABI being
+				   produced. relocates pointer size
+				   field */
+
+    unsigned char de_offset_size;	/* section offset. Here to
+					   avoid test of abi in macro
+					   at run time MIPS -n32 4,
+					   -64 8.  */
+
+    unsigned char de_pointer_size;	/* size of pointer in target.
+					   Here to avoid test of abi in 
+					   macro at run time MIPS -n32 
+					   4, -64 is 8.  */
+
+    unsigned char de_is_64bit;	/* non-zero if is 64bit. Else 32 bit:
+				   used for passing this info as a flag 
+				 */
+    unsigned char de_relocation_record_size;	/* reloc record size
+						   varies by ABI and
+						   relocation-output
+						   method (stream or
+						   symbolic) */
+
+    unsigned char de_64bit_extension;	/* non-zero if creating 64 bit
+					   offsets using dwarf2-99
+					   extension proposal */
+
+    int de_ar_data_attribute_form;	/* data8, data4 abi dependent */
+    int de_ar_ref_attr_form;	/* ref8 ref4 , abi dependent */
+
+    /* simple name relocations */
+    _dwarf_pro_reloc_name_func_ptr de_reloc_name;
+
+    /* relocations for a length, requiring a pair of symbols */
+    _dwarf_pro_reloc_length_func_ptr de_reloc_pair;
+
+    _dwarf_pro_transform_relocs_func_ptr de_transform_relocs_to_disk;
+
+    /* following used for macro buffers */
+    unsigned long de_compose_avail;
+    unsigned long de_compose_used_len;
+
+    unsigned char de_same_endian;
+    void *(*de_copy_word) (void *, const void *, size_t);
+
+    /* Add new fields at the END of this struct to preserve some hope
+       of sensible behavior on dbg passing between DSOs linked with
+       mismatched libdwarf producer versions. */
+
+    Dwarf_P_Marker de_markers;  /* pointer to array of markers */
+    unsigned de_marker_n_alloc;
+    unsigned de_marker_n_used;
+    int de_sect_sa_next_to_return;  /* Iterator on sring attrib sects */
+    /* String attributes data of each section. */
+    struct Dwarf_P_Per_Sect_String_Attrs_s de_sect_string_attr[NUM_DEBUG_SECTIONS];
+};
+
+
+#define CURRENT_VERSION_STAMP		2
+
+Dwarf_Unsigned _dwarf_add_simple_name_entry(Dwarf_P_Debug dbg,
+					    Dwarf_P_Die die,
+					    char *entry_name,
+					    enum dwarf_sn_kind
+					    entrykind,
+					    Dwarf_Error * error);
+
+
+#define DISTINGUISHED_VALUE 0xffffffff	/* 64bit extension flag */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_pubnames.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,63 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_ELFACCESS_H
+#include <elfaccess.h>
+#endif
+#include "pro_incl.h"
+#include "pro_section.h"
+
+
+/*
+    This function adds another public name to the 
+    list of public names for the given Dwarf_P_Debug.  
+    It returns 0 on error, and 1 otherwise.
+*/
+
+Dwarf_Unsigned
+dwarf_add_pubname(Dwarf_P_Debug dbg,
+		  Dwarf_P_Die die,
+		  char *pubname_name, Dwarf_Error * error)
+{
+    return
+	_dwarf_add_simple_name_entry(dbg, die, pubname_name,
+				     dwarf_snk_pubname, error);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,268 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#include <stdio.h>
+#include <string.h>
+/*#include <elfaccess.h> */
+#include "pro_incl.h"
+
+
+/*Do initial alloc of newslots slots.
+  Fails only if malloc fails.
+
+  Supposed to be called before any relocs allocated.
+  Ignored if after any allocated.
+
+  Part of an optimization, so that for a known 'newslots' 
+  relocations count we can preallocate the right size block.
+  Called from just 2 places.
+
+  returns DW_DLV_OK or  DW_DLV_ERROR
+*/
+int
+_dwarf_pro_pre_alloc_n_reloc_slots(Dwarf_P_Debug dbg,
+				   int rel_sec_index,
+				   Dwarf_Unsigned newslots)
+{
+    unsigned long len;
+    struct Dwarf_P_Relocation_Block_s *data;
+    Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[rel_sec_index];
+    unsigned long slots_in_blk = (unsigned long) newslots;
+    unsigned long rel_rec_size = dbg->de_relocation_record_size;
+
+    if (prel->pr_first_block)
+	return DW_DLV_OK;	/* do nothing */
+
+    len = sizeof(struct Dwarf_P_Relocation_Block_s) +
+	slots_in_blk * rel_rec_size;
+
+
+    data = (struct Dwarf_P_Relocation_Block_s *)
+	_dwarf_p_get_alloc(dbg, len);
+    if (!data) {
+	return DW_DLV_ERROR;
+    }
+    data->rb_slots_in_block = slots_in_blk;	/* could use default
+						   here, as fallback in 
+						   case our origininal
+						   estimate wrong. When 
+						   we call this we
+						   presumably know what 
+						   we are doing, so
+						   keep this count for
+						   now */
+    data->rb_next_slot_to_use = 0;
+    data->rb_where_to_add_next =
+	((char *) data) + sizeof(struct Dwarf_P_Relocation_Block_s);
+    data->rb_data = data->rb_where_to_add_next;
+
+    prel->pr_first_block = data;
+    prel->pr_last_block = data;
+    prel->pr_block_count = 1;
+
+
+    return DW_DLV_OK;
+}
+
+
+/*Do alloc of slots.
+  Fails only if malloc fails.
+
+  Only allocator used.
+
+  returns DW_DLV_OK or  DW_DLV_ERROR
+*/
+int
+_dwarf_pro_alloc_reloc_slots(Dwarf_P_Debug dbg, int rel_sec_index)
+{
+    unsigned long len;
+    struct Dwarf_P_Relocation_Block_s *data;
+    Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[rel_sec_index];
+    unsigned long slots_in_blk = prel->pr_slots_per_block_to_alloc;
+    unsigned long rel_rec_size = dbg->de_relocation_record_size;
+
+    len = sizeof(struct Dwarf_P_Relocation_Block_s) +
+	slots_in_blk * rel_rec_size;
+
+    data = (struct Dwarf_P_Relocation_Block_s *)
+	_dwarf_p_get_alloc(dbg, len);
+    if (!data) {
+	return DW_DLV_ERROR;
+    }
+
+    if (prel->pr_first_block) {
+	prel->pr_last_block->rb_next = data;
+	prel->pr_last_block = data;
+	prel->pr_block_count += 1;
+
+    } else {
+
+	prel->pr_first_block = data;
+	prel->pr_last_block = data;
+	prel->pr_block_count = 1;
+    }
+
+    data->rb_slots_in_block = slots_in_blk;
+    data->rb_next_slot_to_use = 0;
+    data->rb_where_to_add_next =
+	((char *) data) + sizeof(struct Dwarf_P_Relocation_Block_s);
+    data->rb_data = data->rb_where_to_add_next;
+
+    return DW_DLV_OK;
+
+}
+
+/*
+	Reserve a slot. return DW_DLV_OK if succeeds.
+
+	Return DW_DLV_ERROR if fails (malloc error).
+
+	Use the relrec_to_fill to pass back a pointer to
+	a slot space to use.
+*/
+int
+_dwarf_pro_reloc_get_a_slot(Dwarf_P_Debug dbg,
+			    int base_sec_index, void **relrec_to_fill)
+{
+    struct Dwarf_P_Relocation_Block_s *data;
+    Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[base_sec_index];
+    unsigned long rel_rec_size = dbg->de_relocation_record_size;
+
+    char *ret_addr;
+
+    data = prel->pr_last_block;
+    if ((data == 0) ||
+	(data->rb_next_slot_to_use >= data->rb_slots_in_block)) {
+	int res;
+
+	res = _dwarf_pro_alloc_reloc_slots(dbg, base_sec_index);
+	if (res != DW_DLV_OK) {
+	    return res;
+	}
+    }
+
+    data = prel->pr_last_block;
+    /* now we have an empty slot */
+    ret_addr = data->rb_where_to_add_next;
+
+    data->rb_where_to_add_next += rel_rec_size;
+    data->rb_next_slot_to_use += 1;
+
+    prel->pr_reloc_total_count += 1;
+
+    *relrec_to_fill = (void *) ret_addr;
+
+    return DW_DLV_OK;
+
+}
+
+/*
+   On success  returns count of
+   .rel.* sections that are symbolic 
+   thru count_of_relocation_sections.
+
+   On success, returns DW_DLV_OK.
+
+   If this is not a 'symbolic' run, returns
+    DW_DLV_NO_ENTRY.
+
+   No errors are possible.
+
+
+
+
+*/
+
+ /*ARGSUSED*/ int
+dwarf_get_relocation_info_count(Dwarf_P_Debug dbg,
+				Dwarf_Unsigned *
+				count_of_relocation_sections,
+				int *drd_buffer_version,
+				Dwarf_Error * error)
+{
+    if (dbg->de_flags & DW_DLC_SYMBOLIC_RELOCATIONS) {
+	int i;
+	unsigned int count = 0;
+
+	for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) {
+	    if (dbg->de_reloc_sect[i].pr_reloc_total_count > 0) {
+		++count;
+	    }
+	}
+	*count_of_relocation_sections = (Dwarf_Unsigned) count;
+	*drd_buffer_version = DWARF_DRD_BUFFER_VERSION;
+	return DW_DLV_OK;
+    }
+    return DW_DLV_NO_ENTRY;
+}
+
+int
+dwarf_get_relocation_info(Dwarf_P_Debug dbg,
+			  Dwarf_Signed * elf_section_index,
+			  Dwarf_Signed * elf_section_index_link,
+			  Dwarf_Unsigned * relocation_buffer_count,
+			  Dwarf_Relocation_Data * reldata_buffer,
+			  Dwarf_Error * error)
+{
+    int next = dbg->de_reloc_next_to_return;
+
+    if (dbg->de_flags & DW_DLC_SYMBOLIC_RELOCATIONS) {
+	int i;
+
+	for (i = next; i < NUM_DEBUG_SECTIONS; ++i) {
+	    Dwarf_P_Per_Reloc_Sect prel = &dbg->de_reloc_sect[i];
+
+	    if (prel->pr_reloc_total_count > 0) {
+		dbg->de_reloc_next_to_return = i + 1;
+
+
+		/* ASSERT: prel->.pr_block_count == 1 */
+
+		*elf_section_index = prel->pr_sect_num_of_reloc_sect;
+		*elf_section_index_link = dbg->de_elf_sects[i];
+		*relocation_buffer_count = prel->pr_reloc_total_count;
+		*reldata_buffer = (Dwarf_Relocation_Data)
+		    (prel->pr_first_block->rb_data);
+		return DW_DLV_OK;
+	    }
+	}
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, DW_DLV_ERROR);
+    }
+    return DW_DLV_NO_ENTRY;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,47 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+
+int _dwarf_pro_pre_alloc_n_reloc_slots(Dwarf_P_Debug dbg,
+				       int rel_sec_index,
+				       Dwarf_Unsigned newslots);
+
+int _dwarf_pro_alloc_reloc_slots(Dwarf_P_Debug dbg, int rel_sec_index);
+
+int _dwarf_pro_reloc_get_a_slot(Dwarf_P_Debug dbg,
+				int base_sec_index,
+				void **relrec_to_fill);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc_stream.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,299 @@
+/*
+
+  Copyright (C) 2000,2001,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_ELFACCESS_H
+#include <elfaccess.h>
+#else
+/* Set r_info  as defined by ELF generic ABI */
+#define Set_REL32_info(r,s,t) ((r).r_info = ELF32_R_INFO(s,t))
+#define Set_REL64_info(r,s,t) ((r).r_info = ELF64_R_INFO(s,t))
+#endif
+#include "pro_incl.h"
+#include "pro_section.h"
+#include "pro_reloc.h"
+#include "pro_reloc_stream.h"
+
+/*
+	Return DW_DLV_ERROR on malloc error or reltarget_length error.
+	Return DW_DLV_OK otherwise
+
+
+
+*/
+ /*ARGSUSED*/ int
+_dwarf_pro_reloc_name_stream64(Dwarf_P_Debug dbg,
+			       int base_sec_index,
+			       Dwarf_Unsigned offset,	/* r_offset of reloc */
+			       Dwarf_Unsigned symidx,
+			       enum Dwarf_Rel_Type type,
+			       int reltarget_length)
+{
+#if HAVE_ELF64_GETEHDR
+    REL64 *elf64_reloc;
+    void *relrec_to_fill;
+    int res;
+    int rel_type;
+
+    res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
+				      &relrec_to_fill);
+    if (res != DW_DLV_OK)
+	return res;
+
+
+    if (type == dwarf_drt_data_reloc) {
+	if (reltarget_length == dbg->de_offset_size) {
+	    rel_type = dbg->de_offset_reloc;
+	} else if (reltarget_length == dbg->de_pointer_size) {
+	    rel_type = dbg->de_ptr_reloc;
+	} else {
+	    return DW_DLV_ERROR;
+	}
+    } else if (type == dwarf_drt_segment_rel) {
+	rel_type = dbg->de_exc_reloc;
+    } else {
+	/* We are in trouble: improper use of stream relocations.
+	   Someone else will diagnose */
+	rel_type = 0;
+    }
+
+    elf64_reloc = (REL64 *)relrec_to_fill;
+    elf64_reloc->r_offset = offset;
+    Set_REL64_info(*elf64_reloc, symidx, rel_type);
+    return DW_DLV_OK;
+#else /* !HAVE_ELF64_GETEHDR */
+    return DW_DLV_ERROR;
+#endif /* #if HAVE_ELF64_GETEHDR */
+}
+
+/*
+	Return DW_DLV_ERROR on malloc error or reltarget_length error.
+	Return DW_DLV_OK otherwise
+	a binary reloc: 32bit ABI
+*/
+int
+_dwarf_pro_reloc_name_stream32(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,	/* r_offset 
+												   of 
+												   reloc 
+												 */
+			       Dwarf_Unsigned symidx,
+			       enum Dwarf_Rel_Type type,
+			       int reltarget_length)
+{
+    REL32 *elf32_reloc;
+    void *relrec_to_fill;
+    int res;
+    int rel_type;
+
+    res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
+				      &relrec_to_fill);
+    if (res != DW_DLV_OK)
+	return res;
+    if (type == dwarf_drt_data_reloc) {
+	if (reltarget_length == dbg->de_offset_size) {
+	    rel_type = dbg->de_offset_reloc;
+	} else if (reltarget_length == dbg->de_pointer_size) {
+	    rel_type = dbg->de_ptr_reloc;
+	} else {
+	    return DW_DLV_ERROR;
+	}
+    } else if (type == dwarf_drt_segment_rel) {
+	rel_type = dbg->de_exc_reloc;
+    } else {
+	/* We are in trouble: improper use of stream relocations.
+	   Someone else will diagnose */
+	rel_type = 0;
+    }
+
+    elf32_reloc = (REL32*)relrec_to_fill;
+    elf32_reloc->r_offset = (Elf32_Addr) offset;
+    Set_REL32_info(*elf32_reloc, (Dwarf_Word) symidx, rel_type);
+    return DW_DLV_OK;
+
+    /* get a slot, fill in the slot entry */
+}
+
+
+
+/*
+	Return DW_DLV_OK.
+	Never can really do anything: lengths cannot
+	be represented as end-start in a stream.
+
+*/
+ /*ARGSUSED*/ int
+_dwarf_pro_reloc_length_stream(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,	/* r_offset 
+												   of 
+												   reloc 
+												 */
+			       Dwarf_Unsigned start_symidx,
+			       Dwarf_Unsigned end_symidx,
+			       enum Dwarf_Rel_Type type,
+			       int reltarget_length)
+{
+    /* get a slot, fill in the slot entry */
+    return DW_DLV_OK;
+}
+
+
+/* 
+        Ensure each stream is a single buffer and
+        add that single buffer to the set of stream buffers.
+
+	By creating a new buffer and copying if necessary.
+
+        Free the input set of buffers if we consolidate.
+        Return -1 on error (malloc failure)
+
+
+        Return DW_DLV_OK on success. Any other return indicates 
+	malloc failed.
+	
+*/
+int
+_dwarf_stream_relocs_to_disk(Dwarf_P_Debug dbg,
+			     Dwarf_Signed * new_sec_count)
+{
+    unsigned long total_size = 0;
+    Dwarf_Small *data;
+    int sec_index;
+    unsigned long i;
+    Dwarf_Error err;
+    Dwarf_Error *error = &err;
+
+    Dwarf_Signed sec_count = 0;
+
+    Dwarf_P_Per_Reloc_Sect p_reloc = &dbg->de_reloc_sect[0];
+
+    for (i = 0; i < NUM_DEBUG_SECTIONS; ++i, ++p_reloc) {
+	unsigned long ct = p_reloc->pr_reloc_total_count;
+	unsigned len;
+	struct Dwarf_P_Relocation_Block_s *p_blk;
+	struct Dwarf_P_Relocation_Block_s *p_blk_last;
+	Dwarf_P_Per_Reloc_Sect prb;
+
+	if (ct == 0) {
+	    continue;
+	}
+	prb = &dbg->de_reloc_sect[i];
+	len = dbg->de_relocation_record_size;
+	++sec_count;
+
+	total_size = ct * len;
+	sec_index = prb->pr_sect_num_of_reloc_sect;
+	if (sec_index == 0) {
+	    /* call de_func or de_func_b, getting section number of
+	       reloc sec */
+	    int rel_section_index;
+	    Dwarf_Unsigned name_idx;
+	    int int_name;
+	    int err;
+
+	    if (dbg->de_func_b) {
+		rel_section_index =
+		    dbg->de_func_b(_dwarf_rel_section_names[i],
+				   /* size */
+				   dbg->de_relocation_record_size,
+				   /* type */ SHT_REL,
+				   /* flags */ 0,
+				   /* link to symtab, which we cannot
+				      know */ 0,
+				   /* info == link to sec rels apply to 
+				    */
+				   dbg->de_elf_sects[i],
+				   &name_idx, &err);
+	    } else {
+		rel_section_index =
+		    dbg->de_func(_dwarf_rel_section_names[i],
+				 /* size */
+				 dbg->de_relocation_record_size,
+				 /* type */ SHT_REL,
+				 /* flags */ 0,
+				 /* link to symtab, which we cannot
+				    know */ 0,
+				 /* info == link to sec rels apply to */
+				 dbg->de_elf_sects[i], &int_name, &err);
+		name_idx = int_name;
+	    }
+	    if (rel_section_index == -1) {
+		{
+		    _dwarf_p_error(dbg, error, DW_DLE_ELF_SECT_ERR);
+		    return (DW_DLV_ERROR);
+		}
+
+	    }
+	    prb->pr_sect_num_of_reloc_sect = rel_section_index;
+	    sec_index = rel_section_index;
+	}
+	GET_CHUNK(dbg, sec_index, data, total_size, &err);
+	p_blk = p_reloc->pr_first_block;
+
+	/* following loop executes at least once. Effects the
+	   consolidation to a single block or, if already a single
+	   block, simply copies to the output buffer. And frees the
+	   input block. The new block is in the de_debug_sects list. */
+	while (p_blk) {
+
+	    unsigned long len =
+		p_blk->rb_where_to_add_next - p_blk->rb_data;
+
+	    memcpy(data, p_blk->rb_data, len);
+
+
+	    data += len;
+
+	    p_blk_last = p_blk;
+	    p_blk = p_blk->rb_next;
+
+	    _dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last);
+	}
+	/* ASSERT: sum of len copied == total_size */
+
+	/* 
+	   We have copied the input, now drop the pointers to it. For
+	   debugging, leave the other data untouched. */
+	p_reloc->pr_first_block = 0;
+	p_reloc->pr_last_block = 0;
+    }
+
+    *new_sec_count = sec_count;
+    return DW_DLV_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc_stream.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,63 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+
+int _dwarf_pro_reloc_name_stream64(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,	/* r_offset 
+													   of 
+													   reloc 
+													 */
+				   Dwarf_Unsigned symidx,
+				   enum Dwarf_Rel_Type,
+				   int reltarget_length);
+int _dwarf_pro_reloc_name_stream32(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,	/* r_offset 
+													   of 
+													   reloc 
+													 */
+				   Dwarf_Unsigned symidx,
+				   enum Dwarf_Rel_Type,
+				   int reltarget_length);
+int _dwarf_pro_reloc_length_stream(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,	/* r_offset 
+													   of 
+													   reloc 
+													 */
+				   Dwarf_Unsigned start_symidx,
+				   Dwarf_Unsigned end_symidx,
+				   enum Dwarf_Rel_Type,
+				   int reltarget_length);
+
+int _dwarf_stream_relocs_to_disk(Dwarf_P_Debug dbg,
+				 Dwarf_Signed * new_sec_count);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc_symbolic.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,299 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#include <stdio.h>
+#include <string.h>
+/*#include <elfaccess.h> */
+#include "pro_incl.h"
+#include "pro_section.h"
+#include "pro_reloc.h"
+#include "pro_reloc_symbolic.h"
+
+/*
+	Return DW_DLV_ERROR on malloc error.
+	Return DW_DLV_OK otherwise
+*/
+
+int
+_dwarf_pro_reloc_name_symbolic(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,	/* r_offset 
+												   of 
+												   reloc 
+												 */
+			       Dwarf_Unsigned symidx,
+			       enum Dwarf_Rel_Type type,
+			       int reltarget_length)
+{
+    /* get a slot, fill in the slot entry */
+    void *relrec_to_fill;
+    int res;
+    struct Dwarf_Relocation_Data_s *slotp;
+
+    res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
+				      &relrec_to_fill);
+    if (res != DW_DLV_OK)
+	return res;
+
+    slotp = (struct Dwarf_Relocation_Data_s *) relrec_to_fill;
+    slotp->drd_type = type;
+    slotp->drd_length = reltarget_length;
+    slotp->drd_offset = offset;
+    slotp->drd_symbol_index = symidx;
+    return DW_DLV_OK;
+
+}
+
+
+
+/*
+	Return DW_DLV_ERROR on malloc error.
+	Return DW_DLV_OK otherwise
+*/
+int
+_dwarf_pro_reloc_length_symbolic(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,	/* r_offset 
+												   of 
+												   reloc 
+												 */
+				 Dwarf_Unsigned start_symidx,
+				 Dwarf_Unsigned end_symidx,
+				 enum Dwarf_Rel_Type type,
+				 int reltarget_length)
+{
+    /* get a slot, fill in the slot entry */
+    void *relrec_to_fill;
+    int res;
+    struct Dwarf_Relocation_Data_s *slotp1;
+    struct Dwarf_Relocation_Data_s *slotp2;
+
+
+
+    res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
+				      &relrec_to_fill);
+    if (res != DW_DLV_OK)
+	return res;
+    slotp1 = (struct Dwarf_Relocation_Data_s *) relrec_to_fill;
+    res = _dwarf_pro_reloc_get_a_slot(dbg, base_sec_index,
+				      &relrec_to_fill);
+    if (res != DW_DLV_OK)
+	return res;
+    slotp2 = (struct Dwarf_Relocation_Data_s *) relrec_to_fill;
+
+    /* ASSERT: type == dwarf_drt_first_of_length_type_pair */
+    slotp1->drd_type = type;
+    slotp1->drd_length = reltarget_length;
+    slotp1->drd_offset = offset;
+    slotp1->drd_symbol_index = start_symidx;
+
+    slotp2->drd_type = dwarf_drt_second_of_length_pair;
+    slotp2->drd_length = reltarget_length;
+    slotp2->drd_offset = offset;
+    slotp2->drd_symbol_index = end_symidx;
+
+    return DW_DLV_OK;
+}
+
+/*
+   Reset whatever fields of Dwarf_P_Per_Reloc_Sect_s
+   we must to allow adding a fresh new single
+   block easily (block consolidation use only).
+
+*/
+static void
+_dwarf_reset_reloc_sect_info(struct Dwarf_P_Per_Reloc_Sect_s *pblk,
+			     unsigned long ct)
+{
+
+
+    /* do not zero pr_sect_num_of_reloc_sect */
+
+    pblk->pr_reloc_total_count = 0;
+    pblk->pr_first_block = 0;
+    pblk->pr_last_block = 0;
+    pblk->pr_block_count = 0;
+    pblk->pr_slots_per_block_to_alloc = ct;
+}
+
+/*
+        Ensure each stream is a single buffer and
+        add that single buffer to the set of stream buffers.
+
+	By creating a new buffer and copying if necessary.
+	(If > 1 block, reduce to 1 block)
+
+        Free the input set of buffers if we consolidate.
+
+	We pass back *new_sec_count as zero because we
+        are not creating normal sections for a .o, but
+	symbolic relocations, separately counted.
+
+        Return -1 on error (malloc failure)
+
+
+        Return DW_DLV_OK on success. Any other return indicates 
+	malloc failed.
+*/
+int
+_dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg,
+			       Dwarf_Signed * new_sec_count)
+{
+    /* unsigned long total_size =0; */
+    Dwarf_Small *data;
+    int sec_index;
+    int res;
+    unsigned long i;
+    Dwarf_Error error;
+
+    Dwarf_Signed sec_count = 0;
+
+    Dwarf_P_Per_Reloc_Sect p_reloc = &dbg->de_reloc_sect[0];
+
+    for (i = 0; i < NUM_DEBUG_SECTIONS; ++i, ++p_reloc) {
+
+	unsigned long ct = p_reloc->pr_reloc_total_count;
+	struct Dwarf_P_Relocation_Block_s *p_blk;
+	struct Dwarf_P_Relocation_Block_s *p_blk_last;
+
+	/* int len */
+	int err;
+
+
+	if (ct == 0) {
+	    continue;
+	}
+
+	/* len = dbg->de_relocation_record_size; */
+	++sec_count;
+
+	/* total_size = ct *len; */
+	sec_index = p_reloc->pr_sect_num_of_reloc_sect;
+	if (sec_index == 0) {
+	    /* call de_func or de_func_b, getting section number of
+	       reloc sec */
+	    int rel_section_index;
+	    int int_name;
+	    Dwarf_Unsigned name_idx;
+
+	    /* 
+	       This is a bit of a fake, as we do not really have true
+	       elf sections at all. Just the data such might contain.
+	       But this lets the caller eventually link things
+	       together: without this call we would not know what rel
+	       data goes with what section when we are asked for the
+	       real arrays. */
+
+	    if (dbg->de_func_b) {
+		rel_section_index =
+		    dbg->de_func_b(_dwarf_rel_section_names[i],
+				   dbg->de_relocation_record_size,
+				   /* type */ SHT_REL,
+				   /* flags */ 0,
+				   /* link to symtab, which we cannot
+				      know */ SHN_UNDEF,
+				   /* sec rels apply to */
+				   dbg->de_elf_sects[i],
+				   &name_idx, &err);
+	    } else {
+		rel_section_index =
+		    dbg->de_func(_dwarf_rel_section_names[i],
+				 dbg->de_relocation_record_size,
+				 /* type */ SHT_REL,
+				 /* flags */ 0,
+				 /* link to symtab, which we cannot
+				    know */ SHN_UNDEF,
+				 /* sec rels apply to, in elf, sh_info */
+				 dbg->de_elf_sects[i], &int_name, &err);
+		name_idx = int_name;
+	    }
+	    if (rel_section_index == -1) {
+		{
+		    _dwarf_p_error(dbg, &error, DW_DLE_ELF_SECT_ERR);
+		    return (DW_DLV_ERROR);
+		}
+	    }
+	    p_reloc->pr_sect_num_of_reloc_sect = rel_section_index;
+	    sec_index = rel_section_index;
+	}
+
+	p_blk = p_reloc->pr_first_block;
+
+	if (p_reloc->pr_block_count > 1) {
+	    struct Dwarf_P_Relocation_Block_s *new_blk;
+
+	    /* HACK , not normal interfaces, trashing p_reloc current
+	       contents! */
+	    _dwarf_reset_reloc_sect_info(p_reloc, ct);
+
+	    /* Creating new single block for all 'ct' entries */
+	    res = _dwarf_pro_pre_alloc_n_reloc_slots(dbg, (int) i, ct);
+
+
+	    if (res != DW_DLV_OK) {
+		return res;
+	    }
+	    new_blk = p_reloc->pr_first_block;
+
+	    data = (Dwarf_Small *) new_blk->rb_data;
+
+	    /* The following loop does the consolidation to a single
+	       block and frees the input block(s). */
+	    do {
+
+		unsigned long len =
+		    p_blk->rb_where_to_add_next - p_blk->rb_data;
+
+		memcpy(data, p_blk->rb_data, len);
+		data += len;
+
+		p_blk_last = p_blk;
+		p_blk = p_blk->rb_next;
+
+		_dwarf_p_dealloc(dbg, (Dwarf_Small *) p_blk_last);
+	    } while (p_blk);
+	    /* ASSERT: sum of len copied == total_size */
+	    new_blk->rb_next_slot_to_use = ct;
+	    new_blk->rb_where_to_add_next = (char *) data;
+	    p_reloc->pr_reloc_total_count = ct;
+
+	    /* have now created a single block, but no change in slots
+	       used (pr_reloc_total_count) */
+	}
+    }
+
+    *new_sec_count = 0;
+    return DW_DLV_OK;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc_symbolic.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,55 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+int _dwarf_pro_reloc_name_symbolic(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,	/* r_offset 
+													   of 
+													   reloc 
+													 */
+				   Dwarf_Unsigned symidx,
+				   enum Dwarf_Rel_Type,
+				   int reltarget_length);
+int
+  _dwarf_pro_reloc_length_symbolic(Dwarf_P_Debug dbg, int base_sec_index, Dwarf_Unsigned offset,	/* r_offset 
+													   of 
+													   reloc 
+													 */
+				   Dwarf_Unsigned start_symidx,
+				   Dwarf_Unsigned end_symidx,
+				   enum Dwarf_Rel_Type,
+				   int reltarget_length);
+
+int _dwarf_symbolic_relocs_to_disk(Dwarf_P_Debug dbg,
+				   Dwarf_Signed * new_sec_count);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_section.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,2217 @@
+/*
+
+  Copyright (C) 2000,2004,2006 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright (C) 2007 David Anderson. All Rights Reserved.
+  Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+/* 
+   SGI has moved from the Crittenden Lane address.
+*/
+
+
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#include <stdio.h>
+#include <string.h>
+#ifdef   HAVE_ELFACCESS_H
+#include <elfaccess.h>
+#endif
+#include "pro_incl.h"
+#include "pro_section.h"
+#include "pro_line.h"
+#include "pro_frame.h"
+#include "pro_die.h"
+#include "pro_macinfo.h"
+#include "pro_types.h"
+
+#ifndef SHF_MIPS_NOSTRIP
+/* if this is not defined, we probably don't need it: just use 0 */
+#define SHF_MIPS_NOSTRIP 0
+#endif
+#ifndef R_MIPS_NONE
+#define R_MIPS_NONE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/* must match up with pro_section.h defines of DEBUG_INFO etc 
+and sectnames (below).  REL_SEC_PREFIX is either ".rel" or ".rela"
+see pro_incl.h
+*/
+char *_dwarf_rel_section_names[] = {
+    REL_SEC_PREFIX ".debug_info",
+    REL_SEC_PREFIX ".debug_line",
+    REL_SEC_PREFIX ".debug_abbrev",	/* no relocations on this, really */
+    REL_SEC_PREFIX ".debug_frame",
+    REL_SEC_PREFIX ".debug_aranges",
+    REL_SEC_PREFIX ".debug_pubnames",
+    REL_SEC_PREFIX ".debug_str",
+    REL_SEC_PREFIX ".debug_funcnames",	/* sgi extension */
+    REL_SEC_PREFIX ".debug_typenames",	/* sgi extension */
+    REL_SEC_PREFIX ".debug_varnames",	/* sgi extension */
+    REL_SEC_PREFIX ".debug_weaknames",	/* sgi extension */
+    REL_SEC_PREFIX ".debug_macinfo",
+    REL_SEC_PREFIX ".debug_loc"
+};
+
+/* names of sections. Ensure that it matches the defines 
+   in pro_section.h, in the same order 
+   Must match also _dwarf_rel_section_names above
+*/
+char *_dwarf_sectnames[] = {
+    ".debug_info",
+    ".debug_line",
+    ".debug_abbrev",
+    ".debug_frame",
+    ".debug_aranges",
+    ".debug_pubnames",
+    ".debug_str",
+    ".debug_funcnames",		/* sgi extension */
+    ".debug_typenames",		/* sgi extension */
+    ".debug_varnames",		/* sgi extension */
+    ".debug_weaknames",		/* sgi extension */
+    ".debug_macinfo",
+    ".debug_loc"
+};
+
+
+
+
+static Dwarf_Ubyte std_opcode_len[] = { 0,	/* DW_LNS_copy */
+    1,				/* DW_LNS_advance_pc */
+    1,				/* DW_LNS_advance_line */
+    1,				/* DW_LNS_set_file */
+    1,				/* DW_LNS_set_column */
+    0,				/* DW_LNS_negate_stmt */
+    0,				/* DW_LNS_set_basic_block */
+    0,				/* DW_LNS_const_add_pc */
+    1,				/* DW_LNS_fixed_advance_pc */
+};
+
+/* struct to hold relocation entries. Its mantained as a linked
+   list of relocation structs, and will then be written at as a
+   whole into the relocation section. Whether its 32 bit or
+   64 bit will be obtained from Dwarf_Debug pointer.
+*/
+
+typedef struct Dwarf_P_Rel_s *Dwarf_P_Rel;
+struct Dwarf_P_Rel_s {
+    Dwarf_P_Rel dr_next;
+    void *dr_rel_datap;
+};
+typedef struct Dwarf_P_Rel_Head_s *Dwarf_P_Rel_Head;
+struct Dwarf_P_Rel_Head_s {
+    struct Dwarf_P_Rel_s *drh_head;
+    struct Dwarf_P_Rel_s *drh_tail;
+};
+
+static int _dwarf_pro_generate_debugline(Dwarf_P_Debug dbg,
+					 Dwarf_Error * error);
+static int _dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg,
+					  Dwarf_Error * error);
+static int _dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg,
+					 Dwarf_Error * error);
+static Dwarf_P_Abbrev _dwarf_pro_getabbrev(Dwarf_P_Die, Dwarf_P_Abbrev);
+static int _dwarf_pro_match_attr
+    (Dwarf_P_Attribute, Dwarf_P_Abbrev, int no_attr);
+
+/* these macros used as return value for below functions */
+#define		OPC_INCS_ZERO		-1
+#define		OPC_OUT_OF_RANGE	-2
+#define		LINE_OUT_OF_RANGE	-3
+static int _dwarf_pro_get_opc(Dwarf_Unsigned addr_adv, int line_adv);
+
+
+/* BEGIN_LEN_SIZE is the size of the 'length' field in total. 
+   Which may be 4,8, or 12 bytes! 
+   4 is standard DWARF2.
+   8 is non-standard MIPS-IRIX 64-bit.
+   12 is standard DWARF3 for 64 bit offsets.
+   Used in various routines: local variable names
+   must match the names here.
+*/
+#define BEGIN_LEN_SIZE (uwordb_size + extension_size)
+
+/*
+	Return TRUE if we need the section, FALSE otherwise
+
+        If any of the 'line-data-related' calls were made
+        including file or directory entries,
+        produce .debug_line .
+
+*/
+static int
+dwarf_need_debug_line_section(Dwarf_P_Debug dbg)
+{
+    if (dbg->de_lines == NULL && dbg->de_file_entries == NULL
+	&& dbg->de_inc_dirs == NULL) {
+	return FALSE;
+    }
+    return TRUE;
+}
+
+/*
+    Convert debug information to  a format such that 
+    it can be written on disk.
+    Called exactly once per execution.
+*/
+Dwarf_Signed
+dwarf_transform_to_disk_form(Dwarf_P_Debug dbg, Dwarf_Error * error)
+{
+    /* 
+       Section data in written out in a number of buffers. Each
+       _generate_*() function returns a cumulative count of buffers for 
+       all the sections. get_section_bytes() returns pointers to these
+       buffers one at a time. */
+    int nbufs;
+    int sect;
+    int name_idx;
+    int err;
+    Dwarf_Unsigned du;
+
+    if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_NOCOUNT);
+    }
+
+    /* Create dwarf section headers */
+    for (sect = 0; sect < NUM_DEBUG_SECTIONS; sect++) {
+	long flags = 0;
+
+	switch (sect) {
+
+	case DEBUG_INFO:
+	    if (dbg->de_dies == NULL)
+		continue;
+	    break;
+
+	case DEBUG_LINE:
+	    if (dwarf_need_debug_line_section(dbg) == FALSE) {
+		continue;
+	    }
+	    break;
+
+	case DEBUG_ABBREV:
+	    if (dbg->de_dies == NULL)
+		continue;
+	    break;
+
+	case DEBUG_FRAME:
+	    if (dbg->de_frame_cies == NULL)
+		continue;
+	    flags = SHF_MIPS_NOSTRIP;
+	    break;
+
+	case DEBUG_ARANGES:
+	    if (dbg->de_arange == NULL)
+		continue;
+	    break;
+
+	case DEBUG_PUBNAMES:
+	    if (dbg->de_simple_name_headers[dwarf_snk_pubname].
+		sn_head == NULL)
+		continue;
+	    break;
+
+	case DEBUG_STR:
+	    if (dbg->de_strings == NULL)
+		continue;
+	    break;
+
+	case DEBUG_FUNCNAMES:
+	    if (dbg->de_simple_name_headers[dwarf_snk_funcname].
+		sn_head == NULL)
+		continue;
+	    break;
+
+	case DEBUG_TYPENAMES:
+	    if (dbg->de_simple_name_headers[dwarf_snk_typename].
+		sn_head == NULL)
+		continue;
+	    break;
+
+	case DEBUG_VARNAMES:
+	    if (dbg->de_simple_name_headers[dwarf_snk_varname].
+		sn_head == NULL)
+		continue;
+	    break;
+
+	case DEBUG_WEAKNAMES:
+	    if (dbg->de_simple_name_headers[dwarf_snk_weakname].
+		sn_head == NULL)
+		continue;
+	    break;
+
+	case DEBUG_MACINFO:
+	    if (dbg->de_first_macinfo == NULL)
+		continue;
+	    break;
+	case DEBUG_LOC:
+	    /* not handled yet */
+	    continue;
+	default:
+	    /* logic error: missing a case */
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR, DW_DLV_NOCOUNT);
+	}
+	{
+	    int new_base_elf_sect;
+
+	    if (dbg->de_func_b) {
+		new_base_elf_sect =
+		    dbg->de_func_b(_dwarf_sectnames[sect],
+				   /* rec size */ 1,
+				   SECTION_TYPE,
+				   flags, SHN_UNDEF, 0, &du, &err);
+
+	    } else {
+		new_base_elf_sect = dbg->de_func(_dwarf_sectnames[sect],
+						 dbg->
+						 de_relocation_record_size,
+						 SECTION_TYPE, flags,
+						 SHN_UNDEF, 0,
+						 &name_idx, &err);
+		du = name_idx;
+	    }
+	    if (new_base_elf_sect == -1) {
+		DWARF_P_DBG_ERROR(dbg, DW_DLE_ELF_SECT_ERR,
+				  DW_DLV_NOCOUNT);
+	    }
+	    dbg->de_elf_sects[sect] = new_base_elf_sect;
+
+	    dbg->de_sect_name_idx[sect] = du;
+	}
+    }
+
+    nbufs = 0;
+
+    /* 
+       Changing the order in which the sections are generated may cause 
+       problems because of relocations. */
+
+    if (dwarf_need_debug_line_section(dbg) == TRUE) {
+	nbufs = _dwarf_pro_generate_debugline(dbg, error);
+	if (nbufs < 0) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGLINE_ERROR,
+			      DW_DLV_NOCOUNT);
+	}
+    }
+
+    if (dbg->de_frame_cies) {
+	nbufs = _dwarf_pro_generate_debugframe(dbg, error);
+	if (nbufs < 0) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGFRAME_ERROR,
+			      DW_DLV_NOCOUNT);
+	}
+    }
+    if (dbg->de_first_macinfo) {
+	nbufs = _dwarf_pro_transform_macro_info_to_disk(dbg, error);
+	if (nbufs < 0) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGMACINFO_ERROR,
+			      DW_DLV_NOCOUNT);
+	}
+    }
+
+    if (dbg->de_dies) {
+	nbufs = _dwarf_pro_generate_debuginfo(dbg, error);
+	if (nbufs < 0) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
+			      DW_DLV_NOCOUNT);
+	}
+    }
+
+    if (dbg->de_arange) {
+	nbufs = _dwarf_transform_arange_to_disk(dbg, error);
+	if (nbufs < 0) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
+			      DW_DLV_NOCOUNT);
+	}
+    }
+
+    if (dbg->de_simple_name_headers[dwarf_snk_pubname].sn_head) {
+	nbufs = _dwarf_transform_simplename_to_disk(dbg,
+						    dwarf_snk_pubname,
+						    DEBUG_PUBNAMES,
+						    error);
+
+
+	if (nbufs < 0) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
+			      DW_DLV_NOCOUNT);
+	}
+    }
+
+    if (dbg->de_simple_name_headers[dwarf_snk_funcname].sn_head) {
+	nbufs = _dwarf_transform_simplename_to_disk(dbg,
+						    dwarf_snk_funcname,
+						    DEBUG_FUNCNAMES,
+						    error);
+	if (nbufs < 0) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
+			      DW_DLV_NOCOUNT);
+	}
+    }
+
+    if (dbg->de_simple_name_headers[dwarf_snk_typename].sn_head) {
+	nbufs = _dwarf_transform_simplename_to_disk(dbg,
+						    dwarf_snk_typename,
+						    DEBUG_TYPENAMES,
+						    error);
+	if (nbufs < 0) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
+			      DW_DLV_NOCOUNT);
+	}
+    }
+
+    if (dbg->de_simple_name_headers[dwarf_snk_varname].sn_head) {
+	nbufs = _dwarf_transform_simplename_to_disk(dbg,
+						    dwarf_snk_varname,
+						    DEBUG_VARNAMES,
+						    error);
+
+	if (nbufs < 0) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
+			      DW_DLV_NOCOUNT);
+	}
+    }
+
+    if (dbg->de_simple_name_headers[dwarf_snk_weakname].sn_head) {
+	nbufs = _dwarf_transform_simplename_to_disk(dbg,
+						    dwarf_snk_weakname,
+						    DEBUG_WEAKNAMES,
+						    error);
+
+	if (nbufs < 0) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
+			      DW_DLV_NOCOUNT);
+	}
+    }
+
+    {
+	Dwarf_Signed new_secs;
+	int res;
+
+	res = dbg->de_transform_relocs_to_disk(dbg, &new_secs);
+	if (res != DW_DLV_OK) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_DEBUGINFO_ERROR,
+			      DW_DLV_NOCOUNT);
+	}
+	nbufs += new_secs;
+    }
+    return nbufs;
+}
+
+
+/*---------------------------------------------------------------
+	Generate debug_line section 
+---------------------------------------------------------------*/
+static int
+_dwarf_pro_generate_debugline(Dwarf_P_Debug dbg, Dwarf_Error * error)
+{
+    Dwarf_P_Inc_Dir curdir = 0;
+    Dwarf_P_F_Entry curentry = 0;
+    Dwarf_P_Line curline = 0;
+    Dwarf_P_Line prevline = 0;
+
+    /* all data named cur* are used to loop thru linked lists */
+
+    int sum_bytes = 0;
+    int prolog_size = 0;
+    unsigned char *data = 0;	/* holds disk form data */
+    int elfsectno = 0;
+    unsigned char *start_line_sec = 0;	/* pointer to the buffer at
+					   section start */
+    /* temps for memcpy */
+    Dwarf_Unsigned du = 0;
+    Dwarf_Ubyte db = 0;
+    Dwarf_Half dh = 0;
+    int res = 0;
+    int uwordb_size = dbg->de_offset_size;
+    int extension_size = dbg->de_64bit_extension ? 4 : 0;
+    int upointer_size = dbg->de_pointer_size;
+    char buff1[ENCODE_SPACE_NEEDED];
+
+
+
+    sum_bytes = 0;
+
+    elfsectno = dbg->de_elf_sects[DEBUG_LINE];
+
+    /* include directories */
+    curdir = dbg->de_inc_dirs;
+    while (curdir) {
+	prolog_size += strlen(curdir->did_name) + 1;
+	curdir = curdir->did_next;
+    }
+    prolog_size++;		/* last null following last directory
+				   entry. */
+
+    /* file entries */
+    curentry = dbg->de_file_entries;
+    while (curentry) {
+	prolog_size +=
+	    strlen(curentry->dfe_name) + 1 + curentry->dfe_nbytes;
+	curentry = curentry->dfe_next;
+    }
+    prolog_size++;		/* last null byte */
+
+
+    prolog_size += BEGIN_LEN_SIZE + sizeof_uhalf(dbg) +	/* version # */
+	uwordb_size +		/* header length */
+	sizeof_ubyte(dbg) +	/* min_instr length */
+	sizeof_ubyte(dbg) +	/* default is_stmt */
+	sizeof_ubyte(dbg) +	/* linebase */
+	sizeof_ubyte(dbg) +	/* linerange */
+	sizeof_ubyte(dbg);	/* opcode base */
+
+    /* length of table specifying # of opnds */
+    prolog_size += sizeof(std_opcode_len);
+
+    GET_CHUNK(dbg, elfsectno, data, prolog_size, error);
+    start_line_sec = data;
+
+    /* copy over the data */
+    /* total_length */
+    du = 0;
+    if (extension_size) {
+	Dwarf_Word x = DISTINGUISHED_VALUE;
+
+	WRITE_UNALIGNED(dbg, (void *) data, (const void *) &x,
+			sizeof(x), extension_size);
+	data += extension_size;
+    }
+
+    WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
+		    sizeof(du), uwordb_size);
+    data += uwordb_size;
+
+    dh = VERSION;
+    WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dh,
+		    sizeof(dh), sizeof(Dwarf_Half));
+    data += sizeof(Dwarf_Half);
+
+    /* header length */
+    du = prolog_size - (BEGIN_LEN_SIZE + sizeof(Dwarf_Half) +
+			uwordb_size);
+    {
+	WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
+			sizeof(du), uwordb_size);
+	data += uwordb_size;
+    }
+    db = MIN_INST_LENGTH;
+    WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+		    sizeof(db), sizeof(Dwarf_Ubyte));
+    data += sizeof(Dwarf_Ubyte);
+    db = DEFAULT_IS_STMT;
+    WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+		    sizeof(db), sizeof(Dwarf_Ubyte));
+    data += sizeof(Dwarf_Ubyte);
+    db = (Dwarf_Ubyte) LINE_BASE;
+    WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+		    sizeof(db), sizeof(Dwarf_Ubyte));
+    data += sizeof(Dwarf_Ubyte);
+    db = LINE_RANGE;
+    WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+		    sizeof(db), sizeof(Dwarf_Ubyte));
+    data += sizeof(Dwarf_Ubyte);
+    db = OPCODE_BASE;
+    WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+		    sizeof(db), sizeof(Dwarf_Ubyte));
+    data += sizeof(Dwarf_Ubyte);
+    WRITE_UNALIGNED(dbg, (void *) data, (const void *) std_opcode_len,
+		    sizeof(std_opcode_len), sizeof(std_opcode_len));
+    data += sizeof(std_opcode_len);
+
+    /* copy over include directories */
+    curdir = dbg->de_inc_dirs;
+    while (curdir) {
+	strcpy((char *) data, curdir->did_name);
+	data += strlen(curdir->did_name) + 1;
+	curdir = curdir->did_next;
+    }
+    *data = '\0';		/* last null */
+    data++;
+
+    /* copy file entries */
+    curentry = dbg->de_file_entries;
+    while (curentry) {
+	strcpy((char *) data, curentry->dfe_name);
+	data += strlen(curentry->dfe_name) + 1;
+	/* copies of leb numbers, no endian issues */
+	memcpy((void *) data,
+	       (const void *) curentry->dfe_args, curentry->dfe_nbytes);
+	data += curentry->dfe_nbytes;
+	curentry = curentry->dfe_next;
+    }
+    *data = '\0';
+    data++;
+
+    sum_bytes += prolog_size;
+
+    curline = dbg->de_lines;
+    prevline = (Dwarf_P_Line)
+	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Line_s));
+    if (prevline == NULL) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_LINE_ALLOC, -1);
+    }
+    _dwarf_pro_reg_init(prevline);
+    /* generate opcodes for line numbers */
+    while (curline) {
+	int nbytes;
+	char *arg;
+	int opc;
+	int no_lns_copy;	/* if lns copy opcode doesnt need to be 
+				   generated, if special opcode or end
+				   sequence */
+	Dwarf_Unsigned addr_adv;
+	int line_adv;		/* supposed to be a reasonably small
+				   number, so the size should not be a
+				   problem. ? */
+
+	no_lns_copy = 0;
+	if (curline->dpl_opc != 0) {
+	    int inst_bytes;	/* no of bytes in extended opcode */
+	    char *str;		/* hold leb encoded inst_bytes */
+	    int str_nbytes;	/* no of bytes in str */
+
+	    switch (curline->dpl_opc) {
+	    case DW_LNE_end_sequence:
+
+		/* Advance pc to end of text section. */
+		addr_adv = curline->dpl_address - prevline->dpl_address;
+		if (addr_adv > 0) {
+		    db = DW_LNS_advance_pc;
+		    res =
+			_dwarf_pro_encode_leb128_nm(addr_adv /
+						    MIN_INST_LENGTH,
+						    &nbytes, buff1,
+						    sizeof(buff1));
+		    if (res != DW_DLV_OK) {
+			DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+		    }
+		    GET_CHUNK(dbg, elfsectno, data,
+			      nbytes + sizeof(Dwarf_Ubyte), error);
+		    WRITE_UNALIGNED(dbg, (void *) data,
+				    (const void *) &db, sizeof(db),
+				    sizeof(Dwarf_Ubyte));
+		    data += sizeof(Dwarf_Ubyte);
+		    /* leb, no endianness issue */
+		    memcpy((void *) data, (const void *) buff1, nbytes);
+		    data += nbytes + sizeof(Dwarf_Ubyte);
+		    sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
+		    prevline->dpl_address = curline->dpl_address;
+		}
+
+		/* first null byte */
+		db = 0;
+		GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
+			  error);
+		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+				sizeof(db), sizeof(Dwarf_Ubyte));
+		data += sizeof(Dwarf_Ubyte);
+		sum_bytes += sizeof(Dwarf_Ubyte);
+
+		/* write length of extended opcode */
+		inst_bytes = sizeof(Dwarf_Ubyte);
+		res =
+		    _dwarf_pro_encode_leb128_nm(inst_bytes, &str_nbytes,
+						buff1, sizeof(buff1));
+		if (res != DW_DLV_OK) {
+		    DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+		}
+		GET_CHUNK(dbg, elfsectno, data, str_nbytes, error);
+		memcpy((void *) data, (const void *) buff1, str_nbytes);
+		data += str_nbytes;
+		sum_bytes += str_nbytes;
+
+		/* write extended opcode */
+		db = DW_LNE_end_sequence;
+		GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
+			  error);
+		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+				sizeof(db), sizeof(Dwarf_Ubyte));
+		data += sizeof(Dwarf_Ubyte);
+		sum_bytes += sizeof(Dwarf_Ubyte);
+		/* reset value to original values */
+		_dwarf_pro_reg_init(prevline);
+		no_lns_copy = 1;
+		/* this is set only for end_sequence, so that a
+		   dw_lns_copy is not generated */
+		break;
+
+	    case DW_LNE_set_address:
+
+		/* first null byte */
+		db = 0;
+		GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
+			  error);
+		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+				sizeof(db), sizeof(Dwarf_Ubyte));
+		data += sizeof(Dwarf_Ubyte);
+		sum_bytes += sizeof(Dwarf_Ubyte);
+
+		/* write length of extended opcode */
+		inst_bytes = sizeof(Dwarf_Ubyte) + upointer_size;
+		res =
+		    _dwarf_pro_encode_leb128_nm(inst_bytes, &str_nbytes,
+						buff1, sizeof(buff1));
+		if (res != DW_DLV_OK) {
+		    DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+		}
+		GET_CHUNK(dbg, elfsectno, data, str_nbytes, error);
+		str = buff1;
+		/* leb number, no endian issue */
+		memcpy((void *) data, (const void *) str, str_nbytes);
+		data += str_nbytes;
+		sum_bytes += str_nbytes;
+
+		/* write extended opcode */
+		db = DW_LNE_set_address;
+		GET_CHUNK(dbg, elfsectno, data, upointer_size +
+			  sizeof(Dwarf_Ubyte), error);
+		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+				sizeof(db), sizeof(Dwarf_Ubyte));
+		data += sizeof(Dwarf_Ubyte);
+		sum_bytes += sizeof(Dwarf_Ubyte);
+
+		/* reloc for address */
+		res = dbg->de_reloc_name(dbg, DEBUG_LINE, sum_bytes,	/* r_offset 
+									 */
+					 curline->dpl_r_symidx,
+					 dwarf_drt_data_reloc,
+					 uwordb_size);
+		if (res != DW_DLV_OK) {
+		    DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+		}
+
+		/* write offset (address) */
+		du = curline->dpl_address;
+		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
+				sizeof(du), upointer_size);
+		data += upointer_size;
+		sum_bytes += upointer_size;
+		prevline->dpl_address = curline->dpl_address;
+		no_lns_copy = 1;
+		break;
+	    }
+	} else {
+	    if (curline->dpl_file != prevline->dpl_file) {
+		db = DW_LNS_set_file;
+		res =
+		    _dwarf_pro_encode_leb128_nm(curline->dpl_file,
+						&nbytes, buff1,
+						sizeof(buff1));
+		if (res != DW_DLV_OK) {
+		    DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+		}
+		arg = buff1;
+		GET_CHUNK(dbg, elfsectno, data,
+			  nbytes + sizeof(Dwarf_Ubyte), error);
+		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+				sizeof(db), sizeof(Dwarf_Ubyte));
+		data += sizeof(Dwarf_Ubyte);
+		memcpy((void *) data, (const void *) arg, nbytes);
+		data += nbytes;
+		sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
+		prevline->dpl_file = curline->dpl_file;
+	    }
+	    if (curline->dpl_column != prevline->dpl_column) {
+		db = DW_LNS_set_column;
+		res = _dwarf_pro_encode_leb128_nm(curline->dpl_column,
+						  &nbytes,
+						  buff1, sizeof(buff1));
+		if (res != DW_DLV_OK) {
+		    DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+		}
+
+		arg = buff1;
+		GET_CHUNK(dbg, elfsectno, data,
+			  nbytes + sizeof(Dwarf_Ubyte), error);
+		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+				sizeof(db), sizeof(Dwarf_Ubyte));
+		data += sizeof(Dwarf_Ubyte);
+		memcpy((void *) data, (const void *) arg, nbytes);
+		data += nbytes;
+		sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
+		prevline->dpl_column = curline->dpl_column;
+	    }
+	    if (curline->dpl_is_stmt != prevline->dpl_is_stmt) {
+		db = DW_LNS_negate_stmt;
+		GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
+			  error);
+		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+				sizeof(db), sizeof(Dwarf_Ubyte));
+		data += sizeof(Dwarf_Ubyte);
+		sum_bytes += sizeof(Dwarf_Ubyte);
+		prevline->dpl_is_stmt = curline->dpl_is_stmt;
+	    }
+	    if (curline->dpl_basic_block == true &&
+		prevline->dpl_basic_block == false) {
+		db = DW_LNS_set_basic_block;
+		GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
+			  error);
+		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+				sizeof(db), sizeof(Dwarf_Ubyte));
+		data += sizeof(Dwarf_Ubyte);
+		sum_bytes += sizeof(Dwarf_Ubyte);
+		prevline->dpl_basic_block = curline->dpl_basic_block;
+	    }
+	    addr_adv = curline->dpl_address - prevline->dpl_address;
+
+	    line_adv = (int) (curline->dpl_line - prevline->dpl_line);
+	    if ((addr_adv % MIN_INST_LENGTH) != 0) {
+		DWARF_P_DBG_ERROR(dbg, DW_DLE_WRONG_ADDRESS, -1);
+	    }
+	    if ((opc = _dwarf_pro_get_opc(addr_adv, line_adv)) > 0) {
+		no_lns_copy = 1;
+		db = opc;
+		GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte),
+			  error);
+		WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+				sizeof(db), sizeof(Dwarf_Ubyte));
+		data += sizeof(Dwarf_Ubyte);
+		sum_bytes += sizeof(Dwarf_Ubyte);
+		prevline->dpl_basic_block = false;
+		prevline->dpl_address = curline->dpl_address;
+		prevline->dpl_line = curline->dpl_line;
+	    } else {
+		if (addr_adv > 0) {
+		    db = DW_LNS_advance_pc;
+		    res =
+			_dwarf_pro_encode_leb128_nm(addr_adv /
+						    MIN_INST_LENGTH,
+						    &nbytes, buff1,
+						    sizeof(buff1));
+		    if (res != DW_DLV_OK) {
+			DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+		    }
+
+		    arg = buff1;
+		    GET_CHUNK(dbg, elfsectno, data,
+			      nbytes + sizeof(Dwarf_Ubyte), error);
+		    WRITE_UNALIGNED(dbg, (void *) data,
+				    (const void *) &db,
+				    sizeof(db), sizeof(Dwarf_Ubyte));
+		    data += sizeof(Dwarf_Ubyte);
+		    memcpy((void *) data, (const void *) arg, nbytes);
+		    data += nbytes + sizeof(Dwarf_Ubyte);
+		    sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
+		    prevline->dpl_basic_block = false;
+		    prevline->dpl_address = curline->dpl_address;
+		}
+		if (line_adv != 0) {
+		    db = DW_LNS_advance_line;
+		    res = _dwarf_pro_encode_signed_leb128_nm(line_adv,
+							     &nbytes,
+							     buff1,
+							     sizeof
+							     (buff1));
+		    if (res != DW_DLV_OK) {
+			DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+		    }
+
+		    arg = buff1;
+		    GET_CHUNK(dbg, elfsectno, data,
+			      nbytes + sizeof(Dwarf_Ubyte), error);
+		    WRITE_UNALIGNED(dbg, (void *) data,
+				    (const void *) &db, sizeof(db),
+				    sizeof(Dwarf_Ubyte));
+		    data += sizeof(Dwarf_Ubyte);
+		    memcpy((void *) data, (const void *) arg, nbytes);
+		    data += nbytes + sizeof(Dwarf_Ubyte);
+		    sum_bytes += nbytes + sizeof(Dwarf_Ubyte);
+		    prevline->dpl_basic_block = false;
+		    prevline->dpl_line = curline->dpl_line;
+		}
+	    }
+	}			/* ends else for opc != 0 */
+	if (no_lns_copy == 0) {	/* if not a special or dw_lne_end_seq
+				   generate a matrix line */
+	    db = DW_LNS_copy;
+	    GET_CHUNK(dbg, elfsectno, data, sizeof(Dwarf_Ubyte), error);
+	    WRITE_UNALIGNED(dbg, (void *) data,
+			    (const void *) &db,
+			    sizeof(db), sizeof(Dwarf_Ubyte));
+	    data += sizeof(Dwarf_Ubyte);
+	    sum_bytes += sizeof(Dwarf_Ubyte);
+	    prevline->dpl_basic_block = false;
+	}
+	curline = curline->dpl_next;
+    }
+
+    /* write total length field */
+    du = sum_bytes - BEGIN_LEN_SIZE;
+    {
+	start_line_sec += extension_size;
+	WRITE_UNALIGNED(dbg, (void *) start_line_sec,
+			(const void *) &du, sizeof(du), uwordb_size);
+    }
+
+    return (int) dbg->de_n_debug_sect;
+}
+
+/*---------------------------------------------------------------
+	Generate debug_frame section 
+---------------------------------------------------------------*/
+static int
+_dwarf_pro_generate_debugframe(Dwarf_P_Debug dbg, Dwarf_Error * error)
+{
+    int elfsectno;
+    int i;
+    int firsttime = 1;
+    int pad;			/* pad for padding to align cies and
+				   fdes */
+    Dwarf_P_Cie curcie;
+    Dwarf_P_Fde curfde;
+    unsigned char *data;
+    Dwarf_sfixed dsw;
+    Dwarf_Unsigned du;
+    Dwarf_Ubyte db;
+    long *cie_offs;		/* holds byte offsets for links to
+				   fde's */
+    unsigned long cie_length;
+    int cie_no;
+    int uwordb_size = dbg->de_offset_size;
+    int extension_size = dbg->de_64bit_extension ? 4 : 0;
+    int upointer_size = dbg->de_pointer_size;
+    Dwarf_Unsigned cur_off;	/* current offset of written data, held 
+				   for relocation info */
+
+    elfsectno = dbg->de_elf_sects[DEBUG_FRAME];
+
+    curcie = dbg->de_frame_cies;
+    cie_length = 0;
+    cur_off = 0;
+    cie_offs = (long *)
+	_dwarf_p_get_alloc(dbg, sizeof(long) * dbg->de_n_cie);
+    if (cie_offs == NULL) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
+    }
+    /* generate cie number as we go along */
+    cie_no = 1;
+    while (curcie) {
+	char *code_al;
+	int c_bytes;
+	char *data_al;
+	int d_bytes;
+	int res;
+	char buff1[ENCODE_SPACE_NEEDED];
+	char buff2[ENCODE_SPACE_NEEDED];
+	char buff3[ENCODE_SPACE_NEEDED];
+	char *augmentation;
+	char *augmented_al;
+	long augmented_fields_length;
+	int a_bytes;
+
+	res = _dwarf_pro_encode_leb128_nm(curcie->cie_code_align,
+					  &c_bytes,
+					  buff1, sizeof(buff1));
+	if (res != DW_DLV_OK) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
+	}
+	/* Before April 1999, the following was using an unsigned
+	   encode. That worked ok even though the decoder used the
+	   correct signed leb read, but doing the encode correctly
+	   (according to the dwarf spec) saves space in the output file 
+	   and is completely compatible.
+
+	   Note the actual stored amount on MIPS was 10 bytes (!) to
+	   store the value -4. (hex)fc ffffffff ffffffff 01 The
+	   libdwarf consumer consumed all 10 bytes too!
+
+	   old version res =
+	   _dwarf_pro_encode_leb128_nm(curcie->cie_data_align,
+
+	   below is corrected signed version. */
+	res = _dwarf_pro_encode_signed_leb128_nm(curcie->cie_data_align,
+						 &d_bytes,
+						 buff2, sizeof(buff2));
+	if (res != DW_DLV_OK) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
+	}
+	code_al = buff1;
+	data_al = buff2;
+
+	/* get the correct offset */
+	if (firsttime) {
+	    cie_offs[cie_no - 1] = 0;
+	    firsttime = 0;
+	} else {
+	    cie_offs[cie_no - 1] = cie_offs[cie_no - 2] +
+		(long) cie_length + BEGIN_LEN_SIZE;
+	}
+	cie_no++;
+	augmentation = curcie->cie_aug;
+	if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) {
+	    augmented_fields_length = 0;
+	    res = _dwarf_pro_encode_leb128_nm(augmented_fields_length,
+					      &a_bytes, buff3,
+					      sizeof(buff3));
+	    augmented_al = buff3;
+	    if (res != DW_DLV_OK) {
+		DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
+	    }
+	    cie_length = uwordb_size +	/* cie_id */
+		sizeof(Dwarf_Ubyte) +	/* cie version */
+		strlen(curcie->cie_aug) + 1 +	/* augmentation */
+		c_bytes +	/* code alignment factor */
+		d_bytes +	/* data alignment factor */
+		sizeof(Dwarf_Ubyte) +	/* return reg address */
+		a_bytes +	/* augmentation length */
+		curcie->cie_inst_bytes;
+	} else {
+	    cie_length = uwordb_size +	/* cie_id */
+		sizeof(Dwarf_Ubyte) +	/* cie version */
+		strlen(curcie->cie_aug) + 1 +	/* augmentation */
+		c_bytes + d_bytes + sizeof(Dwarf_Ubyte) +	/* return 
+								   reg
+								   address 
+								 */
+		curcie->cie_inst_bytes;
+	}
+	pad = (int) PADDING(cie_length, upointer_size);
+	cie_length += pad;
+	GET_CHUNK(dbg, elfsectno, data, cie_length +
+		  BEGIN_LEN_SIZE, error);
+	if (extension_size) {
+	    Dwarf_Unsigned x = DISTINGUISHED_VALUE;
+
+	    WRITE_UNALIGNED(dbg, (void *) data,
+			    (const void *) &x,
+			    sizeof(x), extension_size);
+	    data += extension_size;
+
+	}
+	du = cie_length;
+	/* total length of cie */
+	WRITE_UNALIGNED(dbg, (void *) data,
+			(const void *) &du, sizeof(du), uwordb_size);
+	data += uwordb_size;
+
+	/* cie-id is a special value. */
+	du = DW_CIE_ID;
+	WRITE_UNALIGNED(dbg, (void *) data, (const void *) &du,
+			sizeof(du), uwordb_size);
+	data += uwordb_size;
+
+	db = curcie->cie_version;
+	WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+			sizeof(db), sizeof(Dwarf_Ubyte));
+	data += sizeof(Dwarf_Ubyte);
+	strcpy((char *) data, curcie->cie_aug);
+	data += strlen(curcie->cie_aug) + 1;
+	memcpy((void *) data, (const void *) code_al, c_bytes);
+	data += c_bytes;
+	memcpy((void *) data, (const void *) data_al, d_bytes);
+	data += d_bytes;
+	db = curcie->cie_ret_reg;
+	WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+			sizeof(db), sizeof(Dwarf_Ubyte));
+	data += sizeof(Dwarf_Ubyte);
+
+	if (strcmp(augmentation, DW_CIE_AUGMENTER_STRING_V0) == 0) {
+	    memcpy((void *) data, (const void *) augmented_al, a_bytes);
+	    data += a_bytes;
+	}
+	memcpy((void *) data, (const void *) curcie->cie_inst,
+	       curcie->cie_inst_bytes);
+	data += curcie->cie_inst_bytes;
+	for (i = 0; i < pad; i++) {
+	    *data = DW_CFA_nop;
+	    data++;
+	}
+	curcie = curcie->cie_next;
+    }
+    /* calculate current offset */
+    cur_off = cie_offs[cie_no - 2] + cie_length + BEGIN_LEN_SIZE;
+
+    /* write out fde's */
+    curfde = dbg->de_frame_fdes;
+    while (curfde) {
+	Dwarf_P_Frame_Pgm curinst;
+	long fde_length;
+	int pad;
+	Dwarf_P_Cie cie_ptr;
+	Dwarf_Word cie_index, index;
+	int oet_length, afl_length, res;
+	int v0_augmentation = 0;
+
+#if 0
+	unsigned char *fde_start_point;
+#endif
+
+	char afl_buff[ENCODE_SPACE_NEEDED];
+
+	/* Find the CIE associated with this fde. */
+	cie_ptr = dbg->de_frame_cies;
+	cie_index = curfde->fde_cie;
+	index = 1;		/* The cie_index of the first cie is 1, 
+				   not 0. */
+	while (cie_ptr && index < cie_index) {
+	    cie_ptr = cie_ptr->cie_next;
+	    index++;
+	}
+	if (cie_ptr == NULL) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_NULL, -1);
+	}
+
+	if (strcmp(cie_ptr->cie_aug, DW_CIE_AUGMENTER_STRING_V0) == 0) {
+	    v0_augmentation = 1;
+	    oet_length = sizeof(Dwarf_sfixed);
+	    /* encode the length of augmented fields. */
+	    res = _dwarf_pro_encode_leb128_nm(oet_length,
+					      &afl_length, afl_buff,
+					      sizeof(afl_buff));
+	    if (res != DW_DLV_OK) {
+		DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_OFFS_ALLOC, -1);
+	    }
+
+	    fde_length = curfde->fde_n_bytes + BEGIN_LEN_SIZE +	/* cie
+								   pointer 
+								 */
+		upointer_size +	/* initial loc */
+		upointer_size +	/* address range */
+		afl_length +	/* augmented field length */
+		oet_length;	/* exception_table offset */
+	} else {
+	    fde_length = curfde->fde_n_bytes + BEGIN_LEN_SIZE +	/* cie
+								   pointer 
+								 */
+		upointer_size +	/* initial loc */
+		upointer_size;	/* address range */
+	}
+
+	/* using fde offset, generate DW_AT_MIPS_fde attribute for the
+	   die corresponding to this fde */
+	if (_dwarf_pro_add_AT_fde(dbg, curfde->fde_die, cur_off, error)
+	    < 0)
+	    return -1;
+
+	/* store relocation for cie pointer */
+	res = dbg->de_reloc_name(dbg, DEBUG_FRAME, cur_off +
+				 BEGIN_LEN_SIZE,
+				 /* r_offset */
+				 dbg->de_sect_name_idx[DEBUG_FRAME],
+				 dwarf_drt_data_reloc, uwordb_size);
+	if (res != DW_DLV_OK) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+	}
+
+	/* store relocation information for initial location */
+	res = dbg->de_reloc_name(dbg, DEBUG_FRAME,
+				 cur_off + BEGIN_LEN_SIZE +
+				 upointer_size,
+				 /* r_offset */
+				 curfde->fde_r_symidx,
+				 dwarf_drt_data_reloc, upointer_size);
+	if (res != DW_DLV_OK) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+	}
+	/* Store the relocation information for the
+	   offset_into_exception_info field, if the offset is valid (0
+	   is a valid offset). */
+	if (v0_augmentation &&
+	    curfde->fde_offset_into_exception_tables >= 0) {
+
+	    res = dbg->de_reloc_name(dbg, DEBUG_FRAME,
+				     /* r_offset, where in cie this
+				        field starts */
+				     cur_off + BEGIN_LEN_SIZE +
+				     uwordb_size + 2 * upointer_size +
+				     afl_length,
+				     curfde->fde_exception_table_symbol,
+				     dwarf_drt_segment_rel,
+				     sizeof(Dwarf_sfixed));
+	    if (res != DW_DLV_OK) {
+		DWARF_P_DBG_ERROR(dbg, DW_DLE_CHUNK_ALLOC, -1);
+	    }
+	}
+
+	/* adjust for padding */
+	pad = (int) PADDING(fde_length, upointer_size);
+	fde_length += pad;
+
+
+	/* write out fde */
+	GET_CHUNK(dbg, elfsectno, data, fde_length + BEGIN_LEN_SIZE,
+		  error);
+#if 0
+	fde_start_point = data;
+#endif
+	du = fde_length;
+	{
+	    if (extension_size) {
+		Dwarf_Word x = DISTINGUISHED_VALUE;
+
+		WRITE_UNALIGNED(dbg, (void *) data,
+				(const void *) &x,
+				sizeof(x), extension_size);
+		data += extension_size;
+	    }
+	    /* length */
+	    WRITE_UNALIGNED(dbg, (void *) data,
+			    (const void *) &du,
+			    sizeof(du), uwordb_size);
+	    data += uwordb_size;
+
+	    /* offset to cie */
+	    du = cie_offs[curfde->fde_cie - 1];
+	    WRITE_UNALIGNED(dbg, (void *) data,
+			    (const void *) &du,
+			    sizeof(du), uwordb_size);
+	    data += uwordb_size;
+
+	    du = curfde->fde_initloc;
+	    WRITE_UNALIGNED(dbg, (void *) data,
+			    (const void *) &du,
+			    sizeof(du), upointer_size);
+	    data += upointer_size;
+
+	    if (dbg->de_reloc_pair &&
+		curfde->fde_end_symbol != 0 &&
+		curfde->fde_addr_range == 0) {
+		/* symbolic reloc, need reloc for length What if we
+		   really know the length? If so, should use the other
+		   part of 'if'. */
+		Dwarf_Unsigned val;
+
+		res = dbg->de_reloc_pair(dbg,
+					 /* DEBUG_ARANGES, */
+					 DEBUG_FRAME, cur_off + 2 * uwordb_size + upointer_size,	/* r_offset 
+													 */
+					 curfde->fde_r_symidx,
+					 curfde->fde_end_symbol,
+					 dwarf_drt_first_of_length_pair,
+					 upointer_size);
+		if (res != DW_DLV_OK) {
+		    {
+			_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+			return (0);
+		    }
+		}
+
+		/* arrange pre-calc so assem text can do .word end -
+		   begin + val (gets val from stream) */
+		val = curfde->fde_end_symbol_offset -
+		    curfde->fde_initloc;
+		WRITE_UNALIGNED(dbg, data,
+				(const void *) &val,
+				sizeof(val), upointer_size);
+		data += upointer_size;
+	    } else {
+
+		du = curfde->fde_addr_range;
+		WRITE_UNALIGNED(dbg, (void *) data,
+				(const void *) &du,
+				sizeof(du), upointer_size);
+		data += upointer_size;
+	    }
+	}
+
+	if (v0_augmentation) {
+	    /* write the encoded augmented field length. */
+	    memcpy((void *) data, (const void *) afl_buff, afl_length);
+	    data += afl_length;
+	    /* write the offset_into_exception_tables field. */
+	    dsw =
+		(Dwarf_sfixed) curfde->fde_offset_into_exception_tables;
+	    WRITE_UNALIGNED(dbg, (void *) data, (const void *) &dsw,
+			    sizeof(dsw), sizeof(Dwarf_sfixed));
+	    data += sizeof(Dwarf_sfixed);
+	}
+
+	curinst = curfde->fde_inst;
+	while (curinst) {
+	    db = curinst->dfp_opcode;
+	    WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+			    sizeof(db), sizeof(Dwarf_Ubyte));
+	    data += sizeof(Dwarf_Ubyte);
+#if 0
+	    if (curinst->dfp_sym_index) {
+		int res;
+
+		res = dbg->de_reloc_name(dbg,
+					 DEBUG_FRAME,
+					 (data - fde_start_point)
+					 + cur_off + uwordb_size,	/* r_offset 
+									 */
+					 curinst->dfp_sym_index,
+					 dwarf_drt_data_reloc,
+					 upointer_size);
+		if (res != DW_DLV_OK) {
+		    {
+			_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+			return (0);
+		    }
+		}
+	    }
+#endif
+	    memcpy((void *) data,
+		   (const void *) curinst->dfp_args,
+		   curinst->dfp_nbytes);
+	    data += curinst->dfp_nbytes;
+	    curinst = curinst->dfp_next;
+	}
+	/* padding */
+	for (i = 0; i < pad; i++) {
+	    *data = DW_CFA_nop;
+	    data++;
+	}
+	cur_off += fde_length + uwordb_size;
+	curfde = curfde->fde_next;
+    }
+
+
+    return (int) dbg->de_n_debug_sect;
+}
+
+/*
+  These functions remember all the markers we see along
+  with the right offset in the .debug_info section so that
+  we can dump them all back to the user with the section info.
+*/
+
+static int
+marker_init(Dwarf_P_Debug dbg,
+	    unsigned count)
+{
+    dbg->de_marker_n_alloc = count;
+    dbg->de_markers = NULL;
+    if (count > 0) {
+	dbg->de_markers = _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Marker_s) *
+					     dbg->de_marker_n_alloc);
+	if (dbg->de_markers == NULL) {
+	    dbg->de_marker_n_alloc = 0;
+	    return -1;
+	}
+    }
+    return 0;
+}
+
+static int
+marker_add(Dwarf_P_Debug dbg,
+	   Dwarf_Unsigned offset,
+	   Dwarf_Unsigned marker)
+{
+    if (dbg->de_marker_n_alloc >= (dbg->de_marker_n_used + 1)) {
+	unsigned n = dbg->de_marker_n_used++;
+	dbg->de_markers[n].ma_offset = offset;
+	dbg->de_markers[n].ma_marker = marker;
+	return 0;
+    }
+
+    return -1;
+}
+
+Dwarf_Signed
+dwarf_get_die_markers(Dwarf_P_Debug dbg,
+		      Dwarf_P_Marker * marker_list, /* pointer to a pointer */
+		      Dwarf_Unsigned * marker_count,
+		      Dwarf_Error * error)
+{
+    if (marker_list == NULL || marker_count == NULL) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, DW_DLV_BADADDR);
+    }
+    if (dbg->de_marker_n_used != dbg->de_marker_n_alloc) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_MAF, DW_DLV_BADADDR);
+    }
+    
+    *marker_list = dbg->de_markers;
+    *marker_count = dbg->de_marker_n_used;
+    return DW_DLV_OK;
+}
+
+/* These functions provide the offsets of DW_FORM_string
+   attributes in the section section_index. These information
+   will enable a producer app that is generating assembly 
+   text output to easily emit those attributes in ascii form 
+   without having to decode the byte stream.
+ */
+static int
+string_attr_init (Dwarf_P_Debug dbg, 
+                  Dwarf_Signed section_index,
+                  unsigned count)
+{
+    Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index];
+    
+    sect_sa->sect_sa_n_alloc = count;
+    sect_sa->sect_sa_list = NULL;
+    if (count > 0) {
+        sect_sa->sect_sa_section_number = section_index;
+        sect_sa->sect_sa_list = _dwarf_p_get_alloc(dbg,
+                                                   sizeof(struct Dwarf_P_String_Attr_s)
+                                                   * sect_sa->sect_sa_n_alloc);
+        if (sect_sa->sect_sa_list == NULL) {
+            sect_sa->sect_sa_n_alloc = 0;
+            return -1;
+        }
+    }
+    return 0;
+}
+
+static int 
+string_attr_add (Dwarf_P_Debug dbg, 
+                 Dwarf_Signed section_index,
+                 Dwarf_Unsigned offset,
+                 Dwarf_P_Attribute attr)
+{
+    Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[section_index];
+    if (sect_sa->sect_sa_n_alloc >= (sect_sa->sect_sa_n_used + 1)) {
+        unsigned n = sect_sa->sect_sa_n_used++;
+        sect_sa->sect_sa_list[n].sa_offset = offset;
+        sect_sa->sect_sa_list[n].sa_nbytes = attr->ar_nbytes;
+        return 0;
+    }
+    
+    return -1;
+}
+
+int
+dwarf_get_string_attributes_count(Dwarf_P_Debug dbg,
+                                  Dwarf_Unsigned *
+                                  count_of_sa_sections,
+                                  int *drd_buffer_version,
+                                  Dwarf_Error *error)
+{
+    int i;
+    unsigned int count = 0;
+    
+    for (i = 0; i < NUM_DEBUG_SECTIONS; ++i) {
+        if (dbg->de_sect_string_attr[i].sect_sa_n_used > 0) {
+            ++count;
+        }
+    }
+    *count_of_sa_sections = (Dwarf_Unsigned) count;
+    *drd_buffer_version = DWARF_DRD_BUFFER_VERSION;
+
+    return DW_DLV_OK;
+}
+
+int 
+dwarf_get_string_attributes_info(Dwarf_P_Debug dbg,
+                                 Dwarf_Signed *elf_section_index,
+                                 Dwarf_Unsigned *sect_sa_buffer_count,
+                                 Dwarf_P_String_Attr *sect_sa_buffer,
+                                 Dwarf_Error *error)
+{
+    int i;
+    int next = dbg->de_sect_sa_next_to_return;
+
+    for (i = next; i < NUM_DEBUG_SECTIONS; ++i) {
+        Dwarf_P_Per_Sect_String_Attrs sect_sa = &dbg->de_sect_string_attr[i];        
+        if (sect_sa->sect_sa_n_used > 0) {
+            dbg->de_sect_sa_next_to_return = i + 1;
+            *elf_section_index = sect_sa->sect_sa_section_number;
+            *sect_sa_buffer_count = sect_sa->sect_sa_n_used;
+            *sect_sa_buffer = sect_sa->sect_sa_list;
+            return DW_DLV_OK;
+        }
+    }
+    return DW_DLV_NO_ENTRY;
+}
+
+
+
+/*---------------------------------------------------------------
+	Generate debug_info and debug_abbrev sections
+---------------------------------------------------------------*/
+static int
+_dwarf_pro_generate_debuginfo(Dwarf_P_Debug dbg, Dwarf_Error * error)
+{
+    int elfsectno_of_debug_info = 0;
+    int abbrevsectno = 0;
+    unsigned char *data = 0;
+    int cu_header_size = 0;
+    Dwarf_P_Abbrev curabbrev = 0;
+    Dwarf_P_Abbrev abbrev_head = 0;
+    Dwarf_P_Abbrev abbrev_tail = 0;
+    Dwarf_P_Die curdie = 0;
+    Dwarf_P_Die first_child = 0;
+    Dwarf_Word dw = 0;
+    Dwarf_Unsigned du = 0;
+    Dwarf_Half dh = 0;
+    Dwarf_Ubyte db = 0;
+    Dwarf_Half version = 0;	/* Need 2 byte quantity. */
+    Dwarf_Unsigned die_off = 0;	/* Offset of die in debug_info. */
+    int n_abbrevs = 0;
+    int res = 0;
+    unsigned marker_count = 0;
+    unsigned string_attr_count = 0;
+    unsigned string_attr_offset = 0;
+
+    Dwarf_Small *start_info_sec = 0;
+
+    int uwordb_size = dbg->de_offset_size;
+    int extension_size = dbg->de_64bit_extension ? 4 : 0;
+
+    abbrev_head = abbrev_tail = NULL;
+    elfsectno_of_debug_info = dbg->de_elf_sects[DEBUG_INFO];
+
+    /* write cu header */
+    cu_header_size = BEGIN_LEN_SIZE + sizeof(Dwarf_Half) +	/* version 
+								   stamp 
+								 */
+	uwordb_size +		/* offset into abbrev table */
+	sizeof(Dwarf_Ubyte);	/* size of target address */
+    GET_CHUNK(dbg, elfsectno_of_debug_info, data, cu_header_size,
+	      error);
+    start_info_sec = data;
+    if (extension_size) {
+	du = DISTINGUISHED_VALUE;
+	WRITE_UNALIGNED(dbg, (void *) data,
+			(const void *) &du, sizeof(du), extension_size);
+	data += extension_size;
+    }
+    du = 0;			/* length of debug_info, not counting
+				   this field itself (unknown at this
+				   point). */
+    WRITE_UNALIGNED(dbg, (void *) data,
+		    (const void *) &du, sizeof(du), uwordb_size);
+    data += uwordb_size;
+
+    version = CURRENT_VERSION_STAMP;	/* assume this length will not
+					   change */
+    WRITE_UNALIGNED(dbg, (void *) data, (const void *) &version,
+		    sizeof(version), sizeof(Dwarf_Half));
+    data += sizeof(Dwarf_Half);
+
+    du = 0;			/* offset into abbrev table, not yet
+				   known. */
+    WRITE_UNALIGNED(dbg, (void *) data,
+		    (const void *) &du, sizeof(du), uwordb_size);
+    data += uwordb_size;
+
+
+    db = dbg->de_pointer_size;
+
+    WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+		    sizeof(db), 1);
+
+    /* We have filled the chunk we got with GET_CHUNK. At this point we 
+       no longer dare use "data" or "start_info_sec" as a pointer any
+       longer except to refer to that first small chunk for the cu
+       header. */
+
+    curdie = dbg->de_dies;
+
+    /* create AT_macro_info if appropriate */
+    if (dbg->de_first_macinfo != NULL) {
+	if (_dwarf_pro_add_AT_macro_info(dbg, curdie, 0, error) < 0)
+	    return -1;
+    }
+
+    /* create AT_stmt_list attribute if necessary */
+    if (dwarf_need_debug_line_section(dbg) == TRUE)
+	if (_dwarf_pro_add_AT_stmt_list(dbg, curdie, error) < 0)
+	    return -1;
+
+    die_off = cu_header_size;
+
+    /* 
+       Relocation for abbrev offset in cu header store relocation
+       record in linked list */
+    res = dbg->de_reloc_name(dbg, DEBUG_INFO, BEGIN_LEN_SIZE +
+			     sizeof(Dwarf_Half),
+			     /* r_offset */
+			     dbg->de_sect_name_idx[DEBUG_ABBREV],
+			     dwarf_drt_data_reloc, uwordb_size);
+    if (res != DW_DLV_OK) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
+    }
+
+    /* pass 0: only top level dies, add at_sibling attribute to those
+       dies with children */
+    first_child = curdie->di_child;
+    while (first_child && first_child->di_right) {
+	if (first_child->di_child)
+	    dwarf_add_AT_reference(dbg,
+				   first_child,
+				   DW_AT_sibling,
+				   first_child->di_right, error);
+	first_child = first_child->di_right;
+    }
+
+    /* pass 1: create abbrev info, get die offsets, calc relocations */
+    marker_count = 0;
+    string_attr_count = 0;
+    while (curdie != NULL) {
+	int nbytes = 0;
+	Dwarf_P_Attribute curattr;
+	Dwarf_P_Attribute new_first_attr;
+	Dwarf_P_Attribute new_last_attr;
+	char *space = 0;
+	int res = 0;
+	char buff1[ENCODE_SPACE_NEEDED];
+	int i = 0;
+
+	curdie->di_offset = die_off;
+
+	if (curdie->di_marker != 0)
+	    marker_count++;
+	
+	curabbrev = _dwarf_pro_getabbrev(curdie, abbrev_head);
+	if (curabbrev == NULL) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
+	}
+	if (abbrev_head == NULL) {
+	    n_abbrevs = 1;
+	    curabbrev->abb_idx = n_abbrevs;
+	    abbrev_tail = abbrev_head = curabbrev;
+	} else {
+	    /* check if its a new abbreviation, if yes, add to tail */
+	    if (curabbrev->abb_idx == 0) {
+		n_abbrevs++;
+		curabbrev->abb_idx = n_abbrevs;
+		abbrev_tail->abb_next = curabbrev;
+		abbrev_tail = curabbrev;
+	    }
+	}
+	res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx,
+					  &nbytes,
+					  buff1, sizeof(buff1));
+	if (res != DW_DLV_OK) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
+	}
+	space = _dwarf_p_get_alloc(dbg, nbytes);
+	if (space == NULL) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
+	}
+	memcpy(space, buff1, nbytes);
+	curdie->di_abbrev = space;
+	curdie->di_abbrev_nbytes = nbytes;
+	die_off += nbytes;
+
+	/* Resorting the attributes!! */
+	new_first_attr = new_last_attr = NULL;
+	curattr = curdie->di_attrs;
+	for (i = 0; i < (int)curabbrev->abb_n_attr; i++) {
+	    Dwarf_P_Attribute ca;
+	    Dwarf_P_Attribute cl;
+
+	    /* The following should always find an attribute! */
+	    for (ca = cl = curattr;
+		 ca && curabbrev->abb_attrs[i] != ca->ar_attribute;
+		 cl = ca, ca = ca->ar_next)
+	    {
+	    }
+
+	    if (!ca) {
+		DWARF_P_DBG_ERROR(dbg,DW_DLE_ABBREV_ALLOC, -1);
+	    }
+
+	    /* Remove the attribute from the old list. */
+	    if (ca == curattr) {
+		curattr = ca->ar_next;
+	    } else {
+		cl->ar_next = ca->ar_next;
+	    }
+
+	    ca->ar_next = NULL;
+		
+	    /* Add the attribute to the new list. */
+	    if (new_first_attr == NULL) {
+		new_first_attr = new_last_attr = ca;
+	    } else {
+		new_last_attr->ar_next = ca;
+		new_last_attr = ca;
+	    }
+	}
+
+	curdie->di_attrs = new_first_attr;
+	    
+	curattr = curdie->di_attrs;
+	
+	while (curattr) {
+	    if (curattr->ar_rel_type != R_MIPS_NONE) {
+		switch (curattr->ar_attribute) {
+		case DW_AT_stmt_list:
+		    curattr->ar_rel_symidx =
+			dbg->de_sect_name_idx[DEBUG_LINE];
+		    break;
+		case DW_AT_MIPS_fde:
+		    curattr->ar_rel_symidx =
+			dbg->de_sect_name_idx[DEBUG_FRAME];
+		    break;
+		case DW_AT_macro_info:
+		    curattr->ar_rel_symidx =
+			dbg->de_sect_name_idx[DEBUG_MACINFO];
+		    break;
+		default:
+		    break;
+		}
+		res = dbg->de_reloc_name(dbg, DEBUG_INFO, die_off + curattr->ar_rel_offset,	/* r_offset 
+												 */
+					 curattr->ar_rel_symidx,
+					 dwarf_drt_data_reloc,
+					 curattr->ar_reloc_len);
+
+		if (res != DW_DLV_OK) {
+		    DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);
+		}
+
+	    }
+            if (curattr->ar_attribute_form == DW_FORM_string) {
+                string_attr_count++;
+            }
+	    die_off += curattr->ar_nbytes;
+	    curattr = curattr->ar_next;
+	}
+	
+	/* depth first search */
+	if (curdie->di_child)
+	    curdie = curdie->di_child;
+	else {
+	    while (curdie != NULL && curdie->di_right == NULL) {
+		curdie = curdie->di_parent;
+		die_off++;	/* since we are writing a null die at
+				   the end of each sibling chain */
+	    }
+	    if (curdie != NULL)
+		curdie = curdie->di_right;
+	}
+	
+    } /* end while (curdie != NULL) */
+
+    res = marker_init(dbg, marker_count);
+    if (res == -1) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);	
+    }
+    res = string_attr_init(dbg, DEBUG_INFO, string_attr_count);
+    if (res == -1) {
+       	DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);	
+    } 
+    
+    /* Pass 2: Write out the die information Here 'data' is a
+       temporary, one block for each GET_CHUNK.  'data' is overused. */
+    curdie = dbg->de_dies;
+    while (curdie != NULL) {
+	Dwarf_P_Attribute curattr;
+
+	if (curdie->di_marker != 0) {
+	    res = marker_add(dbg, curdie->di_offset, curdie->di_marker);
+	    if (res == -1) {
+		DWARF_P_DBG_ERROR(dbg, DW_DLE_REL_ALLOC, -1);	
+	    }
+	}
+
+	/* index to abbreviation table */
+	GET_CHUNK(dbg, elfsectno_of_debug_info,
+		  data, curdie->di_abbrev_nbytes, error);
+
+	memcpy((void *) data,
+	       (const void *) curdie->di_abbrev,
+	       curdie->di_abbrev_nbytes);
+
+	/* Attribute values - need to fill in all form attributes */
+	curattr = curdie->di_attrs;
+        string_attr_offset = curdie->di_offset + curdie->di_abbrev_nbytes;
+        
+	while (curattr) {
+	    GET_CHUNK(dbg, elfsectno_of_debug_info, data,
+		      (unsigned long) curattr->ar_nbytes, error);
+	    switch (curattr->ar_attribute_form) {
+	    case DW_FORM_ref1:
+		{
+		    if (curattr->ar_ref_die->di_offset >
+			(unsigned) 0xff) {
+			DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1);
+		    }
+		    db = curattr->ar_ref_die->di_offset;
+		    WRITE_UNALIGNED(dbg, (void *) data,
+				    (const void *) &db,
+				    sizeof(db), sizeof(Dwarf_Ubyte));
+		    break;
+		}
+	    case DW_FORM_ref2:
+		{
+		    if (curattr->ar_ref_die->di_offset >
+			(unsigned) 0xffff) {
+			DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1);
+		    }
+		    dh = curattr->ar_ref_die->di_offset;
+		    WRITE_UNALIGNED(dbg, (void *) data,
+				    (const void *) &dh,
+				    sizeof(dh), sizeof(Dwarf_Half));
+		    break;
+		}
+	    case DW_FORM_ref_addr:
+		{
+		    /* curattr->ar_ref_die == NULL!
+ 		     *
+		     * ref_addr doesn't take a CU-offset.
+		     * This is different than other refs.
+		     * This value will be set by the user of the
+ 		     * producer library using a relocation.
+		     * No need to set a value here.
+		     */
+#if 0		    
+		    du = curattr->ar_ref_die->di_offset;
+		    {
+			/* ref to offset of die */
+			WRITE_UNALIGNED(dbg, (void *) data,
+					(const void *) &du,
+					sizeof(du), uwordb_size);
+		    }
+#endif		
+		    break;
+
+		}
+	    case DW_FORM_ref4:
+		{
+		    if (curattr->ar_ref_die->di_offset >
+			(unsigned) 0xffffffff) {
+			DWARF_P_DBG_ERROR(dbg, DW_DLE_OFFSET_UFLW, -1);
+		    }
+		    dw = (Dwarf_Word) curattr->ar_ref_die->di_offset;
+		    WRITE_UNALIGNED(dbg, (void *) data,
+				    (const void *) &dw,
+				    sizeof(dw), sizeof(Dwarf_ufixed));
+		    break;
+		}
+	    case DW_FORM_ref8:
+		du = curattr->ar_ref_die->di_offset;
+		WRITE_UNALIGNED(dbg, (void *) data,
+				(const void *) &du,
+				sizeof(du), sizeof(Dwarf_Unsigned));
+		break;
+	    case DW_FORM_ref_udata:
+		{		/* unsigned leb128 offset */
+
+		    int nbytes;
+		    char buff1[ENCODE_SPACE_NEEDED];
+
+		    res =
+			_dwarf_pro_encode_leb128_nm(curattr->
+						    ar_ref_die->
+						    di_offset, &nbytes,
+						    buff1,
+						    sizeof(buff1));
+		    if (res != DW_DLV_OK) {
+			DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
+		    }
+
+		    memcpy(data, buff1, nbytes);
+		    break;
+		}
+	    default:
+		memcpy((void *) data,
+		       (const void *) curattr->ar_data,
+		       curattr->ar_nbytes);
+		break;
+	    }
+            if (curattr->ar_attribute_form == DW_FORM_string) {
+                string_attr_add(dbg, DEBUG_INFO, string_attr_offset, curattr);
+            }
+            string_attr_offset += curattr->ar_nbytes;
+	    curattr = curattr->ar_next;
+	}
+
+	/* depth first search */
+	if (curdie->di_child)
+	    curdie = curdie->di_child;
+	else {
+	    while (curdie != NULL && curdie->di_right == NULL) {
+		GET_CHUNK(dbg, elfsectno_of_debug_info, data, 1, error);
+		*data = '\0';
+		curdie = curdie->di_parent;
+	    }
+	    if (curdie != NULL)
+		curdie = curdie->di_right;
+	}
+    } /* end while (curdir != NULL) */
+
+    /* Write out debug_info size */
+    /* Dont include length field or extension bytes */
+    du = die_off - BEGIN_LEN_SIZE;
+    WRITE_UNALIGNED(dbg, (void *) (start_info_sec + extension_size),
+		    (const void *) &du, sizeof(du), uwordb_size);
+
+
+    data = 0;			/* Emphasise not usable now */
+
+    /* Write out debug_abbrev section */
+    abbrevsectno = dbg->de_elf_sects[DEBUG_ABBREV];
+
+    curabbrev = abbrev_head;
+    while (curabbrev) {
+	char *val;
+	int nbytes;
+	int idx;
+	int res;
+	char buff1[ENCODE_SPACE_NEEDED];
+
+	res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_idx, &nbytes,
+					  buff1, sizeof(buff1));
+	if (res != DW_DLV_OK) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
+	}
+
+	GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
+	val = buff1;
+	memcpy((void *) data, (const void *) val, nbytes);
+	res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_tag, &nbytes,
+					  buff1, sizeof(buff1));
+	if (res != DW_DLV_OK) {
+	    DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
+	}
+	val = buff1;
+	GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
+	memcpy((void *) data, (const void *) val, nbytes);
+	db = curabbrev->abb_children;
+	GET_CHUNK(dbg, abbrevsectno, data, sizeof(Dwarf_Ubyte), error);
+	WRITE_UNALIGNED(dbg, (void *) data, (const void *) &db,
+			sizeof(db), sizeof(Dwarf_Ubyte));
+
+	/* add attributes and forms */
+	for (idx = 0; idx < curabbrev->abb_n_attr; idx++) {
+	    res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_attrs[idx],
+					      &nbytes,
+					      buff1, sizeof(buff1));
+	    if (res != DW_DLV_OK) {
+		DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
+	    }
+	    val = buff1;
+	    GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
+	    memcpy((void *) data, (const void *) val, nbytes);
+	    res = _dwarf_pro_encode_leb128_nm(curabbrev->abb_forms[idx],
+					      &nbytes,
+					      buff1, sizeof(buff1));
+	    if (res != DW_DLV_OK) {
+		DWARF_P_DBG_ERROR(dbg, DW_DLE_ABBREV_ALLOC, -1);
+	    }
+	    val = buff1;
+	    GET_CHUNK(dbg, abbrevsectno, data, nbytes, error);
+	    memcpy((void *) data, (const void *) val, nbytes);
+	}
+	GET_CHUNK(dbg, abbrevsectno, data, 2, error);	/* two zeros,
+							   for last
+							   entry, see
+							   dwarf2 sec
+							   7.5.3 */
+	*data = 0;
+	data++;
+	*data = 0;
+
+	curabbrev = curabbrev->abb_next;
+    }
+
+    GET_CHUNK(dbg, abbrevsectno, data, 1, error);	/* one zero,
+							   for end of
+							   cu, see
+							   dwarf2 sec
+							   7.5.3 */
+    *data = 0;
+
+
+    return (int) dbg->de_n_debug_sect;
+}
+
+
+/*---------------------------------------------------------------------
+	Get a buffer of section data. 
+	section_idx is the elf-section number that this data applies to. 
+	length shows length of returned data 
+----------------------------------------------------------------------*/
+ /*ARGSUSED*/			/* pretend all args used */
+    Dwarf_Ptr
+dwarf_get_section_bytes(Dwarf_P_Debug dbg,
+			Dwarf_Signed dwarf_section,
+			Dwarf_Signed * section_idx,
+			Dwarf_Unsigned * length, Dwarf_Error * error)
+{
+    Dwarf_Ptr buf;
+
+    if (dbg->de_version_magic_number != PRO_VERSION_MAGIC) {
+	DWARF_P_DBG_ERROR(dbg, DW_DLE_IA, NULL);
+    }
+
+    if (dbg->de_debug_sects == 0) {
+	/* no more data !! */
+	return NULL;
+    }
+    if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) {
+	/* no data ever entered !! */
+	return NULL;
+    }
+    *section_idx = dbg->de_debug_sects->ds_elf_sect_no;
+    *length = dbg->de_debug_sects->ds_nbytes;
+
+    buf = (Dwarf_Ptr *) dbg->de_debug_sects->ds_data;
+
+    dbg->de_debug_sects = dbg->de_debug_sects->ds_next;
+
+    /* We may want to call the section stuff more than once: see
+       dwarf_reset_section_bytes() do not do: dbg->de_n_debug_sect--; */
+
+    return buf;
+}
+
+/*
+	No errors possible.
+*/
+void
+dwarf_reset_section_bytes(Dwarf_P_Debug dbg)
+{
+    dbg->de_debug_sects = dbg->de_first_debug_sect;
+    /* No need to reset; commented out decrement. dbg->de_n_debug_sect
+       = ???; */
+    dbg->de_reloc_next_to_return = 0;
+    dbg->de_sect_sa_next_to_return = 0;
+}
+
+/*
+    Storage handler. Gets either a new chunk of memory, or
+    a pointer in existing memory, from the linked list attached
+    to dbg at de_debug_sects, depending on size of nbytes
+
+    Assume dbg not null, checked in top level routine 
+
+    Returns a pointer to the allocated buffer space for the
+    lib to fill in,  predincrements next-to-use count so the
+    space requested is already counted 'used' 
+    when this returns (ie, reserved).
+
+*/
+Dwarf_Small *
+_dwarf_pro_buffer(Dwarf_P_Debug dbg,
+		  int elfsectno, unsigned long nbytes)
+{
+    Dwarf_P_Section_Data cursect;
+
+
+    cursect = dbg->de_current_active_section;
+    /* By using MAGIC_SECT_NO we allow the following MAGIC_SECT_NO must 
+       not match any legit section number. test to have just two
+       clauses (no NULL pointer test) See dwarf_producer_init(). */
+    if ((cursect->ds_elf_sect_no != elfsectno) ||
+	((cursect->ds_nbytes + nbytes) > cursect->ds_orig_alloc)
+	) {
+
+	/* Either the elf section has changed or there is not enough
+	   space in the current section.
+
+	   Create a new Dwarf_P_Section_Data_s for the chunk. and have
+	   space 'on the end' for the buffer itself so we just do one
+	   malloc (not two).
+
+	 */
+	unsigned long space = nbytes;
+
+	if (nbytes < CHUNK_SIZE)
+	    space = CHUNK_SIZE;
+
+	cursect = (Dwarf_P_Section_Data)
+	    _dwarf_p_get_alloc(dbg,
+			       sizeof(struct Dwarf_P_Section_Data_s)
+			       + space);
+
+
+	if (cursect == NULL)
+	    return (NULL);
+
+	/* _dwarf_p_get_alloc zeroes the space... */
+
+	cursect->ds_data = (char *) cursect +
+	    sizeof(struct Dwarf_P_Section_Data_s);
+	cursect->ds_orig_alloc = space;
+	cursect->ds_elf_sect_no = elfsectno;
+	cursect->ds_nbytes = nbytes;	/* reserve this number of bytes 
+					   of space for caller to fill
+					   in */
+
+	/* Now link on the end of the list, and mark this one as the
+	   current one */
+
+	if (dbg->de_debug_sects->ds_elf_sect_no == MAGIC_SECT_NO) {
+	    /* the only entry is the special one for 'no entry' so
+	       delete that phony one while adding this initial real
+	       one. */
+	    dbg->de_debug_sects = cursect;
+	    dbg->de_current_active_section = cursect;
+	    dbg->de_first_debug_sect = cursect;
+	} else {
+	    dbg->de_current_active_section->ds_next = cursect;
+	    dbg->de_current_active_section = cursect;
+	}
+	dbg->de_n_debug_sect++;
+
+	return ((Dwarf_Small *) cursect->ds_data);
+    }
+
+    /* There is enough space in the current buffer */
+    {
+	Dwarf_Small *space_for_caller = (Dwarf_Small *)
+	    (cursect->ds_data + cursect->ds_nbytes);
+
+	cursect->ds_nbytes += nbytes;
+	return space_for_caller;
+    }
+}
+
+
+/*------------------------------------------------------------
+	Given address advance and line advance, it gives 
+	either special opcode, or a number < 0
+------------------------------------------------------------*/
+static int
+_dwarf_pro_get_opc(Dwarf_Unsigned addr_adv, int line_adv)
+{
+    int opc;
+
+    addr_adv = addr_adv / MIN_INST_LENGTH;
+    if (line_adv == 0 && addr_adv == 0)
+	return OPC_INCS_ZERO;
+    if (line_adv >= LINE_BASE && line_adv < LINE_BASE + LINE_RANGE) {
+	opc =
+	    (line_adv - LINE_BASE) + (addr_adv * LINE_RANGE) +
+	    OPCODE_BASE;
+	if (opc > 255)
+	    return OPC_OUT_OF_RANGE;
+	return opc;
+    } else
+	return LINE_OUT_OF_RANGE;
+}
+
+/*-----------------------------------------------------------------------
+	Handles abbreviations. It takes a die, searches through 
+	current list of abbreviations for matching one. If it
+	finds one, it returns a pointer to it, and if it doesnt, 
+	it returns a new one. Upto the user of this function to 
+	link it up to the abbreviation head. If its a new one,
+	abb_idx has 0.
+-----------------------------------------------------------------------*/
+static Dwarf_P_Abbrev
+_dwarf_pro_getabbrev(Dwarf_P_Die die, Dwarf_P_Abbrev head)
+{
+    Dwarf_P_Abbrev curabbrev;
+    Dwarf_P_Attribute curattr;
+    int res1;
+    int nattrs;
+    int match;
+    Dwarf_ufixed *forms = 0;
+    Dwarf_ufixed *attrs = 0;
+
+    curabbrev = head;
+    while (curabbrev) {
+	if ((die->di_tag == curabbrev->abb_tag) &&
+	    ((die->di_child != NULL &&
+	      curabbrev->abb_children == DW_CHILDREN_yes) ||
+	     (die->di_child == NULL &&
+	      curabbrev->abb_children == DW_CHILDREN_no)) &&
+	    (die->di_n_attr == curabbrev->abb_n_attr)) {
+
+	    /* There is a chance of a match. */
+	    curattr = die->di_attrs;
+	    match = 1;		/* Assume match found. */
+	    while (match && curattr) {
+		res1 = _dwarf_pro_match_attr(curattr,
+					     curabbrev,
+					     (int) curabbrev->
+					     abb_n_attr);
+		if (res1 == 0)
+		    match = 0;
+		curattr = curattr->ar_next;
+	    }
+	    if (match == 1)
+		return curabbrev;
+	}
+	curabbrev = curabbrev->abb_next;
+    }
+
+    /* no match, create new abbreviation */
+    if (die->di_n_attr != 0) {
+	forms = (Dwarf_ufixed *)
+	    _dwarf_p_get_alloc(die->di_dbg,
+			       sizeof(Dwarf_ufixed) * die->di_n_attr);
+	if (forms == NULL)
+	    return NULL;
+	attrs = (Dwarf_ufixed *)
+	    _dwarf_p_get_alloc(die->di_dbg,
+			       sizeof(Dwarf_ufixed) * die->di_n_attr);
+	if (attrs == NULL)
+	    return NULL;
+    }
+    nattrs = 0;
+    curattr = die->di_attrs;
+    while (curattr) {
+	attrs[nattrs] = curattr->ar_attribute;
+	forms[nattrs] = curattr->ar_attribute_form;
+	nattrs++;
+	curattr = curattr->ar_next;
+    }
+
+    curabbrev = (Dwarf_P_Abbrev)
+	_dwarf_p_get_alloc(die->di_dbg, sizeof(struct Dwarf_P_Abbrev_s));
+    if (curabbrev == NULL)
+	return NULL;
+
+    if (die->di_child == NULL)
+	curabbrev->abb_children = DW_CHILDREN_no;
+    else
+	curabbrev->abb_children = DW_CHILDREN_yes;
+    curabbrev->abb_tag = die->di_tag;
+    curabbrev->abb_attrs = attrs;
+    curabbrev->abb_forms = forms;
+    curabbrev->abb_n_attr = die->di_n_attr;
+    curabbrev->abb_idx = 0;
+    curabbrev->abb_next = NULL;
+
+    return curabbrev;
+}
+
+/*------------------------------------------------------------------
+	Tries to see if given attribute and form combination 
+	exists in the given abbreviation
+-------------------------------------------------------------------*/
+static int
+_dwarf_pro_match_attr(Dwarf_P_Attribute attr,
+		      Dwarf_P_Abbrev abbrev, int no_attr)
+{
+    int i;
+    int found = 0;
+
+    for (i = 0; i < no_attr; i++) {
+	if (attr->ar_attribute == abbrev->abb_attrs[i] &&
+	    attr->ar_attribute_form == abbrev->abb_forms[i]) {
+	    found = 1;
+	    break;
+	}
+    }
+    return found;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_section.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,112 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+
+
+/* relocation section names */
+extern char *_dwarf_rel_section_names[];
+
+/* section names */
+extern char *_dwarf_sectnames[];
+
+/* struct to hold relocation entries. Its mantained as a linked
+   list of relocation structs, and will then be written at as a 
+   whole into the relocation section. Whether its 32 bit or
+   64 bit will be obtained from Dwarf_Debug pointer.
+*/
+
+
+
+
+
+/*
+	struct stores a chunk of data pertaining to a section 
+*/
+struct Dwarf_P_Section_Data_s {
+    int ds_elf_sect_no;		/* elf section number */
+    char *ds_data;		/* data contained in section */
+    unsigned long ds_nbytes;	/* bytes of data used so far */
+    unsigned long ds_orig_alloc;	/* bytes allocated originally */
+    Dwarf_P_Section_Data ds_next;	/* next on the list */
+};
+
+/* Used to allow a dummy initial struct (which we
+   drop before it gets used
+   This must not match any legitimate 'section' number.
+*/
+#define MAGIC_SECT_NO -3
+
+/* Size of chunk of data allocated in one alloc 
+   Not clear if this is the best size.
+   Used to be just 4096 for user data, the section data struct
+   was a separate malloc.
+*/
+#define 	CHUNK_SIZE (4096 - sizeof (struct Dwarf_P_Section_Data_s))
+
+/*
+	chunk alloc routine - 
+	if chunk->ds_data is nil, it will alloc CHUNK_SIZE bytes, 
+	and return pointer to the beginning. If chunk is not nil, 
+	it will see if there's enoungh space for nbytes in current 
+	chunk, if not, add new chunk to linked list, and return 
+	a char * pointer to it. Return null if unsuccessful.
+*/
+Dwarf_Small *_dwarf_pro_buffer(Dwarf_P_Debug dbg, int sectno,
+			       unsigned long nbytes);
+
+#define GET_CHUNK(dbg,sectno,ptr,nbytes,error) \
+	{ \
+	    (ptr) = _dwarf_pro_buffer((dbg),(sectno),(nbytes)); \
+	    if ((ptr) == NULL) { \
+		DWARF_P_DBG_ERROR(dbg,DW_DLE_CHUNK_ALLOC,-1); \
+	    } \
+	}
+
+
+
+int
+  _dwarf_transform_arange_to_disk(Dwarf_P_Debug dbg,
+				  Dwarf_Error * error);
+
+/* These are for creating ELF section type codes.
+*/
+#if defined(linux) || defined(__BEOS__) || !defined(SHT_MIPS_DWARF)
+/* Intel's SoftSdv accepts only this */
+#define SECTION_TYPE            SHT_PROGBITS
+#else
+#define SECTION_TYPE            SHT_MIPS_DWARF
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_types.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,296 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_ELFACCESS_H
+#include <elfaccess.h>
+#endif
+#include "pro_incl.h"
+#include "pro_section.h"
+
+
+/*
+    This function adds another type name to the 
+    list of type names for the given Dwarf_P_Debug.  
+    It returns 0 on error, and 1 otherwise.
+*/
+Dwarf_Unsigned
+dwarf_add_typename(Dwarf_P_Debug dbg,
+		   Dwarf_P_Die die,
+		   char *type_name, Dwarf_Error * error)
+{
+    return
+	_dwarf_add_simple_name_entry(dbg, die, type_name,
+				     dwarf_snk_typename, error);
+}
+
+/*
+  The following is the generic 'add a simple name entry'
+  for any of the simple name sections. 
+
+  See enum dwarf_sn_kind in pro_opaque.h
+ 
+*/
+Dwarf_Unsigned
+_dwarf_add_simple_name_entry(Dwarf_P_Debug dbg,
+			     Dwarf_P_Die die,
+			     char *entry_name,
+			     enum dwarf_sn_kind entrykind,
+			     Dwarf_Error * error)
+{
+    Dwarf_P_Simple_nameentry nameentry;
+    Dwarf_P_Simple_name_header hdr;
+    char *name;
+    int uword_size;
+
+    if (dbg == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DBG_NULL);
+	return (0);
+    }
+
+    if (die == NULL) {
+	_dwarf_p_error(NULL, error, DW_DLE_DIE_NULL);
+	return (0);
+    }
+
+
+    nameentry = (Dwarf_P_Simple_nameentry)
+	_dwarf_p_get_alloc(dbg,
+			   sizeof(struct Dwarf_P_Simple_nameentry_s));
+    if (nameentry == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (0);
+    }
+
+    name = _dwarf_p_get_alloc(dbg, strlen(entry_name) + 1);
+    if (name == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (0);
+    }
+    strcpy(name, entry_name);
+
+    nameentry->sne_die = die;
+    nameentry->sne_name = name;
+    nameentry->sne_name_len = strlen(name);
+    uword_size = dbg->de_offset_size;
+
+    hdr = &dbg->de_simple_name_headers[entrykind];
+    if (hdr->sn_head == NULL)
+	hdr->sn_head = hdr->sn_tail = nameentry;
+    else {
+	hdr->sn_tail->sne_next = nameentry;
+	hdr->sn_tail = nameentry;
+    }
+    hdr->sn_count++;
+    hdr->sn_net_len += uword_size + nameentry->sne_name_len + 1;
+
+    return (1);
+}
+
+
+
+/*
+     _dwarf_transform_simplename_to_disk writes 
+     ".rel.debug_pubnames",
+     ".rel.debug_funcnames",       sgi extension
+     ".rel.debug_typenames",       sgi extension
+     ".rel.debug_varnames",        sgi extension
+     ".rel.debug_weaknames",       sgi extension 
+     to disk.
+	section_index indexes one of those sections.
+	entrykind is one of those 'kind's.
+
+*/
+int
+_dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, enum dwarf_sn_kind entrykind, int section_index,	/* in 
+													   de_elf_sects 
+													   etc 
+													 */
+				    Dwarf_Error * error)
+{
+
+
+    /* Used to fill in 0. */
+    const Dwarf_Signed big_zero = 0;
+
+    /* Used to scan the section data buffers. */
+    Dwarf_P_Section_Data debug_sect;
+
+    Dwarf_Signed debug_info_size;
+
+    Dwarf_P_Simple_nameentry nameentry_original;
+    Dwarf_P_Simple_nameentry nameentry;
+    Dwarf_Small *stream_bytes;
+    Dwarf_Small *cur_stream_bytes_ptr;
+    Dwarf_Unsigned stream_bytes_count;
+    Dwarf_Unsigned adjusted_length;	/* count excluding length field 
+					 */
+
+
+    int uword_size = dbg->de_offset_size;
+    int extension_size = dbg->de_64bit_extension ? 4 : 0;
+
+    Dwarf_P_Simple_name_header hdr;
+
+
+    /* ***** BEGIN CODE ***** */
+
+    debug_info_size = 0;
+    for (debug_sect = dbg->de_debug_sects; debug_sect != NULL;
+	 debug_sect = debug_sect->ds_next) {
+	/* We want the size of the .debug_info section for this CU
+	   because the dwarf spec requires us to output it below so we
+	   look for it specifically. */
+	if (debug_sect->ds_elf_sect_no == dbg->de_elf_sects[DEBUG_INFO]) {
+	    debug_info_size += debug_sect->ds_nbytes;
+	}
+    }
+
+    hdr = &dbg->de_simple_name_headers[entrykind];
+    /* Size of the .debug_typenames (or similar) section header. */
+    stream_bytes_count = extension_size + uword_size +	/* Size of
+							   length
+							   field. */
+	sizeof(Dwarf_Half) +	/* Size of version field. */
+	uword_size +		/* Size of .debug_info offset. */
+	uword_size;		/* Size of .debug_names. */
+
+
+
+    nameentry_original = hdr->sn_head;
+    nameentry = nameentry_original;
+    /* add in the content size */
+    stream_bytes_count += hdr->sn_net_len;
+
+    /* Size of the last 0 offset. */
+    stream_bytes_count += uword_size;
+
+    /* Now we know how long the entire section is */
+    GET_CHUNK(dbg, dbg->de_elf_sects[section_index],
+	      stream_bytes, (unsigned long) stream_bytes_count, error);
+    if (stream_bytes == NULL) {
+	_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+	return (0);
+    }
+    cur_stream_bytes_ptr = stream_bytes;
+
+    if (extension_size) {
+	Dwarf_Unsigned x = DISTINGUISHED_VALUE;
+
+	WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
+			(const void *) &x, sizeof(x), extension_size);
+	cur_stream_bytes_ptr += extension_size;
+
+    }
+    /* Write the adjusted length of .debug_*names section. */
+    adjusted_length = stream_bytes_count - uword_size - extension_size;
+    WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
+		    (const void *) &adjusted_length,
+		    sizeof(adjusted_length), uword_size);
+    cur_stream_bytes_ptr += uword_size;
+
+    /* Write the version as 2 bytes. */
+    {
+	Dwarf_Half verstamp = CURRENT_VERSION_STAMP;
+
+	WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
+			(const void *) &verstamp,
+			sizeof(verstamp), sizeof(Dwarf_Half));
+	cur_stream_bytes_ptr += sizeof(Dwarf_Half);
+    }
+
+    /* Write the offset of the compile-unit. */
+    WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
+		    (const void *) &big_zero,
+		    sizeof(big_zero), uword_size);
+    cur_stream_bytes_ptr += uword_size;
+
+    /* now create the relocation for the compile_unit offset */
+    {
+	int res = dbg->de_reloc_name(dbg,
+				     section_index,
+				     extension_size + uword_size +
+				     sizeof(Dwarf_Half)
+				     /* r_offset */
+				     ,
+				     /* debug_info section name symbol */
+				     dbg->de_sect_name_idx[DEBUG_INFO],
+				     dwarf_drt_data_reloc,
+				     uword_size);
+
+	if (res != DW_DLV_OK) {
+	    {
+		_dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL);
+		return (0);
+	    }
+	}
+    }
+
+    /* Write the size of .debug_info section. */
+    WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
+		    (const void *) &debug_info_size,
+		    sizeof(debug_info_size), uword_size);
+    cur_stream_bytes_ptr += uword_size;
+
+
+    for (nameentry = nameentry_original;
+	 nameentry != NULL; nameentry = nameentry->sne_next) {
+
+	/* Copy offset of die from start of compile-unit. */
+	WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
+			(const void *) &nameentry->sne_die->di_offset,
+			sizeof(nameentry->sne_die->di_offset),
+			uword_size);
+	cur_stream_bytes_ptr += uword_size;
+
+	/* Copy the type name. */
+	strcpy((char *) cur_stream_bytes_ptr, nameentry->sne_name);
+	cur_stream_bytes_ptr += nameentry->sne_name_len + 1;
+    }
+
+    WRITE_UNALIGNED(dbg, cur_stream_bytes_ptr,
+		    (const void *) &big_zero,
+		    sizeof(big_zero), uword_size);
+
+
+
+
+    return (int) dbg->de_n_debug_sect;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_types.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,44 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+/* pro_types.h */
+
+
+int _dwarf_transform_simplename_to_disk(Dwarf_P_Debug dbg, enum dwarf_sn_kind entrykind, int section_index,	/* in 
+														   de_elf_sects 
+														   etc 
+														 */
+					Dwarf_Error * error);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_util.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,148 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+  Portions Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public
+  License along with this program; if not, write the Free Software
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+
+#define IS_64BIT(dbg) 	((dbg)->de_flags & DW_DLC_SIZE_64 ? 1 : 0)
+#define ISA_IA64(dbg) 	((dbg)->de_flags & DW_DLC_ISA_IA64 ? 1 : 0)
+
+/* definition of sizes of types, given target machine */
+#define sizeof_sbyte(dbg) 	sizeof(Dwarf_Sbyte)
+#define sizeof_ubyte(dbg)	sizeof(Dwarf_Ubyte)
+#define sizeof_uhalf(dbg)	sizeof(Dwarf_Half)
+/* certain sizes not defined here, but set in dbg record.
+   See pro_init.c
+*/
+
+/* Computes amount of padding necessary to align n to a k-boundary. */
+/* Important: Assumes n, k both GREATER than zero. */
+#define PADDING(n, k) ( (k)-1 - ((n)-1)%(k) )
+
+/* The following defines are only important for users of the
+** producer part of libdwarf, and such should have these
+** defined correctly (as necessary) 
+** by the #include <elf.h> done in pro_incl.h
+** before the #include "pro_util.h".
+** For others producer macros do not matter so 0 is a usable value, and
+** zero values let compilation succeed on more non-MIPS architectures.
+** A better approach would be welcome.
+*/
+/* R_MIPS* are #define so #ifndef works */
+/* R_IA_64* are not necessarily #define (might be enum) so #ifndef
+   is useless, we use the configure script generating 
+   HAVE_R_IA_64_DIR32LSB and HAVE_R_IA64_DIR32LSB.
+*/
+#ifndef R_MIPS_64
+#define R_MIPS_64 0
+#endif
+#ifndef R_MIPS_32
+#define R_MIPS_32 0
+#endif
+#ifndef R_MIPS_SCN_DISP
+#define R_MIPS_SCN_DISP 0
+#endif
+
+/* R_IA_64_DIR32LSB came before the now-standard R_IA64_DIR32LSB
+   (etc) was defined.  This now deals with either form,
+   preferring the new form if available.  */
+#ifdef HAVE_R_IA64_DIR32LSB
+#define DWARF_PRO_R_IA64_DIR32LSB R_IA64_DIR32LSB
+#define DWARF_PRO_R_IA64_DIR64LSB R_IA64_DIR64LSB
+#define DWARF_PRO_R_IA64_SEGREL64LSB R_IA64_SEGREL64LSB
+#define DWARF_PRO_R_IA64_SEGREL32LSB R_IA64_SEGREL32LSB
+#endif
+#if defined(HAVE_R_IA_64_DIR32LSB) && !defined(HAVE_R_IA64_DIR32LSB)
+#define DWARF_PRO_R_IA64_DIR32LSB R_IA_64_DIR32LSB
+#define DWARF_PRO_R_IA64_DIR64LSB R_IA_64_DIR64LSB
+#define DWARF_PRO_R_IA64_SEGREL64LSB R_IA_64_SEGREL64LSB
+#define DWARF_PRO_R_IA64_SEGREL32LSB R_IA_64_SEGREL32LSB
+#endif
+#if !defined(HAVE_R_IA_64_DIR32LSB) && !defined(HAVE_R_IA64_DIR32LSB)
+#define DWARF_PRO_R_IA64_DIR32LSB 0
+#define DWARF_PRO_R_IA64_DIR64LSB 0
+#define DWARF_PRO_R_IA64_SEGREL64LSB 0
+#define DWARF_PRO_R_IA64_SEGREL32LSB 0
+#endif
+
+/*
+ * The default "I don't know" value can't be zero.
+ * Because that's the sentinel value that means "no relocation".
+ * In order to use this library in 'symbolic relocation mode we
+ * don't care if this value is the right relocation value,
+ * only that it's non-NULL.  So at the end, we define it
+ * to something sensible.
+ */
+
+
+
+#if defined(sun)
+#if defined(sparc)
+#define Get_REL64_isa(dbg)         (R_SPARC_UA64)
+#define Get_REL32_isa(dbg)         (R_SPARC_UA32)
+#define Get_REL_SEGREL_isa(dbg)    (R_SPARC_NONE) /* I don't know! */
+#else  /* i386 */
+#define Get_REL64_isa(dbg)         (R_386_32)	/* Any non-zero value is ok */
+#define Get_REL32_isa(dbg)         (R_386_32)
+#define Get_REL_SEGREL_isa(dbg)    (R_386_NONE) /* I don't know! */
+#endif /* sparc || i386 */
+#else  /* !sun */
+#ifdef HAVE_SYS_IA64_ELF_H
+#define Get_REL64_isa(dbg)         (ISA_IA64(dbg) ? \
+				DWARF_PRO_R_IA64_DIR64LSB : R_MIPS_64)
+#define Get_REL32_isa(dbg)         (ISA_IA64(dbg) ? \
+				DWARF_PRO_R_IA64_DIR32LSB : R_MIPS_32)
+
+
+/* ia64 uses 32bit dwarf offsets for sections */
+#define Get_REL_SEGREL_isa(dbg)    (ISA_IA64(dbg) ? \
+				DWARF_PRO_R_IA64_SEGREL32LSB : R_MIPS_SCN_DISP)
+#else /* HAVE_SYS_IA64_ELF_H */
+
+#if !defined(linux) && !defined(__BEOS__)
+#define Get_REL64_isa(dbg)         (R_MIPS_64)
+#define Get_REL32_isa(dbg)         (R_MIPS_32)
+#define Get_REL_SEGREL_isa(dbg)    (R_MIPS_SCN_DISP)
+#else
+#define Get_REL64_isa(dbg)	(1)
+#define Get_REL32_isa(dbg)	(1)   /* these are used on linux */
+#define Get_REL_SEGREL_isa(dbg)	(1)   /* non zero values, see comments above */
+#endif
+
+#endif /* HAVE_SYS_IA64_ELF_H */
+#endif /* !sun */
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_vars.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,62 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_ELFACCESS_H
+#include <elfaccess.h>
+#endif
+#include "pro_incl.h"
+#include "pro_section.h"
+
+/*
+    This function adds another variable name to the 
+    list of variable names for the given Dwarf_P_Debug.  
+    It returns 0 on error, and 1 otherwise.
+*/
+Dwarf_Unsigned
+dwarf_add_varname(Dwarf_P_Debug dbg,
+		  Dwarf_P_Die die, char *var_name, Dwarf_Error * error)
+{
+    return
+	_dwarf_add_simple_name_entry(dbg, die, var_name,
+				     dwarf_snk_varname, error);
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_weaks.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,61 @@
+/*
+
+  Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
+
+  This program is free software; you can redistribute it and/or modify it
+  under the terms of version 2.1 of the GNU Lesser General Public License 
+  as published by the Free Software Foundation.
+
+  This program is distributed in the hope that it would be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+  Further, this software is distributed without any warranty that it is
+  free of the rightful claim of any third person regarding infringement 
+  or the like.  Any license provided herein, whether implied or 
+  otherwise, applies only to this software file.  Patent licenses, if
+  any, provided herein do not apply to combinations of this program with 
+  other software, or any other product whatsoever.  
+
+  You should have received a copy of the GNU Lesser General Public 
+  License along with this program; if not, write the Free Software 
+  Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
+  USA.
+
+  Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
+  Mountain View, CA 94043, or:
+
+  http://www.sgi.com
+
+  For further information regarding this notice, see:
+
+  http://oss.sgi.com/projects/GenInfo/NoticeExplan
+
+*/
+
+
+
+#include "config.h"
+#include "libdwarfdefs.h"
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_ELFACCESS_H
+#include <elfaccess.h>
+#endif
+#include "pro_incl.h"
+#include "pro_section.h"
+
+/*
+    This function adds another weak name to the 
+    list of weak names for the given Dwarf_P_Debug.  
+    It returns 0 on error, and 1 otherwise.
+*/
+Dwarf_Unsigned
+dwarf_add_weakname(Dwarf_P_Debug dbg,
+		   Dwarf_P_Die die,
+		   char *weak_name, Dwarf_Error * error)
+{
+    return
+	_dwarf_add_simple_name_entry(dbg, die, weak_name,
+				     dwarf_snk_weakname, error);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/COPYING.LIB	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,481 @@
+		  GNU LIBRARY GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1991 Free Software Foundation, Inc.
+    		    59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL.  It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Library General Public License, applies to some
+specially designated Free Software Foundation software, and to any
+other libraries whose authors decide to use it.  You can use it for
+your libraries, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if
+you distribute copies of the library, or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link a program with the library, you must provide
+complete object files to the recipients so that they can relink them
+with the library, after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  Our method of protecting your rights has two steps: (1) copyright
+the library, and (2) offer you this license which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  Also, for each distributor's protection, we want to make certain
+that everyone understands that there is no warranty for this free
+library.  If the library is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original
+version, so that any problems introduced by others will not reflect on
+the original authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that companies distributing free
+software will individually obtain patent licenses, thus in effect
+transforming the program into proprietary software.  To prevent this,
+we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+  Most GNU software, including some libraries, is covered by the ordinary
+GNU General Public License, which was designed for utility programs.  This
+license, the GNU Library General Public License, applies to certain
+designated libraries.  This license is quite different from the ordinary
+one; be sure to read it in full, and don't assume that anything in it is
+the same as in the ordinary license.
+
+  The reason we have a separate public license for some libraries is that
+they blur the distinction we usually make between modifying or adding to a
+program and simply using it.  Linking a program with a library, without
+changing the library, is in some sense simply using the library, and is
+analogous to running a utility program or application program.  However, in
+a textual and legal sense, the linked executable is a combined work, a
+derivative of the original library, and the ordinary General Public License
+treats it as such.
+
+  Because of this blurred distinction, using the ordinary General
+Public License for libraries did not effectively promote software
+sharing, because most developers did not use the libraries.  We
+concluded that weaker conditions might promote sharing better.
+
+  However, unrestricted linking of non-free programs would deprive the
+users of those programs of all benefit from the free status of the
+libraries themselves.  This Library General Public License is intended to
+permit developers of non-free programs to use free libraries, while
+preserving your freedom as a user of such programs to change the free
+libraries that are incorporated in them.  (We have not seen how to achieve
+this as regards changes in header files, but we have achieved it as regards
+changes in the actual functions of the Library.)  The hope is that this
+will lead to faster development of free libraries.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, while the latter only
+works together with the library.
+
+  Note that it is possible for a library to be covered by the ordinary
+General Public License rather than by this special one.
+
+		  GNU LIBRARY GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library which
+contains a notice placed by the copyright holder or other authorized
+party saying it may be distributed under the terms of this Library
+General Public License (also called "this License").  Each licensee is
+addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+  
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also compile or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    c) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    d) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the source code distributed need not include anything that is normally
+distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Library General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+			    NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms of the
+ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.  It is
+safest to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least the
+"copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library 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
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the library, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/ChangeLog	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1392 @@
+Fri Sep  7 14:04:20 CEST 2007, Michael Riepe <libelf@mr511.de>
+
+	* acconfig.h:
+		add ENABLE_SANITY_CHECKS.
+
+	* aclocal.m4:
+		fix --enable-gnu-names.
+
+	* configure.in:
+		add --enable-sanity-checks.
+		fix --enable-extended-format.
+
+	* lib/data.c:
+		add _elf_sanity_checks variable.
+
+	* lib/private.h:
+		declare _elf_sanity_checks and constants.
+
+	* lib/strptr.c:
+		enable/disable sanity check.
+
+	* lib/version.c:
+		set _elf_sanity_checks from $LIBELF_SANITY_CHECKS.
+
+Fri Jun 29 23:27:15 CEST 2007, Michael Riepe <libelf@mr511.de>
+
+	* lib/Makefile.in:
+		improved make -jX patch.
+
+Wed Jun 20 08:04:30 CEST 2007, Michael Riepe <libelf@mr511.de>
+
+	* lib/Makefile.in:
+		add "make -jX install" patch by Joel Martin.
+
+Tue Nov 21 21:21:12 CET 2006, Michael Riepe <libelf@mr511.de>
+
+	* lib/Makefile.w32:
+		fix Windows compilation bug.
+
+Thu Sep  7 17:55:42 CEST 2006, Michael Riepe <libelf@mr511.de>
+
+	* acconfig.h:
+	* aclocal.m4:
+	* configure.in:
+	* lib/config.h.w32:
+	* lib/gelf.h:
+	* lib/private.h:
+	* lib/sys_elf.h.in:
+	* lib/sys_elf.h.w32:
+		port to QNX Neutrino, thanks to darkelf.
+
+Fri Aug 25 14:46:34 CEST 2006, Michael Riepe <libelf@mr511.de>
+
+	* Makefile.in:
+		add trackinstall target.
+
+Mon Aug 21 20:26:47 CEST 2006, Michael Riepe <libelf@mr511.de>
+
+	* Makefile.in:
+		drop w32 from DISTSUBDIRS.
+	* lib/Makefile.in:
+		add new files to DISTFILES.
+	* lib/Makefile.w32:
+	* lib/build.bat:
+	* lib/config.h.w32:
+	* lib/libelf.def:
+	* lib/sys_elf.h.w32:
+		adopted from w32 subdirectory.
+
+Fri Aug 18 02:04:58 CEST 2006, Michael Riepe <libelf@mr511.de>
+
+	* lib/begin.c:
+		let getnum return a size_t.
+	* lib/libelf.h:
+		replace __value because it's a reserved word in VC++ 2005.
+	* lib/nlist.c:
+		don't declare open() on W32.
+	* lib/private.h:
+		use <io.h> on W32.
+	* w32/Makefile.w32:
+		fix W32 DLL build.
+	* w32/build.bat:
+		add more examples for vcvars32.bat location.
+
+Fri Jul 28 00:56:00 CEST 2006, Michael Riepe <libelf@mr511.de>
+
+	* lib/32.xlatetof.c:
+	* lib/64.xlatetof.c:
+		check for dsize == -1.
+	* lib/verdef.h:
+	* lib/verneed.h:
+		improve section translators.
+
+Tue Jul 11 18:53:00 CEST 2006, Michael Riepe <libelf@mr511.de>
+
+	* w32/libelf.def:
+		add missing functions.
+
+Sat Jul  8 00:50:00 CEST 2006, Michael Riepe <libelf@mr511.de>
+
+	* VERSION:
+		bump up to 0.8.9.
+
+Sat Jul  8 00:17:00 CEST 2006, Michael Riepe <libelf@mr511.de>
+
+	* lib/32.newehdr.c:
+		make return value compatible with Solaris.
+	* lib/32.newphdr.c:
+		handle 65535+ segments.
+		make return value compatible with Solaris.
+	* lib/cook.c:
+		handle 65535+ segments.
+	* lib/elf_repl.h:
+		add new definitions.
+	* lib/libelf.h:
+		add/rename functions.
+	* lib/newscn.c:
+		fix section creation (was broken in 0.8.7).
+	* lib/private.h:
+		add SHN_XINDEX and PN_XNUM in case they're missing.
+		centrally define LIBELF_SUCCESS and LIBELF_FAILURE.
+	* lib/update.c:
+		handle 65535+ segments.
+		use elf->e_phnum internally.
+	* lib/x.elfext.c:
+		add elf_getphnum().
+		rename elfx_get_shnum() and elfx_get_shstrndx().
+		make return values compatible with Solaris.
+
+Fri Jul  7 19:01:04 CEST 2006, Michael Riepe <libelf@mr511.de>
+
+	* VERSION:
+		bump up to 0.8.8.
+
+Fri Jul  7 18:27:25 CEST 2006, Michael Riepe <libelf@mr511.de>
+
+	* lib/Makefile.in:
+		add lib/x.elfext.c.
+	* lib/libelf.h:
+		add functions from lib/x.elfext.c.
+	* lib/newscn.c:
+		simplify _elf_update_shnum().
+
+Tue Apr 25 16:26:39 CEST 2006, Michael Riepe <libelf@mr511.de>
+
+	* lib/gelf.h:
+	* lib/libelf.h:
+	* lib/nlist.h:
+	* lib/private.h:
+		add workaround for broken compilers.
+
+Mon Apr 24 16:24:32 CEST 2006, Michael Riepe <libelf@mr511.de>
+
+	* po/de.po:
+		update.
+
+Fri Apr 21 19:17:46 CEST 2006, Michael Riepe <libelf@mr511.de>
+
+	* acconfig.h:
+	* configure.in:
+		add --enable-extended-format.
+	* aclocal.m4:
+		search for msgmerge.
+	* lib/cook.c:
+		change _elf_item buffering.
+		handle extended format (with unusual entsize).
+	* lib/errors.h:
+	 	add ERROR_EHDR_SHENTSIZE and ERROR_EHDR_PHENTSIZE.
+	* po/Makefile.in:
+		use msgmerge instead of tupdate.
+ 
+Thu Oct 20 21:08:02 CEST 2005, Michael Riepe <libelf@mr511.de>
+
+	* lib/input.c:
+	* lib/update.c:
+		handle partial reads and writes.
+
+Tue Aug 16 01:48:17 CEST 2005, Michael Riepe <libelf@mr511.de>
+
+	* lib/begin.c:
+		add workaround for archive member misalignment.
+	* VERSION:
+		bump up to 0.8.7
+
+Tue Jul 19 11:56:26 CEST 2005, Michael Riepe <libelf@mr511.de>
+
+	* README:
+	* w32/build.bat:
+		update.
+	* w32/libelf.def:
+		fix syntax.
+
+Tue Jun 28 00:31:24 CEST 2005, Michael Riepe <libelf@mr511.de>
+
+	* Makefile.in:
+		remove superfluous slash.
+
+Tue Jun 21 03:58:47 CEST 2005, Michael Riepe <libelf@mr511.de>
+
+	* lib/Makefile.in:
+		get rid of lib/pic subdir.
+
+Sat May 21 17:39:28 CEST 2005, Michael Riepe <libelf@mr511.de>
+
+	* (global):
+		remove my e-mail address from all copyright clauses.
+
+Sun May 15 23:08:30 CEST 2005, Michael Riepe <libelf@mr511.de>
+
+	* configure.in:
+		check if $CC can copile <elf.h>.
+	* lib/private.h:
+		#include <stdint.h> before <sys/types.h> (fixes glibc bug).
+
+Sun May  8 23:40:35 CEST 2005, Michael Riepe <libelf@mr511.de>
+
+	* Makefile.in:
+		add instroot variable.
+		install libelf.pc.
+	* configure.in:
+		create libelf.pc.
+
+Sun Mar 20 15:41:22 CET 2005, Michael Riepe <libelf@mr511.de>
+
+	* (global):
+		change my e-mail address.
+
+Fri Jan 28 23:09:57 CET 2005, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* po/Makefile.in:
+		use modified gmo2msg.
+	* po/gmo2msg.c:
+		make gmo2msg output more portable.
+
+Thu Oct  7 11:37:09 CEST 2004, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/cook.c:
+		only use Elf64_Shdr if __LIBELF64 is true.
+
+Fri Sep 17 02:55:47 CEST 2004, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/elf_repl.h:
+		add some ABI and architecture definitions.
+	* w32/config.h:
+		manual update.
+
+Sat Jul 10 17:33:15 CEST 2004, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* acconfig.h:
+	* aclocal.m4:
+	* lib/errmsg.c:
+		check for dgettext, not for gettext.
+	* configure.in:
+		check for -lintl.
+	* po/Makefile.in:
+		use -lintl when building gmo2msg.
+
+Sun Jul  4 23:57:21 CEST 2004, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* Makefile.in:
+		add w32 subdir.
+	* README:
+		update for 0.8.6.
+	* configure.in:
+		create w32/Makefile.
+
+Sat Jul  3 20:42:00 CEST 2004, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/32.xlatetof.c:
+	* lib/64.xlatetof.c:
+	* lib/Makefile.in:
+		give up on <libelf_u.h>.
+	* lib/getarsym.c:
+
+Wed Jun 23 01:07:46 CEST 2004, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* config.guess:
+	* config.sub:
+		update from FSF.
+
+Tue May  4 22:02:01 CEST 2004, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* config.guess:
+	* config.sub:
+		update from FSF.
+
+Tue Mar 30 15:09:00 CEST 2004, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/32.xlatetof.c:
+	* lib/64.xlatetof.c:
+	* lib/Makefile.in:
+		use <libelf_u.h> to work around W32 compiler problems.
+
+Mon Feb 16 06:19:11 CET 2004, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* Makefile.in:
+		generate old-format tar file.
+
+Sat Jan 24 03:42:39 CET 2004, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/32.xlatetof.c:
+	* lib/64.xlatetof.c:
+		replace NULL with 0 -- some compilers don't like (void*).
+	* lib/getarsym.c:
+	* lib/nlist.c:
+		add cast to suppress compiler warning.
+
+Fri Jan 23 05:11:46 CET 2004, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/update.c:
+		#undef max before #define.
+
+Wed Jan 21 18:15:50 CET 2004, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/begin.c:
+		better support for Cygwin .lib archive files.
+
+Mon Jan 19 15:36:21 CET 2004, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/libelf.h:
+	* lib/memset.c:
+		include <stddef.h> unconditionally.
+
+Fri Jan 16 23:13:25 CET 2004, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* aclocal.m4:
+		support Intel C Compiler.
+	* lib/32.newehdr.c:
+	* lib/32.newphdr.c:
+		remove elf->e_free_ehdr and elf->e_free_phdr.
+	* lib/cook.c:
+		always allocate ehdr and phdr.
+	* lib/end.c:
+		always deallocate ehdr and phdr.
+	* lib/private.h:
+		remove elf->e_free_ehdr and elf->e_free_phdr.
+		change valid_type to suppress compiler warning.
+	* lib/update.c:
+		not necessary to update elf->e_ehdr and elf->e_phdr.
+
+Thu Jan 15 22:43:00 CET 2004, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* VERSION:
+		bump up to 0.8.6.
+	* configure.in:
+		check for __int64.
+	* lib/32.xlatetof.c:
+	* lib/64.xlatetof.c:
+	* lib/gelf.h:
+	* lib/nlist.h:
+		test _WIN32 macro.
+	* lib/begin.c:
+		add (off_t) cast to suppress compiler warning.
+	* lib/libelf.h:
+	* lib/memset.c:
+		conditionally include <stddef.h> for size_t.
+	* lib/nlist.c:
+		declare open() on W32 systems.
+
+Tue Dec 16 20:02:30 CET 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* Makefile.in:
+		let disttest target make dist again.
+
+Sat Dec 13 16:14:31 CET 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/update.c:
+		call lseek before ftruncate.
+
+Fri Dec  5 16:25:16 CET 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* aclocal.m4:
+		add explanation for --enable-maintainer-mode
+	* lib/Makefile.in:
+	* po/Makefile.in:
+		add instroot make variable
+	* README:
+		add hint how to use it
+
+Thu Nov  6 17:35:00 CET 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* Makefile.in:
+	* lib/Makefile.in:
+	* po/Makefile.in:
+		add check targets
+		add MANIFEST to distribution
+	* aclocal.m4:
+		add mr_PACKAGE macro
+	* configure.in:
+		use mr_PACKAGE macro
+
+Sat Oct 25 15:22:59 CEST 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/elf_repl.h:
+		add EM_SPARC64
+
+Thu Oct  9 23:08:56 CEST 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/x.movscn.c:
+	* lib/x.remscn.c:
+		verify that file is really an ELF file
+
+Wed Oct  8 17:10:09 CEST 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* config.guess:
+	* config.sub:
+		latest versions from FSF
+
+Sat May 24 18:55:14 CEST 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* config.guess:
+		latest version from FSF
+	* lib/Makefile.in:
+	* lib/libelf.h:
+	* lib/x.movscn.c:
+	* lib/x.remscn.c:
+		add elfx_movscn() and elfx_remscn()
+	* lib/newscn.c:
+		update e_shnum properly
+	* lib/private.h:
+		declare _elf_update_shnum()
+
+Fri May 23 18:25:48 CEST 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* aclocal.m4:
+		provide name suffixes only
+	* lib/Makefile.in:
+		use name suffixes
+
+Fri May 23 01:24:26 CEST 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* README:
+		update for 0.8.5
+		add section about LFS
+	* config.guess:
+		latest version from FSF
+	* configure.in:
+	* lib/Makefile.in:
+		use local pic object directory
+	* lib/checksum.c:
+		detect d_buf == NULL
+
+Sun May 18 16:49:10 CEST 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* VERSION:
+		bump up to 0.8.5
+	* lib/strptr.c:
+		make elf_strptr() work safely with fragmented string tables
+	* lib/errors.h:
+		new error code and message for elf_strptr()
+	* po/de.po:
+	* po/libelf.po:
+		regenerated
+
+Mon May 12 15:29:12 CEST 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/update.c:
+		improved fix for elf_update `null buffer' bug
+
+Mon May 12 00:34:44 CEST 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* config.guess:
+	* config.sub:
+		latest versions from FSF
+
+Sun May 11 01:44:06 CEST 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/verdef.h:
+	* lib/verneed.h:
+		fix elf_update `null buffer' error.
+		Thanks to Bart Trojanowski who reported the bug.
+
+Wed May  7 20:26:17 CEST 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* configure.in:
+		fix maintainer mode default
+	* lib/verdef.h:
+	* lib/verneed.h:
+		only check d_buf if there is at least one element
+
+Mon Mar 31 17:08:04 CEST 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* VERSION:
+		bump up to 0.8.4
+
+Sun Mar 23 16:06:43 CET 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* configure.in:
+		fix --enable-compat
+
+Thu Feb 27 14:35:12 CET 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* Makefile.in:
+		add `test-dist' target
+	* lib/errors.h:
+		new error code
+	* po/de.po:
+	* po/libelf.pot:
+		regenerated
+
+Wed Feb 26 17:48:58 CET 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* config.guess:
+	* config.sub:
+		latest versions from FSF
+
+Wed Jan 15 22:50:53 CET 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/begin.c:
+		fix overflow check
+
+Sun Jan 12 04:27:31 CET 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* configure.in:
+		prefer int for __libelf_i32_t (if int has 32 bits)
+
+Thu Jan  2 17:40:22 CET 2003, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* README:
+		update for 0.8.3
+	* config.guess:
+	* config.sub:
+		update from ftp.gnu.org
+	* lib/cook.c:
+		require space for one SHDR only
+	* lib/elf_repl.h:
+		fix DT_ENCODING value
+
+Tue Dec 31 16:27:19 CET 2002, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/cook.c:
+		honor ELF extensions for >= 0xff00 sections
+	* lib/elf_repl.h:
+		add definitions from lates ELF spec
+	* lib/errors.h:
+	* po/libelf.pot:
+	* po/de.po:
+		new error message
+	* lib/private.h:
+		define missing pieces
+	* lib/update.c:
+		handle >= 0xff00 sections
+
+Mon Dec 23 00:23:20 CET 2002, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/Makefile.in:
+		fix dependencies.
+	* lib/cook.c:
+		add quirks mode for broken 64-bit architectures.
+	* lib/update.c:
+		do not override sh_entsize unless it's set to 0.
+	* lib/verdef.h:
+	* lib/verneed.h:
+		work around possible SEGV in translation routines.
+
+Sat Dec 14 23:33:10 CET 2002, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* ChangeLog:
+		add missing entries for 0.8.2 release.
+	* VERSION:
+		bump up to 0.8.3.
+	* lib/32.xlatetof.c:
+	* lib/64.xlatetof.c:
+	* lib/verdef.h:
+	* lib/verneed.h:
+		fix ISO C violations (required for MacOS X).
+	* po/gmo2msg.c:
+		create SUSv3 compliant .msg files.
+
+Thu Jun 11 19:00:19 CEST 2002, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* README:
+		update for 0.8.2.
+	* VERSION:
+		bump up to 0.8.2.
+	* lib/32.xlatetof.c:
+	* lib/64.xlatetof.c:
+		fix typos in for loop.
+	* lib/nlist.c:
+		add O_BINARY to file mode
+		(defaults to 0 on systems that lack it).
+
+Tue Dec 25 14:42:51 CET 2001, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* VERSION:
+		set version to 0.8.0.
+	* README:
+		update version.
+
+Tue Oct 30 17:05:03 CET 2001, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* Makefile.in:
+		use uid/gid=0 when creating the distribution tar file.
+
+Mon Oct 15 23:47:10 CEST 2001, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* configure.in:
+		check for <ar.h> and <fcntl.h>.
+		create ./pic when configuring.
+	* lib/Makefile.in:
+		move .o to ../pic/$@, not ../pic.
+	* lib/begin.c:
+		define struct ar_hdr and friends if <ar.h> is missing.
+		use lseek(..., SEEK_END).
+	* lib/input.c:
+		use lseek(..., SEEK_SET).
+	* lib/nlist.c:
+		include <fcntl.h> conditionally.
+		define O_RDONLY if it is missing.
+	* lib/private.h:
+		define SEEK_{SET,CUR,END} if they're missing.
+	* lib/update.c:
+		explicitly pass file descriptor to _elf_output().
+		use lseek(..., SEEK_SET).
+
+Tue Oct  9 22:46:01 CEST 2001, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* aclocal.m4:
+		remove superfluous case.
+
+Mon Oct  8 17:56:04 CEST 2001, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/opt.delscn.c:
+		handle versioning sections properly.
+
+Mon Oct  8 17:02:43 CEST 2001, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/32.xlatetof.c:
+	* lib/64.xlatetof.c:
+		override encoding when calculating the destination buffer
+		size for translation to a file.
+
+Sun Oct  7 21:31:01 CEST 2001, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* configure.in:
+		drop OBJS64; always compile 64-bit sources.
+	* lib/32.xlatetof.c:
+	* lib/64.xlatetof.c:
+		add translators for versioning structures.
+	* lib/Makefile.in:
+		drop OBJS64; add versioning support files.
+	* lib/errors.h:
+		add error codes for versioning support.
+	* lib/gelfehdr.c:
+	* lib/gelfphdr.c:
+	* lib/gelfshdr.c:
+	* lib/gelftrans.c:
+	* lib/swap64.c:
+		guard code with `#if __LIBELF64'.
+	* lib/private.h:
+		add translator declarations.
+	* po/de.po:
+	* po/libelf.pot:
+		add error messages for versioning support.
+
+Sun Oct  7 16:54:15 CEST 2001, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* acconfig.h:
+	* configure.in:
+		improve auto-configuration.
+	* lib/Makefile.in:
+	* po/Makefile.in
+		let users override distdir.
+	* lib/cook.c:
+		improved bugfix based on new auto-configuration.
+	* lib/getdata.c:
+		prepare src first to prevent SEGV.
+	* lib/private.h:
+	* lib/update.c:
+		cosmetic changes.
+
+Sun Oct  7 05:50:19 CEST 2001, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* configure.in:
+	* lib/cook.c:
+		fix compilation problem on Linux (SHT_SUNW_ver* undefined).
+	* lib/32.xlatetof.c:
+	* lib/64.xlatetof.c:
+		make translator functions calculate the destination size.
+		add _elf32_xltsize and _elf64_xltsize entry points.
+	* lib/private.h:
+		declare _elf32_xltsize and _elf64_xltsize.
+	* lib/getdata.c:
+	* lib/update.c:
+		use _elf32_xltsize and _elf64_xltsize.
+
+Fri Oct  5 20:35:31 CEST 2001, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/elf_repl.h:
+		add DT_VERSYM.
+	* lib/ext_types.h:
+		correct type names.
+	* lib/libelf.h:
+		add ELF_T_VDEF and ELF_T_VNEED.
+	* lib/32.fsize.c:
+		add table entries for versioning structures.
+	* lib/cook.c:
+		replace _elf_scn_types[] with _elf_scn_type().
+	* lib/private.h:
+		likewise; also remove valid_scntype() macro.
+	* lib/update.c:
+		call _elf_scn_type(), but do not set sh_entsize
+		for ELF_T_VDEF / ELF_T_VNEED.
+	* acconfig.h:
+	* lib/sys_elf.h.in:
+		added __LIBELF_SYMBOL_VERSIONS.
+	* configure.in:
+		check for symbol versioning definitions.
+	* lib/Makefile.in:
+		added gelf.h dependency.
+
+Wed Oct  3 22:46:33 CEST 2001, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/swap64.c:
+		new file; separate 64-bit functions.
+	* lib/64.xlatetof.c:
+		remove 64-bit conversion functions.
+	* lib/byteswap.h:
+		replace casts to long / unsigned long.
+		add prototypes for 64-bit conversion functions.
+	* configure.in:
+	* lib/Makefile.in:
+		add lib/swap64.c.
+	* lib/ext_types.h:
+		add type definitions for versioning.
+	* lib/elf_repl.h:
+	* lib/gelf.h:
+		cosmetic changes.
+
+Wed Oct  3 00:00:27 CEST 2001, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/elf_repl.h:
+		added lots of new definitions.
+	* lib/gelf.h:
+	* lib/libelf.h:
+	* lib/sys_elf.h.in:
+		cosmetic changes.
+
+Fri Sep 28 22:42:36 CEST 2001, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/32.xlatetof.c:
+	* lib/64.xlatetof.c:
+		remove `const' when compiling with -fPIC.
+
+Fri Sep 28 20:14:42 CEST 2001, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* README:
+		add pointers to documentation.
+	* lib/64.xlatetof.c:
+		fixed conversion thinko.
+		(Jakub Jelinek <jakub@redhat.com> found this - thanks!)
+	* lib/gelf.h:
+	* lib/32.fsize.c:
+		add gelf_msize.
+	* lib/libelf.h:
+		add comment that elf{32,64}_checksum is missing.
+
+Tue Sep 11 02:43:47 CEST 2001, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* README:
+		corrected typo.
+	* lib/cook.c:
+	* lib/private.h:
+	* lib/update.c:
+		replaces _ELFxx_ALIGN_xHDR with _fsize() call.
+
+Sun Sep  2 20:58:09 CEST 2001, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* Makefile.in:
+	* configure.in:
+	* lib/Makefile.in:
+	* po/Makefile.in:
+		add maintainer mode.
+
+Sat Sep  1 15:11:42 CEST 2001, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/sys_elf.h.in: add more fixes for broken <elf.h> files.
+
+Sat Sep  1 05:01:16 CEST 2001, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* ChangeLog: major update. Yes, I'm back.
+
+	* COPYING.LIB: updated version from FSF.
+
+	* README: updated for 0.7.1.
+
+Thu Apr 20 17:09:41 CEST 2000, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/gelftrans.c:
+	* lib/elf_repl.h:
+		add explicit casts to ELF64_R_SYM and ELF64_R_INFO.
+
+Thu Apr 13 20:15:45 CEST 2000, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/update.c: better checks for overlapping sections.
+
+	* lib/errors.h:
+	* po/de.po:
+	* po/libelf.pot:
+		new error message.
+
+Thu Apr  6 19:15:46 CEST 2000, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/strptr.c: rename `sd' variable.
+
+Fri Mar 31 20:11:14 CEST 2000, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* Makefile.in: also pass CPPFLAGS and LDFLAGS to config.status.
+
+Fri Mar 31 20:02:55 CEST 2000, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* aclocal.m4: add -DPIC define when building position-independent code.
+
+	* lib/32.xlatetof.c:
+	* lib/64.xlatetof.c:
+	* lib/errmsg.c:
+		make array members const when PIC is undefined.
+
+Fri Mar 31 14:42:32 CEST 2000, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/32.newehdr.c: make _elf_newehdr() function private again.
+
+	* lib/32.newphdr.c: make _elf_newphdr() function private again.
+
+	* lib/strptr.c: add support for 64-bit ELF format.
+
+Wed Mar 29 18:49:43 CEST 2000, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/gelfshdr.c: remove ELF class check.
+
+Mon Mar 27 01:24:50 CEST 2000, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/gelf.h: #include <libelf.h> when compiling libelf.
+
+Sun Mar 26 15:02:54 CEST 2000, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/private.h: #include <gelf.h> header file.
+
+	* lib/gelfehdr.c: move gelf_newehdr() function to lib/32.newehdr.c.
+
+	* lib/gelfphdr.c: move gelf_newphdr() function to lib/32.newphdr.c.
+
+	* lib/32.newehdr.c: add gelf_newehdr() function.
+
+	* lib/32.newphdr.c: add gelf_newphdr() function.
+
+	* lib/gelfshdr.c:
+	* lib/gelftrans.c:
+		remove explicit <gelf.h> include.
+
+Sun Mar 26 06:22:20 CEST 2000, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* acconfig.h:
+	* configure.in:
+	* lib/private.h:
+	* lib/sys_elf.h.in:
+		rename NEED_LINK_H to __LIBELF_NEED_LINK_H.
+
+	* lib/32.newehdr.c: make _elf_newehdr() function public.
+
+	* lib/32.newphdr.c: make _elf_newphdr() function public.
+
+	* lib/gelf.h:
+		include <link.h> if needed.
+		choke if 64-bit is not supported.
+		add generic versions of ELF32_* and ELF64_* macros.
+
+	* lib/gelftrans.c:
+		define ELF32_R_* and ELF64_R_* macros (missing on some systems).
+
+Sun Mar 26 05:27:15 CEST 2000, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* configure.in:
+		add check for existing <gelf.h> header.
+		build new source files when 64-bit is enabled.
+
+	* lib/Makefile.in:
+		add new source files.
+		make install-compat if --enable-compat was given.
+
+	* po/de.po:
+	* po/libelf.pot:
+		new error messages.
+
+Sun Mar 26 05:00:20 CEST 2000, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* Makefile.in:
+	* lib/Makefile.in:
+	* po/Makefile.in:
+		remove Makefile last in `make distclean'.
+
+	* aclocal.m4: explicitly state the default in --enable-* help texts.
+
+	* configure.in:
+		set ALL_LINGUAS automatically.
+		add `--enable-compat' option.
+
+	* lib/private.h: add sd_scn member to struct Scn_Data.
+
+	* lib/cook.c:
+	* lib/end.c:
+	* lib/getdata.c:
+	* lib/newdata.c:
+	* lib/opt.delscn.c:
+	* lib/rawdata.c:
+	* lib/update.c:
+		handle new sd_scn member.
+
+	* lib/gelf.h: new public header file.
+
+	* lib/gelfehdr.c: new file, implements the gelf_getehdr(),
+		gelf_update_ehdr() and gelf_newehdr() functions.
+
+	* lib/gelfphdr.c: new file, implements the gelf_getphdr(),
+		gelf_update_phdr() and gelf_newphdr() functions.
+
+	* lib/gelfshdr.c: new file, implements the gelf_getshdr()
+		and gelf_update_shdr() functions.
+
+	* lib/gelftrans.c: new file, implements the gelf_getsym(),
+		gelf_update_sym(), gelf_getdyn(), gelf_update_dyn(),
+		gelf_getrela(), gelf_update_rela(), gelf_getrel() and
+		gelf_update_rel() functions.
+
+	* lib/begin.c: add gelf_getclass() function.
+
+	* lib/32.fsize.c: add gelf_fsize() function.
+
+	* lib/32.getphdr.c: make _elf_getphdr() function public.
+
+	* lib/64.xlatetof.c:
+		add gelf_xlatetom() and gelf_xlatetof() functions.
+		remove `const' from array members.
+
+	* lib/errors.h: add GElf error messages.
+
+	* po/de.po:
+	* po/libelf.pot:
+		new error message.
+
+Thu Nov  4 21:17:34 CET 1999, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/32.xlatetof.c:
+	* lib/errmsg.c:
+	* po/gmo2msg.c:
+		remove `const' from array members.
+
+Thu Nov  4 20:16:36 CET 1999, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/Makefile.in: add assert.c; remove stamp-h in `make distclean'.
+
+	* lib/assert.c: new file, implements the __elf_assert() function.
+
+	* lib/private.h: use __elf_assert() in elf_assert() macro.
+
+Wed Mar 17 16:21:02 CET 1999, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* configure.in: add "de" to ALL_LINGUAS.
+
+	* lib/elf_repl.h: lots of new #defines.
+
+	* lib/hash.c:
+	* lib/libelf.h:
+		elf_hash() takes an `const unsigned char *'.
+
+	* po/gmo2msg.c: copy comments from .gmo file.
+
+Fri Mar  5 16:28:08 CET 1999, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* VERSION: set version to 0.7.1.
+
+	* po/de.po: new file.
+
+Fri Nov 27 22:24:00 MET 1998, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/memset.c: rename and rewrite.
+	* lib/private.h: rename __memset.
+
+Tue Aug 25 17:17:18 MEST 1998, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* aclocal.m4: remove superfluous #include.
+
+	* lib/32.xlatetof.c:
+	* lib/64.xlatetof.c: fix for picky instances of cpp(1).
+
+Sun Aug 23 18:26:53 MEST 1998, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* aclocal.m4:
+	* lib/Makefile.in: add DEPSHLIBS, set to -lc for Linux.
+
+	* README: add DEPSHLIBS description.
+
+Sat Aug 22 15:50:41 MEST 1998, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/begin.c: add workaround for broken ar(1) & friends.
+
+	* lib/32.getshdr.c: fix typo.
+
+Thu Aug  6 18:11:52 MEST 1998, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/getdata.c: fixed SEGV bug.
+
+	* lib/cook.c:
+	* lib/getdata.c:
+	* lib/newdata.c:
+	* lib/rawdata.c:
+	* lib/private.h: removed sd_scn and (Elf_Data*) casts.
+
+Fri Jun 12 21:24:50 MEST 1998, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* lib/*.c: move rcsid[] after <private.h>.
+
+	* lib/32.xlatetof.c:
+	* lib/64.xlatetof.c: replace broken Exn() macro with Cat2().
+
+	* lib/64.xlatetof.c: change `char*' to `unsigned char*'.
+
+	* lib/private.h: add `extern char *realloc();'.
+
+	* aclocal.m4:
+	* configure.in: remove leading spaces in cpp directives.
+
+Sun Jun  7 16:02:31 MEST 1998, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* README: update for 0.7.0 release.
+
+Sun Jun  4 15:26:49 MEST 1998, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* acconfig.h: add __libelf64* and __libelf_*_t.
+
+	* configure.in: clean up, add checks for 64-bit support.
+
+	* lib/64.xlatetof.c: new file, based on lib/32.xlatetof.c.
+
+	* lib/Makefile.in: add target for 64.xlatetof.o.
+
+	* lib/cook.c: check for 32-bit overflow.
+
+	* lib/elf_repl.h:
+	* lib/ext_types.h: add 64-bit data types.
+
+	* lib/private.h: add 64-bit definitions.
+
+	* lib/sys_elf.h.in: add __LIBELF64* and __libelf_*_t.
+
+	* lib/update.c: add full 64-bit support.
+
+Mon Jun  1 16:29:07 MEST 1998, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* VERSION: change version to 0.7.0.
+
+	* configure.in:
+		add lib/sys_elf.h to AC_CONFIG_HEADER.
+		new option --disable-elf64.
+
+	* Makefile.in: add target for lib/sys_elf.h.
+
+	* acconfig.h: add __LIBELF_HEADER_ELF_H.
+
+	* lib/Makefile.in: add sys_elf.h(.in).
+
+	* lib/32.fsize.c:
+	* lib/32.getehdr.c:
+	* lib/32.getphdr.c:
+	* lib/32.getshdr.c:
+	* lib/32.newehdr.c:
+	* lib/32.newphdr.c:
+	* lib/cook.c:
+	* lib/getdata.c:
+	* lib/libelf.h:
+	* lib/newscn.c:
+	* lib/nlist.c:
+	* lib/opt.delscn.c:
+	* lib/private.h:
+	* lib/update.c:
+		merged with 64bit code.
+
+	* lib/begin.c:
+	* lib/input.c:
+		bug fixes.
+
+Fri Aug  1 19:33:33 MEST 1997, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* VERSION: change version to 0.6.5.
+	
+	* lib/libelf.h: add declaration for elf_memory.
+
+	* lib/private.h: add e_memory flag.
+	
+	* lib/begin.c: add elf_memory, change archive freezing logic.
+
+	* lib/end.c: do not free e_data if e_memory is set.
+
+Tue Oct 22 21:31:56 MEST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* (all files): add RCS Id, import to CVS.
+
+	* Makefile.in: pass $(CC) to config.status.
+
+	* README: change for upcoming 0.6.5 release.
+
+	* aclocal.m4 (mr_ENABLE_NLS): add --enable-gnu-names option
+
+	* configure.in: change search order for <elf.h>.
+
+	* lib/begin.c (_elf_arhdr): add check for truncated archive member.
+
+	* lib/cook.c (_elf32_cook): add checks for misaligned tables.
+
+	* lib/errors.h:
+		fix wrong error message (ERROR_WRONLY).
+		add error messages for misaligned tables.
+
+	* lib/private.h: add constants for table alignments.
+
+	* po/Makefile.in: do not run mkinstalldirs directly, use $(SHELL).
+
+	* po/libelf.pot: rebuild.
+
+Tue Jul 30 17:22:41 MET DST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* VERSION: change version to 0.6.4.
+
+	* Makefile.in:
+		add DISTSUBDIRS.
+		add po/Makefile target.
+
+	* po/Makefile.in:
+	* po/gmo2msg.c:
+	* po/libelf.pot:
+	* po/stamp-po:
+		new files.
+
+	* aclocal.m4 (mr_ENABLE_NLS):
+		add MSGFILES.
+		set GMOFILES, MSGFILES and POFILES even if NLS is disabled.
+
+	* configure.in:
+		add ALL_LINGUAS.
+
+	* lib/nlist.c:
+		call elf_errno() to clear pending error.
+
+Tue Jul 28 23:53:44 MET DST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* VERSION: change version to 0.6.3.
+
+	* configure.in: fix creation of sys_elf.h.
+
+	* lib/Makefile.in:
+		move elf_repl.h to PRIVHDRS.
+		do not depend on HDRS and AUXHDRS.
+
+Sat Jul 27 18:27:09 MET DST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* VERSION: change version to 0.6.2.
+
+	* Makefile.in:
+		remove support from SUBDIRS.
+		remove subdirs/Makefile target.
+
+	* acconfig.h:
+		add ENABLE_DEBUG.
+		remove HAVE_NLS.
+
+	* aclocal.m4:
+		add mr_ENABLE_DEBUG.
+
+	* configure.in:
+		use mr_ENABLE_DEBUG.
+
+	* lib/Makefile.in:
+		add LD variable.
+		add elf_repl.h to DISTFILES.
+
+	* lib/libelf.h:
+		add check for __LIBELF_INTERNAL__.
+
+	* lib/private.h:
+		#define __LIBELF_INTERNAL__.
+		use ENABLE_DEBUG.
+
+	* support/elf.h:
+		move to lib/elf_repl.h.
+
+	* support/Makefile.in:
+		remove.
+
+Sat Jul 27 06:25:23 MET DST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* VERSION: change version to 0.6.1.
+
+	* aclocal.m4: add shared library support for sparc-sun-solaris2.
+
+	* lib/libelf.h.in: remove.
+
+	* lib/libelf.h: new file.
+
+	* configure.in:
+		remove broken check for existing installation.
+		remove @install_headers@ and @elf_h@.
+		do not build libelf.h from libelf.h.in.
+		create lib/sys_elf.h.
+
+	* lib/Makefile.in:
+		remove libelf.h and $(AUXHDRS) targets.
+		remove libelf.h.in from DISTFILES.
+		add libelf.h to DISTFILES.
+		add dummy_shlib target for broken make.
+
+Sat Jul 27 01:01:45 MET DST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* VERSION: change version to 0.6.0.
+
+	* lib: new directory.
+
+	* config.sub:
+	* config.guess:
+		new files.
+
+	* shared:
+	* shared/Makefile.in:
+		remove.
+
+	* aclocal.m4:
+	* configure.in:
+		add shared library check.
+
+	* Makefile.in:
+	* lib/Makefile.in:
+		change for new directory structure.
+		integrate shared library support.
+
+	* Makefile.in:
+		remove libelf.lsm from DISTFILES.
+
+	* libelf.lsm: remove.
+
+Thu Jul 25 19:35:05 MET DST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* VERSION: change version to 0.5.9.
+
+	* aclocal.m4: rewrite NLS check.
+
+Tue Jul 23 18:59:05 MET DST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* Makefile.in: add install-compat and uninstall-compat targets.
+
+	* configure.in:
+	* aclocal.m4:
+		fix check for NLS support.
+
+	* acconfig.h: add HAVE_CATGETS and HAVE_GETTEXT.
+
+	* errmsg.c (elf_errmsg): use HAVE_GETTEXT.
+
+Sun Jul 21 22:52:02 MET DST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* VERSION: change version to 0.5.8.
+
+	* private.h:
+	* 32.getshdr.c:
+	* cook.c:
+	* end.c:
+	* newscn.c:
+	* opt.delscn.c:
+	* update.c:
+		change allocation of section headers.
+
+	* errors.h: fix speeling error.
+
+Sat Jul 13 22:51:16 MET DST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* VERSION: change version to 0.5.7.
+
+	* private.h: add e_dsize member to struct Elf.
+
+	* begin.c (elf_begin): set e_dsize.
+
+	* update.c (_elf32_update_pointers):
+		never let e_data become shorter than e_dsize bytes.
+		use correct base pointer.
+
+Sat Jun 15 16:28:50 MET DST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* 32.xlatetof.c: change `char' to `unsigned char'.
+
+Tue May 28 19:00:30 MET DST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* Makefile.in:
+		HP-UX make wants non-empty target, change it.
+		add targets for TAGS and libelf.po.
+
+	* errors.h: mark strings for GNU gettext.
+
+	* mkmsgs: recognize new errors.h format.
+
+	* errmsg.c (elf_errmsg): add gettext support.
+
+Mon May 27 20:30:30 MET DST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* VERSION: change version to 0.5.6.
+
+	* aclocal.m4:
+	* configure.in: use new AC_CACHE_CHECK macro.
+
+	* Makefile.in:
+	* shared/Makefile.in: use @...dir@.
+
+	* Makefile.in: pass $(SRCS) and $(OBJS) to shared/Makefile.
+
+Sat May 25 01:00:15 MET DST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* update.c (elf_update): assert e_data is malloc'ed.
+
+	* begin.c (elf_begin): mmap e_data if possible.
+
+	* end.c (elf_end): munmap e_data if necessary.
+
+	* input.c (_elf_mmap): new function.
+
+	* private.h: add _elf_mmap and e_unmap_data.
+
+	* errmsg.c: make pointer array constant.
+
+Thu May 23 19:24:47 MET DST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* update.c (elf_update): mmap(MAP_SHARED) wants non-empty file.
+
+Tue May 21 15:33:07 MET DST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* begin.c (elf_begin): re-read memory image of archive members.
+
+	* cook.c (_elf32_item):
+	* getdata.c (_elf32_cook_scn): always use memory image.
+
+	* update.c (_elf_update): use mmap if possible.
+
+	* configure.in: check for mmap.
+
+Mon May 20 18:15:54 MET DST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* nlist.c (_elf_nlist): fix broken st_name range check.
+
+	* update.c (_elf32_write): check status of elf_getdata.
+
+	* cook.c (_elf32_item):
+	* getdata.c (_elf32_cook_scn):
+		use memory image when file is not an archive member.
+
+	* rawdata.c (elf_rawdata): copy raw image rather than referencing it.
+
+Wed May 15 20:04:39 MET DST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* rawdata.c (elf_rawdata): use raw image if it is present.
+
+	* cntl.c (elf_cntl): fix archive handling, ignore ELF_C_FDREAD for non-ELF files.
+
+Fri May 10 17:16:44 MET DST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* begin.c (_elf_arhdr): fix handling of long archive member names.
+
+	* configure.in: move version information to external file.
+
+	* Makefile.in: add VERSION to DISTFILES.
+
+	* VERSION: new file.
+
+Sat May  4 20:56:43 MET DST 1996, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* configure.in: change version to 0.5.5.
+
+	* Makefile.in: add libelf.lsm and ChangeLog to DISTFILES.
+
+	* rawdata.c: reorder cases to avoid unnecessary malloc/free.
+
+	* all files: update copyright phrase.
+
+	* ChangeLog:
+	* libelf.lsm: new files.
+
+Sun Oct 29 19:34:00 MET 1995, Michael Riepe <michael@stud.uni-hannover.de>
+
+	* configure.in: change version to 0.5.3.
+
+	* Makefile.in:
+	* shared/Makefile.in: add opt.delscn.c.
+
+	* libelf.h.in: add declaration for elf_delscn.
+
+	* opt.delscn.c: new file.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/INSTALL	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,176 @@
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, a file
+`config.cache' that saves the results of its tests to speed up
+reconfiguring, and a file `config.log' containing compiler output
+(useful mainly for debugging `configure').
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If at some point `config.cache'
+contains results you don't want to keep, you may remove or edit it.
+
+   The file `configure.in' is used to create `configure' by a program
+called `autoconf'.  You only need `configure.in' if you want to change
+it or regenerate `configure' using a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  You can give `configure'
+initial values for variables by setting them in the environment.  Using
+a Bourne-compatible shell, you can do that on the command line like
+this:
+     CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
+
+Or on systems that have the `env' program, you can do it like this:
+     env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not supports the `VPATH'
+variable, you have to compile the package for one architecture at a time
+in the source code directory.  After you have installed the package for
+one architecture, use `make distclean' before reconfiguring for another
+architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' can not figure out
+automatically, but needs to determine by the type of host the package
+will run on.  Usually `configure' can figure that out, but if it prints
+a message saying it can not guess the host type, give it the
+`--host=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name with three fields:
+     CPU-COMPANY-SYSTEM
+
+See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the host type.
+
+   If you are building compiler tools for cross-compiling, you can also
+use the `--target=TYPE' option to select the type of system they will
+produce code for and the `--build=TYPE' option to select the type of
+system on which you are compiling the package.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Operation Controls
+==================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--cache-file=FILE'
+     Use and save the results of the tests in FILE instead of
+     `./config.cache'.  Set FILE to `/dev/null' to disable caching, for
+     debugging `configure'.
+
+`--help'
+     Print a summary of the options to `configure', and exit.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`--version'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`configure' also accepts some other, not widely useful, options.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/MANIFEST	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,95 @@
+25275 COPYING.LIB
+34569 ChangeLog
+7462 INSTALL
+5904 Makefile.in
+12535 README
+7 VERSION
+2951 acconfig.h
+9377 aclocal.m4
+43611 config.guess
+3987 config.h.in
+31160 config.sub
+110753 configure
+11732 configure.in
+2186 install-sh
+4794 lib/32.fsize.c
+1552 lib/32.getehdr.c
+1553 lib/32.getphdr.c
+1660 lib/32.getshdr.c
+2177 lib/32.newehdr.c
+3051 lib/32.newphdr.c
+12318 lib/32.xlatetof.c
+14217 lib/64.xlatetof.c
+7986 lib/Makefile.in
+3999 lib/Makefile.w32
+1115 lib/assert.c
+10791 lib/begin.c
+1685 lib/build.bat
+3562 lib/byteswap.h
+3933 lib/checksum.c
+1897 lib/cntl.c
+4851 lib/config.h.w32
+12550 lib/cook.c
+1179 lib/data.c
+24540 lib/elf_repl.h
+2895 lib/end.c
+2133 lib/errmsg.c
+1033 lib/errno.c
+6218 lib/errors.h
+8103 lib/ext_types.h
+993 lib/fill.c
+2396 lib/flag.c
+5099 lib/gelf.h
+4147 lib/gelfehdr.c
+3961 lib/gelfphdr.c
+3753 lib/gelfshdr.c
+9451 lib/gelftrans.c
+1171 lib/getarhdr.c
+2417 lib/getarsym.c
+1092 lib/getbase.c
+3837 lib/getdata.c
+1349 lib/getident.c
+1445 lib/getscn.c
+1207 lib/hash.c
+2558 lib/input.c
+1084 lib/kind.c
+1214 lib/libelf.def
+8157 lib/libelf.h
+1501 lib/memset.c
+1094 lib/ndxscn.c
+1553 lib/newdata.c
+3484 lib/newscn.c
+1352 lib/next.c
+1603 lib/nextscn.c
+5894 lib/nlist.c
+1447 lib/nlist.h
+5067 lib/opt.delscn.c
+12797 lib/private.h
+1282 lib/rand.c
+2538 lib/rawdata.c
+1469 lib/rawfile.c
+3389 lib/strptr.c
+2281 lib/swap64.c
+3808 lib/sys_elf.h.in
+4066 lib/sys_elf.h.w32
+25824 lib/update.c
+6880 lib/verdef.h
+1582 lib/verdef_32_tof.c
+1582 lib/verdef_32_tom.c
+1610 lib/verdef_64_tof.c
+1610 lib/verdef_64_tom.c
+7131 lib/verneed.h
+1431 lib/version.c
+4234 lib/x.elfext.c
+2717 lib/x.movscn.c
+2866 lib/x.remscn.c
+238 libelf.pc.in
+619 mkinstalldirs
+4589 po/Makefile.in
+8748 po/de.gmo
+52 po/de.msg
+11328 po/de.po
+3007 po/gmo2msg.c
+6483 po/libelf.pot
+10 po/stamp-po
+10 stamp-h.in
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/Makefile.in	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,198 @@
+# Makefile for libelf.
+# Copyright (C) 1995 - 2005 Michael Riepe
+# 
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+# 
+# This library 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
+# Library General Public License for more details.
+# 
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+# @(#) $Id: Makefile.in,v 1.29 2006/08/25 12:46:34 michael Exp $
+
+instroot =
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+
+pkgdir = $(libdir)/pkgconfig
+
+MV = mv -f
+RM = rm -f
+LN_S = @LN_S@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+
+CC = @CC@
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+
+# no user serviceable parts below
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+@SET_MAKE@
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+SUBDIRS = lib @POSUB@
+DISTSUBDIRS = lib po
+
+DISTFILES = \
+	acconfig.h aclocal.m4 ChangeLog config.guess config.h.in \
+	config.sub configure configure.in COPYING.LIB INSTALL install-sh \
+	Makefile.in mkinstalldirs README stamp-h.in VERSION libelf.pc.in
+
+all: all-recursive all-local
+check: check-recursive check-local
+install: install-recursive install-local
+uninstall: uninstall-recursive uninstall-local
+mostlyclean: mostlyclean-recursive mostlyclean-local
+clean: clean-recursive clean-local
+distclean: distclean-recursive distclean-local
+maintainer-clean: maintainer-clean-recursive maintainer-clean-local
+
+install-compat uninstall-compat:
+	cd lib && $(MAKE) $@
+
+all-recursive check-recursive install-recursive uninstall-recursive \
+clean-recursive distclean-recursive mostlyclean-recursive \
+maintainer-clean-recursive:
+	@subdirs="$(SUBDIRS)"; for subdir in $$subdirs; do \
+	  target=`echo $@|sed 's,-recursive,,'`; \
+	  echo making $$target in $$subdir; \
+	  (cd $$subdir && $(MAKE) $$target) || exit 1; \
+	done
+
+all-local:
+
+check-local:
+
+install-local: $(srcdir)/mkinstalldirs libelf.pc
+	$(SHELL) $(srcdir)/mkinstalldirs $(instroot)$(pkgdir)
+	$(INSTALL_DATA) libelf.pc $(instroot)$(pkgdir)
+
+uninstall-local:
+	$(RM) $(instroot)$(pkgdir)/libelf.pc
+
+mostlyclean-local:
+	$(RM) *~ core errlist
+
+clean-local: mostlyclean-local
+
+distclean-local: clean-local
+	$(RM) config.cache config.h config.log config.status stamp-h
+	$(RM) Makefile
+	$(RM) libelf.pc
+
+maintainer-clean-local: distclean-local
+	@echo "This command is intended for maintainers to use;"
+	@echo "it deletes files that may require special tools to rebuild."
+	$(RM) config.h.in configure stamp-dist
+	$(RM) -r $(distdir)
+
+# maintainer only
+
+MAINT = @MAINT@
+
+distdir = $(PACKAGE)-$(VERSION)
+DISTPERMS = --owner=root --group=root --numeric-owner
+$(MAINT)dist: ./stamp-dist
+$(MAINT)./stamp-dist: $(DISTFILES)
+	$(RM) -r $(distdir)
+	mkdir $(distdir)
+	files="$(DISTFILES)"; for file in $$files; do \
+	  ln $(srcdir)/$$file $(distdir) || \
+	    cp -p $(srcdir)/$$file $(distdir) || exit 1; \
+	done
+	subdirs="$(DISTSUBDIRS)"; for subdir in $$subdirs; do \
+	  (cd $$subdir && $(MAKE) dist) || exit 1; \
+	done
+	cd $(distdir) && \
+	    find . -type f ! -name MANIFEST -exec wc -c {} \; | \
+	    sed 's, \./, ,' | sort -k2 >MANIFEST
+	-$(RM) $(distdir).tar.gz.bak $(PACKAGE).tar.gz
+	-$(MV) $(distdir).tar.gz $(distdir).tar.gz.bak
+	tar cvohfz $(distdir).tar.gz $(DISTPERMS) $(distdir)
+	$(LN_S) $(distdir).tar.gz $(PACKAGE).tar.gz
+	$(RM) stamp-dist && echo timestamp > stamp-dist
+
+$(MAINT)check-dist:
+	$(RM) -r disttest
+	mkdir disttest
+	@echo 'unset CC CFLAGS CPPFLAGS LDFLAGS LIBS' >disttest/config.site
+	cd disttest && CONFIG_SITE=config.site ../$(distdir)/configure
+	$(MAKE) -C disttest
+	$(MAKE) -C disttest check
+	$(MAKE) -C disttest dist
+
+.PHONY: tags
+tags:
+	rm -f tags
+	ctags lib/*.c lib/*.h
+
+TRACKFS = trackfs
+trackinstall:
+	$(TRACKFS) -l install.log -b backup.cpio $(MAKE) install
+
+# For the justification of the following Makefile rules, see node
+# `Automatic Remaking' in GNU Autoconf documentation.
+
+$(MAINT)$(srcdir)/configure: $(srcdir)/configure.in $(srcdir)/aclocal.m4
+	$(RM) $(srcdir)/configure
+	cd $(srcdir) && autoconf
+
+$(MAINT)$(srcdir)/config.h.in: $(srcdir)/stamp-h.in
+$(MAINT)$(srcdir)/stamp-h.in: $(srcdir)/configure.in $(srcdir)/acconfig.h
+	$(RM) $(srcdir)/config.h.in
+	cd $(srcdir) && autoheader
+	cd $(srcdir) && $(RM) stamp-h.in && echo timestamp > stamp-h.in
+
+$(MAINT)config.h: stamp-h
+$(MAINT)stamp-h: config.h.in config.status
+	CONFIG_FILES= CONFIG_HEADERS=config.h ./config.status
+	$(RM) stamp-h && echo timestamp > stamp-h
+
+$(MAINT)Makefile: Makefile.in config.status
+	CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status
+
+$(MAINT)lib/Makefile: lib/Makefile.in config.status
+	CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status
+
+$(MAINT)lib/sys_elf.h: lib/stamp-h
+$(MAINT)lib/stamp-h: lib/sys_elf.h.in config.status
+	CONFIG_FILES= CONFIG_HEADERS=lib/sys_elf.h ./config.status
+	$(RM) lib/stamp-h && echo timestamp > lib/stamp-h
+
+$(MAINT)po/Makefile: po/Makefile.in config.status
+	CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status
+
+$(MAINT)libelf.pc: libelf.pc.in config.status
+	CONFIG_FILES=$@ CONFIG_HEADERS= ./config.status
+
+RECHECK_FLAGS = CC='$(CC)' CPPFLAGS='$(CPPFLAGS)' \
+	CFLAGS='$(CFLAGS)' LDFLAGS='$(LDFLAGS)' LIBS='$(LIBS)'
+
+$(MAINT)config.status: configure config.h.in VERSION
+	$(RECHECK_FLAGS) ./config.status --recheck
+
+$(MAINT)reconfig:
+	$(RM) config.cache
+	$(RECHECK_FLAGS) ./config.status --recheck
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/README	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,310 @@
+This is the public release of libelf-0.8.10, a free ELF object
+file access library. If you have problems with applications
+that use libelf and work with the commercial (SVR4, Solaris)
+version but not with this one, please contact me.
+
+IMPORTANT NOTE: If you have libelf-0.5.2 installed, you probably
+have a file .../include/elf.h that contains the single line
+``#include <libelf/elf.h>''. REMOVE THIS FILE BEFORE YOU RUN
+configure.
+
+Installation is straightforward - the package is autoconf'ed.  Just do
+``cd libelf-0.8.10; ./configure; make; make install''.  Header files
+will be installed in .../include/libelf/.  If your system does not
+provide its own versions of libelf.h, nlist.h or gelf.h, ``make
+install'' will add the missing headers.  If you prefer not to have
+these files installed in /usr/include, use ``--disable-compat'' and
+add ``-I /usr/include/libelf'' to your CFLAGS when compiling
+libelf-based programs.
+
+Note to distribution makers:  You can install libelf in a separate root
+hierarchy by using the command ``make instroot=/my/root install''.
+You should also use the ``--enable-compat'' configure option in that
+case, or run ``make instroot=/my/root install-compat'' manually, to
+install all the required header files.
+
+If you are running Linux with libc 5.* as the default C library,
+and you plan to use the 64-bit functions, you must either use
+``-I.../include/libelf'', or remove /usr/include/libelf.h and use
+``--enable-compat'' when running configure. Libc 6.* (aka glibc2)
+doesn't have its own <libelf.h>, <nlist.h> or <gelf.h>.
+
+You need an ANSI/ISO C compiler to build libelf. Gcc is optimal.
+
+On some systems (in particular, Solaris and all variants of Linux),
+``make'' will try to build a shared library. If you run into problems
+on your system, please pass ``--disable-shared'' to configure.
+If you build a shared library and want it to be installed as
+``libelf-0.8.10.so'' rather than ``libelf.so.0.8.10'', please use
+``./configure --enable-gnu-names''. Other files, e.g. ``libelf.so'' and
+``libelf.so.0'' are NOT affected.
+
+Another configure option, ``--enable-debug'', adds debugging code to
+libelf; if you don't run into problems, you will probably not need it.
+
+When creating an ELF shared library, it is possible to add references
+to other shared libraries in the DYNAMIC section of the resulting
+file. The make variable DEPSHLIBS contains a list of libraries to add.
+It is set to ``-lc'' on Linux systems, and empty otherwise. To
+override this setting, use something like ``make DEPSHLIBS="-la -lb"''.
+For Linux, `-lc' is included automagically.
+
+NLS is available and enabled by default.  To turn it off, pass the
+``--disable-nls'' option to configure.
+
+Libelf can use gettext or catgets for accessing message
+catalogs.  If gettext is available AND is part of libc (i.e. not
+in a separate library), it will be used. Otherwise, configure
+will look for catgets.  If you have gettext in a separate
+library and want to use it, you should pass the library's name
+to configure, e.g. ``LIBS=-lintl ./configure''. Note that you
+MUST link your libelf-based applications with -lintl then,
+which is probably not what you want, or change the DEPSHLIBS variable
+described above (in case you're building a shared library).
+
+If you have GNU gettext 0.10 installed on your system, and if GNU gettext
+runs on top of the catgets interface (rather old Linux systems, using
+libc5), configure will refuse to use it and use catgets instead. If you
+absolutely want to use GNU gettext, go ahead and rebuild it (which is
+IMHO a good idea in general in this case):
+
+	cd .../gettext-0.10
+	ac_cv_func_catgets=no ac_cv_func_gettext=no ./configure
+	make
+	make install
+
+After that, return to the libelf build directory, remove
+config.cache, and start over.
+
+*** Large File Support (LFS) applications ***
+
+Some 32-bit systems support files that are larger than the address space
+of the architecture.  On these, the `off_t' data type may have 32 or
+64 bits, depending on the API you choose.  Since off_t is also part of
+the libelf API, in particular the Elf_Data and Elf_Arhdr structures,
+an application compiled with large file support will need a version of
+libelf that has also been compiled with LFS; otherwise, it won't work
+correctly.  Similarly, a program compiled without LFS needs a library
+compiled without LFS.
+
+Note that libelf is currently unable to process large files on 32-bit
+architectures, whether you compile it for LFS or not, for the simple
+reason that the files won't fit into the processes' address space.
+Therefore, libelf is compiled without LFS by default.  It can of course
+read and write ELF files for 64-bit architectures, but they will be
+limited in length on a 32-bit system.
+
+You may compile libelf with large file support by setting CPPFLAGS at
+configuration time:
+
+	CPPFLAGS=`getconf LFS_CFLAGS` ./configure
+
+But I really, really recommend you don't, because it breaks binary
+compatibility with existing libelf based applications.
+
+*** 64-bit support ***
+
+Starting with libelf-0.7.0, libelf also supports 64-bit ELF files.
+This is enabled by default unless your system (or your compiler) does
+not support 64-bit integers, or lacks 64-bit declarations in <elf.h>.
+If you have problems building with 64-bit support, please do
+
+    ./configure --disable-elf64
+
+for the moment, and contact me. Please note that I haven't tested 64-bit
+support much.  There are still some unresolved problems, e.g. IRIX
+uses different Elf64_Rel and Elf64_Rela structures (they replaced the
+r_info member), and the enumeration values for Elf_Type differ from
+the commercial (SVR4) implementation of libelf - they broke binary
+compatibility for no good reason, and I'm not willing to follow their
+footsteps. The result is that libelf-0.7.* ist upward compatible with
+libelf-0.6.4 (as it should be) but INCOMPATIBLE WITH SVR4 LIBELF. If you
+have both versions installed, you'd better make sure that you link with
+the library that matches the <libelf.h> you're #include'ing.
+
+*** Symbol Versioning ***
+
+Libelf >= 0.8.0 supports the data structures and definitions used for
+symbol versioning on Solaris and Linux, in particular, the Elfxx_Verdef,
+Elfxx_Verdaux, Elfxx_Verneed, Elfxx_Vernaux and Elfxx_Versym structures
+and the SHT_XXX_verdef, SHT_XXX_verneed and SHT_XXX_versym section types
+(where `xx' is either `32' or `64', and `XXX' is either `SUNW' or `GNU').
+Libelf now translates versioning sections to/from their external
+representation properly (earlier versions left them in `raw' format,
+with the data type set to ELF_T_BYTE).  This may cause problems on
+systems which use the same (OS-specific) section types for different
+purposes.  The configure program tries to figure out if your OS uses
+versioning; if that check fails, you can use
+
+    ./configure --disable-versioning
+
+to turn off versioning translation support.
+
+*** W32 Support ***
+
+There is now some support for building on W32 systems (requires Microsoft
+VC++).  In order to build a W32 DLL, cd into the `lib' subdirectory, edit
+build.bat if necessary (it needs the path to your compiler binaries) and
+run it.  If you're lucky, libelf.dll and the import/export libraries will
+be built.  If not, please drop me a line.
+
+I tested it on XP Pro (SP2), using VC++ 2005 Express Edition.
+Apparently, Visual Studio .NET 2003 works fine as well.
+
+Various notes regarding the W32 port:
+
+    - When you open() an ELF file, remember to use the O_BINARY flag.
+    - You may have to add /MD to the linker command line.
+
+*** Missing things ***
+
+	* There is no documentation.  You can use the Solaris
+	  manpages instead (available at http://docs.sun.com/).
+	  The ELF file format is described in several places;
+	  among them Suns "Linker and Libraries Guide" and the
+	  "System V Application Binary Interface" documents;
+	  http://www.caldera.com/developer/devspecs/gabi41.pdf and
+	  http://www.caldera.com/developer/gabi/ are probably good
+	  starting points. Processor-specific documentation is spread
+	  across a number of `Processor Supplement' documents, one
+	  for each architecture; you'll have to use a search engine to
+	  find them.
+
+	* The COFF file format is not understood. This is so obsolete
+	  that it will probably never be implemented.
+
+	* nlist(3) is incomplete; the n_type and n_sclass
+	  members of struct nl are set to zero even if type
+	  (that is, debug) information is available.
+
+	* Libelf does not translate Solaris' `Move' and `Syminfo'
+	  sections. You can read them using elf_getdata(), but you'll
+	  only get raw (untranslated) bytes.
+
+Changes since 0.8.9:
+
+	* Ported to QNX Neutrino.
+	* Fixed Windows build errors.
+	* Parallel (make -j) installation should work now.
+
+	* It's now possible to enable and disable select sanity checks
+	  libelf performs. Currently, this affects the "NUL terminated
+	  string table entry" check performed in elf_strptr(). By
+	  default, the function will return an error if the string
+	  requested is not properly terminated - because some
+	  applications might dump core otherwise. If you configure
+	  libelf with `--disable-sanity-checks', however, the check
+	  (and, in the future, probably others as well) is disabled
+	  by default. You can still turn it on and off at runtime by
+	  setting the LIBELF_SANITY_CHECKS environment variable to
+	  an integer value:
+
+	      # disable all sanity checks
+	      export LIBELF_SANITY_CHECKS=0
+
+	      # enable all sanity checks
+	      export LIBELF_SANITY_CHECKS=-1
+
+	  Each bit of the value corresponds to a particular check,
+	  so you could use LIBELF_SANITY_CHECKS=1 to enable only
+	  the elf_strptr() check. You may also use a value in hex
+	  (0x...) or octal (0...) format.
+ 
+Changes since 0.8.8:
+
+	* Improved translator for symbol versioning sections.
+	* The W32 library is now built in the `lib' subdirectory.
+	* Windows DLLs should work now.
+
+Changes since 0.8.6:
+
+	* added elf_getphnum().
+	* added elf_getshnum().
+	* added elf_getshstrndx().
+	* added elfx_update_shstrndx().
+	* handle interrupted reads/writes more gracefully.
+	* added (partial) support for unusual e_[ps]hentsize values.
+	* fixed the bugs introduced in 0.8.7.
+
+Changes since 0.8.5:
+
+	* added W32 support.
+	* added workaround for alignment errors in archive members.
+	* my email address has changed again ;)
+
+Changes since 0.8.4:
+
+	* elf_strptr() should now work more safely with fragmented
+	  or badly formatted string tables.
+
+Changes since 0.8.3:
+
+	* Fixed a bug in elf_update() that was introduced in 0.8.3.
+
+Changes since 0.8.2:
+
+	* Should compile on MacOSX now.
+
+	* Can read and write files with more than 65280 sections
+
+	* Tries to handle 64-bit ELF files that use 8-byte hash table
+	  entries. In particular, libelf tries to guess the data type in
+	  elf_getdata(), and doesn't override sh_entsize in elf_update()
+	  any longer. If you want the library to pick the entry size,
+	  you must set its value to 0 before you call elf_update().
+
+	* No longer dumps core in elf_update() when a versioning section
+	  has no data. Instead, it returns an error message. Note that
+	  you're supposed to provide a valid d_buf for any section, unless
+	  it's empty or has SHT_NOBITS type.
+
+	* Building a shared library is now the default (if supported).
+
+Changes since 0.8.0:
+
+	* Corrected typo in lib/{32,64}.xlatetof.c that sometimes
+	  caused a compilation failure.
+
+	* Use open(name, O_RDONLY|O_BINARY) in lib/nlist.c.
+
+Changes since 0.7.0:
+
+	* I implemented the gelf_* interface, as found on Solaris.
+	  I don't know whether it's compatible -- the Solaris manpage
+	  isn't very specific, so I had to guess return values etc. in
+	  some cases.
+
+	* Added elf{32,64}_checksum (supposed to be compatible with
+	  Solaris).
+
+	* Added symbol versioning support.
+
+Changes since 0.6.4:
+
+	* Fixed configure for IRIX systems
+	* Added check for truncated archive members
+	* Added check for misaligned SHDR/PHDR tables
+	* Support for building libelf together with GNU libc
+	* Added elf_memory(3)
+	* Added 64-bit support
+
+Changes since 0.5.2:
+
+	* some bug fixes
+	* mmap support
+	* new directory layout
+	* There is a new function, elf_delscn(), that deletes
+	  a section from an ELF file. It also adjusts the
+	  sh_link and sh_info members in the section header
+	  table, if (and ONLY if) the ELF standard indicates
+	  that these values are section indices. References
+	  to the deleted section will be cleared, so be careful.
+	* my email address has changed ;)
+
+Where to get libelf:
+
+	ftp://ftp.ibiblio.org/pub/Linux/libs/
+	http://www.mr511.de/software/
+
+Michael "Tired" Riepe
+<libelf@mr511.de>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/VERSION	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1 @@
+0.8.10
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/acconfig.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,89 @@
+/*
+ * acconfig.h - Special definitions for libelf, processed by autoheader.
+ * Copyright (C) 1995 - 2001, 2004, 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* @(#) $Id: acconfig.h,v 1.15 2007/09/07 12:07:59 michael Exp $ */
+
+/* Define if you want to include extra debugging code */
+#undef ENABLE_DEBUG
+
+/* Define if you want to support extended ELF formats */
+#undef ENABLE_EXTENDED_FORMAT
+
+/* Define if you want ELF format sanity checks by default */
+#undef ENABLE_SANITY_CHECKS
+
+/* Define if memmove() does not copy overlapping arrays correctly */
+#undef HAVE_BROKEN_MEMMOVE
+
+/* Define if you have the catgets function. */
+#undef HAVE_CATGETS
+
+/* Define if you have the dgettext function. */
+#undef HAVE_DGETTEXT
+
+/* Define if you have the memset function.  */
+#undef HAVE_MEMSET
+
+/* Define if struct nlist is declared in <elf.h> or <sys/elf.h> */
+#undef HAVE_STRUCT_NLIST_DECLARATION
+
+/* Define if Elf32_Dyn is declared in <link.h> */
+#undef __LIBELF_NEED_LINK_H
+
+/* Define if Elf32_Dyn is declared in <sys/link.h> */
+#undef __LIBELF_NEED_SYS_LINK_H
+
+/* Define to `<elf.h>' or `<sys/elf.h>' if one of them is present */
+#undef __LIBELF_HEADER_ELF_H
+
+/* Define if you want 64-bit support (and your system supports it) */
+#undef __LIBELF64
+
+/* Define if you want 64-bit support, and are running IRIX */
+#undef __LIBELF64_IRIX
+
+/* Define if you want 64-bit support, and are running Linux */
+#undef __LIBELF64_LINUX
+
+/* Define if you want symbol versioning (and your system supports it) */
+#undef __LIBELF_SYMBOL_VERSIONS
+
+/* Define if symbol versioning uses Sun section type (SHT_SUNW_*) */
+#undef __LIBELF_SUN_SYMBOL_VERSIONS
+
+/* Define if symbol versioning uses GNU section types (SHT_GNU_*) */
+#undef __LIBELF_GNU_SYMBOL_VERSIONS
+
+/* Define to a 64-bit signed integer type if one exists */
+#undef __libelf_i64_t
+
+/* Define to a 64-bit unsigned integer type if one exists */
+#undef __libelf_u64_t
+
+/* Define to a 32-bit signed integer type if one exists */
+#undef __libelf_i32_t
+
+/* Define to a 32-bit unsigned integer type if one exists */
+#undef __libelf_u32_t
+
+/* Define to a 16-bit signed integer type if one exists */
+#undef __libelf_i16_t
+
+/* Define to a 16-bit unsigned integer type if one exists */
+#undef __libelf_u16_t
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/aclocal.m4	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,336 @@
+# aclocal.m4 - Local additions to Autoconf macros.
+# Copyright (C) 1995 - 2006 Michael Riepe
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+# @(#) $Id: aclocal.m4,v 1.27 2007/09/07 12:07:59 michael Exp $
+
+AC_PREREQ(2.13)
+
+dnl mr_PACKAGE(package-name)
+AC_DEFUN(mr_PACKAGE, [changequote(<<, >>)dnl
+  changequote([, ])dnl
+  PACKAGE=$1
+  VERSION=`cat $srcdir/VERSION`
+  AC_SUBST(PACKAGE)
+  AC_SUBST(VERSION)
+  AC_ARG_ENABLE(maintainer-mode,
+    [  --enable-maintainer-mode
+                          enable maintainer-specific make rules (default: auto)],
+    [mr_enable_maintainer_mode="$enableval"],
+    [case :${I_AM_THE_MAINTAINER_OF}: in
+      *:$1:*) mr_enable_maintainer_mode=yes;;
+      *) mr_enable_maintainer_mode=no;;
+    esac])
+  if test x"$mr_enable_maintainer_mode" = x"yes"; then
+    MAINT=
+  else
+    MAINT='maintainer-only-'
+  fi
+  AC_SUBST(MAINT)
+])
+
+AC_DEFUN(mr_ENABLE_NLS, [
+  AC_PROVIDE([$0])
+
+  # Needed for `make dist' even if NLS is disabled.
+  GMOFILES=
+  MSGFILES=
+  POFILES=
+  for mr_lang in $ALL_LINGUAS; do
+    GMOFILES="$GMOFILES $mr_lang.gmo"
+    MSGFILES="$MSGFILES $mr_lang.msg"
+    POFILES="$POFILES $mr_lang.po"
+  done
+  AC_SUBST(GMOFILES)
+  AC_SUBST(MSGFILES)
+  AC_SUBST(POFILES)
+
+  AC_MSG_CHECKING([whether NLS is requested])
+  AC_ARG_ENABLE(nls,
+    [  --enable-nls            use Native Language Support (default: yes)],
+    [mr_enable_nls="$enableval"],
+    [mr_enable_nls=yes])
+  AC_MSG_RESULT($mr_enable_nls)
+
+  CATOBJEXT=
+  INSTOBJEXT=
+  localedir=
+  if test "$mr_enable_nls" = yes; then
+    mr_PATH=`echo ":$PATH" | sed -e 's,:[^:]*openwin[^:]*,,g' -e 's,^:,,'`
+    AC_CACHE_CHECK([for dgettext],
+      mr_cv_func_dgettext, [
+	AC_TRY_LINK([#include <libintl.h>],
+	  [char *s = dgettext("", ""); return 0],
+	  [mr_cv_func_dgettext=yes],
+	  [mr_cv_func_dgettext=no])
+    ])
+    if test "$mr_cv_func_dgettext" = yes; then
+      AC_PATH_PROG(MSGFMT, msgfmt, no, $mr_PATH)
+      if test "$MSGFMT" != no; then
+	AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT, $mr_PATH)
+	AC_PATH_PROG(XGETTEXT, xgettext, xgettext, $mr_PATH)
+	AC_PATH_PROG(MSGMERGE, msgmerge, msgmerge, $mr_PATH)
+	AC_CACHE_CHECK([for GNU gettext],
+	  mr_cv_gnu_gettext, [
+	    AC_TRY_LINK([],
+	      [extern int _nl_msg_cat_cntr; return _nl_msg_cat_cntr],
+	      [mr_cv_gnu_gettext=yes],
+	      [mr_cv_gnu_gettext=no])
+	])
+	if test "$mr_cv_gnu_gettext" = yes; then
+	  AC_CACHE_CHECK([for losing catgets-based GNU gettext],
+	    mr_cv_catgets_based_gettext, [
+	      AC_TRY_LINK([],
+		[extern int _msg_tbl_length; return _msg_tbl_length],
+		[mr_cv_catgets_based_gettext=yes],
+		[mr_cv_catgets_based_gettext=no])
+	  ])
+	  if test "$mr_cv_catgets_based_gettext" = yes; then
+	    # This loses completely. Turn it off and use catgets.
+	    LIBS=`echo $LIBS | sed 's,-lintl,,g'`
+	    mr_cv_func_dgettext=no
+	  else
+	    # Is there a better test for this case?
+	    AC_CACHE_CHECK([for pure GNU gettext],
+	      mr_cv_pure_gnu_gettext, [
+		AC_TRY_LINK([],
+		  [extern int gettext(); return gettext()],
+		  [mr_cv_pure_gnu_gettext=yes],
+		  [mr_cv_pure_gnu_gettext=no])
+	    ])
+	    if test "$mr_cv_pure_gnu_gettext" = yes; then
+	      CATOBJEXT=.gmo
+	      localedir='$(prefix)/share/locale'
+	    else
+	      CATOBJEXT=.mo
+	      localedir='$(prefix)/lib/locale'
+	    fi
+	    INSTOBJEXT=.mo
+	  fi
+	else
+	  # System provided gettext
+	  CATOBJEXT=.mo
+	  INSTOBJEXT=.mo
+	  localedir='$(prefix)/lib/locale'
+	fi
+      else
+	# Gettext but no msgfmt. Try catgets.
+	mr_cv_func_dgettext=no
+      fi
+    fi
+    if test "$mr_cv_func_dgettext" = yes; then
+      AC_DEFINE(HAVE_DGETTEXT)
+    else
+      AC_CACHE_CHECK([for catgets], mr_cv_func_catgets, [
+	AC_TRY_LINK([#include <nl_types.h>],
+	  [catgets(catopen("",0),0,0,"");return 0;],
+	  [mr_cv_func_catgets=yes],
+	  [mr_cv_func_catgets=no])
+      ])
+      if test "$mr_cv_func_catgets" = yes; then
+	AC_PATH_PROG(GENCAT, gencat, no, $mr_PATH)
+	if test "$GENCAT" != no; then
+	  AC_DEFINE(HAVE_CATGETS)
+	  AC_PATH_PROG(GMSGFMT, [gmsgfmt msgfmt], msgfmt, $mr_PATH)
+	  AC_PATH_PROG(XGETTEXT, xgettext, xgettext, $mr_PATH)
+	  CATOBJEXT=.cat
+	  INSTOBJEXT=.cat
+	  localedir='$(prefix)/lib/locale'
+	fi
+      else
+	AC_MSG_WARN([no NLS support, disabled])
+	mr_enable_nls=no
+      fi
+    fi
+  fi
+  AC_SUBST(CATOBJEXT)
+  AC_SUBST(INSTOBJEXT)
+  AC_SUBST(localedir)
+
+  POSUB=
+  CATALOGS=
+  if test "$mr_enable_nls" = yes; then
+    AC_MSG_CHECKING([for catalogs to be installed])
+    mr_linguas=
+    for mr_lang in ${LINGUAS=$ALL_LINGUAS}; do
+      case " $ALL_LINGUAS " in
+	*" $mr_lang "*)
+	  mr_linguas="$mr_linguas$mr_lang "
+	  CATALOGS="$CATALOGS $mr_lang$CATOBJEXT"
+	  ;;
+      esac
+    done
+    AC_MSG_RESULT($mr_linguas)
+    POSUB=po
+  fi
+  AC_SUBST(CATALOGS)
+  AC_SUBST(POSUB)
+])
+
+AC_DEFUN(mr_TARGET_ELF, [
+  AC_PROVIDE([$0])
+  AC_CACHE_CHECK([for native ELF system],
+    mr_cv_target_elf,
+    [AC_TRY_RUN(changequote(<<, >>)dnl
+<<#include <stdio.h>
+int
+main(int argc, char **argv) {
+  char buf[BUFSIZ];
+  FILE *fp;
+  int n;
+
+  if ((fp = fopen(*argv, "r")) == NULL) {
+    exit(1);
+  }
+  n = fread(buf, 1, sizeof(buf), fp);
+  if (n >= 52
+   && buf[0] == '\177'
+   && buf[1] == 'E'
+   && buf[2] == 'L'
+   && buf[3] == 'F') {
+    exit(0);
+  }
+  exit(1);
+}>>, changequote([, ])dnl
+      mr_cv_target_elf=yes,
+      mr_cv_target_elf=no,
+      mr_cv_target_elf=no)])])
+
+AC_DEFUN(mr_ENABLE_SHARED, [
+  AC_PROVIDE([$0])
+  PICFLAGS=
+  SHLIB_SFX=
+  SHLINK_SFX=
+  SONAME_SFX=
+  LINK_SHLIB=
+  INSTALL_SHLIB=
+  DEPSHLIBS=
+  AC_MSG_CHECKING([whether to build a shared library])
+  AC_ARG_ENABLE(shared,
+    [  --enable-shared         build shared library (default: yes)],
+    [mr_enable_shared="$enableval"],
+    [mr_enable_shared=yes])
+  AC_MSG_RESULT($mr_enable_shared)
+  if test "$mr_enable_shared" = yes; then
+    AC_MSG_CHECKING([whether GNU naming conventions are requested])
+    AC_ARG_ENABLE(gnu-names,
+      [  --enable-gnu-names      use GNU library naming conventions (default: no)],
+      [mr_enable_gnu_names="$enableval"],
+      [mr_enable_gnu_names=no])
+    AC_MSG_RESULT($mr_enable_gnu_names)
+    AC_REQUIRE([AC_CANONICAL_HOST])
+    AC_REQUIRE([AC_PROG_CC])
+    AC_PATH_PROG(LD, ld, ld)
+    case "$host" in
+      *-linux*|*-gnu*)
+	if test "$GCC" = yes; then
+	  mr_TARGET_ELF
+	  if test "$mr_cv_target_elf" = yes; then
+	    PICFLAGS='-fPIC -DPIC'
+	    if test "$mr_enable_gnu_names" = yes
+	    then SHLIB_SFX='-$(VERSION).so'
+	    else SHLIB_SFX='.so.$(VERSION)'
+	    fi
+	    SHLINK_SFX='.so'
+	    SONAME_SFX='.so.$(MAJOR)'
+	    LINK_SHLIB='$(CC) -shared -Wl,-soname,$(SONAME)'
+	    INSTALL_SHLIB='$(INSTALL_PROGRAM)'
+	    DEPSHLIBS='-lc'
+	  else
+	    AC_MSG_WARN([shared libraries not supported for $host])
+	    mr_enable_shared=no
+	  fi
+	elif ${CC} -V 2>&1 | grep 'Intel(R) C++ Compiler' >/dev/null 2>&1; then
+	  AC_MSG_WARN([Use --disable-shared if $CC fails to build the shared library])
+	  PICFLAGS='-fPIC -DPIC'
+	  if test "$mr_enable_gnu_names" = yes
+	  then SHLIB_SFX='-$(VERSION).so'
+	  else SHLIB_SFX='.so.$(VERSION)'
+	  fi
+	  SHLINK_SFX='.so'
+	  SONAME_SFX='.so.$(MAJOR)'
+	  LINK_SHLIB='$(CC) -shared -Wl,-soname,$(SONAME)'
+	  INSTALL_SHLIB='$(INSTALL_PROGRAM)'
+	  DEPSHLIBS='-lc'
+	else
+	  AC_MSG_WARN([GNU CC required for building shared libraries])
+	  mr_enable_shared=no
+	fi
+	;;
+      i386-pc-nto-qnx*)
+	mr_TARGET_ELF
+	if test "$mr_cv_target_elf" = yes; then
+	  PICFLAGS='-fPIC -DPIC'
+	  if test "$mr_enable_gnu_names" = yes
+	  then SHLIB_SFX='-$(VERSION).so'
+	  else SHLIB_SFX='.so.$(VERSION)'
+	  fi
+	  SHLINK_SFX='.so'
+	  SONAME_SFX='.so.$(MAJOR)'
+	  LINK_SHLIB='$(CC) -shared -Wl,-soname,$(SONAME)'
+	  INSTALL_SHLIB='$(INSTALL_PROGRAM)'
+	  DEPSHLIBS='-lc'
+	else
+	  AC_MSG_WARN([shared libraries not supported for $host])
+	  mr_enable_shared=no
+	fi
+	;;
+      sparc-sun-solaris2*)
+	if test "$GCC" = yes; then
+	  PICFLAGS='-fPIC -DPIC'
+	else
+	  PICFLAGS='-K PIC -DPIC'
+	fi
+	if test "$mr_enable_gnu_names" = yes
+	then SHLIB_SFX='-$(MAJOR).so'
+	else SHLIB_SFX='.so.$(MAJOR)'
+	fi
+	SONAME_SFX='.so.$(MAJOR)'
+	SHLINK_SFX='.so'
+	LINK_SHLIB='$(LD) -G -z text -h $(SONAME)'
+	INSTALL_SHLIB='$(INSTALL_PROGRAM)'
+	;;
+      *)
+	AC_MSG_WARN([shared libraries not supported for $host])
+	mr_enable_shared=no
+	;;
+    esac
+  else
+    mr_enable_shared=no
+  fi
+  AC_SUBST(PICFLAGS)
+  AC_SUBST(SHLIB_SFX)
+  AC_SUBST(SHLINK_SFX)
+  AC_SUBST(SONAME_SFX)
+  AC_SUBST(LINK_SHLIB)
+  AC_SUBST(INSTALL_SHLIB)
+  AC_SUBST(DEPSHLIBS)
+  DO_SHLIB="$mr_enable_shared"
+  AC_SUBST(DO_SHLIB)
+])
+
+AC_DEFUN(mr_ENABLE_DEBUG, [
+  AC_PROVIDE([$0])
+  AC_ARG_ENABLE(debug,
+    [  --enable-debug          include extra debugging code (default: no)],
+    [mr_enable_debug="$enableval"],
+    [mr_enable_debug=no])
+  if test "$mr_enable_debug" = yes; then
+    AC_DEFINE(ENABLE_DEBUG)
+  fi
+])
+
+# vi: set ts=8 sw=2 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/config.guess	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1459 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2004-06-11'
+
+# This file 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit 0 ;;
+    amd64:OpenBSD:*:*)
+	echo x86_64-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    arc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    cats:OpenBSD:*:*)
+	echo arm-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    luna88k:OpenBSD:*:*)
+    	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    pmax:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mipseb-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    wgrisc:OpenBSD:*:*)
+	echo mipsel-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:OpenBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:MirBSD:*:*)
+	echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit 0 ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit 0 ;;
+    Alpha*:OpenVMS:*:*)
+	echo alpha-hp-vms
+	exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit 0 ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit 0;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit 0 ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit 0 ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit 0 ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit 0 ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit 0 ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit 0 ;;
+    DRS?6000:UNIX_SV:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7 && exit 0 ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit 0 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit 0 ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit 0 ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c \
+	  && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && exit 0
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit 0 ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit 0 ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit 0 ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit 0 ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit 0 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit 0 ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit 0 ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit 0 ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+		echo rs6000-ibm-aix3.2.5
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit 0 ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    # avoid double evaluation of $set_cc_for_build
+	    test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+	echo unknown-hitachi-hiuxwe2
+	exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit 0 ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit 0 ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit 0 ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    *:UNICOS/mp:*:*)
+	echo nv1-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:FreeBSD:*:*)
+	# Determine whether the default compiler uses glibc.
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#if __GLIBC__ >= 2
+	LIBC=gnu
+	#else
+	LIBC=
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	# GNU/KFreeBSD systems have a "k" prefix to indicate we are using
+	# FreeBSD's kernel, but not the complete OS.
+	case ${LIBC} in gnu) kernel_only='k' ;; esac
+	echo ${UNAME_MACHINE}-unknown-${kernel_only}freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`${LIBC:+-$LIBC}
+	exit 0 ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit 0 ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit 0 ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit 0 ;;
+    x86:Interix*:[34]*)
+	echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+	exit 0 ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit 0 ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit 0 ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit 0 ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit 0 ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit 0 ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit 0 ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit 0 ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit 0 ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit 0 ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit 0 ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit 0 ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit 0 ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit 0 ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit 0 ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#ifdef __INTEL_COMPILER
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit 0 ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit 0 ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit 0 ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit 0 ;;
+	i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit 0 ;;
+    i*86:*:5:[78]*)
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit 0 ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit 0 ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit 0 ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit 0 ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit 0 ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit 0 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit 0 ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit 0 ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit 0 ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit 0 ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit 0 ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit 0 ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Darwin:*:*)
+	case `uname -p` in
+	    *86) UNAME_PROCESSOR=i686 ;;
+	    powerpc) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit 0 ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit 0 ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit 0 ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit 0 ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit 0 ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit 0 ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit 0 ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit 0 ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit 0 ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit 0 ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit 0 ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit 0 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit 0 ;;
+    c34*)
+	echo c34-convex-bsd
+	exit 0 ;;
+    c38*)
+	echo c38-convex-bsd
+	exit 0 ;;
+    c4*)
+	echo c4-convex-bsd
+	exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/config.h.in	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,151 @@
+/* config.h.in.  Generated automatically from configure.in by autoheader.  */
+
+/* Define to empty if the keyword does not work.  */
+#undef const
+
+/* Define if you have a working `mmap' system call.  */
+#undef HAVE_MMAP
+
+/* Define to `long' if <sys/types.h> doesn't define.  */
+#undef off_t
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+#undef size_t
+
+/* Define if you have the ANSI C header files.  */
+#undef STDC_HEADERS
+
+/* Define if you want to include extra debugging code */
+#undef ENABLE_DEBUG
+
+/* Define if you want to support extended ELF formats */
+#undef ENABLE_EXTENDED_FORMAT
+
+/* Define if you want ELF format sanity checks by default */
+#undef ENABLE_SANITY_CHECKS
+
+/* Define if memmove() does not copy overlapping arrays correctly */
+#undef HAVE_BROKEN_MEMMOVE
+
+/* Define if you have the catgets function. */
+#undef HAVE_CATGETS
+
+/* Define if you have the dgettext function. */
+#undef HAVE_DGETTEXT
+
+/* Define if you have the memset function.  */
+#undef HAVE_MEMSET
+
+/* Define if struct nlist is declared in <elf.h> or <sys/elf.h> */
+#undef HAVE_STRUCT_NLIST_DECLARATION
+
+/* Define if Elf32_Dyn is declared in <link.h> */
+#undef __LIBELF_NEED_LINK_H
+
+/* Define if Elf32_Dyn is declared in <sys/link.h> */
+#undef __LIBELF_NEED_SYS_LINK_H
+
+/* Define to `<elf.h>' or `<sys/elf.h>' if one of them is present */
+#undef __LIBELF_HEADER_ELF_H
+
+/* Define if you want 64-bit support (and your system supports it) */
+#undef __LIBELF64
+
+/* Define if you want 64-bit support, and are running IRIX */
+#undef __LIBELF64_IRIX
+
+/* Define if you want 64-bit support, and are running Linux */
+#undef __LIBELF64_LINUX
+
+/* Define if you want symbol versioning (and your system supports it) */
+#undef __LIBELF_SYMBOL_VERSIONS
+
+/* Define if symbol versioning uses Sun section type (SHT_SUNW_*) */
+#undef __LIBELF_SUN_SYMBOL_VERSIONS
+
+/* Define if symbol versioning uses GNU section types (SHT_GNU_*) */
+#undef __LIBELF_GNU_SYMBOL_VERSIONS
+
+/* Define to a 64-bit signed integer type if one exists */
+#undef __libelf_i64_t
+
+/* Define to a 64-bit unsigned integer type if one exists */
+#undef __libelf_u64_t
+
+/* Define to a 32-bit signed integer type if one exists */
+#undef __libelf_i32_t
+
+/* Define to a 32-bit unsigned integer type if one exists */
+#undef __libelf_u32_t
+
+/* Define to a 16-bit signed integer type if one exists */
+#undef __libelf_i16_t
+
+/* Define to a 16-bit unsigned integer type if one exists */
+#undef __libelf_u16_t
+
+/* The number of bytes in a __int64.  */
+#undef SIZEOF___INT64
+
+/* The number of bytes in a int.  */
+#undef SIZEOF_INT
+
+/* The number of bytes in a long.  */
+#undef SIZEOF_LONG
+
+/* The number of bytes in a long long.  */
+#undef SIZEOF_LONG_LONG
+
+/* The number of bytes in a short.  */
+#undef SIZEOF_SHORT
+
+/* Define if you have the ftruncate function.  */
+#undef HAVE_FTRUNCATE
+
+/* Define if you have the getpagesize function.  */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the memcmp function.  */
+#undef HAVE_MEMCMP
+
+/* Define if you have the memcpy function.  */
+#undef HAVE_MEMCPY
+
+/* Define if you have the memmove function.  */
+#undef HAVE_MEMMOVE
+
+/* Define if you have the memset function.  */
+#undef HAVE_MEMSET
+
+/* Define if you have the <ar.h> header file.  */
+#undef HAVE_AR_H
+
+/* Define if you have the <elf.h> header file.  */
+#undef HAVE_ELF_H
+
+/* Define if you have the <fcntl.h> header file.  */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <gelf.h> header file.  */
+#undef HAVE_GELF_H
+
+/* Define if you have the <libelf.h> header file.  */
+#undef HAVE_LIBELF_H
+
+/* Define if you have the <link.h> header file.  */
+#undef HAVE_LINK_H
+
+/* Define if you have the <nlist.h> header file.  */
+#undef HAVE_NLIST_H
+
+/* Define if you have the <stdint.h> header file.  */
+#undef HAVE_STDINT_H
+
+/* Define if you have the <sys/elf.h> header file.  */
+#undef HAVE_SYS_ELF_H
+
+/* Define if you have the <sys/link.h> header file.  */
+#undef HAVE_SYS_LINK_H
+
+/* Define if you have the <unistd.h> header file.  */
+#undef HAVE_UNISTD_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/config.sub	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1549 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+
+timestamp='2004-03-12'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file 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; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
+  kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| m32r | m32rle | m68000 | m68k | m88k | mcore \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| msp430 \
+	| ns16k | ns32k \
+	| openrisc | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \
+	| strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xscale | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* \
+	| bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| msp430-* \
+	| none-* | np1-* | nv1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
+	| xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	cr16c)
+		basic_machine=cr16c-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	mmix*)
+		basic_machine=mmix-knuth
+		os=-mmixware
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nv1)
+		basic_machine=nv1-cray
+		os=-unicosmp
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	or32 | or32-*)
+		basic_machine=or32-unknown
+		os=-coff
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+    c4x-* | tic4x-*)
+        os=-coff
+        ;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-ibm)
+		os=-aix
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/configure	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,3910 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13 
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+  --enable-maintainer-mode
+                          enable maintainer-specific make rules (default: auto)"
+ac_help="$ac_help
+  --enable-compat         install <libelf.h>, <nlist.h> and <gelf.h> (default: auto)"
+ac_help="$ac_help
+  --enable-elf64          compile in 64-bit support (default: auto)"
+ac_help="$ac_help
+  --enable-versioning     compile in versioning support (default: auto)"
+ac_help="$ac_help
+  --enable-nls            use Native Language Support (default: yes)"
+ac_help="$ac_help
+  --enable-shared         build shared library (default: yes)"
+ac_help="$ac_help
+  --enable-gnu-names      use GNU library naming conventions (default: no)"
+ac_help="$ac_help
+  --enable-extended-format    support extended file formats (default: no)"
+ac_help="$ac_help
+  --enable-sanity-checks      enable sanity checks by default (default: yes)"
+ac_help="$ac_help
+  --enable-debug          include extra debugging code (default: no)"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  case "$ac_option" in
+  -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) ac_optarg= ;;
+  esac
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case "$ac_option" in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir="$ac_optarg" ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build="$ac_optarg" ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file="$ac_optarg" ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir="$ac_optarg" ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    eval "enable_${ac_feature}=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+    fi
+    ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix="$ac_optarg" ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he)
+    # Omit some internal or obsolete options to make the list less imposing.
+    # This message is too long to be a string in the A/UX 3.1 sh.
+    cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+  --cache-file=FILE       cache test results in FILE
+  --help                  print this message
+  --no-create             do not create output files
+  --quiet, --silent       do not print \`checking...' messages
+  --version               print the version of autoconf that created configure
+Directory and file names:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+                          [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+                          [same as prefix]
+  --bindir=DIR            user executables in DIR [EPREFIX/bin]
+  --sbindir=DIR           system admin executables in DIR [EPREFIX/sbin]
+  --libexecdir=DIR        program executables in DIR [EPREFIX/libexec]
+  --datadir=DIR           read-only architecture-independent data in DIR
+                          [PREFIX/share]
+  --sysconfdir=DIR        read-only single-machine data in DIR [PREFIX/etc]
+  --sharedstatedir=DIR    modifiable architecture-independent data in DIR
+                          [PREFIX/com]
+  --localstatedir=DIR     modifiable single-machine data in DIR [PREFIX/var]
+  --libdir=DIR            object code libraries in DIR [EPREFIX/lib]
+  --includedir=DIR        C header files in DIR [PREFIX/include]
+  --oldincludedir=DIR     C header files for non-gcc in DIR [/usr/include]
+  --infodir=DIR           info documentation in DIR [PREFIX/info]
+  --mandir=DIR            man documentation in DIR [PREFIX/man]
+  --srcdir=DIR            find the sources in DIR [configure dir or ..]
+  --program-prefix=PREFIX prepend PREFIX to installed program names
+  --program-suffix=SUFFIX append SUFFIX to installed program names
+  --program-transform-name=PROGRAM
+                          run sed PROGRAM on installed program names
+EOF
+    cat << EOF
+Host type:
+  --build=BUILD           configure for building on BUILD [BUILD=HOST]
+  --host=HOST             configure for HOST [guessed]
+  --target=TARGET         configure for TARGET [TARGET=HOST]
+Features and packages:
+  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
+  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --x-includes=DIR        X include files are in DIR
+  --x-libraries=DIR       X library files are in DIR
+EOF
+    if test -n "$ac_help"; then
+      echo "--enable and --with options recognized:$ac_help"
+    fi
+    exit 0 ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host="$ac_optarg" ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir="$ac_optarg" ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir="$ac_optarg" ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir="$ac_optarg" ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir="$ac_optarg" ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir="$ac_optarg" ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir="$ac_optarg" ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir="$ac_optarg" ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix="$ac_optarg" ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix="$ac_optarg" ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix="$ac_optarg" ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name="$ac_optarg" ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir="$ac_optarg" ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir="$ac_optarg" ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site="$ac_optarg" ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir="$ac_optarg" ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir="$ac_optarg" ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target="$ac_optarg" ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers)
+    echo "configure generated by autoconf version 2.13"
+    exit 0 ;;
+
+  -with-* | --with-*)
+    ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case "$ac_option" in
+      *=*) ;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_${ac_package}='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+    # Reject names that are not valid shell variable names.
+    if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+      { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+    fi
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    eval "with_${ac_package}=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes="$ac_optarg" ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries="$ac_optarg" ;;
+
+  -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+    ;;
+
+  *)
+    if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+      echo "configure: warning: $ac_option: invalid host type" 1>&2
+    fi
+    if test "x$nonopt" != xNONE; then
+      { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+    fi
+    nonopt="$ac_option"
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+  exec 6>/dev/null
+else
+  exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+  case "$ac_arg" in
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c) ;;
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+  *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+  ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+  *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+  esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set.  These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}"   = set; then LANG=C;   export LANG;   fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}"    = set; then LC_CTYPE=C;    export LC_CTYPE;    fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=VERSION
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_prog=$0
+  ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+  test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+  else
+    { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+  fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    echo "loading site script $ac_site_file"
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  echo "loading cache $cache_file"
+  . $cache_file
+else
+  echo "creating cache $cache_file"
+  > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+  # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+  if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+    ac_n= ac_c='
+' ac_t='	'
+  else
+    ac_n=-n ac_c= ac_t=
+  fi
+else
+  ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+
+
+
+    PACKAGE=libelf
+  VERSION=`cat $srcdir/VERSION`
+  
+  
+  # Check whether --enable-maintainer-mode or --disable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+  enableval="$enable_maintainer_mode"
+  mr_enable_maintainer_mode="$enableval"
+else
+  case :${I_AM_THE_MAINTAINER_OF}: in
+      *:libelf:*) mr_enable_maintainer_mode=yes;;
+      *) mr_enable_maintainer_mode=no;;
+    esac
+fi
+
+  if test x"$mr_enable_maintainer_mode" = x"yes"; then
+    MAINT=
+  else
+    MAINT='maintainer-only-'
+  fi
+  
+
+
+ALL_LINGUAS=`cd $srcdir/po && echo *.po | sed 's/\.po//g'`
+
+set `echo $VERSION | sed 's/\./ /g'`
+MAJOR=${1-1}
+MINOR=${2-0}
+PATCH=${3-0}
+
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:582: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftestmake <<\EOF
+all:
+	@echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+  eval ac_cv_prog_make_${ac_make}_set=yes
+else
+  eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  SET_MAKE=
+else
+  echo "$ac_t""no" 1>&6
+  SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:611: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="gcc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+  # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:641: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_prog_rejected=no
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+        ac_prog_rejected=yes
+	continue
+      fi
+      ac_cv_prog_CC="cc"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+  # We found a bogon in the path, so make sure we never use it.
+  set dummy $ac_cv_prog_CC
+  shift
+  if test $# -gt 0; then
+    # We chose a different compiler from the bogus one.
+    # However, it has the same basename, so the bogon will be chosen
+    # first if we set CC to just the basename; use the full file name.
+    shift
+    set dummy "$ac_dir/$ac_word" "$@"
+    shift
+    ac_cv_prog_CC="$@"
+  fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+  if test -z "$CC"; then
+    case "`uname -s`" in
+    *win32* | *WIN32*)
+      # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:692: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$CC"; then
+  ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_CC="cl"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+  echo "$ac_t""$CC" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+ ;;
+    esac
+  fi
+  test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:724: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 735 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:740: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  ac_cv_prog_cc_works=yes
+  # If we can't run a trivial program, we are probably using a cross compiler.
+  if (./conftest; exit) 2>/dev/null; then
+    ac_cv_prog_cc_cross=no
+  else
+    ac_cv_prog_cc_cross=yes
+  fi
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+  { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:766: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:771: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.c <<EOF
+#ifdef __GNUC__
+  yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:780: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+  ac_cv_prog_gcc=yes
+else
+  ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+  GCC=yes
+else
+  GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:799: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+  ac_cv_prog_cc_g=yes
+else
+  ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+  CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+  if test "$GCC" = yes; then
+    CFLAGS="-g -O2"
+  else
+    CFLAGS="-g"
+  fi
+else
+  if test "$GCC" = yes; then
+    CFLAGS="-O2"
+  else
+    CFLAGS=
+  fi
+fi
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:831: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+  CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    # This must be in double quotes, not single quotes, because CPP may get
+  # substituted into the Makefile and "${CC-cc}" will confuse make.
+  CPP="${CC-cc} -E"
+  # On the NeXT, cc -E runs the code through the compiler's parser,
+  # not just through cpp.
+  cat > conftest.$ac_ext <<EOF
+#line 846 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:852: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -E -traditional-cpp"
+  cat > conftest.$ac_ext <<EOF
+#line 863 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:869: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP="${CC-cc} -nologo -E"
+  cat > conftest.$ac_ext <<EOF
+#line 880 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:886: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  :
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+  ac_cv_prog_CPP="$CPP"
+fi
+  CPP="$ac_cv_prog_CPP"
+else
+  ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+  if test -f $ac_dir/install-sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f $ac_dir/install.sh; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  fi
+done
+if test -z "$ac_aux_dir"; then
+  { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program.  We prefer a C program (faster),
+# so one script is as good as another.  But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:941: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+    IFS="${IFS= 	}"; ac_save_IFS="$IFS"; IFS=":"
+  for ac_dir in $PATH; do
+    # Account for people who put trailing slashes in PATH elements.
+    case "$ac_dir/" in
+    /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+    *)
+      # OSF1 and SCO ODT 3.0 have their own names for install.
+      # Don't use installbsd from OSF since it installs stuff as root
+      # by default.
+      for ac_prog in ginstall scoinst install; do
+        if test -f $ac_dir/$ac_prog; then
+	  if test $ac_prog = install &&
+            grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+	    # AIX install.  It has an incompatible calling convention.
+	    :
+	  else
+	    ac_cv_path_install="$ac_dir/$ac_prog -c"
+	    break 2
+	  fi
+	fi
+      done
+      ;;
+    esac
+  done
+  IFS="$ac_save_IFS"
+
+fi
+  if test "${ac_cv_path_install+set}" = set; then
+    INSTALL="$ac_cv_path_install"
+  else
+    # As a last resort, use the slow shell script.  We don't cache a
+    # path for INSTALL within a source directory, because that will
+    # break other packages using the cache if that directory is
+    # removed, or if the path is relative.
+    INSTALL="$ac_install_sh"
+  fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:996: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_prog_RANLIB="ranlib"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+  echo "$ac_t""$RANLIB" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:1024: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+  rm -f conftestdata
+  ac_cv_prog_LN_S="ln -s"
+else
+  ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+  echo "$ac_t""yes" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1047: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1052 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1060: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  ac_cv_header_stdc=yes
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+  # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1077 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "memchr" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1095 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "free" >/dev/null 2>&1; then
+  :
+else
+  rm -rf conftest*
+  ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+  # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+  :
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1116 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1127: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  :
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+  cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+for ac_hdr in unistd.h stdint.h fcntl.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1154: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1159 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1164: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_hdr in elf.h sys/elf.h link.h sys/link.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1194: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1199 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1204: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking if ${CC} can compile elf.h""... $ac_c" 1>&6
+echo "configure:1231: checking if ${CC} can compile elf.h" >&5
+if eval "test \"`echo '$''{'libelf_cv_elf_h_works'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+  cat > conftest.$ac_ext <<EOF
+#line 1237 "configure"
+#include "confdefs.h"
+#if HAVE_ELF_H
+    #include <elf.h>
+    #elif HAVE_SYS_ELF_H
+    #include <sys/elf.h>
+    #endif
+int main() {
+Elf32_Ehdr dummy
+; return 0; }
+EOF
+if { (eval echo configure:1248: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  libelf_cv_elf_h_works=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  libelf_cv_elf_h_works=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$libelf_cv_elf_h_works" 1>&6
+if test "$libelf_cv_elf_h_works" = no; then
+  ac_cv_header_elf_h=no
+  ac_cv_header_sys_elf_h=no
+fi
+if test "$ac_cv_header_elf_h" = yes; then
+  cat >> confdefs.h <<\EOF
+#define __LIBELF_HEADER_ELF_H <elf.h>
+EOF
+
+elif test "$ac_cv_header_sys_elf_h" = yes; then
+  cat >> confdefs.h <<\EOF
+#define __LIBELF_HEADER_ELF_H <sys/elf.h>
+EOF
+
+fi
+
+for ac_hdr in ar.h libelf.h nlist.h gelf.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1282: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1287 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1292: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking whether to install <libelf.h>, <nlist.h> and <gelf.h>""... $ac_c" 1>&6
+echo "configure:1319: checking whether to install <libelf.h>, <nlist.h> and <gelf.h>" >&5
+# Check whether --enable-compat or --disable-compat was given.
+if test "${enable_compat+set}" = set; then
+  enableval="$enable_compat"
+  DO_COMPAT="$enableval"
+else
+  if test "$ac_cv_header_libelf_h$ac_cv_header_nlist_h$ac_cv_header_gelf_h" = yesyesyes
+  then DO_COMPAT=no
+  else DO_COMPAT=yes
+  fi
+fi
+
+echo "$ac_t""$DO_COMPAT" 1>&6
+
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1335: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1340 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this.  */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this.  */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this.  */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+   It does not let you subtract one const X* pointer from another in an arm
+   of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this.  */
+  char *t;
+  char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+  *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this.  */
+  int x[] = {25, 17};
+  const int *foo = &x[0];
+  ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+  typedef const int *iptr;
+  iptr p = 0;
+  ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+     "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+  struct s { int j; const int *ap[3]; };
+  struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+  const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:1389: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  ac_cv_c_const=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+  cat >> confdefs.h <<\EOF
+#define const 
+EOF
+
+fi
+
+echo $ac_n "checking for off_t""... $ac_c" 1>&6
+echo "configure:1410: checking for off_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1415 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_off_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_off_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_off_t" 1>&6
+if test $ac_cv_type_off_t = no; then
+  cat >> confdefs.h <<\EOF
+#define off_t long
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:1443: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1448 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+  rm -rf conftest*
+  ac_cv_type_size_t=yes
+else
+  rm -rf conftest*
+  ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+  cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+
+echo $ac_n "checking size of short""... $ac_c" 1>&6
+echo "configure:1477: checking size of short" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_sizeof_short=2
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1485 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(short));
+  exit(0);
+}
+EOF
+if { (eval echo configure:1496: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_short=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_short=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_short" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_SHORT $ac_cv_sizeof_short
+EOF
+
+
+echo $ac_n "checking size of int""... $ac_c" 1>&6
+echo "configure:1516: checking size of int" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_sizeof_int=4
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1524 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(int));
+  exit(0);
+}
+EOF
+if { (eval echo configure:1535: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_int=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_int=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_int" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+EOF
+
+
+echo $ac_n "checking size of long""... $ac_c" 1>&6
+echo "configure:1555: checking size of long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_sizeof_long=4
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1563 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(long));
+  exit(0);
+}
+EOF
+if { (eval echo configure:1574: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_long=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_LONG $ac_cv_sizeof_long
+EOF
+
+
+echo $ac_n "checking size of long long""... $ac_c" 1>&6
+echo "configure:1594: checking size of long long" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_sizeof_long_long=0
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1602 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(long long));
+  exit(0);
+}
+EOF
+if { (eval echo configure:1613: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_long_long=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_long_long=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_long_long" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long
+EOF
+
+
+# Windows port
+echo $ac_n "checking size of __int64""... $ac_c" 1>&6
+echo "configure:1634: checking size of __int64" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof___int64'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_sizeof___int64=0
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1642 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(__int64));
+  exit(0);
+}
+EOF
+if { (eval echo configure:1653: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof___int64=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof___int64=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof___int64" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF___INT64 $ac_cv_sizeof___int64
+EOF
+
+
+
+if test "$ac_cv_header_elf_h" = yes \
+|| test "$ac_cv_header_sys_elf_h" = yes; then
+
+  # Slowaris declares Elf32_Dyn in <link.h>.
+  # QNX declares Elf32_Dyn in <sys/link.h>.
+  echo $ac_n "checking for struct Elf32_Dyn""... $ac_c" 1>&6
+echo "configure:1679: checking for struct Elf32_Dyn" >&5
+if eval "test \"`echo '$''{'libelf_cv_struct_elf32_dyn'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+    cat > conftest.$ac_ext <<EOF
+#line 1685 "configure"
+#include "confdefs.h"
+#include __LIBELF_HEADER_ELF_H
+int main() {
+Elf32_Dyn x
+; return 0; }
+EOF
+if { (eval echo configure:1692: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  libelf_cv_struct_elf32_dyn=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cat > conftest.$ac_ext <<EOF
+#line 1700 "configure"
+#include "confdefs.h"
+#include <link.h>
+int main() {
+Elf32_Dyn x
+; return 0; }
+EOF
+if { (eval echo configure:1707: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  libelf_cv_struct_elf32_dyn=link.h
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cat > conftest.$ac_ext <<EOF
+#line 1715 "configure"
+#include "confdefs.h"
+#include <sys/link.h>
+int main() {
+Elf32_Dyn x
+; return 0; }
+EOF
+if { (eval echo configure:1722: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  libelf_cv_struct_elf32_dyn=sys/link.h
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  libelf_cv_struct_elf32_dyn=no
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$libelf_cv_struct_elf32_dyn" 1>&6
+  if test "$libelf_cv_struct_elf32_dyn" = link.h; then
+    cat >> confdefs.h <<\EOF
+#define __LIBELF_NEED_LINK_H 1
+EOF
+
+  elif test "$libelf_cv_struct_elf32_dyn" = sys/link.h; then
+    cat >> confdefs.h <<\EOF
+#define __LIBELF_NEED_SYS_LINK_H 1
+EOF
+
+  elif test "$libelf_cv_struct_elf32_dyn" = no; then
+    { echo "configure: error: no declaration for Elf32_Dyn" 1>&2; exit 1; }
+  fi
+
+  # Linux declares struct nlist in <elf.h>.
+  echo $ac_n "checking for struct nlist in elf.h""... $ac_c" 1>&6
+echo "configure:1755: checking for struct nlist in elf.h" >&5
+if eval "test \"`echo '$''{'libelf_cv_struct_nlist'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+    cat > conftest.$ac_ext <<EOF
+#line 1761 "configure"
+#include "confdefs.h"
+#include __LIBELF_HEADER_ELF_H
+int main() {
+struct nlist nl
+; return 0; }
+EOF
+if { (eval echo configure:1768: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  libelf_cv_struct_nlist=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  libelf_cv_struct_nlist=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$libelf_cv_struct_nlist" 1>&6
+  if test "$libelf_cv_struct_nlist" = yes; then
+    cat >> confdefs.h <<\EOF
+#define HAVE_STRUCT_NLIST_DECLARATION 1
+EOF
+
+  fi
+
+  # Check for 64-bit data types.
+  echo $ac_n "checking for struct Elf64_Ehdr""... $ac_c" 1>&6
+echo "configure:1790: checking for struct Elf64_Ehdr" >&5
+if eval "test \"`echo '$''{'libelf_cv_struct_elf64_ehdr'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1795 "configure"
+#include "confdefs.h"
+#include __LIBELF_HEADER_ELF_H
+int main() {
+Elf64_Ehdr x
+; return 0; }
+EOF
+if { (eval echo configure:1802: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  libelf_cv_struct_elf64_ehdr=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  libelf_cv_struct_elf64_ehdr=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$libelf_cv_struct_elf64_ehdr" 1>&6
+
+  # Linux lacks typedefs for scalar ELF64_* types.
+  echo $ac_n "checking for Elf64_Addr""... $ac_c" 1>&6
+echo "configure:1818: checking for Elf64_Addr" >&5
+if eval "test \"`echo '$''{'libelf_cv_type_elf64_addr'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1823 "configure"
+#include "confdefs.h"
+#include __LIBELF_HEADER_ELF_H
+int main() {
+Elf64_Addr x
+; return 0; }
+EOF
+if { (eval echo configure:1830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  libelf_cv_type_elf64_addr=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  libelf_cv_type_elf64_addr=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$libelf_cv_type_elf64_addr" 1>&6
+
+  # IRIX' struct Elf64_Rel is slightly different. Ugh.
+  echo $ac_n "checking for struct Elf64_Rel""... $ac_c" 1>&6
+echo "configure:1846: checking for struct Elf64_Rel" >&5
+if eval "test \"`echo '$''{'libelf_cv_struct_elf64_rel'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1851 "configure"
+#include "confdefs.h"
+#include __LIBELF_HEADER_ELF_H
+int main() {
+Elf64_Rel x; x.r_info = 1
+; return 0; }
+EOF
+if { (eval echo configure:1858: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  libelf_cv_struct_elf64_rel=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  cat > conftest.$ac_ext <<EOF
+#line 1866 "configure"
+#include "confdefs.h"
+#include __LIBELF_HEADER_ELF_H
+int main() {
+Elf64_Rel x; x.r_sym = 1
+; return 0; }
+EOF
+if { (eval echo configure:1873: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  libelf_cv_struct_elf64_rel=irix
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  libelf_cv_struct_elf64_rel=no
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$libelf_cv_struct_elf64_rel" 1>&6
+
+  case "$libelf_cv_struct_elf64_ehdr:\
+$libelf_cv_type_elf64_addr:\
+$libelf_cv_struct_elf64_rel" in
+    yes:yes:yes)
+      libelf_64bit=yes;;
+    yes:yes:irix)
+      cat >> confdefs.h <<\EOF
+#define __LIBELF64_IRIX 1
+EOF
+
+      libelf_64bit=yes;;
+    yes:no:yes)
+      cat >> confdefs.h <<\EOF
+#define __LIBELF64_LINUX 1
+EOF
+
+      libelf_64bit=yes;;
+    *)
+      libelf_64bit=no;;
+  esac
+
+  # Check for symbol versioning definitions
+  echo $ac_n "checking for Elf32_Verdef""... $ac_c" 1>&6
+echo "configure:1912: checking for Elf32_Verdef" >&5
+if eval "test \"`echo '$''{'libelf_cv_verdef32'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1917 "configure"
+#include "confdefs.h"
+#include __LIBELF_HEADER_ELF_H
+      #if __LIBELF_NEED_LINK_H
+      #include <link.h>	/* Solaris wants this */
+      #endif
+int main() {
+struct {
+	Elf32_Verdef vd;
+	Elf32_Verdaux vda;
+	Elf32_Verneed vn;
+	Elf32_Vernaux vna;
+      } x
+; return 0; }
+EOF
+if { (eval echo configure:1932: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  libelf_cv_verdef32=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  libelf_cv_verdef32=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$libelf_cv_verdef32" 1>&6
+
+  echo $ac_n "checking for Elf64_Verdef""... $ac_c" 1>&6
+echo "configure:1947: checking for Elf64_Verdef" >&5
+if eval "test \"`echo '$''{'libelf_cv_verdef64'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1952 "configure"
+#include "confdefs.h"
+#include __LIBELF_HEADER_ELF_H
+      #if __LIBELF_NEED_LINK_H
+      #include <link.h>	/* Solaris wants this */
+      #endif
+int main() {
+struct {
+	Elf64_Verdef vd;
+	Elf64_Verdaux vda;
+	Elf64_Verneed vn;
+	Elf64_Vernaux vna;
+      } x
+; return 0; }
+EOF
+if { (eval echo configure:1967: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  libelf_cv_verdef64=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  libelf_cv_verdef64=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$libelf_cv_verdef64" 1>&6
+
+  echo $ac_n "checking for SHT_SUNW_verdef""... $ac_c" 1>&6
+echo "configure:1982: checking for SHT_SUNW_verdef" >&5
+if eval "test \"`echo '$''{'libelf_cv_sun_verdef'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 1987 "configure"
+#include "confdefs.h"
+#include __LIBELF_HEADER_ELF_H
+int main() {
+Elf32_Word x = SHT_SUNW_verdef + SHT_SUNW_verneed + SHT_SUNW_versym
+; return 0; }
+EOF
+if { (eval echo configure:1994: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  libelf_cv_sun_verdef=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  libelf_cv_sun_verdef=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$libelf_cv_sun_verdef" 1>&6
+
+  echo $ac_n "checking for SHT_GNU_verdef""... $ac_c" 1>&6
+echo "configure:2009: checking for SHT_GNU_verdef" >&5
+if eval "test \"`echo '$''{'libelf_cv_gnu_verdef'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2014 "configure"
+#include "confdefs.h"
+#include __LIBELF_HEADER_ELF_H
+int main() {
+Elf32_Word x = SHT_GNU_verdef + SHT_GNU_verneed + SHT_GNU_versym
+; return 0; }
+EOF
+if { (eval echo configure:2021: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+  rm -rf conftest*
+  libelf_cv_gnu_verdef=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  libelf_cv_gnu_verdef=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$libelf_cv_gnu_verdef" 1>&6
+else
+  # lib/elf_repl.h supports 64-bit
+  libelf_64bit=yes
+
+  # lib/elf_repl.h supports symbol versioning
+  libelf_cv_verdef32=yes
+  libelf_cv_verdef64=yes
+  libelf_cv_sun_verdef=yes
+  libelf_cv_gnu_verdef=yes
+fi
+
+echo $ac_n "checking for 64-bit integer""... $ac_c" 1>&6
+echo "configure:2046: checking for 64-bit integer" >&5
+if eval "test \"`echo '$''{'libelf_cv_int64'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+  if test "$ac_cv_sizeof_long" = 8; then
+    libelf_cv_int64='long'
+  elif test "$ac_cv_sizeof___int64" = 8; then
+    libelf_cv_int64='__int64'
+  elif test "$ac_cv_sizeof_long_long" = 8; then
+    libelf_cv_int64='long long'
+  else
+    libelf_cv_int64=no
+  fi
+fi
+
+echo "$ac_t""$libelf_cv_int64" 1>&6
+if test "$libelf_cv_int64" = no; then
+  libelf_64bit=no
+else
+  cat >> confdefs.h <<EOF
+#define __libelf_i64_t $libelf_cv_int64
+EOF
+
+  cat >> confdefs.h <<EOF
+#define __libelf_u64_t unsigned $libelf_cv_int64
+EOF
+
+fi
+
+echo $ac_n "checking for 32-bit integer""... $ac_c" 1>&6
+echo "configure:2077: checking for 32-bit integer" >&5
+if eval "test \"`echo '$''{'libelf_cv_int32'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+  if test "$ac_cv_sizeof_int" = 4; then
+    libelf_cv_int32='int'
+  elif test "$ac_cv_sizeof_long" = 4; then
+    libelf_cv_int32='long'
+  else
+    libelf_cv_int32=no
+  fi
+fi
+
+echo "$ac_t""$libelf_cv_int32" 1>&6
+if test "$libelf_cv_int32" = no; then
+  { echo "configure: error: neither int nor long is 32-bit" 1>&2; exit 1; }
+else
+  cat >> confdefs.h <<EOF
+#define __libelf_i32_t $libelf_cv_int32
+EOF
+
+  cat >> confdefs.h <<EOF
+#define __libelf_u32_t unsigned $libelf_cv_int32
+EOF
+
+fi
+
+echo $ac_n "checking for 16-bit integer""... $ac_c" 1>&6
+echo "configure:2106: checking for 16-bit integer" >&5
+if eval "test \"`echo '$''{'libelf_cv_int16'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+  if test "$ac_cv_sizeof_short" = 2; then
+    libelf_cv_int16='short'
+  elif test "$ac_cv_sizeof_int" = 2; then
+    libelf_cv_int16='int'
+  else
+    libelf_cv_int16=no
+  fi
+fi
+
+echo "$ac_t""$libelf_cv_int16" 1>&6
+if test "$libelf_cv_int16" = no; then
+  { echo "configure: error: neither short nor int is 16-bit" 1>&2; exit 1; }
+else
+  cat >> confdefs.h <<EOF
+#define __libelf_i16_t $libelf_cv_int16
+EOF
+
+  cat >> confdefs.h <<EOF
+#define __libelf_u16_t unsigned $libelf_cv_int16
+EOF
+
+fi
+
+for ac_hdr in unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2138: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2143 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2148: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=yes"
+else
+  echo "$ac_err" >&5
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in getpagesize
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2177: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2182 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2205: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+echo $ac_n "checking for working mmap""... $ac_c" 1>&6
+echo "configure:2230: checking for working mmap" >&5
+if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  ac_cv_func_mmap_fixed_mapped=no
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2238 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Haertel and Jim Avera for this test.
+   Here is a matrix of mmap possibilities:
+	mmap private not fixed
+	mmap private fixed at somewhere currently unmapped
+	mmap private fixed at somewhere already mapped
+	mmap shared not fixed
+	mmap shared fixed at somewhere currently unmapped
+	mmap shared fixed at somewhere already mapped
+   For private mappings, we should verify that changes cannot be read()
+   back from the file, nor mmap's back from the file at a different
+   address.  (There have been systems where private was not correctly
+   implemented like the infamous i386 svr4.0, and systems where the
+   VM page cache was not coherent with the filesystem buffer cache
+   like early versions of FreeBSD and possibly contemporary NetBSD.)
+   For shared mappings, we should conversely verify that changes get
+   propogated back to all the places they're supposed to be.
+
+   Grep wants private fixed already mapped.
+   The main things grep needs to know about mmap are:
+   * does it exist and is it safe to write into the mmap'd area
+   * how to use it (BSD variants)  */
+#include <sys/types.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+
+/* This mess was copied from the GNU getpagesize.h.  */
+#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+# endif
+
+/* Assume that all systems that can run configure have sys/param.h.  */
+# ifndef HAVE_SYS_PARAM_H
+#  define HAVE_SYS_PARAM_H 1
+# endif
+
+# ifdef _SC_PAGESIZE
+#  define getpagesize() sysconf(_SC_PAGESIZE)
+# else /* no _SC_PAGESIZE */
+#  ifdef HAVE_SYS_PARAM_H
+#   include <sys/param.h>
+#   ifdef EXEC_PAGESIZE
+#    define getpagesize() EXEC_PAGESIZE
+#   else /* no EXEC_PAGESIZE */
+#    ifdef NBPG
+#     define getpagesize() NBPG * CLSIZE
+#     ifndef CLSIZE
+#      define CLSIZE 1
+#     endif /* no CLSIZE */
+#    else /* no NBPG */
+#     ifdef NBPC
+#      define getpagesize() NBPC
+#     else /* no NBPC */
+#      ifdef PAGESIZE
+#       define getpagesize() PAGESIZE
+#      endif /* PAGESIZE */
+#     endif /* no NBPC */
+#    endif /* no NBPG */
+#   endif /* no EXEC_PAGESIZE */
+#  else /* no HAVE_SYS_PARAM_H */
+#   define getpagesize() 8192	/* punt totally */
+#  endif /* no HAVE_SYS_PARAM_H */
+# endif /* no _SC_PAGESIZE */
+
+#endif /* no HAVE_GETPAGESIZE */
+
+#ifdef __cplusplus
+extern "C" { void *malloc(unsigned); }
+#else
+char *malloc();
+#endif
+
+int
+main()
+{
+	char *data, *data2, *data3;
+	int i, pagesize;
+	int fd;
+
+	pagesize = getpagesize();
+
+	/*
+	 * First, make a file with some known garbage in it.
+	 */
+	data = malloc(pagesize);
+	if (!data)
+		exit(1);
+	for (i = 0; i < pagesize; ++i)
+		*(data + i) = rand();
+	umask(0);
+	fd = creat("conftestmmap", 0600);
+	if (fd < 0)
+		exit(1);
+	if (write(fd, data, pagesize) != pagesize)
+		exit(1);
+	close(fd);
+
+	/*
+	 * Next, try to mmap the file at a fixed address which
+	 * already has something else allocated at it.  If we can,
+	 * also make sure that we see the same garbage.
+	 */
+	fd = open("conftestmmap", O_RDWR);
+	if (fd < 0)
+		exit(1);
+	data2 = malloc(2 * pagesize);
+	if (!data2)
+		exit(1);
+	data2 += (pagesize - ((int) data2 & (pagesize - 1))) & (pagesize - 1);
+	if (data2 != mmap(data2, pagesize, PROT_READ | PROT_WRITE,
+	    MAP_PRIVATE | MAP_FIXED, fd, 0L))
+		exit(1);
+	for (i = 0; i < pagesize; ++i)
+		if (*(data + i) != *(data2 + i))
+			exit(1);
+
+	/*
+	 * Finally, make sure that changes to the mapped area
+	 * do not percolate back to the file as seen by read().
+	 * (This is a bug on some variants of i386 svr4.0.)
+	 */
+	for (i = 0; i < pagesize; ++i)
+		*(data2 + i) = *(data2 + i) + 1;
+	data3 = malloc(pagesize);
+	if (!data3)
+		exit(1);
+	if (read(fd, data3, pagesize) != pagesize)
+		exit(1);
+	for (i = 0; i < pagesize; ++i)
+		if (*(data + i) != *(data3 + i))
+			exit(1);
+	close(fd);
+	unlink("conftestmmap");
+	exit(0);
+}
+
+EOF
+if { (eval echo configure:2378: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_func_mmap_fixed_mapped=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_func_mmap_fixed_mapped=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_mmap_fixed_mapped" 1>&6
+if test $ac_cv_func_mmap_fixed_mapped = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_MMAP 1
+EOF
+
+fi
+
+for ac_func in ftruncate memcmp memcpy memmove
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2403: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2408 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2431: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+fi
+done
+
+for ac_func in memset
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2458: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2463 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func(); below.  */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2486: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+    ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+  cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+ 
+else
+  echo "$ac_t""no" 1>&6
+LIBOBJS="$LIBOBJS ${ac_func}.${ac_objext}"
+fi
+done
+
+
+if test "$ac_cv_func_memset" = yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_MEMSET 1
+EOF
+
+fi
+
+echo $ac_n "checking whether overlapping arrays are copied correctly""... $ac_c" 1>&6
+echo "configure:2520: checking whether overlapping arrays are copied correctly" >&5
+if eval "test \"`echo '$''{'libelf_cv_working_memmove'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  libelf_cv_working_memmove='maybe not'
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2528 "configure"
+#include "confdefs.h"
+#include "confdefs.h"
+#if HAVE_MEMMOVE
+extern void *memmove();
+#else
+extern void bcopy();
+#define memmove(d,s,n) bcopy((s),(d),(n))
+#endif
+extern int strcmp();
+main() {
+  char buf[] = "0123456789";
+  memmove(buf + 1, buf, 9);
+  if (strcmp(buf, "0012345678")) exit(1);
+  exit(0);
+}
+EOF
+if { (eval echo configure:2545: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+      libelf_cv_working_memmove=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  libelf_cv_working_memmove=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$libelf_cv_working_memmove" 1>&6
+if test "$libelf_cv_working_memmove" != yes; then
+  cat >> confdefs.h <<\EOF
+#define HAVE_BROKEN_MEMMOVE 1
+EOF
+
+fi
+
+echo $ac_n "checking the coffee machine""... $ac_c" 1>&6
+echo "configure:2568: checking the coffee machine" >&5
+if eval "test \"`echo '$''{'mr_cv_coffee_machine'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  mr_cv_coffee_machine='empty - operator may not work as expected'
+fi
+
+echo "$ac_t""$mr_cv_coffee_machine" 1>&6
+
+echo $ac_n "checking whether 64-bit ELF support is sufficient""... $ac_c" 1>&6
+echo "configure:2578: checking whether 64-bit ELF support is sufficient" >&5
+echo "$ac_t""$libelf_64bit" 1>&6
+echo $ac_n "checking whether to include 64-bit support""... $ac_c" 1>&6
+echo "configure:2581: checking whether to include 64-bit support" >&5
+if test "$libelf_64bit" = no; then
+  libelf_enable_64bit=no
+else
+  # Check whether --enable-elf64 or --disable-elf64 was given.
+if test "${enable_elf64+set}" = set; then
+  enableval="$enable_elf64"
+  libelf_enable_64bit="$enableval"
+else
+  libelf_enable_64bit=yes
+fi
+
+fi
+echo "$ac_t""$libelf_enable_64bit" 1>&6
+if test "$libelf_enable_64bit" = yes; then
+  cat >> confdefs.h <<\EOF
+#define __LIBELF64 1
+EOF
+
+fi
+
+echo $ac_n "checking whether versioning support is sufficient""... $ac_c" 1>&6
+echo "configure:2603: checking whether versioning support is sufficient" >&5
+libelf_versioning=no
+case "$libelf_enable_64bit:$libelf_cv_verdef32:$libelf_cv_verdef64" in
+  no:yes:* | yes:yes:yes)
+    if test "$libelf_cv_sun_verdef" = yes; then
+      cat >> confdefs.h <<\EOF
+#define __LIBELF_SUN_SYMBOL_VERSIONS 1
+EOF
+
+      libelf_versioning=yes
+    elif test "$libelf_cv_gnu_verdef" = yes; then
+      cat >> confdefs.h <<\EOF
+#define __LIBELF_GNU_SYMBOL_VERSIONS 1
+EOF
+
+      libelf_versioning=yes
+    fi;;
+esac
+echo "$ac_t""$libelf_versioning" 1>&6
+echo $ac_n "checking whether to include versioning support""... $ac_c" 1>&6
+echo "configure:2623: checking whether to include versioning support" >&5
+if test "$libelf_versioning" = no; then
+  libelf_enable_versioning=no
+else
+  # Check whether --enable-versioning or --disable-versioning was given.
+if test "${enable_versioning+set}" = set; then
+  enableval="$enable_versioning"
+  libelf_enable_versioning="$enableval"
+else
+  libelf_enable_versioning=yes
+fi
+
+fi
+echo "$ac_t""$libelf_enable_versioning" 1>&6
+if test "$libelf_enable_versioning" = yes; then
+  cat >> confdefs.h <<\EOF
+#define __LIBELF_SYMBOL_VERSIONS 1
+EOF
+
+fi
+
+
+  
+
+  # Needed for `make dist' even if NLS is disabled.
+  GMOFILES=
+  MSGFILES=
+  POFILES=
+  for mr_lang in $ALL_LINGUAS; do
+    GMOFILES="$GMOFILES $mr_lang.gmo"
+    MSGFILES="$MSGFILES $mr_lang.msg"
+    POFILES="$POFILES $mr_lang.po"
+  done
+  
+  
+  
+
+  echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
+echo "configure:2661: checking whether NLS is requested" >&5
+  # Check whether --enable-nls or --disable-nls was given.
+if test "${enable_nls+set}" = set; then
+  enableval="$enable_nls"
+  mr_enable_nls="$enableval"
+else
+  mr_enable_nls=yes
+fi
+
+  echo "$ac_t""$mr_enable_nls" 1>&6
+
+  CATOBJEXT=
+  INSTOBJEXT=
+  localedir=
+  if test "$mr_enable_nls" = yes; then
+    mr_PATH=`echo ":$PATH" | sed -e 's,:^:*openwin^:*,,g' -e 's,^:,,'`
+    echo $ac_n "checking for dgettext""... $ac_c" 1>&6
+echo "configure:2678: checking for dgettext" >&5
+if eval "test \"`echo '$''{'mr_cv_func_dgettext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+	cat > conftest.$ac_ext <<EOF
+#line 2684 "configure"
+#include "confdefs.h"
+#include <libintl.h>
+int main() {
+char *s = dgettext("", ""); return 0
+; return 0; }
+EOF
+if { (eval echo configure:2691: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  mr_cv_func_dgettext=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  mr_cv_func_dgettext=no
+fi
+rm -f conftest*
+    
+fi
+
+echo "$ac_t""$mr_cv_func_dgettext" 1>&6
+    if test "$mr_cv_func_dgettext" = yes; then
+      # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2709: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$MSGFMT" in
+  /*)
+  ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$mr_PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no"
+  ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test -n "$MSGFMT"; then
+  echo "$ac_t""$MSGFMT" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+      if test "$MSGFMT" != no; then
+	# Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2746: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$GMSGFMT" in
+  /*)
+  ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$mr_PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+  ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+  echo "$ac_t""$GMSGFMT" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+	# Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2782: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$XGETTEXT" in
+  /*)
+  ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$mr_PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT="xgettext"
+  ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+  echo "$ac_t""$XGETTEXT" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+	# Extract the first word of "msgmerge", so it can be a program name with args.
+set dummy msgmerge; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:2818: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_MSGMERGE'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$MSGMERGE" in
+  /*)
+  ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_MSGMERGE="$MSGMERGE" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$mr_PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_MSGMERGE="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_MSGMERGE" && ac_cv_path_MSGMERGE="msgmerge"
+  ;;
+esac
+fi
+MSGMERGE="$ac_cv_path_MSGMERGE"
+if test -n "$MSGMERGE"; then
+  echo "$ac_t""$MSGMERGE" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+	echo $ac_n "checking for GNU gettext""... $ac_c" 1>&6
+echo "configure:2852: checking for GNU gettext" >&5
+if eval "test \"`echo '$''{'mr_cv_gnu_gettext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+	    cat > conftest.$ac_ext <<EOF
+#line 2858 "configure"
+#include "confdefs.h"
+
+int main() {
+extern int _nl_msg_cat_cntr; return _nl_msg_cat_cntr
+; return 0; }
+EOF
+if { (eval echo configure:2865: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  mr_cv_gnu_gettext=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  mr_cv_gnu_gettext=no
+fi
+rm -f conftest*
+	
+fi
+
+echo "$ac_t""$mr_cv_gnu_gettext" 1>&6
+	if test "$mr_cv_gnu_gettext" = yes; then
+	  echo $ac_n "checking for losing catgets-based GNU gettext""... $ac_c" 1>&6
+echo "configure:2881: checking for losing catgets-based GNU gettext" >&5
+if eval "test \"`echo '$''{'mr_cv_catgets_based_gettext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+	      cat > conftest.$ac_ext <<EOF
+#line 2887 "configure"
+#include "confdefs.h"
+
+int main() {
+extern int _msg_tbl_length; return _msg_tbl_length
+; return 0; }
+EOF
+if { (eval echo configure:2894: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  mr_cv_catgets_based_gettext=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  mr_cv_catgets_based_gettext=no
+fi
+rm -f conftest*
+	  
+fi
+
+echo "$ac_t""$mr_cv_catgets_based_gettext" 1>&6
+	  if test "$mr_cv_catgets_based_gettext" = yes; then
+	    # This loses completely. Turn it off and use catgets.
+	    LIBS=`echo $LIBS | sed 's,-lintl,,g'`
+	    mr_cv_func_dgettext=no
+	  else
+	    # Is there a better test for this case?
+	    echo $ac_n "checking for pure GNU gettext""... $ac_c" 1>&6
+echo "configure:2915: checking for pure GNU gettext" >&5
+if eval "test \"`echo '$''{'mr_cv_pure_gnu_gettext'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+		cat > conftest.$ac_ext <<EOF
+#line 2921 "configure"
+#include "confdefs.h"
+
+int main() {
+extern int gettext(); return gettext()
+; return 0; }
+EOF
+if { (eval echo configure:2928: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  mr_cv_pure_gnu_gettext=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  mr_cv_pure_gnu_gettext=no
+fi
+rm -f conftest*
+	    
+fi
+
+echo "$ac_t""$mr_cv_pure_gnu_gettext" 1>&6
+	    if test "$mr_cv_pure_gnu_gettext" = yes; then
+	      CATOBJEXT=.gmo
+	      localedir='$(prefix)/share/locale'
+	    else
+	      CATOBJEXT=.mo
+	      localedir='$(prefix)/lib/locale'
+	    fi
+	    INSTOBJEXT=.mo
+	  fi
+	else
+	  # System provided gettext
+	  CATOBJEXT=.mo
+	  INSTOBJEXT=.mo
+	  localedir='$(prefix)/lib/locale'
+	fi
+      else
+	# Gettext but no msgfmt. Try catgets.
+	mr_cv_func_dgettext=no
+      fi
+    fi
+    if test "$mr_cv_func_dgettext" = yes; then
+      cat >> confdefs.h <<\EOF
+#define HAVE_DGETTEXT 1
+EOF
+
+    else
+      echo $ac_n "checking for catgets""... $ac_c" 1>&6
+echo "configure:2969: checking for catgets" >&5
+if eval "test \"`echo '$''{'mr_cv_func_catgets'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  
+	cat > conftest.$ac_ext <<EOF
+#line 2975 "configure"
+#include "confdefs.h"
+#include <nl_types.h>
+int main() {
+catgets(catopen("",0),0,0,"");return 0;
+; return 0; }
+EOF
+if { (eval echo configure:2982: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  mr_cv_func_catgets=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  mr_cv_func_catgets=no
+fi
+rm -f conftest*
+      
+fi
+
+echo "$ac_t""$mr_cv_func_catgets" 1>&6
+      if test "$mr_cv_func_catgets" = yes; then
+	# Extract the first word of "gencat", so it can be a program name with args.
+set dummy gencat; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3000: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GENCAT'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$GENCAT" in
+  /*)
+  ac_cv_path_GENCAT="$GENCAT" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_GENCAT="$GENCAT" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$mr_PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_GENCAT="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_GENCAT" && ac_cv_path_GENCAT="no"
+  ;;
+esac
+fi
+GENCAT="$ac_cv_path_GENCAT"
+if test -n "$GENCAT"; then
+  echo "$ac_t""$GENCAT" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+	if test "$GENCAT" != no; then
+	  cat >> confdefs.h <<\EOF
+#define HAVE_CATGETS 1
+EOF
+
+	  # Extract the first word of "gmsgfmt msgfmt", so it can be a program name with args.
+set dummy gmsgfmt msgfmt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3041: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$GMSGFMT" in
+  /*)
+  ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$mr_PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_GMSGFMT="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="msgfmt"
+  ;;
+esac
+fi
+GMSGFMT="$ac_cv_path_GMSGFMT"
+if test -n "$GMSGFMT"; then
+  echo "$ac_t""$GMSGFMT" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+	  # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3077: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$XGETTEXT" in
+  /*)
+  ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$mr_PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT="xgettext"
+  ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test -n "$XGETTEXT"; then
+  echo "$ac_t""$XGETTEXT" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+	  CATOBJEXT=.cat
+	  INSTOBJEXT=.cat
+	  localedir='$(prefix)/lib/locale'
+	fi
+      else
+	echo "configure: warning: no NLS support, disabled" 1>&2
+	mr_enable_nls=no
+      fi
+    fi
+  fi
+  
+  
+  
+
+  POSUB=
+  CATALOGS=
+  if test "$mr_enable_nls" = yes; then
+    echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
+echo "configure:3128: checking for catalogs to be installed" >&5
+    mr_linguas=
+    for mr_lang in ${LINGUAS=$ALL_LINGUAS}; do
+      case " $ALL_LINGUAS " in
+	*" $mr_lang "*)
+	  mr_linguas="$mr_linguas$mr_lang "
+	  CATALOGS="$CATALOGS $mr_lang$CATOBJEXT"
+	  ;;
+      esac
+    done
+    echo "$ac_t""$mr_linguas" 1>&6
+    POSUB=po
+  fi
+  
+  
+
+LIBINTL=
+echo $ac_n "checking for gettext in -lintl""... $ac_c" 1>&6
+echo "configure:3146: checking for gettext in -lintl" >&5
+ac_lib_var=`echo intl'_'gettext | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  ac_save_LIBS="$LIBS"
+LIBS="-lintl  $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 3154 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error.  */
+/* We use char because int might match the return type of a gcc2
+    builtin and then its argument prototype would still apply.  */
+char gettext();
+
+int main() {
+gettext()
+; return 0; }
+EOF
+if { (eval echo configure:3165: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=yes"
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -rf conftest*
+  eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+  echo "$ac_t""yes" 1>&6
+  LIBINTL=-lintl
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:3194: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+  case $nonopt in
+  NONE)
+    if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+    else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+    fi ;;
+  *) host_alias=$nonopt ;;
+  esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+
+  
+  PICFLAGS=
+  SHLIB_SFX=
+  SHLINK_SFX=
+  SONAME_SFX=
+  LINK_SHLIB=
+  INSTALL_SHLIB=
+  DEPSHLIBS=
+  echo $ac_n "checking whether to build a shared library""... $ac_c" 1>&6
+echo "configure:3224: checking whether to build a shared library" >&5
+  # Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+  enableval="$enable_shared"
+  mr_enable_shared="$enableval"
+else
+  mr_enable_shared=yes
+fi
+
+  echo "$ac_t""$mr_enable_shared" 1>&6
+  if test "$mr_enable_shared" = yes; then
+    echo $ac_n "checking whether GNU naming conventions are requested""... $ac_c" 1>&6
+echo "configure:3236: checking whether GNU naming conventions are requested" >&5
+    # Check whether --enable-gnu-names or --disable-gnu-names was given.
+if test "${enable_gnu_names+set}" = set; then
+  enableval="$enable_gnu_names"
+  mr_enable_gnu_names="$enableval"
+else
+  mr_enable_gnu_names=no
+fi
+
+    echo "$ac_t""$mr_enable_gnu_names" 1>&6
+    
+    
+    # Extract the first word of "ld", so it can be a program name with args.
+set dummy ld; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3251: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  case "$LD" in
+  /*)
+  ac_cv_path_LD="$LD" # Let the user override the test with a path.
+  ;;
+  ?:/*)			 
+  ac_cv_path_LD="$LD" # Let the user override the test with a dos path.
+  ;;
+  *)
+  IFS="${IFS= 	}"; ac_save_ifs="$IFS"; IFS=":"
+  ac_dummy="$PATH"
+  for ac_dir in $ac_dummy; do 
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      ac_cv_path_LD="$ac_dir/$ac_word"
+      break
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_LD" && ac_cv_path_LD="ld"
+  ;;
+esac
+fi
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+  echo "$ac_t""$LD" 1>&6
+else
+  echo "$ac_t""no" 1>&6
+fi
+
+    case "$host" in
+      *-linux*|*-gnu*)
+	if test "$GCC" = yes; then
+	  
+  
+  echo $ac_n "checking for native ELF system""... $ac_c" 1>&6
+echo "configure:3290: checking for native ELF system" >&5
+if eval "test \"`echo '$''{'mr_cv_target_elf'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  mr_cv_target_elf=no
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3298 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+int
+main(int argc, char **argv) {
+  char buf[BUFSIZ];
+  FILE *fp;
+  int n;
+
+  if ((fp = fopen(*argv, "r")) == NULL) {
+    exit(1);
+  }
+  n = fread(buf, 1, sizeof(buf), fp);
+  if (n >= 52
+   && buf[0] == '\177'
+   && buf[1] == 'E'
+   && buf[2] == 'L'
+   && buf[3] == 'F') {
+    exit(0);
+  }
+  exit(1);
+}
+EOF
+if { (eval echo configure:3321: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+        mr_cv_target_elf=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  mr_cv_target_elf=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$mr_cv_target_elf" 1>&6
+	  if test "$mr_cv_target_elf" = yes; then
+	    PICFLAGS='-fPIC -DPIC'
+	    if test "$mr_enable_gnu_names" = yes
+	    then SHLIB_SFX='-$(VERSION).so'
+	    else SHLIB_SFX='.so.$(VERSION)'
+	    fi
+	    SHLINK_SFX='.so'
+	    SONAME_SFX='.so.$(MAJOR)'
+	    LINK_SHLIB='$(CC) -shared -Wl,-soname,$(SONAME)'
+	    INSTALL_SHLIB='$(INSTALL_PROGRAM)'
+	    DEPSHLIBS='-lc'
+	  else
+	    echo "configure: warning: shared libraries not supported for $host" 1>&2
+	    mr_enable_shared=no
+	  fi
+	elif ${CC} -V 2>&1 | grep 'Intel(R) C++ Compiler' >/dev/null 2>&1; then
+	  echo "configure: warning: Use --disable-shared if $CC fails to build the shared library" 1>&2
+	  PICFLAGS='-fPIC -DPIC'
+	  if test "$mr_enable_gnu_names" = yes
+	  then SHLIB_SFX='-$(VERSION).so'
+	  else SHLIB_SFX='.so.$(VERSION)'
+	  fi
+	  SHLINK_SFX='.so'
+	  SONAME_SFX='.so.$(MAJOR)'
+	  LINK_SHLIB='$(CC) -shared -Wl,-soname,$(SONAME)'
+	  INSTALL_SHLIB='$(INSTALL_PROGRAM)'
+	  DEPSHLIBS='-lc'
+	else
+	  echo "configure: warning: GNU CC required for building shared libraries" 1>&2
+	  mr_enable_shared=no
+	fi
+	;;
+      i386-pc-nto-qnx*)
+	
+  
+  echo $ac_n "checking for native ELF system""... $ac_c" 1>&6
+echo "configure:3372: checking for native ELF system" >&5
+if eval "test \"`echo '$''{'mr_cv_target_elf'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+  mr_cv_target_elf=no
+else
+  cat > conftest.$ac_ext <<EOF
+#line 3380 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+int
+main(int argc, char **argv) {
+  char buf[BUFSIZ];
+  FILE *fp;
+  int n;
+
+  if ((fp = fopen(*argv, "r")) == NULL) {
+    exit(1);
+  }
+  n = fread(buf, 1, sizeof(buf), fp);
+  if (n >= 52
+   && buf[0] == '\177'
+   && buf[1] == 'E'
+   && buf[2] == 'L'
+   && buf[3] == 'F') {
+    exit(0);
+  }
+  exit(1);
+}
+EOF
+if { (eval echo configure:3403: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+        mr_cv_target_elf=yes
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  mr_cv_target_elf=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$mr_cv_target_elf" 1>&6
+	if test "$mr_cv_target_elf" = yes; then
+	  PICFLAGS='-fPIC -DPIC'
+	  if test "$mr_enable_gnu_names" = yes
+	  then SHLIB_SFX='-$(VERSION).so'
+	  else SHLIB_SFX='.so.$(VERSION)'
+	  fi
+	  SHLINK_SFX='.so'
+	  SONAME_SFX='.so.$(MAJOR)'
+	  LINK_SHLIB='$(CC) -shared -Wl,-soname,$(SONAME)'
+	  INSTALL_SHLIB='$(INSTALL_PROGRAM)'
+	  DEPSHLIBS='-lc'
+	else
+	  echo "configure: warning: shared libraries not supported for $host" 1>&2
+	  mr_enable_shared=no
+	fi
+	;;
+      sparc-sun-solaris2*)
+	if test "$GCC" = yes; then
+	  PICFLAGS='-fPIC -DPIC'
+	else
+	  PICFLAGS='-K PIC -DPIC'
+	fi
+	if test "$mr_enable_gnu_names" = yes
+	then SHLIB_SFX='-$(MAJOR).so'
+	else SHLIB_SFX='.so.$(MAJOR)'
+	fi
+	SONAME_SFX='.so.$(MAJOR)'
+	SHLINK_SFX='.so'
+	LINK_SHLIB='$(LD) -G -z text -h $(SONAME)'
+	INSTALL_SHLIB='$(INSTALL_PROGRAM)'
+	;;
+      *)
+	echo "configure: warning: shared libraries not supported for $host" 1>&2
+	mr_enable_shared=no
+	;;
+    esac
+  else
+    mr_enable_shared=no
+  fi
+  
+  
+  
+  
+  
+  
+  
+  DO_SHLIB="$mr_enable_shared"
+  
+
+
+# Check whether --enable-extended-format or --disable-extended-format was given.
+if test "${enable_extended_format+set}" = set; then
+  enableval="$enable_extended_format"
+  mr_enable_extended_format="$enableval"
+else
+  mr_enable_extended_format=no
+fi
+
+if test "$mr_enable_extended_format" = yes; then
+  cat >> confdefs.h <<\EOF
+#define ENABLE_EXTENDED_FORMAT 1
+EOF
+
+fi
+
+# Check whether --enable-sanity-checks or --disable-sanity-checks was given.
+if test "${enable_sanity_checks+set}" = set; then
+  enableval="$enable_sanity_checks"
+  mr_enable_sanity_checks="$enableval"
+else
+  mr_enable_sanity_checks=yes
+fi
+
+if test "$mr_enable_sanity_checks" = yes; then
+  cat >> confdefs.h <<\EOF
+#define ENABLE_SANITY_CHECKS 1
+EOF
+
+fi
+
+
+  
+  # Check whether --enable-debug or --disable-debug was given.
+if test "${enable_debug+set}" = set; then
+  enableval="$enable_debug"
+  mr_enable_debug="$enableval"
+else
+  mr_enable_debug=no
+fi
+
+  if test "$mr_enable_debug" = yes; then
+    cat >> confdefs.h <<\EOF
+#define ENABLE_DEBUG 1
+EOF
+
+  fi
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs.  It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already.  You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+  case `(ac_space=' '; set | grep ac_space) 2>&1` in
+  *ac_space=\ *)
+    # `set' does not quote correctly, so add quotes (double-quote substitution
+    # turns \\\\ into \\, and sed turns \\ into \).
+    sed -n \
+      -e "s/'/'\\\\''/g" \
+      -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+    ;;
+  *)
+    # `set' quotes correctly as required by POSIX, so do not add quotes.
+    sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+    ;;
+  esac >> confcache
+if cmp -s $cache_file confcache; then
+  :
+else
+  if test -w $cache_file; then
+    echo "updating cache $cache_file"
+    cat confcache > $cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[ 	]*VPATH[ 	]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+  case "\$ac_option" in
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+    exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+  -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+    echo "$CONFIG_STATUS generated by autoconf version 2.13"
+    exit 0 ;;
+  -help | --help | --hel | --he | --h)
+    echo "\$ac_cs_usage"; exit 0 ;;
+  *) echo "\$ac_cs_usage"; exit 1 ;;
+  esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "Makefile lib/Makefile po/Makefile libelf.pc config.h lib/sys_elf.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@MAINT@%$MAINT%g
+s%@MAJOR@%$MAJOR%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@CC@%$CC%g
+s%@CPP@%$CPP%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@RANLIB@%$RANLIB%g
+s%@LN_S@%$LN_S%g
+s%@DO_COMPAT@%$DO_COMPAT%g
+s%@LIBOBJS@%$LIBOBJS%g
+s%@GMOFILES@%$GMOFILES%g
+s%@MSGFILES@%$MSGFILES%g
+s%@POFILES@%$POFILES%g
+s%@MSGFMT@%$MSGFMT%g
+s%@GMSGFMT@%$GMSGFMT%g
+s%@XGETTEXT@%$XGETTEXT%g
+s%@MSGMERGE@%$MSGMERGE%g
+s%@GENCAT@%$GENCAT%g
+s%@CATOBJEXT@%$CATOBJEXT%g
+s%@INSTOBJEXT@%$INSTOBJEXT%g
+s%@localedir@%$localedir%g
+s%@CATALOGS@%$CATALOGS%g
+s%@POSUB@%$POSUB%g
+s%@LIBINTL@%$LIBINTL%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@LD@%$LD%g
+s%@PICFLAGS@%$PICFLAGS%g
+s%@SHLIB_SFX@%$SHLIB_SFX%g
+s%@SHLINK_SFX@%$SHLINK_SFX%g
+s%@SONAME_SFX@%$SONAME_SFX%g
+s%@LINK_SHLIB@%$LINK_SHLIB%g
+s%@INSTALL_SHLIB@%$INSTALL_SHLIB%g
+s%@DEPSHLIBS@%$DEPSHLIBS%g
+s%@DO_SHLIB@%$DO_SHLIB%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+  if test $ac_beg -gt 1; then
+    sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+  else
+    sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+  fi
+  if test ! -s conftest.s$ac_file; then
+    ac_more_lines=false
+    rm -f conftest.s$ac_file
+  else
+    if test -z "$ac_sed_cmds"; then
+      ac_sed_cmds="sed -f conftest.s$ac_file"
+    else
+      ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+    fi
+    ac_file=`expr $ac_file + 1`
+    ac_beg=$ac_end
+    ac_end=`expr $ac_end + $ac_max_sed_cmds`
+  fi
+done
+if test -z "$ac_sed_cmds"; then
+  ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Makefile lib/Makefile po/Makefile libelf.pc"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+  # Remove last slash and all that follows it.  Not all systems have dirname.
+  ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+  if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+    # The file is in a subdirectory.
+    test ! -d "$ac_dir" && mkdir "$ac_dir"
+    ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+    # A "../" for each directory in $ac_dir_suffix.
+    ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+  else
+    ac_dir_suffix= ac_dots=
+  fi
+
+  case "$ac_given_srcdir" in
+  .)  srcdir=.
+      if test -z "$ac_dots"; then top_srcdir=.
+      else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+  /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+  *) # Relative path.
+    srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+    top_srcdir="$ac_dots$ac_given_srcdir" ;;
+  esac
+
+  case "$ac_given_INSTALL" in
+  [/$]*) INSTALL="$ac_given_INSTALL" ;;
+  *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+  esac
+
+  echo creating "$ac_file"
+  rm -f "$ac_file"
+  configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+  case "$ac_file" in
+  *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+  *) ac_comsub= ;;
+  esac
+
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ 	]*\)#\([ 	]*define[ 	][ 	]*\)'
+ac_dB='\([ 	][ 	]*\)[^ 	]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_uB='\([ 	]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ 	]*\)#\([ 	]*\)undef\([ 	][ 	]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+  CONFIG_HEADERS="config.h lib/sys_elf.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case "$ac_file" in
+  *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+       ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+  *) ac_file_in="${ac_file}.in" ;;
+  esac
+
+  echo creating $ac_file
+
+  rm -f conftest.frag conftest.in conftest.out
+  ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+  cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h.  And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments.  This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ 	]*#[ 	]*undef[ 	][ 	]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+  ac_lines=`grep -c . conftest.vals`
+  # grep -c gives empty output for an empty file on some AIX systems.
+  if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+  # Write a limited-size here document to conftest.frag.
+  echo '  cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+  sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+  echo 'CEOF
+  sed -f conftest.frag conftest.in > conftest.out
+  rm -f conftest.in
+  mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+  sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+  rm -f conftest.vals
+  mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+  rm -f conftest.frag conftest.h
+  echo "/* $ac_file.  Generated automatically by configure.  */" > conftest.h
+  cat conftest.in >> conftest.h
+  rm -f conftest.in
+  if cmp -s $ac_file conftest.h 2>/dev/null; then
+    echo "$ac_file is unchanged"
+    rm -f conftest.h
+  else
+    # Remove last slash and all that follows it.  Not all systems have dirname.
+      ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+      if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+      # The file is in a subdirectory.
+      test ! -d "$ac_dir" && mkdir "$ac_dir"
+    fi
+    rm -f $ac_file
+    mv conftest.h $ac_file
+  fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+echo timestamp > stamp-h; echo timestamp > lib/stamp-h
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
+
+# vi: set ts=8 sw=2 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/configure.in	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,379 @@
+# configure.in - Configure template for libelf.
+# Process this file with autoconf to produce a configure script.
+# Copyright (C) 1995 - 2006 Michael Riepe
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library 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
+# Library General Public License for more details.
+#
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+# @(#) $Id: configure.in,v 1.40 2007/09/07 12:07:59 michael Exp $
+
+AC_INIT(VERSION)
+AC_CONFIG_HEADER(config.h lib/sys_elf.h)
+
+AC_PREREQ(2.13)
+
+mr_PACKAGE(libelf)
+
+dnl NOTE: there must be at least one .po file!
+ALL_LINGUAS=`cd $srcdir/po && echo *.po | sed 's/\.po//g'`
+
+dnl Assuming all arguments have already been processed...
+set `echo $VERSION | sed 's/\./ /g'`
+MAJOR=${1-1}
+MINOR=${2-0}
+PATCH=${3-0}
+AC_SUBST(MAJOR)
+
+dnl Checks for programs.
+AC_PROG_MAKE_SET
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_RANLIB
+AC_PROG_LN_S
+
+dnl Checks for libraries.
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS(unistd.h stdint.h fcntl.h)
+AC_CHECK_HEADERS(elf.h sys/elf.h link.h sys/link.h)
+AC_CACHE_CHECK([if ${CC} can compile elf.h], libelf_cv_elf_h_works, [
+  AC_TRY_COMPILE(
+    [#if HAVE_ELF_H
+    #include <elf.h>
+    #elif HAVE_SYS_ELF_H
+    #include <sys/elf.h>
+    #endif],
+    [Elf32_Ehdr dummy],
+    [libelf_cv_elf_h_works=yes],
+    [libelf_cv_elf_h_works=no])
+])
+if test "$libelf_cv_elf_h_works" = no; then
+  ac_cv_header_elf_h=no
+  ac_cv_header_sys_elf_h=no
+fi
+if test "$ac_cv_header_elf_h" = yes; then
+  AC_DEFINE(__LIBELF_HEADER_ELF_H, [<elf.h>])
+elif test "$ac_cv_header_sys_elf_h" = yes; then
+  AC_DEFINE(__LIBELF_HEADER_ELF_H, [<sys/elf.h>])
+fi
+
+AC_CHECK_HEADERS(ar.h libelf.h nlist.h gelf.h)
+AC_MSG_CHECKING([whether to install <libelf.h>, <nlist.h> and <gelf.h>])
+AC_ARG_ENABLE(compat,
+  [  --enable-compat         install <libelf.h>, <nlist.h> and <gelf.h> (default: auto)],
+  [DO_COMPAT="$enableval"],
+  [if test "$ac_cv_header_libelf_h$ac_cv_header_nlist_h$ac_cv_header_gelf_h" = yesyesyes
+  then DO_COMPAT=no
+  else DO_COMPAT=yes
+  fi])
+AC_MSG_RESULT($DO_COMPAT)
+AC_SUBST(DO_COMPAT)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_OFF_T
+AC_TYPE_SIZE_T
+
+AC_CHECK_SIZEOF(short,2)
+AC_CHECK_SIZEOF(int,4)
+AC_CHECK_SIZEOF(long,4)
+AC_CHECK_SIZEOF(long long,0)
+# Windows port
+AC_CHECK_SIZEOF(__int64, 0)
+
+if test "$ac_cv_header_elf_h" = yes \
+|| test "$ac_cv_header_sys_elf_h" = yes; then
+
+  # Slowaris declares Elf32_Dyn in <link.h>.
+  # QNX declares Elf32_Dyn in <sys/link.h>.
+  AC_CACHE_CHECK([for struct Elf32_Dyn], libelf_cv_struct_elf32_dyn, [
+    AC_TRY_COMPILE([#include __LIBELF_HEADER_ELF_H], [Elf32_Dyn x],
+      [libelf_cv_struct_elf32_dyn=yes],
+      AC_TRY_COMPILE([#include <link.h>], [Elf32_Dyn x],
+	[libelf_cv_struct_elf32_dyn=link.h],
+	AC_TRY_COMPILE([#include <sys/link.h>], [Elf32_Dyn x],
+	  [libelf_cv_struct_elf32_dyn=sys/link.h],
+	  [libelf_cv_struct_elf32_dyn=no])))])
+  if test "$libelf_cv_struct_elf32_dyn" = link.h; then
+    AC_DEFINE(__LIBELF_NEED_LINK_H)
+  elif test "$libelf_cv_struct_elf32_dyn" = sys/link.h; then
+    AC_DEFINE(__LIBELF_NEED_SYS_LINK_H)
+  elif test "$libelf_cv_struct_elf32_dyn" = no; then
+    AC_MSG_ERROR([no declaration for Elf32_Dyn])
+  fi
+
+  # Linux declares struct nlist in <elf.h>.
+  AC_CACHE_CHECK([for struct nlist in elf.h], libelf_cv_struct_nlist, [
+    AC_TRY_COMPILE([#include __LIBELF_HEADER_ELF_H], [struct nlist nl],
+      [libelf_cv_struct_nlist=yes],
+      [libelf_cv_struct_nlist=no])])
+  if test "$libelf_cv_struct_nlist" = yes; then
+    AC_DEFINE(HAVE_STRUCT_NLIST_DECLARATION)
+  fi
+
+  # Check for 64-bit data types.
+  AC_CACHE_CHECK([for struct Elf64_Ehdr], libelf_cv_struct_elf64_ehdr,
+    AC_TRY_COMPILE([#include __LIBELF_HEADER_ELF_H],
+      [Elf64_Ehdr x],
+      [libelf_cv_struct_elf64_ehdr=yes],
+      [libelf_cv_struct_elf64_ehdr=no]))
+
+  # Linux lacks typedefs for scalar ELF64_* types.
+  AC_CACHE_CHECK([for Elf64_Addr], libelf_cv_type_elf64_addr,
+    AC_TRY_COMPILE([#include __LIBELF_HEADER_ELF_H],
+      [Elf64_Addr x],
+      [libelf_cv_type_elf64_addr=yes],
+      [libelf_cv_type_elf64_addr=no]))
+
+  # IRIX' struct Elf64_Rel is slightly different. Ugh.
+  AC_CACHE_CHECK([for struct Elf64_Rel], libelf_cv_struct_elf64_rel,
+    AC_TRY_COMPILE([#include __LIBELF_HEADER_ELF_H],
+      [Elf64_Rel x; x.r_info = 1],
+      [libelf_cv_struct_elf64_rel=yes],
+      AC_TRY_COMPILE([#include __LIBELF_HEADER_ELF_H],
+	[Elf64_Rel x; x.r_sym = 1],
+	[libelf_cv_struct_elf64_rel=irix],
+	[libelf_cv_struct_elf64_rel=no])))
+
+  case "$libelf_cv_struct_elf64_ehdr:\
+$libelf_cv_type_elf64_addr:\
+$libelf_cv_struct_elf64_rel" in
+    yes:yes:yes)
+      libelf_64bit=yes;;
+    yes:yes:irix)
+      AC_DEFINE(__LIBELF64_IRIX)
+      libelf_64bit=yes;;
+    yes:no:yes)
+      AC_DEFINE(__LIBELF64_LINUX)
+      libelf_64bit=yes;;
+    *)
+      libelf_64bit=no;;
+  esac
+
+  # Check for symbol versioning definitions
+  AC_CACHE_CHECK([for Elf32_Verdef], libelf_cv_verdef32,
+    AC_TRY_COMPILE(
+      [#include __LIBELF_HEADER_ELF_H
+      #if __LIBELF_NEED_LINK_H
+      #include <link.h>	/* Solaris wants this */
+      #endif],
+      [struct {
+	Elf32_Verdef vd;
+	Elf32_Verdaux vda;
+	Elf32_Verneed vn;
+	Elf32_Vernaux vna;
+      } x],
+      [libelf_cv_verdef32=yes],
+      [libelf_cv_verdef32=no]))
+
+  AC_CACHE_CHECK([for Elf64_Verdef], libelf_cv_verdef64,
+    AC_TRY_COMPILE(
+      [#include __LIBELF_HEADER_ELF_H
+      #if __LIBELF_NEED_LINK_H
+      #include <link.h>	/* Solaris wants this */
+      #endif],
+      [struct {
+	Elf64_Verdef vd;
+	Elf64_Verdaux vda;
+	Elf64_Verneed vn;
+	Elf64_Vernaux vna;
+      } x],
+      [libelf_cv_verdef64=yes],
+      [libelf_cv_verdef64=no]))
+
+  AC_CACHE_CHECK([for SHT_SUNW_verdef], libelf_cv_sun_verdef,
+    AC_TRY_COMPILE([#include __LIBELF_HEADER_ELF_H],
+      [Elf32_Word x = SHT_SUNW_verdef + SHT_SUNW_verneed + SHT_SUNW_versym],
+      [libelf_cv_sun_verdef=yes],
+      [libelf_cv_sun_verdef=no]))
+
+  AC_CACHE_CHECK([for SHT_GNU_verdef], libelf_cv_gnu_verdef,
+    AC_TRY_COMPILE([#include __LIBELF_HEADER_ELF_H],
+      [Elf32_Word x = SHT_GNU_verdef + SHT_GNU_verneed + SHT_GNU_versym],
+      [libelf_cv_gnu_verdef=yes],
+      [libelf_cv_gnu_verdef=no]))
+else
+  # lib/elf_repl.h supports 64-bit
+  libelf_64bit=yes
+
+  # lib/elf_repl.h supports symbol versioning
+  libelf_cv_verdef32=yes
+  libelf_cv_verdef64=yes
+  libelf_cv_sun_verdef=yes
+  libelf_cv_gnu_verdef=yes
+fi
+
+AC_CACHE_CHECK([for 64-bit integer], libelf_cv_int64, [
+  if test "$ac_cv_sizeof_long" = 8; then
+    libelf_cv_int64='long'
+  elif test "$ac_cv_sizeof___int64" = 8; then
+    libelf_cv_int64='__int64'
+  elif test "$ac_cv_sizeof_long_long" = 8; then
+    libelf_cv_int64='long long'
+  else
+    libelf_cv_int64=no
+  fi])
+if test "$libelf_cv_int64" = no; then
+  libelf_64bit=no
+else
+  AC_DEFINE_UNQUOTED(__libelf_i64_t, [$libelf_cv_int64])
+  AC_DEFINE_UNQUOTED(__libelf_u64_t, [unsigned $libelf_cv_int64])
+fi
+
+AC_CACHE_CHECK([for 32-bit integer], libelf_cv_int32, [
+  if test "$ac_cv_sizeof_int" = 4; then
+    libelf_cv_int32='int'
+  elif test "$ac_cv_sizeof_long" = 4; then
+    libelf_cv_int32='long'
+  else
+    libelf_cv_int32=no
+  fi])
+if test "$libelf_cv_int32" = no; then
+  AC_MSG_ERROR([neither int nor long is 32-bit])
+else
+  AC_DEFINE_UNQUOTED(__libelf_i32_t, [$libelf_cv_int32])
+  AC_DEFINE_UNQUOTED(__libelf_u32_t, [unsigned $libelf_cv_int32])
+fi
+
+AC_CACHE_CHECK([for 16-bit integer], libelf_cv_int16, [
+  if test "$ac_cv_sizeof_short" = 2; then
+    libelf_cv_int16='short'
+  elif test "$ac_cv_sizeof_int" = 2; then
+    libelf_cv_int16='int'
+  else
+    libelf_cv_int16=no
+  fi])
+if test "$libelf_cv_int16" = no; then
+  AC_MSG_ERROR([neither short nor int is 16-bit])
+else
+  AC_DEFINE_UNQUOTED(__libelf_i16_t, [$libelf_cv_int16])
+  AC_DEFINE_UNQUOTED(__libelf_u16_t, [unsigned $libelf_cv_int16])
+fi
+
+dnl Checks for library functions.
+AC_FUNC_MMAP
+AC_CHECK_FUNCS(ftruncate memcmp memcpy memmove)
+AC_REPLACE_FUNCS(memset)
+if test "$ac_cv_func_memset" = yes; then
+  AC_DEFINE(HAVE_MEMSET)
+fi
+
+AC_CACHE_CHECK([whether overlapping arrays are copied correctly],
+  libelf_cv_working_memmove,
+  [AC_TRY_RUN(changequote(<<, >>)dnl
+<<#include "confdefs.h"
+#if HAVE_MEMMOVE
+extern void *memmove();
+#else
+extern void bcopy();
+#define memmove(d,s,n) bcopy((s),(d),(n))
+#endif
+extern int strcmp();
+main() {
+  char buf[] = "0123456789";
+  memmove(buf + 1, buf, 9);
+  if (strcmp(buf, "0012345678")) exit(1);
+  exit(0);
+}>>, changequote([, ])dnl
+    libelf_cv_working_memmove=yes,
+    libelf_cv_working_memmove=no,
+    libelf_cv_working_memmove='maybe not')])
+if test "$libelf_cv_working_memmove" != yes; then
+  AC_DEFINE(HAVE_BROKEN_MEMMOVE)
+fi
+
+AC_CACHE_CHECK([the coffee machine], mr_cv_coffee_machine,
+  [mr_cv_coffee_machine='empty - operator may not work as expected'])
+
+dnl Check for 64-bit support.
+AC_MSG_CHECKING([whether 64-bit ELF support is sufficient])
+AC_MSG_RESULT($libelf_64bit)
+AC_MSG_CHECKING([whether to include 64-bit support])
+if test "$libelf_64bit" = no; then
+  libelf_enable_64bit=no
+else
+  AC_ARG_ENABLE(elf64,
+    [  --enable-elf64          compile in 64-bit support (default: auto)],
+    [libelf_enable_64bit="$enableval"],
+    [libelf_enable_64bit=yes])
+fi
+AC_MSG_RESULT($libelf_enable_64bit)
+if test "$libelf_enable_64bit" = yes; then
+  AC_DEFINE(__LIBELF64)
+fi
+
+AC_MSG_CHECKING([whether versioning support is sufficient])
+libelf_versioning=no
+case "$libelf_enable_64bit:$libelf_cv_verdef32:$libelf_cv_verdef64" in
+  no:yes:* | yes:yes:yes)
+    if test "$libelf_cv_sun_verdef" = yes; then
+      AC_DEFINE(__LIBELF_SUN_SYMBOL_VERSIONS)
+      libelf_versioning=yes
+    elif test "$libelf_cv_gnu_verdef" = yes; then
+      AC_DEFINE(__LIBELF_GNU_SYMBOL_VERSIONS)
+      libelf_versioning=yes
+    fi;;
+esac
+AC_MSG_RESULT($libelf_versioning)
+AC_MSG_CHECKING([whether to include versioning support])
+if test "$libelf_versioning" = no; then
+  libelf_enable_versioning=no
+else
+  AC_ARG_ENABLE(versioning,
+    [  --enable-versioning     compile in versioning support (default: auto)],
+    [libelf_enable_versioning="$enableval"],
+    [libelf_enable_versioning=yes])
+fi
+AC_MSG_RESULT($libelf_enable_versioning)
+if test "$libelf_enable_versioning" = yes; then
+  AC_DEFINE(__LIBELF_SYMBOL_VERSIONS)
+fi
+
+dnl Check for NLS support.
+mr_ENABLE_NLS
+dnl this is for gmo2msg...
+LIBINTL=
+AC_CHECK_LIB(intl, gettext, [LIBINTL=-lintl])
+AC_SUBST(LIBINTL)
+
+dnl Check for shared library support.
+mr_ENABLE_SHARED
+
+dnl Check for extended ELF format support
+AC_ARG_ENABLE(extended-format,
+  [  --enable-extended-format    support extended file formats (default: no)],
+  [mr_enable_extended_format="$enableval"],
+  [mr_enable_extended_format=no])
+if test "$mr_enable_extended_format" = yes; then
+  AC_DEFINE(ENABLE_EXTENDED_FORMAT)
+fi
+
+dnl Check if ELF sanity checks should be enabled
+AC_ARG_ENABLE(sanity-checks,
+  [  --enable-sanity-checks      enable sanity checks by default (default: yes)],
+  [mr_enable_sanity_checks="$enableval"],
+  [mr_enable_sanity_checks=yes])
+if test "$mr_enable_sanity_checks" = yes; then
+  AC_DEFINE(ENABLE_SANITY_CHECKS)
+fi
+
+dnl Check for debug support.
+mr_ENABLE_DEBUG
+
+AC_OUTPUT([Makefile lib/Makefile po/Makefile libelf.pc],
+  [echo timestamp > stamp-h; echo timestamp > lib/stamp-h])
+
+# vi: set ts=8 sw=2 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/install-sh	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+#
+# install - install a program, script, or datafile
+# This comes from X11R5; it is not part of GNU.
+#
+# $XConsortium: install.sh,v 1.2 89/12/18 14:47:22 jim Exp $
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.
+#
+
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+
+instcmd="$mvprog"
+chmodcmd=""
+chowncmd=""
+chgrpcmd=""
+stripcmd=""
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=""
+dst=""
+
+while [ x"$1" != x ]; do
+    case $1 in
+	-c) instcmd="$cpprog"
+	    shift
+	    continue;;
+
+	-m) chmodcmd="$chmodprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-o) chowncmd="$chownprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-g) chgrpcmd="$chgrpprog $2"
+	    shift
+	    shift
+	    continue;;
+
+	-s) stripcmd="$stripprog"
+	    shift
+	    continue;;
+
+	*)  if [ x"$src" = x ]
+	    then
+		src=$1
+	    else
+		dst=$1
+	    fi
+	    shift
+	    continue;;
+    esac
+done
+
+if [ x"$src" = x ]
+then
+	echo "install:  no input file specified"
+	exit 1
+fi
+
+if [ x"$dst" = x ]
+then
+	echo "install:  no destination specified"
+	exit 1
+fi
+
+
+# If destination is a directory, append the input filename; if your system
+# does not like double slashes in filenames, you may need to add some logic
+
+if [ -d $dst ]
+then
+	dst="$dst"/`basename $src`
+fi
+
+# Make a temp file name in the proper directory.
+
+dstdir=`dirname $dst`
+dsttmp=$dstdir/#inst.$$#
+
+# Move or copy the file name to the temp name
+
+$doit $instcmd $src $dsttmp
+
+# and set any options; do chmod last to preserve setuid bits
+
+if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; fi
+if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; fi
+if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; fi
+if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; fi
+
+# Now rename the file to the real destination.
+
+$doit $rmcmd $dst
+$doit $mvcmd $dsttmp $dst
+
+
+exit 0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/32.fsize.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,155 @@
+/*
+32.fsize.c - implementation of the elf{32,64}_fsize(3) functions.
+Copyright (C) 1995 - 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+#include <ext_types.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: 32.fsize.c,v 1.12 2005/05/21 15:39:19 michael Exp $";
+#endif /* lint */
+
+const size_t
+_elf_fmsize[2][EV_CURRENT - EV_NONE][ELF_T_NUM][2] = {
+    /* ELFCLASS32 */
+    {
+	/* version 1 */
+	{
+	    { sizeof(unsigned char),  sizeof(unsigned char)      },
+	    { sizeof(Elf32_Addr),     sizeof(__ext_Elf32_Addr)   },
+	    { sizeof(Elf32_Dyn),      sizeof(__ext_Elf32_Dyn)    },
+	    { sizeof(Elf32_Ehdr),     sizeof(__ext_Elf32_Ehdr)   },
+	    { sizeof(Elf32_Half),     sizeof(__ext_Elf32_Half)   },
+	    { sizeof(Elf32_Off),      sizeof(__ext_Elf32_Off)    },
+	    { sizeof(Elf32_Phdr),     sizeof(__ext_Elf32_Phdr)   },
+	    { sizeof(Elf32_Rela),     sizeof(__ext_Elf32_Rela)   },
+	    { sizeof(Elf32_Rel),      sizeof(__ext_Elf32_Rel)    },
+	    { sizeof(Elf32_Shdr),     sizeof(__ext_Elf32_Shdr)   },
+	    { sizeof(Elf32_Sword),    sizeof(__ext_Elf32_Sword)  },
+	    { sizeof(Elf32_Sym),      sizeof(__ext_Elf32_Sym)    },
+	    { sizeof(Elf32_Word),     sizeof(__ext_Elf32_Word)   },
+	    { 0, 0 },	/* there is no Elf32_Sxword */
+	    { 0, 0 },	/* there is no Elf32_Xword */
+	    /* XXX: check Solaris values */
+	    { 0, 0 },	/* Elf32_Verdef/Verdaux size varies */
+	    { 0, 0 },	/* Elf32_Verneed/Vernaux size varies */
+	},
+    },
+#if __LIBELF64
+    /* ELFCLASS64 */
+    {
+	/* version 1 */
+	{
+	    { sizeof(unsigned char),  sizeof(unsigned char)      },
+	    { sizeof(Elf64_Addr),     sizeof(__ext_Elf64_Addr)   },
+	    { sizeof(Elf64_Dyn),      sizeof(__ext_Elf64_Dyn)    },
+	    { sizeof(Elf64_Ehdr),     sizeof(__ext_Elf64_Ehdr)   },
+	    { sizeof(Elf64_Half),     sizeof(__ext_Elf64_Half)   },
+	    { sizeof(Elf64_Off),      sizeof(__ext_Elf64_Off)    },
+	    { sizeof(Elf64_Phdr),     sizeof(__ext_Elf64_Phdr)   },
+	    { sizeof(Elf64_Rela),     sizeof(__ext_Elf64_Rela)   },
+	    { sizeof(Elf64_Rel),      sizeof(__ext_Elf64_Rel)    },
+	    { sizeof(Elf64_Shdr),     sizeof(__ext_Elf64_Shdr)   },
+	    { sizeof(Elf64_Sword),    sizeof(__ext_Elf64_Sword)  },
+	    { sizeof(Elf64_Sym),      sizeof(__ext_Elf64_Sym)    },
+	    { sizeof(Elf64_Word),     sizeof(__ext_Elf64_Word)   },
+	    { sizeof(Elf64_Sxword),   sizeof(__ext_Elf64_Sxword) },
+	    { sizeof(Elf64_Xword),    sizeof(__ext_Elf64_Xword)  },
+	    /* XXX: check Solaris values */
+	    { 0, 0 },	/* Elf64_Verdef/Verdaux size varies */
+	    { 0, 0 },	/* Elf64_Verneed/Vernaux size varies */
+	},
+    },
+#endif /* __LIBELF64 */
+};
+
+static size_t
+_elf_fsize(unsigned cls, Elf_Type type, unsigned ver) {
+    size_t n = 0;
+
+    if (!valid_version(ver)) {
+	seterr(ERROR_UNKNOWN_VERSION);
+    }
+    else if (!valid_type(type)) {
+	seterr(ERROR_UNKNOWN_TYPE);
+    }
+    else if (!(n = _fsize(cls, ver, type))) {
+	seterr(ERROR_UNKNOWN_TYPE);
+    }
+    return n;
+}
+
+size_t
+elf32_fsize(Elf_Type type, size_t count, unsigned ver) {
+    return count * _elf_fsize(ELFCLASS32, type, ver);
+}
+
+#if __LIBELF64
+
+size_t
+elf64_fsize(Elf_Type type, size_t count, unsigned ver) {
+    return count * _elf_fsize(ELFCLASS64, type, ver);
+}
+
+size_t
+gelf_fsize(Elf *elf, Elf_Type type, size_t count, unsigned ver) {
+    if (elf) {
+	if (elf->e_kind != ELF_K_ELF) {
+	    seterr(ERROR_NOTELF);
+	}
+	else if (valid_class(elf->e_class)) {
+	    return count * _elf_fsize(elf->e_class, type, ver);
+	}
+	else {
+	    seterr(ERROR_UNKNOWN_CLASS);
+	}
+    }
+    return 0;
+}
+
+/*
+ * Extension: report memory size
+ */
+size_t
+gelf_msize(Elf *elf, Elf_Type type, size_t count, unsigned ver) {
+    size_t n;
+
+    if (elf) {
+	if (elf->e_kind != ELF_K_ELF) {
+	    seterr(ERROR_NOTELF);
+	}
+	else if (!valid_class(elf->e_class)) {
+	    seterr(ERROR_UNKNOWN_CLASS);
+	}
+	else if (!valid_version(ver)) {
+	    seterr(ERROR_UNKNOWN_VERSION);
+	}
+	else if (!valid_type(type)) {
+	    seterr(ERROR_UNKNOWN_TYPE);
+	}
+	else if (!(n = _msize(elf->e_class, ver, type))) {
+	    seterr(ERROR_UNKNOWN_TYPE);
+	}
+	else {
+	    return count * n;
+	}
+    }
+    return 0;
+}
+
+#endif /* __LIBELF64 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/32.getehdr.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,56 @@
+/*
+32.getehdr.c - implementation of the elf{32,64}_getehdr(3) functions.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: 32.getehdr.c,v 1.8 2005/05/21 15:39:19 michael Exp $";
+#endif /* lint */
+
+char*
+_elf_getehdr(Elf *elf, unsigned cls) {
+    if (!elf) {
+	return NULL;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (elf->e_kind != ELF_K_ELF) {
+	seterr(ERROR_NOTELF);
+    }
+    else if (elf->e_class != cls) {
+	seterr(ERROR_CLASSMISMATCH);
+    }
+    else if (elf->e_ehdr || _elf_cook(elf)) {
+	return elf->e_ehdr;
+    }
+    return NULL;
+}
+
+Elf32_Ehdr*
+elf32_getehdr(Elf *elf) {
+    return (Elf32_Ehdr*)_elf_getehdr(elf, ELFCLASS32);
+}
+
+#if __LIBELF64
+
+Elf64_Ehdr*
+elf64_getehdr(Elf *elf) {
+    return (Elf64_Ehdr*)_elf_getehdr(elf, ELFCLASS64);
+}
+
+#endif /* __LIBELF64 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/32.getphdr.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,56 @@
+/*
+32.getphdr.c - implementation of the elf{32,64}_getphdr(3) functions.
+Copyright (C) 1995 - 2000 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: 32.getphdr.c,v 1.10 2005/05/21 15:39:19 michael Exp $";
+#endif /* lint */
+
+char*
+_elf_getphdr(Elf *elf, unsigned cls) {
+    if (!elf) {
+	return NULL;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (elf->e_kind != ELF_K_ELF) {
+	seterr(ERROR_NOTELF);
+    }
+    else if (elf->e_class != cls) {
+	seterr(ERROR_CLASSMISMATCH);
+    }
+    else if (elf->e_ehdr || _elf_cook(elf)) {
+	return elf->e_phdr;
+    }
+    return NULL;
+}
+
+Elf32_Phdr*
+elf32_getphdr(Elf *elf) {
+    return (Elf32_Phdr*)_elf_getphdr(elf, ELFCLASS32);
+}
+
+#if __LIBELF64
+
+Elf64_Phdr*
+elf64_getphdr(Elf *elf) {
+    return (Elf64_Phdr*)_elf_getphdr(elf, ELFCLASS64);
+}
+
+#endif /* __LIBELF64 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/32.getshdr.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,58 @@
+/*
+32.getshdr.c - implementation of the elf{32,64}_getshdr(3) functions.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: 32.getshdr.c,v 1.9 2005/05/21 15:39:19 michael Exp $";
+#endif /* lint */
+
+Elf32_Shdr*
+elf32_getshdr(Elf_Scn *scn) {
+    if (!scn) {
+	return NULL;
+    }
+    elf_assert(scn->s_magic == SCN_MAGIC);
+    elf_assert(scn->s_elf);
+    elf_assert(scn->s_elf->e_magic == ELF_MAGIC);
+    if (scn->s_elf->e_class == ELFCLASS32) {
+	return &scn->s_shdr32;
+    }
+    seterr(ERROR_CLASSMISMATCH);
+    return NULL;
+}
+
+#if __LIBELF64
+
+Elf64_Shdr*
+elf64_getshdr(Elf_Scn *scn) {
+    if (!scn) {
+	return NULL;
+    }
+    elf_assert(scn->s_magic == SCN_MAGIC);
+    elf_assert(scn->s_elf);
+    elf_assert(scn->s_elf->e_magic == ELF_MAGIC);
+    if (scn->s_elf->e_class == ELFCLASS64) {
+	return &scn->s_shdr64;
+    }
+    seterr(ERROR_CLASSMISMATCH);
+    return NULL;
+}
+
+#endif /* __LIBELF64 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/32.newehdr.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,80 @@
+/*
+ * 32.newehdr.c - implementation of the elf{32,64}_newehdr(3) functions.
+ * Copyright (C) 1995 - 2006 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: 32.newehdr.c,v 1.15 2006/07/07 22:15:31 michael Exp $";
+#endif /* lint */
+
+static char*
+_elf_newehdr(Elf *elf, unsigned cls) {
+    size_t size;
+
+    if (!elf) {
+	return NULL;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (elf->e_readable) {
+	return _elf_getehdr(elf, cls);
+    }
+    else if (!elf->e_ehdr) {
+	size = _msize(cls, _elf_version, ELF_T_EHDR);
+	elf_assert(size);
+	if ((elf->e_ehdr = (char*)malloc(size))) {
+	    memset(elf->e_ehdr, 0, size);
+	    elf->e_ehdr_flags |= ELF_F_DIRTY;
+	    elf->e_kind = ELF_K_ELF;
+	    elf->e_class = cls;
+	    return elf->e_ehdr;
+	}
+	seterr(ERROR_MEM_EHDR);
+    }
+    else if (elf->e_class != cls) {
+	seterr(ERROR_CLASSMISMATCH);
+    }
+    else {
+	elf_assert(elf->e_kind == ELF_K_ELF);
+	return elf->e_ehdr;
+    }
+    return NULL;
+}
+
+Elf32_Ehdr*
+elf32_newehdr(Elf *elf) {
+    return (Elf32_Ehdr*)_elf_newehdr(elf, ELFCLASS32);
+}
+
+#if __LIBELF64
+
+Elf64_Ehdr*
+elf64_newehdr(Elf *elf) {
+    return (Elf64_Ehdr*)_elf_newehdr(elf, ELFCLASS64);
+}
+
+unsigned long
+gelf_newehdr(Elf *elf, int cls) {
+    if (!valid_class(cls) || !_msize(cls, _elf_version, ELF_T_EHDR)) {
+	seterr(ERROR_UNKNOWN_CLASS);
+	return 0;
+    }
+    return (unsigned long)_elf_newehdr(elf, cls);
+}
+
+#endif /* __LIBELF64 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/32.newphdr.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,118 @@
+/*
+ * 32.newphdr.c - implementation of the elf{32,64}_newphdr(3) functions.
+ * Copyright (C) 1995 - 2006 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: 32.newphdr.c,v 1.15 2006/07/07 22:15:41 michael Exp $";
+#endif /* lint */
+
+static char*
+_elf_newphdr(Elf *elf, size_t count, unsigned cls) {
+    size_t extcount = 0;
+    Elf_Scn *scn = NULL;
+    char *phdr = NULL;
+    size_t size;
+
+    if (!elf) {
+	return NULL;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (!elf->e_ehdr && !elf->e_readable) {
+	seterr(ERROR_NOEHDR);
+    }
+    else if (elf->e_kind != ELF_K_ELF) {
+	seterr(ERROR_NOTELF);
+    }
+    else if (elf->e_class != cls) {
+	seterr(ERROR_CLASSMISMATCH);
+    }
+    else if (elf->e_ehdr || _elf_cook(elf)) {
+	size = _msize(cls, _elf_version, ELF_T_PHDR);
+	elf_assert(size);
+	if (!(scn = _elf_first_scn(elf))) {
+	    return NULL;
+	}
+	if (count) {
+	    if (!(phdr = (char*)malloc(count * size))) {
+		seterr(ERROR_MEM_PHDR);
+		return NULL;
+	    }
+	    memset(phdr, 0, count * size);
+	}
+	elf_assert(elf->e_ehdr);
+	elf->e_phnum = count;
+	if (count >= PN_XNUM) {
+	    /*
+	     * get NULL section (create it if necessary)
+	     */
+	    extcount = count;
+	    count = PN_XNUM;
+	}
+	if (cls == ELFCLASS32) {
+	    ((Elf32_Ehdr*)elf->e_ehdr)->e_phnum = count;
+	    scn->s_shdr32.sh_info = extcount;
+	}
+#if __LIBELF64
+	else if (cls == ELFCLASS64) {
+	    ((Elf64_Ehdr*)elf->e_ehdr)->e_phnum = count;
+	    scn->s_shdr64.sh_info = extcount;
+	}
+#endif /* __LIBELF64 */
+	else {
+	    seterr(ERROR_UNIMPLEMENTED);
+	    if (phdr) {
+		free(phdr);
+	    }
+	    return NULL;
+	}
+	if (elf->e_phdr) {
+	    free(elf->e_phdr);
+	}
+	elf->e_phdr = phdr;
+	elf->e_phdr_flags |= ELF_F_DIRTY;
+	elf->e_ehdr_flags |= ELF_F_DIRTY;
+	scn->s_scn_flags |= ELF_F_DIRTY;
+	return phdr;
+    }
+    return NULL;
+}
+
+Elf32_Phdr*
+elf32_newphdr(Elf *elf, size_t count) {
+    return (Elf32_Phdr*)_elf_newphdr(elf, count, ELFCLASS32);
+}
+
+#if __LIBELF64
+
+Elf64_Phdr*
+elf64_newphdr(Elf *elf, size_t count) {
+    return (Elf64_Phdr*)_elf_newphdr(elf, count, ELFCLASS64);
+}
+
+unsigned long
+gelf_newphdr(Elf *elf, size_t phnum) {
+    if (!valid_class(elf->e_class)) {
+	seterr(ERROR_UNKNOWN_CLASS);
+	return 0;
+    }
+    return (unsigned long)_elf_newphdr(elf, phnum, elf->e_class);
+}
+
+#endif /* __LIBELF64 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/32.xlatetof.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,438 @@
+/*
+ * 32.xlatetof.c - implementation of the elf32_xlateto[fm](3) functions.
+ * Copyright (C) 1995 - 2006 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+#include <ext_types.h>
+#include <byteswap.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: 32.xlatetof.c,v 1.26 2006/07/27 22:33:40 michael Exp $";
+#endif /* lint */
+
+/*
+ * Ugly, ugly
+ */
+#ifdef _WIN32
+# define Cat2(a,b)a##b
+# define Cat3(a,b,c)a##b##c
+# define Ex1(m1,m2,a,b)m1##m2(a##b)
+# define Ex2(m1,m2,a,b,c)m1##m2(a,b##c)
+#else /* _WIN32 */
+# define x
+# if defined/**/x
+#  define Cat2(a,b)a##b
+#  define Cat3(a,b,c)a##b##c
+#  define Ex1(m1,m2,a,b)m1##m2(a##b)
+#  define Ex2(m1,m2,a,b,c)m1##m2(a,b##c)
+# else
+#  define Cat2(a,b)a/**/b
+#  define Cat3(a,b,c)a/**/b/**/c
+#  define Ex1(m1,m2,a,b)m1/**/m2(a/**/b)
+#  define Ex2(m1,m2,a,b,c)m1/**/m2(a,b/**/c)
+# endif
+# undef x
+#endif /* _WIN32 */
+
+/*
+ * auxiliary macros for execution order reversal
+ */
+#define seq_forw(a,b) a b
+#define seq_back(a,b) b a
+
+/*
+ * function instantiator
+ */
+#define copy_type_e_io(name,e,io,tfrom,tto,copy)		\
+    static size_t						\
+    Cat3(name,_,io)(unsigned char *dst, const unsigned char *src, size_t n) {	\
+	n /= sizeof(tfrom);					\
+	if (n && dst) {						\
+	    const tfrom *from = (const tfrom*)src;		\
+	    tto *to = (tto*)dst;				\
+	    size_t i;						\
+								\
+	    if (sizeof(tfrom) < sizeof(tto)) {			\
+		from += n;					\
+		to += n;					\
+		for (i = 0; i < n; i++) {			\
+		    --from;					\
+		    --to;					\
+		    copy(e,io,seq_back)				\
+		}						\
+	    }							\
+	    else {						\
+		for (i = 0; i < n; i++) {			\
+		    copy(e,io,seq_forw)				\
+		    from++;					\
+		    to++;					\
+		}						\
+	    }							\
+	}							\
+	return n * sizeof(tto);					\
+    }
+
+#define copy_type_e(name,e,type,copy)				\
+    copy_type_e_io(name,e,tom,Cat2(__ext_,type),type,copy)	\
+    copy_type_e_io(name,e,tof,type,Cat2(__ext_,type),copy)
+
+/*
+ * master function instantiator
+ */
+#define copy_type(name,version,type,copy)		\
+    copy_type_e(Cat3(name,L,version),L,type,copy)	\
+    copy_type_e(Cat3(name,M,version),M,type,copy)
+
+/*
+ * scalar copying
+ */
+#define copy_scalar_tom(type)	*to = Cat2(__load_,type)(*from);
+#define copy_scalar_tof(type)	Cat2(__store_,type)(*to, *from);
+
+/*
+ * structure member copying
+ */
+#define copy_tom(mb,type)	to->mb = Cat2(__load_,type)(from->mb);
+#define copy_tof(mb,type)	Cat2(__store_,type)(to->mb, from->mb);
+
+/*
+ * structure member copying (direction independent)
+ */
+#define copy_byte(e,io,mb)	to->mb = from->mb;
+#define copy_addr(e,io,mb)	Ex2(copy_,io,mb,u32,e)
+#define copy_half(e,io,mb)	Ex2(copy_,io,mb,u16,e)
+#define copy_off(e,io,mb)	Ex2(copy_,io,mb,u32,e)
+#define copy_sword(e,io,mb)	Ex2(copy_,io,mb,i32,e)
+#define copy_word(e,io,mb)	Ex2(copy_,io,mb,u32,e)
+#define copy_arr(e,io,mb)	\
+    array_copy(to->mb, sizeof(to->mb), from->mb, sizeof(from->mb));
+
+/*
+ * scalar copying (direction independent)
+ * these macros are used as `copy' arguments to copy_type()
+ */
+#define copy_addr_11(e,io,seq)	Ex1(copy_scalar_,io,u32,e)
+#define copy_half_11(e,io,seq)	Ex1(copy_scalar_,io,u16,e)
+#define copy_off_11(e,io,seq)	Ex1(copy_scalar_,io,u32,e)
+#define copy_sword_11(e,io,seq)	Ex1(copy_scalar_,io,i32,e)
+#define copy_word_11(e,io,seq)	Ex1(copy_scalar_,io,u32,e)
+
+/*
+ * structure copying (direction independent)
+ * these macros are used as `copy' arguments to copy_type()
+ */
+#define copy_dyn_11(e,io,seq)		\
+    seq(copy_sword(e,io,d_tag),		\
+    seq(copy_addr(e,io,d_un.d_ptr),	\
+    nullcopy))
+#define copy_ehdr_11(e,io,seq)		\
+    seq(copy_arr(e,io,e_ident),		\
+    seq(copy_half(e,io,e_type),		\
+    seq(copy_half(e,io,e_machine),	\
+    seq(copy_word(e,io,e_version),	\
+    seq(copy_addr(e,io,e_entry),	\
+    seq(copy_off(e,io,e_phoff),		\
+    seq(copy_off(e,io,e_shoff),		\
+    seq(copy_word(e,io,e_flags),	\
+    seq(copy_half(e,io,e_ehsize),	\
+    seq(copy_half(e,io,e_phentsize),	\
+    seq(copy_half(e,io,e_phnum),	\
+    seq(copy_half(e,io,e_shentsize),	\
+    seq(copy_half(e,io,e_shnum),	\
+    seq(copy_half(e,io,e_shstrndx),	\
+    nullcopy))))))))))))))
+#define copy_phdr_11(e,io,seq)		\
+    seq(copy_word(e,io,p_type),		\
+    seq(copy_off(e,io,p_offset),	\
+    seq(copy_addr(e,io,p_vaddr),	\
+    seq(copy_addr(e,io,p_paddr),	\
+    seq(copy_word(e,io,p_filesz),	\
+    seq(copy_word(e,io,p_memsz),	\
+    seq(copy_word(e,io,p_flags),	\
+    seq(copy_word(e,io,p_align),	\
+    nullcopy))))))))
+#define copy_rela_11(e,io,seq)		\
+    seq(copy_addr(e,io,r_offset),	\
+    seq(copy_word(e,io,r_info),		\
+    seq(copy_sword(e,io,r_addend),	\
+    nullcopy)))
+#define copy_rel_11(e,io,seq)		\
+    seq(copy_addr(e,io,r_offset),	\
+    seq(copy_word(e,io,r_info),		\
+    nullcopy))
+#define copy_shdr_11(e,io,seq)		\
+    seq(copy_word(e,io,sh_name),	\
+    seq(copy_word(e,io,sh_type),	\
+    seq(copy_word(e,io,sh_flags),	\
+    seq(copy_addr(e,io,sh_addr),	\
+    seq(copy_off(e,io,sh_offset),	\
+    seq(copy_word(e,io,sh_size),	\
+    seq(copy_word(e,io,sh_link),	\
+    seq(copy_word(e,io,sh_info),	\
+    seq(copy_word(e,io,sh_addralign),	\
+    seq(copy_word(e,io,sh_entsize),	\
+    nullcopy))))))))))
+#define copy_sym_11(e,io,seq)		\
+    seq(copy_word(e,io,st_name),	\
+    seq(copy_addr(e,io,st_value),	\
+    seq(copy_word(e,io,st_size),	\
+    seq(copy_byte(e,io,st_info),	\
+    seq(copy_byte(e,io,st_other),	\
+    seq(copy_half(e,io,st_shndx),	\
+    nullcopy))))))
+
+#define nullcopy /**/
+
+static size_t
+byte_copy(unsigned char *dst, const unsigned char *src, size_t n) {
+    if (n && dst && dst != src) {
+#if HAVE_BROKEN_MEMMOVE
+	size_t i;
+
+	if (dst >= src + n || dst + n <= src) {
+	    memcpy(dst, src, n);
+	}
+	else if (dst < src) {
+	    for (i = 0; i < n; i++) {
+		dst[i] = src[i];
+	    }
+	}
+	else {
+	    for (i = n; --i; ) {
+		dst[i] = src[i];
+	    }
+	}
+#else /* HAVE_BROKEN_MEMMOVE */
+	memmove(dst, src, n);
+#endif /* HAVE_BROKEN_MEMMOVE */
+    }
+    return n;
+}
+
+static void
+array_copy(unsigned char *dst, size_t dlen, const unsigned char *src, size_t slen) {
+    byte_copy(dst, src, dlen < slen ? dlen : slen);
+    if (dlen > slen) {
+	memset(dst + slen, 0, dlen - slen);
+    }
+}
+
+/*
+ * instantiate copy functions
+ */
+copy_type(addr_32,_,Elf32_Addr,copy_addr_11)
+copy_type(half_32,_,Elf32_Half,copy_half_11)
+copy_type(off_32,_,Elf32_Off,copy_off_11)
+copy_type(sword_32,_,Elf32_Sword,copy_sword_11)
+copy_type(word_32,_,Elf32_Word,copy_word_11)
+copy_type(dyn_32,11,Elf32_Dyn,copy_dyn_11)
+copy_type(ehdr_32,11,Elf32_Ehdr,copy_ehdr_11)
+copy_type(phdr_32,11,Elf32_Phdr,copy_phdr_11)
+copy_type(rela_32,11,Elf32_Rela,copy_rela_11)
+copy_type(rel_32,11,Elf32_Rel,copy_rel_11)
+copy_type(shdr_32,11,Elf32_Shdr,copy_shdr_11)
+copy_type(sym_32,11,Elf32_Sym,copy_sym_11)
+
+typedef size_t (*xlator)(unsigned char*, const unsigned char*, size_t);
+typedef xlator xltab[ELF_T_NUM][2];
+
+/*
+ * translation table (32-bit, version 1 -> version 1)
+ */
+#if PIC
+static xltab
+#else /* PIC */
+static const xltab
+#endif /* PIC */
+xlate32_11[/*encoding*/] = {
+    {
+	{ byte_copy,        byte_copy       },
+	{ addr_32L__tom,    addr_32L__tof   },
+	{ dyn_32L11_tom,    dyn_32L11_tof   },
+	{ ehdr_32L11_tom,   ehdr_32L11_tof  },
+	{ half_32L__tom,    half_32L__tof   },
+	{ off_32L__tom,	    off_32L__tof    },
+	{ phdr_32L11_tom,   phdr_32L11_tof  },
+	{ rela_32L11_tom,   rela_32L11_tof  },
+	{ rel_32L11_tom,    rel_32L11_tof   },
+	{ shdr_32L11_tom,   shdr_32L11_tof  },
+	{ sword_32L__tom,   sword_32L__tof  },
+	{ sym_32L11_tom,    sym_32L11_tof   },
+	{ word_32L__tom,    word_32L__tof   },
+	{ 0,                0               },	/* there is no Sxword */
+	{ 0,                0               },	/* there is no Xword */
+#if __LIBELF_SYMBOL_VERSIONS
+	{ _elf_verdef_32L11_tom,  _elf_verdef_32L11_tof  },
+	{ _elf_verneed_32L11_tom, _elf_verneed_32L11_tof },
+#else /* __LIBELF_SYMBOL_VERSIONS */
+	{ 0,                0               },
+	{ 0,                0               },
+#endif /* __LIBELF_SYMBOL_VERSIONS */
+    },
+    {
+	{ byte_copy,        byte_copy       },
+	{ addr_32M__tom,    addr_32M__tof   },
+	{ dyn_32M11_tom,    dyn_32M11_tof   },
+	{ ehdr_32M11_tom,   ehdr_32M11_tof  },
+	{ half_32M__tom,    half_32M__tof   },
+	{ off_32M__tom,	    off_32M__tof    },
+	{ phdr_32M11_tom,   phdr_32M11_tof  },
+	{ rela_32M11_tom,   rela_32M11_tof  },
+	{ rel_32M11_tom,    rel_32M11_tof   },
+	{ shdr_32M11_tom,   shdr_32M11_tof  },
+	{ sword_32M__tom,   sword_32M__tof  },
+	{ sym_32M11_tom,    sym_32M11_tof   },
+	{ word_32M__tom,    word_32M__tof   },
+	{ 0,                0               },	/* there is no Sxword */
+	{ 0,                0               },	/* there is no Xword */
+#if __LIBELF_SYMBOL_VERSIONS
+	{ _elf_verdef_32M11_tom,  _elf_verdef_32M11_tof  },
+	{ _elf_verneed_32M11_tom, _elf_verneed_32M11_tof },
+#else /* __LIBELF_SYMBOL_VERSIONS */
+	{ 0,                0               },
+	{ 0,                0               },
+#endif /* __LIBELF_SYMBOL_VERSIONS */
+    },
+};
+
+/*
+ * main translation table (32-bit)
+ */
+#if PIC
+static xltab*
+#else /* PIC */
+static const xltab *const
+#endif /* PIC */
+xlate32[EV_CURRENT - EV_NONE][EV_CURRENT - EV_NONE] = {
+    { xlate32_11, },
+};
+
+#define translator(sv,dv,enc,type,d)	\
+    (xlate32[(sv) - EV_NONE - 1]	\
+	    [(dv) - EV_NONE - 1]	\
+	    [(enc) - ELFDATA2LSB]	\
+	    [(type) - ELF_T_BYTE]	\
+	    [d])
+
+/*
+ * destination buffer size
+ */
+size_t
+_elf32_xltsize(const Elf_Data *src, unsigned dv, unsigned encode, int tof) {
+    Elf_Type type = src->d_type;
+    unsigned sv = src->d_version;
+    xlator op;
+
+    if (!valid_version(sv) || !valid_version(dv)) {
+	seterr(ERROR_UNKNOWN_VERSION);
+	return (size_t)-1;
+    }
+    if (tof) {
+	/*
+	 * Encoding doesn't really matter (the translator only looks at
+	 * the source, which resides in memory), but we need a proper
+	 * encoding to select a translator...
+	 */
+	encode = ELFDATA2LSB;
+    }
+    else if (!valid_encoding(encode)) {
+	seterr(ERROR_UNKNOWN_ENCODING);
+	return (size_t)-1;
+    }
+    if (!valid_type(type)) {
+	seterr(ERROR_UNKNOWN_TYPE);
+	return (size_t)-1;
+    }
+    if (!(op = translator(sv, dv, encode, type, tof))) {
+	seterr(ERROR_UNKNOWN_TYPE);
+	return (size_t)-1;
+    }
+    return (*op)(NULL, src->d_buf, src->d_size);
+}
+
+/*
+ * direction-independent translation
+ */
+static Elf_Data*
+elf32_xlate(Elf_Data *dst, const Elf_Data *src, unsigned encode, int tof) {
+    Elf_Type type;
+    int dv;
+    int sv;
+    size_t dsize;
+    size_t tmp;
+    xlator op;
+
+    if (!src || !dst) {
+	return NULL;
+    }
+    if (!src->d_buf || !dst->d_buf) {
+	seterr(ERROR_NULLBUF);
+	return NULL;
+    }
+    if (!valid_encoding(encode)) {
+	seterr(ERROR_UNKNOWN_ENCODING);
+	return NULL;
+    }
+    sv = src->d_version;
+    dv = dst->d_version;
+    if (!valid_version(sv) || !valid_version(dv)) {
+	seterr(ERROR_UNKNOWN_VERSION);
+	return NULL;
+    }
+    type = src->d_type;
+    if (!valid_type(type)) {
+	seterr(ERROR_UNKNOWN_TYPE);
+	return NULL;
+    }
+    op = translator(sv, dv, encode, type, tof);
+    if (!op) {
+	seterr(ERROR_UNKNOWN_TYPE);
+	return NULL;
+    }
+    dsize = (*op)(NULL, src->d_buf, src->d_size);
+    if (dsize == (size_t)-1) {
+	return NULL;
+    }
+    if (dst->d_size < dsize) {
+	seterr(ERROR_DST2SMALL);
+	return NULL;
+    }
+    if (dsize) {
+	tmp = (*op)(dst->d_buf, src->d_buf, src->d_size);
+	if (tmp == (size_t)-1) {
+	    return NULL;
+	}
+	elf_assert(tmp == dsize);
+    }
+    dst->d_size = dsize;
+    dst->d_type = type;
+    return dst;
+}
+
+/*
+ * finally, the "official" translation functions
+ */
+Elf_Data*
+elf32_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned encode) {
+    return elf32_xlate(dst, src, encode, 0);
+}
+
+Elf_Data*
+elf32_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned encode) {
+    return elf32_xlate(dst, src, encode, 1);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/64.xlatetof.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,512 @@
+/*
+ * 64.xlatetof.c - implementation of the elf64_xlateto[fm](3) functions.
+ * Copyright (C) 1995 - 2006 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+#include <ext_types.h>
+#include <byteswap.h>
+
+#if __LIBELF64
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: 64.xlatetof.c,v 1.26 2006/07/27 22:33:40 michael Exp $";
+#endif /* lint */
+
+/*
+ * Ugly, ugly
+ */
+#ifdef _WIN32
+# define Cat2(a,b)a##b
+# define Cat3(a,b,c)a##b##c
+# define Ex1(m1,m2,a,b)m1##m2(a##b)
+# define Ex2(m1,m2,a,b,c)m1##m2(a,b##c)
+#else /* _WIN32 */
+# define x
+# if defined/**/x
+#  define Cat2(a,b)a##b
+#  define Cat3(a,b,c)a##b##c
+#  define Ex1(m1,m2,a,b)m1##m2(a##b)
+#  define Ex2(m1,m2,a,b,c)m1##m2(a,b##c)
+# else
+#  define Cat2(a,b)a/**/b
+#  define Cat3(a,b,c)a/**/b/**/c
+#  define Ex1(m1,m2,a,b)m1/**/m2(a/**/b)
+#  define Ex2(m1,m2,a,b,c)m1/**/m2(a,b/**/c)
+# endif
+# undef x
+#endif /* _WIN32 */
+
+/*
+ * auxiliary macros for execution order reversal
+ */
+#define seq_forw(a,b) a b
+#define seq_back(a,b) b a
+
+/*
+ * function instantiator
+ */
+#define copy_type_e_io(name,e,io,tfrom,tto,copy)		\
+    static size_t						\
+    Cat3(name,_,io)(unsigned char *dst, const unsigned char *src, size_t n) {	\
+	n /= sizeof(tfrom);					\
+	if (n && dst) {						\
+	    const tfrom *from = (const tfrom*)src;		\
+	    tto *to = (tto*)dst;				\
+	    size_t i;						\
+								\
+	    if (sizeof(tfrom) < sizeof(tto)) {			\
+		from += n;					\
+		to += n;					\
+		for (i = 0; i < n; i++) {			\
+		    --from;					\
+		    --to;					\
+		    copy(e,io,seq_back)				\
+		}						\
+	    }							\
+	    else {						\
+		for (i = 0; i < n; i++) {			\
+		    copy(e,io,seq_forw)				\
+		    from++;					\
+		    to++;					\
+		}						\
+	    }							\
+	}							\
+	return n * sizeof(tto);					\
+    }
+
+#define copy_type_e(name,e,type,copy)				\
+    copy_type_e_io(name,e,tom,Cat2(__ext_,type),type,copy)	\
+    copy_type_e_io(name,e,tof,type,Cat2(__ext_,type),copy)
+
+/*
+ * master function instantiator
+ */
+#define copy_type(name,version,type,copy)		\
+    copy_type_e(Cat3(name,L,version),L,type,copy)	\
+    copy_type_e(Cat3(name,M,version),M,type,copy)
+
+/*
+ * scalar copying
+ */
+#define copy_scalar_tom(type)	*to = Cat2(__load_,type)(*from);
+#define copy_scalar_tof(type)	Cat2(__store_,type)(*to, *from);
+
+/*
+ * structure member copying
+ */
+#define copy_tom(mb,type)	to->mb = Cat2(__load_,type)(from->mb);
+#define copy_tof(mb,type)	Cat2(__store_,type)(to->mb, from->mb);
+
+/*
+ * structure member copying (direction independent)
+ */
+#define copy_byte(e,io,mb)	to->mb = from->mb;
+#define copy_addr(e,io,mb)	Ex2(copy_,io,mb,u64,e)
+#define copy_half(e,io,mb)	Ex2(copy_,io,mb,u16,e)
+#define copy_off(e,io,mb)	Ex2(copy_,io,mb,u64,e)
+#define copy_sword(e,io,mb)	Ex2(copy_,io,mb,i32,e)
+#define copy_word(e,io,mb)	Ex2(copy_,io,mb,u32,e)
+#define copy_sxword(e,io,mb)	Ex2(copy_,io,mb,i64,e)
+#define copy_xword(e,io,mb)	Ex2(copy_,io,mb,u64,e)
+#define copy_arr(e,io,mb)	\
+    array_copy(to->mb, sizeof(to->mb), from->mb, sizeof(from->mb));
+
+/*
+ * scalar copying (direction independent)
+ * these macros are used as `copy' arguments to copy_type()
+ */
+#define copy_addr_11(e,io,seq)	Ex1(copy_scalar_,io,u64,e)
+#define copy_half_11(e,io,seq)	Ex1(copy_scalar_,io,u16,e)
+#define copy_off_11(e,io,seq)	Ex1(copy_scalar_,io,u64,e)
+#define copy_sword_11(e,io,seq)	Ex1(copy_scalar_,io,i32,e)
+#define copy_word_11(e,io,seq)	Ex1(copy_scalar_,io,u32,e)
+#define copy_sxword_11(e,io,seq)Ex1(copy_scalar_,io,i64,e)
+#define copy_xword_11(e,io,seq)	Ex1(copy_scalar_,io,u64,e)
+
+/*
+ * structure copying (direction independent)
+ * these macros are used as `copy' arguments to copy_type()
+ */
+#define copy_dyn_11(e,io,seq)		\
+    seq(copy_xword(e,io,d_tag),		\
+    seq(copy_addr(e,io,d_un.d_ptr),	\
+    nullcopy))
+#define copy_ehdr_11(e,io,seq)		\
+    seq(copy_arr(e,io,e_ident),		\
+    seq(copy_half(e,io,e_type),		\
+    seq(copy_half(e,io,e_machine),	\
+    seq(copy_word(e,io,e_version),	\
+    seq(copy_addr(e,io,e_entry),	\
+    seq(copy_off(e,io,e_phoff),		\
+    seq(copy_off(e,io,e_shoff),		\
+    seq(copy_word(e,io,e_flags),	\
+    seq(copy_half(e,io,e_ehsize),	\
+    seq(copy_half(e,io,e_phentsize),	\
+    seq(copy_half(e,io,e_phnum),	\
+    seq(copy_half(e,io,e_shentsize),	\
+    seq(copy_half(e,io,e_shnum),	\
+    seq(copy_half(e,io,e_shstrndx),	\
+    nullcopy))))))))))))))
+#define copy_phdr_11(e,io,seq)		\
+    seq(copy_word(e,io,p_type),		\
+    seq(copy_word(e,io,p_flags),	\
+    seq(copy_off(e,io,p_offset),	\
+    seq(copy_addr(e,io,p_vaddr),	\
+    seq(copy_addr(e,io,p_paddr),	\
+    seq(copy_xword(e,io,p_filesz),	\
+    seq(copy_xword(e,io,p_memsz),	\
+    seq(copy_xword(e,io,p_align),	\
+    nullcopy))))))))
+#if __LIBELF64_IRIX
+#define copy_rela_11(e,io,seq)		\
+    seq(copy_addr(e,io,r_offset),	\
+    seq(copy_word(e,io,r_sym),		\
+    seq(copy_byte(e,io,r_ssym),		\
+    seq(copy_byte(e,io,r_type3),	\
+    seq(copy_byte(e,io,r_type2),	\
+    seq(copy_byte(e,io,r_type),		\
+    seq(copy_sxword(e,io,r_addend),	\
+    nullcopy)))))))
+#define copy_rel_11(e,io,seq)		\
+    seq(copy_addr(e,io,r_offset),	\
+    seq(copy_word(e,io,r_sym),		\
+    seq(copy_byte(e,io,r_ssym),		\
+    seq(copy_byte(e,io,r_type3),	\
+    seq(copy_byte(e,io,r_type2),	\
+    seq(copy_byte(e,io,r_type),		\
+    nullcopy))))))
+#else /* __LIBELF64_IRIX */
+#define copy_rela_11(e,io,seq)		\
+    seq(copy_addr(e,io,r_offset),	\
+    seq(copy_xword(e,io,r_info),	\
+    seq(copy_sxword(e,io,r_addend),	\
+    nullcopy)))
+#define copy_rel_11(e,io,seq)		\
+    seq(copy_addr(e,io,r_offset),	\
+    seq(copy_xword(e,io,r_info),	\
+    nullcopy))
+#endif /* __LIBELF64_IRIX */
+#define copy_shdr_11(e,io,seq)		\
+    seq(copy_word(e,io,sh_name),	\
+    seq(copy_word(e,io,sh_type),	\
+    seq(copy_xword(e,io,sh_flags),	\
+    seq(copy_addr(e,io,sh_addr),	\
+    seq(copy_off(e,io,sh_offset),	\
+    seq(copy_xword(e,io,sh_size),	\
+    seq(copy_word(e,io,sh_link),	\
+    seq(copy_word(e,io,sh_info),	\
+    seq(copy_xword(e,io,sh_addralign),	\
+    seq(copy_xword(e,io,sh_entsize),	\
+    nullcopy))))))))))
+#define copy_sym_11(e,io,seq)		\
+    seq(copy_word(e,io,st_name),	\
+    seq(copy_byte(e,io,st_info),	\
+    seq(copy_byte(e,io,st_other),	\
+    seq(copy_half(e,io,st_shndx),	\
+    seq(copy_addr(e,io,st_value),	\
+    seq(copy_xword(e,io,st_size),	\
+    nullcopy))))))
+
+#define nullcopy /**/
+
+static size_t
+byte_copy(unsigned char *dst, const unsigned char *src, size_t n) {
+    if (n && dst && dst != src) {
+#if HAVE_BROKEN_MEMMOVE
+	size_t i;
+
+	if (dst >= src + n || dst + n <= src) {
+	    memcpy(dst, src, n);
+	}
+	else if (dst < src) {
+	    for (i = 0; i < n; i++) {
+		dst[i] = src[i];
+	    }
+	}
+	else {
+	    for (i = n; --i; ) {
+		dst[i] = src[i];
+	    }
+	}
+#else /* HAVE_BROKEN_MEMMOVE */
+	memmove(dst, src, n);
+#endif /* HAVE_BROKEN_MEMMOVE */
+    }
+    return n;
+}
+
+static void
+array_copy(unsigned char *dst, size_t dlen, const unsigned char *src, size_t slen) {
+    byte_copy(dst, src, dlen < slen ? dlen : slen);
+    if (dlen > slen) {
+	memset(dst + slen, 0, dlen - slen);
+    }
+}
+
+/*
+ * instantiate copy functions
+ */
+copy_type(addr_64,_,Elf64_Addr,copy_addr_11)
+copy_type(half_64,_,Elf64_Half,copy_half_11)
+copy_type(off_64,_,Elf64_Off,copy_off_11)
+copy_type(sword_64,_,Elf64_Sword,copy_sword_11)
+copy_type(word_64,_,Elf64_Word,copy_word_11)
+copy_type(sxword_64,_,Elf64_Sxword,copy_sxword_11)
+copy_type(xword_64,_,Elf64_Xword,copy_xword_11)
+copy_type(dyn_64,11,Elf64_Dyn,copy_dyn_11)
+copy_type(ehdr_64,11,Elf64_Ehdr,copy_ehdr_11)
+copy_type(phdr_64,11,Elf64_Phdr,copy_phdr_11)
+copy_type(rela_64,11,Elf64_Rela,copy_rela_11)
+copy_type(rel_64,11,Elf64_Rel,copy_rel_11)
+copy_type(shdr_64,11,Elf64_Shdr,copy_shdr_11)
+copy_type(sym_64,11,Elf64_Sym,copy_sym_11)
+
+typedef size_t (*xlator)(unsigned char*, const unsigned char*, size_t);
+typedef xlator xltab[ELF_T_NUM][2];
+
+/*
+ * translation table (64-bit, version 1 -> version 1)
+ */
+#if PIC
+static xltab
+#else /* PIC */
+static const xltab
+#endif /* PIC */
+xlate64_11[/*encoding*/] = {
+    {
+	{ byte_copy,        byte_copy       },
+	{ addr_64L__tom,    addr_64L__tof   },
+	{ dyn_64L11_tom,    dyn_64L11_tof   },
+	{ ehdr_64L11_tom,   ehdr_64L11_tof  },
+	{ half_64L__tom,    half_64L__tof   },
+	{ off_64L__tom,     off_64L__tof    },
+	{ phdr_64L11_tom,   phdr_64L11_tof  },
+	{ rela_64L11_tom,   rela_64L11_tof  },
+	{ rel_64L11_tom,    rel_64L11_tof   },
+	{ shdr_64L11_tom,   shdr_64L11_tof  },
+	{ sword_64L__tom,   sword_64L__tof  },
+	{ sym_64L11_tom,    sym_64L11_tof   },
+	{ word_64L__tom,    word_64L__tof   },
+	{ sxword_64L__tom,  sxword_64L__tof },
+	{ xword_64L__tom,   xword_64L__tof  },
+#if __LIBELF_SYMBOL_VERSIONS
+	{ _elf_verdef_64L11_tom,  _elf_verdef_64L11_tof  },
+	{ _elf_verneed_64L11_tom, _elf_verneed_64L11_tof },
+#else /* __LIBELF_SYMBOL_VERSIONS */
+	{ 0,                0               },
+	{ 0,                0               },
+#endif /* __LIBELF_SYMBOL_VERSIONS */
+    },
+    {
+	{ byte_copy,        byte_copy       },
+	{ addr_64M__tom,    addr_64M__tof   },
+	{ dyn_64M11_tom,    dyn_64M11_tof   },
+	{ ehdr_64M11_tom,   ehdr_64M11_tof  },
+	{ half_64M__tom,    half_64M__tof   },
+	{ off_64M__tom,     off_64M__tof    },
+	{ phdr_64M11_tom,   phdr_64M11_tof  },
+	{ rela_64M11_tom,   rela_64M11_tof  },
+	{ rel_64M11_tom,    rel_64M11_tof   },
+	{ shdr_64M11_tom,   shdr_64M11_tof  },
+	{ sword_64M__tom,   sword_64M__tof  },
+	{ sym_64M11_tom,    sym_64M11_tof   },
+	{ word_64M__tom,    word_64M__tof   },
+	{ sxword_64M__tom,  sxword_64M__tof },
+	{ xword_64M__tom,   xword_64M__tof  },
+#if __LIBELF_SYMBOL_VERSIONS
+	{ _elf_verdef_64M11_tom,  _elf_verdef_64M11_tof  },
+	{ _elf_verneed_64M11_tom, _elf_verneed_64M11_tof },
+#else /* __LIBELF_SYMBOL_VERSIONS */
+	{ 0,                0               },
+	{ 0,                0               },
+#endif /* __LIBELF_SYMBOL_VERSIONS */
+    },
+};
+
+/*
+ * main translation table (64-bit)
+ */
+#if PIC
+static xltab*
+#else /* PIC */
+static const xltab *const
+#endif /* PIC */
+xlate64[EV_CURRENT - EV_NONE][EV_CURRENT - EV_NONE] = {
+    { xlate64_11, },
+};
+
+#define translator(sv,dv,enc,type,d)	\
+    (xlate64[(sv) - EV_NONE - 1]	\
+	    [(dv) - EV_NONE - 1]	\
+	    [(enc) - ELFDATA2LSB]	\
+	    [(type) - ELF_T_BYTE]	\
+	    [d])
+
+/*
+ * destination buffer size
+ */
+size_t
+_elf64_xltsize(const Elf_Data *src, unsigned dv, unsigned encode, int tof) {
+    Elf_Type type = src->d_type;
+    unsigned sv = src->d_version;
+    xlator op;
+
+    if (!valid_version(sv) || !valid_version(dv)) {
+	seterr(ERROR_UNKNOWN_VERSION);
+	return (size_t)-1;
+    }
+    if (tof) {
+	/*
+	 * Encoding doesn't really matter (the translator only looks at
+	 * the source, which resides in memory), but we need a proper
+	 * encoding to select a translator...
+	 */
+	encode = ELFDATA2LSB;
+    }
+    else if (!valid_encoding(encode)) {
+	seterr(ERROR_UNKNOWN_ENCODING);
+	return (size_t)-1;
+    }
+    if (!valid_type(type)) {
+	seterr(ERROR_UNKNOWN_TYPE);
+	return (size_t)-1;
+    }
+    if (!(op = translator(sv, dv, encode, type, tof))) {
+	seterr(ERROR_UNKNOWN_TYPE);
+	return (size_t)-1;
+    }
+    return (*op)(NULL, src->d_buf, src->d_size);
+}
+
+/*
+ * direction-independent translation
+ */
+static Elf_Data*
+elf64_xlate(Elf_Data *dst, const Elf_Data *src, unsigned encode, int tof) {
+    Elf_Type type;
+    int dv;
+    int sv;
+    size_t dsize;
+    size_t tmp;
+    xlator op;
+
+    if (!src || !dst) {
+	return NULL;
+    }
+    if (!src->d_buf || !dst->d_buf) {
+	seterr(ERROR_NULLBUF);
+	return NULL;
+    }
+    if (!valid_encoding(encode)) {
+	seterr(ERROR_UNKNOWN_ENCODING);
+	return NULL;
+    }
+    sv = src->d_version;
+    dv = dst->d_version;
+    if (!valid_version(sv) || !valid_version(dv)) {
+	seterr(ERROR_UNKNOWN_VERSION);
+	return NULL;
+    }
+    type = src->d_type;
+    if (!valid_type(type)) {
+	seterr(ERROR_UNKNOWN_TYPE);
+	return NULL;
+    }
+    op = translator(sv, dv, encode, type, tof);
+    if (!op) {
+	seterr(ERROR_UNKNOWN_TYPE);
+	return NULL;
+    }
+    dsize = (*op)(NULL, src->d_buf, src->d_size);
+    if (dsize == (size_t)-1) {
+	return NULL;
+    }
+    if (dst->d_size < dsize) {
+	seterr(ERROR_DST2SMALL);
+	return NULL;
+    }
+    if (dsize) {
+	tmp = (*op)(dst->d_buf, src->d_buf, src->d_size);
+	if (tmp == (size_t)-1) {
+	    return NULL;
+	}
+	elf_assert(tmp == dsize);
+    }
+    dst->d_size = dsize;
+    dst->d_type = type;
+    return dst;
+}
+
+/*
+ * finally, the "official" translation functions
+ */
+Elf_Data*
+elf64_xlatetom(Elf_Data *dst, const Elf_Data *src, unsigned encode) {
+    return elf64_xlate(dst, src, encode, 0);
+}
+
+Elf_Data*
+elf64_xlatetof(Elf_Data *dst, const Elf_Data *src, unsigned encode) {
+    return elf64_xlate(dst, src, encode, 1);
+}
+
+Elf_Data*
+gelf_xlatetom(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) {
+    if (elf) {
+	if (elf->e_kind != ELF_K_ELF) {
+	    seterr(ERROR_NOTELF);
+	}
+	else if (elf->e_class == ELFCLASS32) {
+	    return elf32_xlatetom(dst, src, encode);
+	}
+	else if (elf->e_class == ELFCLASS64) {
+	    return elf64_xlatetom(dst, src, encode);
+	}
+	else if (valid_class(elf->e_class)) {
+	    seterr(ERROR_UNIMPLEMENTED);
+	}
+	else {
+	    seterr(ERROR_UNKNOWN_CLASS);
+	}
+    }
+    return NULL;
+}
+
+Elf_Data*
+gelf_xlatetof(Elf *elf, Elf_Data *dst, const Elf_Data *src, unsigned encode) {
+    if (elf) {
+	if (elf->e_kind != ELF_K_ELF) {
+	    seterr(ERROR_NOTELF);
+	}
+	else if (elf->e_class == ELFCLASS32) {
+	    return elf32_xlatetof(dst, src, encode);
+	}
+	else if (elf->e_class == ELFCLASS64) {
+	    return elf64_xlatetof(dst, src, encode);
+	}
+	else if (valid_class(elf->e_class)) {
+	    seterr(ERROR_UNIMPLEMENTED);
+	}
+	else {
+	    seterr(ERROR_UNKNOWN_CLASS);
+	}
+    }
+    return NULL;
+}
+
+#endif /* __LIBELF64__ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/Makefile.in	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,278 @@
+# lib/Makefile for libelf.
+# Copyright (C) 1995 - 2006 Michael Riepe
+# 
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+# 
+# This library 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
+# Library General Public License for more details.
+# 
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+# @(#) $Id: Makefile.in,v 1.38 2007/06/29 21:34:25 michael Exp $
+
+instroot =
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+libdir = @libdir@
+includedir = @includedir@
+installdirs = $(libdir) $(includedir) $(includedir)/libelf
+
+CC = @CC@
+LD = @LD@
+AR = ar
+MV = mv -f
+RM = rm -f
+LN_S = @LN_S@
+RANLIB = @RANLIB@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+DEFS = -DHAVE_CONFIG_H
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+DEPSHLIBS = @DEPSHLIBS@
+
+DO_SHLIB = @DO_SHLIB@
+PICFLAGS = @PICFLAGS@
+SHLIB_SFX = @SHLIB_SFX@
+SHLINK_SFX = @SHLINK_SFX@
+SONAME_SFX = @SONAME_SFX@
+LINK_SHLIB = @LINK_SHLIB@
+INSTALL_SHLIB = @INSTALL_SHLIB@
+
+SHLIB = libelf$(SHLIB_SFX)
+SHLINK = libelf$(SHLINK_SFX)
+SONAME = libelf$(SONAME_SFX)
+
+# install includes in includedir?
+DO_COMPAT = @DO_COMPAT@
+
+COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
+
+# no user serviceable parts below
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+MAJOR = @MAJOR@
+
+SHELL = /bin/sh
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+topdir = ..
+subdir = lib
+
+.SUFFIXES:
+.SUFFIXES: .c .o
+.c.o:
+	@$(RM) $@ $(@:.o=.os)
+	if test -n "$(PICFLAGS)"; then \
+	  $(COMPILE) $(PICFLAGS) $< && $(MV) $@ $(@:.o=.os); \
+	else true; fi
+	$(COMPILE) $<
+
+INCLUDES = -I$(topdir) -I. -I$(srcdir)
+
+# generic sources
+SRCS1 = begin.c cntl.c end.c errmsg.c errno.c fill.c flag.c getarhdr.c \
+	getarsym.c getbase.c getdata.c getident.c getscn.c hash.c kind.c \
+	ndxscn.c newdata.c newscn.c next.c nextscn.c rand.c rawdata.c \
+	rawfile.c strptr.c update.c version.c checksum.c
+OBJS1 = begin.o cntl.o end.o errmsg.o errno.o fill.o flag.o getarhdr.o \
+	getarsym.o getbase.o getdata.o getident.o getscn.o hash.o kind.o \
+	ndxscn.o newdata.o newscn.o next.o nextscn.o rand.o rawdata.o \
+	rawfile.o strptr.o update.o version.o checksum.o
+
+# 32-bit sources
+SRCS2 = 32.fsize.c 32.getehdr.c 32.getphdr.c 32.getshdr.c 32.newehdr.c \
+	32.newphdr.c 32.xlatetof.c
+OBJS2 = 32.fsize.o 32.getehdr.o 32.getphdr.o 32.getshdr.o 32.newehdr.o \
+	32.newphdr.o 32.xlatetof.o
+
+# support
+SRCS3 = cook.c data.c input.c assert.c
+OBJS3 = cook.o data.o input.o assert.o
+
+# nlist
+SRCS4 = nlist.c
+OBJS4 = nlist.o
+
+# opt
+SRCS5 = opt.delscn.c x.remscn.c x.movscn.c x.elfext.c
+OBJS5 = opt.delscn.o x.remscn.o x.movscn.o x.elfext.o
+
+# 64-bit sources
+SRCS64 = 64.xlatetof.c gelfehdr.c gelfphdr.c gelfshdr.c gelftrans.c swap64.c
+OBJS64 = 64.xlatetof.o gelfehdr.o gelfphdr.o gelfshdr.o gelftrans.o swap64.o
+
+# Versioning sources
+SRCS_V = verdef_32_tof.c verdef_32_tom.c verdef_64_tof.c verdef_64_tom.c
+OBJS_V = verdef_32_tof.o verdef_32_tom.o verdef_64_tof.o verdef_64_tom.o
+HDRS_V = verdef.h verneed.h
+
+SRCS = $(SRCS1) $(SRCS2) $(SRCS3) $(SRCS4) $(SRCS5) $(SRCS64) $(SRCS_V)
+OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) $(OBJS64) $(OBJS_V)
+
+# missing functions
+LIBSRCS = memset.c
+LIBOBJS = @LIBOBJS@
+
+# public header files
+HDRS = libelf.h nlist.h gelf.h
+
+# public header files (created by configure)
+AUXHDRS = sys_elf.h
+
+# private header files
+PRIVHDRS = byteswap.h errors.h ext_types.h private.h elf_repl.h \
+	$(HDRS_V)
+
+DISTFILES = $(SRCS) $(LIBSRCS) $(HDRS) $(PRIVHDRS) Makefile.in sys_elf.h.in \
+    Makefile.w32 build.bat config.h.w32 libelf.def sys_elf.h.w32
+
+all: libelf.a shared-$(DO_SHLIB)
+
+check:
+
+shared-yes: $(SHLIB)
+shared-no:
+
+libelf.a: $(OBJS) $(LIBOBJS)
+	@$(RM) $@
+	$(AR) rcv $@ $(OBJS) $(LIBOBJS)
+	$(RANLIB) $@
+
+$(SHLIB): libelf.a
+	@$(RM) $(SHLIB)
+	$(LINK_SHLIB) -o $(SHLIB) $(OBJS:.o=.os) $(LIBOBJS:.o=.os) $(DEPSHLIBS)
+	if test "$(SONAME)" = "$(SHLIB)"; then true; else \
+	  $(RM) $(SONAME) && $(LN_S) $(SHLIB) $(SONAME); \
+	fi
+	if test "$(SHLINK)" = "$(SHLIB)"; then true; else \
+	  $(RM) $(SHLINK) && $(LN_S) $(SHLIB) $(SHLINK); \
+	fi
+
+install: install-data \
+	install-shared-$(DO_SHLIB) install-compat-$(DO_COMPAT)
+
+installdirs: $(top_srcdir)/mkinstalldirs
+	dirs="$(installdirs)"; for dir in $$dirs; do \
+	    $(SHELL) $(top_srcdir)/mkinstalldirs $(instroot)$$dir; \
+	done
+
+install-data: all installdirs
+	$(INSTALL_DATA) libelf.a $(instroot)$(libdir)
+	-cd $(instroot)$(libdir) && $(RANLIB) libelf.a
+	files="$(HDRS) $(AUXHDRS) elf_repl.h"; for file in $$files; do \
+	  if test -r $$file; then \
+	    $(INSTALL_DATA) $$file $(instroot)$(includedir)/libelf; \
+	  else \
+	    $(INSTALL_DATA) $(srcdir)/$$file $(instroot)$(includedir)/libelf; \
+	  fi; \
+	done
+
+uninstall: uninstall-data \
+	uninstall-shared-$(DO_SHLIB) uninstall-compat-$(DO_COMPAT)
+
+uninstall-data:
+	$(RM) $(instroot)$(libdir)/libelf.a
+	$(RM) -r $(instroot)$(includedir)/libelf
+
+install-shared-yes: install-shared
+install-shared-no:
+install-shared: installdirs $(SHLIB)
+	$(INSTALL_SHLIB) $(SHLIB) $(instroot)$(libdir)
+	if test "$(SONAME)" = "$(SHLIB)"; then true; else \
+	  cd $(instroot)$(libdir) && $(RM) $(SONAME) && $(LN_S) $(SHLIB) $(SONAME); \
+	fi
+	if test "$(SHLINK)" = "$(SHLIB)"; then true; else \
+	  cd $(instroot)$(libdir) && $(RM) $(SHLINK) && $(LN_S) $(SHLIB) $(SHLINK); \
+	fi
+
+uninstall-shared-yes: uninstall-shared
+uninstall-shared-no:
+uninstall-shared:
+	cd $(instroot)$(libdir) && $(RM) $(SHLIB) $(SONAME) $(SHLINK)
+
+install-compat-yes: install-compat
+install-compat-no:
+install-compat: installdirs
+	files="$(HDRS)"; for file in $$files; do \
+	  if test -f $(instroot)$(includedir)/$$file; then true; else \
+	    echo "#include <libelf/$$file>" > $(instroot)$(includedir)/$$file; \
+	  fi; \
+	done
+
+uninstall-compat-yes: uninstall-compat
+uninstall-compat-no:
+uninstall-compat:
+	files="$(HDRS)"; for file in $$files; do \
+	  if grep "^#include <libelf/$$file>\$$" $(instroot)$(includedir)/$$file >/dev/null 2>&1; then \
+	    $(RM) $(instroot)$(includedir)/$$file; \
+	  else true; fi; \
+	done
+
+mostlyclean:
+	$(RM) *.o *.a *.os $(SHLIB) $(SONAME) $(SHLINK)
+	$(RM) *~ core a.out errlist
+
+clean: mostlyclean
+
+distclean: clean
+	$(RM) stamp-h $(AUXHDRS)
+	$(RM) Makefile
+
+maintainer-clean: distclean
+
+# maintainer only
+
+MAINT = @MAINT@
+
+distdir = $(PACKAGE)-$(VERSION)
+distsubdir = $(topdir)/$(distdir)/$(subdir)
+$(MAINT)dist: $(DISTFILES)
+	if test -d $(distsubdir); then true; else mkdir $(distsubdir); fi
+	files="$(DISTFILES)"; for file in $$files; do \
+	  ln $(srcdir)/$$file $(distsubdir) || \
+	    cp -p $(srcdir)/$$file $(distsubdir) || exit 1; \
+	done
+
+# For the justification of the following Makefile rules, see node
+# `Automatic Remaking' in GNU Autoconf documentation.
+
+$(MAINT)Makefile: Makefile.in $(topdir)/config.status
+	cd $(topdir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
+
+$(MAINT)sys_elf.h: stamp-h
+$(MAINT)stamp-h: sys_elf.h.in $(topdir)/config.status
+	cd $(topdir) && CONFIG_FILES= CONFIG_HEADERS=$(subdir)/sys_elf.h ./config.status
+	$(RM) stamp-h && echo timestamp > stamp-h
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
+
+# dependencies
+$(OBJS): private.h $(topdir)/config.h libelf.h gelf.h errors.h $(AUXHDRS)
+32.fsize.o: ext_types.h
+32.xlatetof.o: byteswap.h ext_types.h
+64.xlatetof.o: byteswap.h ext_types.h
+getarsym.o: byteswap.h
+memset.o: $(topdir)/config.h
+nlist.o: nlist.h
+swap64.o: byteswap.h
+$(OBJS_V): byteswap.h ext_types.h $(HDRS_V)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/Makefile.w32	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,166 @@
+# lib/Makefile.w32 - Makefile for W32 port.
+# Copyright (C) 1995 - 2006 Michael Riepe
+# 
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+# 
+# This library 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
+# Library General Public License for more details.
+# 
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+# @(#) $Id: Makefile.w32,v 1.2 2006/11/21 20:21:12 michael Exp $
+
+instroot =
+
+prefix = 
+exec_prefix = 
+libdir = 
+includedir = 
+installdirs = $(libdir) $(includedir) $(includedir)/libelf
+
+CC = cl /nologo
+LD = link /nologo
+AR = 
+MV = 
+RM = del
+LN_S = 
+RANLIB = 
+INSTALL = 
+INSTALL_DATA = 
+INSTALL_PROGRAM = 
+
+CFLAGS = /O2 /W2 /TC /MD
+CPPFLAGS = 
+DEFS = /DHAVE_CONFIG_H
+LDFLAGS = 
+LIBS = 
+DEPSHLIBS = 
+
+DO_SHLIB = 
+PICFLAGS = 
+SHLIB_SFX = .dll
+SHLINK_SFX = 
+SONAME_SFX = 
+LINK_SHLIB = $(LD) /DLL $(LDFLAGS)
+
+SHLIB = libelf$(SHLIB_SFX)
+SHLINK = libelf$(SHLINK_SFX)
+SONAME = libelf$(SONAME_SFX)
+
+# install includes in includedir?
+DO_COMPAT = 
+
+INCLUDES = /I.
+
+COMPILE = $(CC) /c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS)
+
+# no user serviceable parts below
+
+PACKAGE = libelf
+VERSION = 0.8.9
+MAJOR = 0
+
+SHELL = /bin/sh
+
+srcdir = .
+top_srcdir = ..
+
+topdir = ..
+subdir = lib
+
+.SUFFIXES:
+.SUFFIXES: .obj .c
+.c.obj:
+	$(COMPILE) $<
+
+# generic sources
+SRCS1 = begin.c cntl.c end.c errmsg.c errno.c fill.c flag.c getarhdr.c \
+	getarsym.c getbase.c getdata.c getident.c getscn.c hash.c kind.c \
+	ndxscn.c newdata.c newscn.c next.c nextscn.c rand.c rawdata.c \
+	rawfile.c strptr.c update.c version.c checksum.c
+OBJS1 = $(SRCS1:.c=.obj)
+
+# 32-bit sources
+SRCS2 = 32.fsize.c 32.getehdr.c 32.getphdr.c 32.getshdr.c 32.newehdr.c \
+	32.newphdr.c 32.xlatetof.c
+OBJS2 = $(SRCS2:.c=.obj)
+
+# support
+SRCS3 = cook.c data.c input.c assert.c
+OBJS3 = $(SRCS3:.c=.obj)
+
+# nlist
+SRCS4 = nlist.c
+OBJS4 = $(SRCS4:.c=.obj)
+
+# opt
+SRCS5 = opt.delscn.c x.remscn.c x.movscn.c x.elfext.c
+OBJS5 = $(SRCS5:.c=.obj)
+
+# 64-bit sources
+SRCS64 = 64.xlatetof.c gelfehdr.c gelfphdr.c gelfshdr.c gelftrans.c swap64.c
+OBJS64 = $(SRCS64:.c=.obj)
+
+# Versioning sources
+SRCS_V = verdef_32_tof.c verdef_32_tom.c verdef_64_tof.c verdef_64_tom.c
+OBJS_V = $(SRCS_V:.c=.obj)
+HDRS_V = verdef.h verneed.h
+
+SRCS = $(SRCS1) $(SRCS2) $(SRCS3) $(SRCS4) $(SRCS5) $(SRCS64) $(SRCS_V)
+OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) $(OBJS5) $(OBJS64) $(OBJS_V)
+
+# missing functions
+LIBSRCS = memset.c
+LIBOBJS = 
+
+# public header files
+HDRS = libelf.h nlist.h gelf.h
+
+# public header files (created by configure)
+AUXHDRS = sys_elf.h
+
+# private header files
+PRIVHDRS = byteswap.h errors.h ext_types.h private.h elf_repl.h $(HDRS_V)
+
+DISTFILES = $(SRCS) $(LIBSRCS) $(HDRS) $(PRIVHDRS) Makefile.in sys_elf.h.in
+
+all: $(OBJS) $(SHLIB)
+
+check:
+
+$(SHLIB): libelf.def $(OBJS) $(LIBOBJS)
+	-@$(RM) $(SHLIB)
+	$(LINK_SHLIB) /OUT:"$(SHLIB)" /DEF:"libelf.def" $(OBJS) $(LIBOBJS) kernel32.lib
+
+install:
+
+mostlyclean:
+	-$(RM) *.obj
+	-$(RM) $(SHLIB)
+	-$(RM) libelf.lib
+	-$(RM) libelf.exp
+
+clean: mostlyclean
+
+distclean: clean
+	-$(RM) $(AUXHDRS)
+
+maintainer-clean: distclean
+
+# dependencies
+$(OBJS): private.h config.h libelf.h gelf.h errors.h $(AUXHDRS)
+32.fsize.obj: ext_types.h
+32.xlatetof.obj: byteswap.h ext_types.h
+64.xlatetof.obj: byteswap.h ext_types.h
+getarsym.obj: byteswap.h
+memset.obj: config.h
+nlist.obj: nlist.h
+swap64.obj: byteswap.h
+$(OBJS_V): byteswap.h ext_types.h $(HDRS_V)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/assert.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,33 @@
+/*
+assert.c - assert function for libelf.
+Copyright (C) 1999 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: assert.c,v 1.4 2005/05/21 15:39:20 michael Exp $";
+#endif /* lint */
+
+#include <stdio.h>
+
+void
+__elf_assert(const char *file, unsigned line, const char *cond) {
+    fprintf(stderr, "%s:%u: libelf assertion failure: %s\n",
+	    file, line, cond);
+    abort();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/begin.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,450 @@
+/*
+ * begin.c - implementation of the elf_begin(3) and elf_memory(3) functions.
+ * Copyright (C) 1995 - 2004 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: begin.c,v 1.20 2006/08/17 23:59:58 michael Exp $";
+#endif /* lint */
+
+#if HAVE_AR_H
+#include <ar.h>
+#else /* HAVE_AR_H */
+
+#define ARMAG	"!<arch>\n"
+#define SARMAG	8
+
+struct ar_hdr {
+    char    ar_name[16];
+    char    ar_date[12];
+    char    ar_uid[6];
+    char    ar_gid[6];
+    char    ar_mode[8];
+    char    ar_size[10];
+    char    ar_fmag[2];
+};
+
+#define ARFMAG	"`\n"
+
+#endif /* HAVE_AR_H */
+
+static const Elf _elf_init = INIT_ELF;
+static const char fmag[] = ARFMAG;
+
+static unsigned long
+getnum(const char *str, size_t len, int base, size_t *err) {
+    unsigned long result = 0;
+
+    while (len && *str == ' ') {
+	str++; len--;
+    }
+    while (len && *str >= '0' && (*str - '0') < base) {
+	result = base * result + *str++ - '0'; len--;
+    }
+    while (len && *str == ' ') {
+	str++; len--;
+    }
+    if (len) {
+	*err = len;
+    }
+    return result;
+}
+
+static void
+_elf_init_ar(Elf *elf) {
+    struct ar_hdr *hdr;
+    size_t offset;
+    size_t size;
+    size_t err = 0;
+
+    elf->e_kind = ELF_K_AR;
+    elf->e_idlen = SARMAG;
+    elf->e_off = SARMAG;
+
+    /* process special members */
+    offset = SARMAG;
+    while (!elf->e_strtab && offset + sizeof(*hdr) <= elf->e_size) {
+	hdr = (struct ar_hdr*)(elf->e_data + offset);
+	if (memcmp(hdr->ar_fmag, fmag, sizeof(fmag) - 1)) {
+	    break;
+	}
+	if (hdr->ar_name[0] != '/') {
+	    break;
+	}
+	size = getnum(hdr->ar_size, sizeof(hdr->ar_size), 10, &err);
+	if (err || !size) {
+	    break;
+	}
+	offset += sizeof(*hdr);
+	if (offset + size > elf->e_size) {
+	    break;
+	}
+	if (hdr->ar_name[1] == '/' && hdr->ar_name[2] == ' ') {
+	    elf->e_strtab = elf->e_data + offset;
+	    elf->e_strlen = size;
+	    break;
+	}
+	if (hdr->ar_name[1] != ' ') {
+	    break;
+	}
+	/*
+	 * Windows (.lib) archives provide two symbol tables
+	 * The first one is the one we want.
+	 */
+	if (!elf->e_symtab) {
+	    elf->e_symtab = elf->e_data + offset;
+	    elf->e_symlen = size;
+	}
+	offset += size + (size & 1);
+    }
+}
+
+static Elf_Arhdr*
+_elf_arhdr(Elf *arf) {
+    struct ar_hdr *hdr;
+    Elf_Arhdr *arhdr;
+    size_t namelen;
+    size_t tmp;
+    char *name;
+    size_t err = 0;
+
+    if (arf->e_off == arf->e_size) {
+	/* no error! */
+	return NULL;
+    }
+    if (arf->e_off < 0 || arf->e_off > arf->e_size) {
+	seterr(ERROR_OUTSIDE);
+	return NULL;
+    }
+    if (arf->e_off + sizeof(*hdr) > arf->e_size) {
+	seterr(ERROR_TRUNC_ARHDR);
+	return NULL;
+    }
+    elf_assert(arf->e_data != NULL);
+    hdr = (struct ar_hdr*)(arf->e_data + arf->e_off);
+    if (memcmp(hdr->ar_fmag, fmag, sizeof(fmag) - 1)) {
+	seterr(ERROR_ARFMAG);
+	return NULL;
+    }
+
+    name = hdr->ar_name;
+    for (namelen = sizeof(hdr->ar_name); namelen > 0; namelen--) {
+	if (name[namelen - 1] != ' ') {
+	    break;
+	}
+    }
+    if (name[0] == '/') {
+	if (name[1] >= '0' && name[1] <= '9') {
+	    if (!arf->e_strtab) {
+		seterr(ERROR_ARSTRTAB);
+		return NULL;
+	    }
+	    tmp = getnum(&name[1], namelen - 1, 10, &err);
+	    if (err) {
+		seterr(ERROR_ARSPECIAL);
+		return NULL;
+	    }
+	    if (tmp < 0 || tmp >= arf->e_strlen) {
+		seterr(ERROR_ARSTRTAB);
+		return NULL;
+	    }
+	    for (namelen = tmp; namelen < arf->e_strlen; namelen++) {
+		if (arf->e_strtab[namelen] == '/') {
+		    break;
+		}
+	    }
+	    if (namelen == arf->e_strlen) {
+		seterr(ERROR_ARSTRTAB);
+		return NULL;
+	    }
+	    name = arf->e_strtab + tmp;
+	    namelen -= tmp;
+	}
+	else if (namelen != 1 && !(namelen == 2 && name[1] == '/')) {
+	    seterr(ERROR_ARSPECIAL);
+	    return NULL;
+	}
+    }
+    else if (namelen > 0 && name[namelen - 1] == '/') {
+	namelen--;
+    }
+    /* XXX some broken software omits the trailing slash
+    else {
+	namelen = 0;
+    }
+    */
+
+    if (!(arhdr = (Elf_Arhdr*)malloc(sizeof(*arhdr) +
+		     sizeof(hdr->ar_name) + namelen + 2))) {
+	seterr(ERROR_MEM_ARHDR);
+	return NULL;
+    }
+
+    arhdr->ar_name = NULL;
+    arhdr->ar_rawname = (char*)(arhdr + 1);
+    arhdr->ar_date = getnum(hdr->ar_date, sizeof(hdr->ar_date), 10, &err);
+    arhdr->ar_uid = getnum(hdr->ar_uid, sizeof(hdr->ar_uid), 10, &err);
+    arhdr->ar_gid = getnum(hdr->ar_gid, sizeof(hdr->ar_gid), 10, &err);
+    arhdr->ar_mode = getnum(hdr->ar_mode, sizeof(hdr->ar_mode), 8, &err);
+    arhdr->ar_size = getnum(hdr->ar_size, sizeof(hdr->ar_size), 10, &err);
+    if (err) {
+	free(arhdr);
+	seterr(ERROR_ARHDR);
+	return NULL;
+    }
+    if (arf->e_off + sizeof(struct ar_hdr) + arhdr->ar_size > arf->e_size) {
+	free(arhdr);
+	seterr(ERROR_TRUNC_MEMBER);
+	return NULL;
+    }
+
+    memcpy(arhdr->ar_rawname, hdr->ar_name, sizeof(hdr->ar_name));
+    arhdr->ar_rawname[sizeof(hdr->ar_name)] = '\0';
+
+    if (namelen) {
+	arhdr->ar_name = arhdr->ar_rawname + sizeof(hdr->ar_name) + 1;
+	memcpy(arhdr->ar_name, name, namelen);
+	arhdr->ar_name[namelen] = '\0';
+    }
+
+    return arhdr;
+}
+
+static void
+_elf_check_type(Elf *elf, size_t size) {
+    elf->e_idlen = size;
+    if (size >= EI_NIDENT && !memcmp(elf->e_data, ELFMAG, SELFMAG)) {
+	elf->e_kind = ELF_K_ELF;
+	elf->e_idlen = EI_NIDENT;
+	elf->e_class = elf->e_data[EI_CLASS];
+	elf->e_encoding = elf->e_data[EI_DATA];
+	elf->e_version = elf->e_data[EI_VERSION];
+    }
+    else if (size >= SARMAG && !memcmp(elf->e_data, ARMAG, SARMAG)) {
+	_elf_init_ar(elf);
+    }
+}
+
+Elf*
+elf_begin(int fd, Elf_Cmd cmd, Elf *ref) {
+    Elf_Arhdr *arhdr = NULL;
+    size_t size = 0;
+    off_t off;
+    Elf *elf;
+
+    elf_assert(_elf_init.e_magic == ELF_MAGIC);
+    if (_elf_version == EV_NONE) {
+	seterr(ERROR_VERSION_UNSET);
+	return NULL;
+    }
+    else if (cmd == ELF_C_NULL) {
+	return NULL;
+    }
+    else if (cmd == ELF_C_WRITE) {
+	ref = NULL;
+    }
+    else if (cmd != ELF_C_READ && cmd != ELF_C_RDWR) {
+	seterr(ERROR_INVALID_CMD);
+	return NULL;
+    }
+    else if (ref) {
+	elf_assert(ref->e_magic == ELF_MAGIC);
+	if (!ref->e_readable || (cmd == ELF_C_RDWR && !ref->e_writable)) {
+	    seterr(ERROR_CMDMISMATCH);
+	    return NULL;
+	}
+	if (ref->e_kind != ELF_K_AR) {
+	    ref->e_count++;
+	    return ref;
+	}
+	if (cmd == ELF_C_RDWR) {
+	    seterr(ERROR_MEMBERWRITE);
+	    return NULL;
+	}
+	if (ref->e_memory) {
+	    fd = ref->e_fd;
+	}
+	else if (fd != ref->e_fd) {
+	    seterr(ERROR_FDMISMATCH);
+	    return NULL;
+	}
+	if (!(arhdr = _elf_arhdr(ref))) {
+	    return NULL;
+	}
+	size = arhdr->ar_size;
+    }
+    else if ((off = lseek(fd, (off_t)0, SEEK_END)) == (off_t)-1
+	  || (off_t)(size = off) != off) {
+	seterr(ERROR_IO_GETSIZE);
+	return NULL;
+    }
+
+    if (!(elf = (Elf*)malloc(sizeof(Elf)))) {
+	seterr(ERROR_MEM_ELF);
+	return NULL;
+    }
+    *elf = _elf_init;
+    elf->e_fd = fd;
+    elf->e_parent = ref;
+    elf->e_size = elf->e_dsize = size;
+
+    if (cmd != ELF_C_READ) {
+	elf->e_writable = 1;
+    }
+    if (cmd != ELF_C_WRITE) {
+	elf->e_readable = 1;
+    }
+    else {
+	return elf;
+    }
+
+    if (ref) {
+	size_t offset = ref->e_off + sizeof(struct ar_hdr);
+	Elf *xelf;
+
+	elf_assert(arhdr);
+	elf->e_arhdr = arhdr;
+	elf->e_base = ref->e_base + offset;
+	/*
+	 * Share the archive's memory image. To avoid
+	 * multiple independent elf descriptors if the
+	 * same member is requested twice, scan the list
+	 * of open members for duplicates.
+	 *
+	 * I don't know how SVR4 handles this case. Don't rely on it.
+	 */
+	for (xelf = ref->e_members; xelf; xelf = xelf->e_link) {
+	    elf_assert(xelf->e_parent == ref);
+	    if (xelf->e_base == elf->e_base) {
+		free(arhdr);
+		free(elf);
+		xelf->e_count++;
+		return xelf;
+	    }
+	}
+	if (size == 0) {
+	    elf->e_data = NULL;
+	}
+#if 1
+	else {
+	    /*
+	     * Archive members may be misaligned.  Freezing them will
+	     * cause libelf to allocate buffers for translated data,
+	     * which should be properly aligned in all cases.
+	     */
+	    elf_assert(!ref->e_cooked);
+	    elf->e_data = elf->e_rawdata = ref->e_data + offset;
+	}
+#else
+	else if (ref->e_data == ref->e_rawdata) {
+	    elf_assert(!ref->e_cooked);
+	    /*
+	     * archive is frozen - freeze member, too
+	     */
+	    elf->e_data = elf->e_rawdata = ref->e_data + offset;
+	}
+	else {
+	    elf_assert(!ref->e_memory);
+	    elf->e_data = ref->e_data + offset;
+	    /*
+	     * The member's memory image may have been modified if
+	     * the member has been processed before. Since we need the
+	     * original image, we have to re-read the archive file.
+	     * Will fail if the archive's file descriptor is disabled.
+	     */
+	    if (!ref->e_cooked) {
+		ref->e_cooked = 1;
+	    }
+	    else if (!_elf_read(ref, elf->e_data, offset, size)) {
+		free(arhdr);
+		free(elf);
+		return NULL;
+	    }
+	}
+#endif
+	elf->e_next = offset + size + (size & 1);
+	elf->e_disabled = ref->e_disabled;
+	elf->e_memory = ref->e_memory;
+	/* parent/child linking */
+	elf->e_link = ref->e_members;
+	ref->e_members = elf;
+	ref->e_count++;
+	/* Slowaris compatibility - do not rely on this! */
+	ref->e_off = elf->e_next;
+    }
+    else if (size) {
+#if HAVE_MMAP
+	/*
+	 * Using mmap on writable files will interfere with elf_update
+	 */
+	if (!elf->e_writable && (elf->e_data = _elf_mmap(elf))) {
+	    elf->e_unmap_data = 1;
+	}
+	else
+#endif /* HAVE_MMAP */
+	if (!(elf->e_data = _elf_read(elf, NULL, 0, size))) {
+	    free(elf);
+	    return NULL;
+	}
+    }
+
+    _elf_check_type(elf, size);
+    return elf;
+}
+
+Elf*
+elf_memory(char *image, size_t size) {
+    Elf *elf;
+
+    elf_assert(_elf_init.e_magic == ELF_MAGIC);
+    if (_elf_version == EV_NONE) {
+	seterr(ERROR_VERSION_UNSET);
+	return NULL;
+    }
+    else if (size == 0 || image == NULL) {
+	/* TODO: set error code? */
+	return NULL;
+    }
+
+    if (!(elf = (Elf*)malloc(sizeof(Elf)))) {
+	seterr(ERROR_MEM_ELF);
+	return NULL;
+    }
+    *elf = _elf_init;
+    elf->e_size = elf->e_dsize = size;
+    elf->e_data = elf->e_rawdata = image;
+    elf->e_readable = 1;
+    elf->e_disabled = 1;
+    elf->e_memory = 1;
+
+    _elf_check_type(elf, size);
+    return elf;
+}
+
+#if __LIBELF64
+
+int
+gelf_getclass(Elf *elf) {
+    if (elf && elf->e_kind == ELF_K_ELF && valid_class(elf->e_class)) {
+	return elf->e_class;
+    }
+    return ELFCLASSNONE;
+}
+
+#endif /* __LIBELF64 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/build.bat	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,36 @@
+@echo off
+
+rem lib/build.bat - build script for W32 port
+rem Copyright (C) 2004 - 2006 Michael Riepe
+rem
+rem This library is free software; you can redistribute it and/or
+rem modify it under the terms of the GNU Library General Public
+rem License as published by the Free Software Foundation; either
+rem version 2 of the License, or (at your option) any later version.
+rem
+rem This library is distributed in the hope that it will be useful,
+rem but WITHOUT ANY WARRANTY; without even the implied warranty of
+rem MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+rem Library General Public License for more details.
+rem
+rem You should have received a copy of the GNU Library General Public
+rem License along with this library; if not, write to the Free Software
+rem Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+rem @(#) $Id: build.bat,v 1.1 2006/08/21 18:03:48 michael Exp $
+
+rem *** BEGIN EDIT HERE ***
+rem Please uncomment the line that suits your system:
+rem call "C:\Program Files\Microsoft Visual Studio\VC98\bin\vcvars32.bat"
+rem call "C:\Program Files\Microsoft Visual Studio 8\VC\bin\vcvars32.bat"
+rem call "C:\Programme\Microsoft Visual Studio\VC98\bin\vcvars32.bat"
+rem call "C:\Programme\Microsoft Visual Studio 8\VC\bin\vcvars32.bat"
+rem OR, if you have to set the path to the compiler directly:
+rem set PATH="C:\PATH\TO\COMPILER\BINARY;%PATH%"
+rem Of course, you'll have to enter the correct path above.
+rem You may also have to change CC (default: cl.exe) in Makefile.w32.
+rem *** END EDIT HERE ***
+
+copy config.h.w32 config.h
+copy sys_elf.h.w32 sys_elf.h
+nmake /nologo /f Makefile.w32 %1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/byteswap.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,95 @@
+/*
+byteswap.h - functions and macros for byte swapping.
+Copyright (C) 1995 - 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+/* @(#) $Id: byteswap.h,v 1.6 2005/05/21 15:39:20 michael Exp $ */
+
+#ifndef _BYTESWAP_H
+#define _BYTESWAP_H
+
+#define lu(from,i,s)	(((__libelf_u32_t)((unsigned char*)(from))[i])<<(s))
+#define li(from,i,s)	(((__libelf_i32_t)((  signed char*)(from))[i])<<(s))
+
+#define __load_u16L(from)	((__libelf_u32_t) \
+    (lu(from,1,8) | lu(from,0,0)))
+#define __load_u16M(from)	((__libelf_u32_t) \
+    (lu(from,0,8) | lu(from,1,0)))
+#define __load_i16L(from)	((__libelf_i32_t) \
+    (li(from,1,8) | lu(from,0,0)))
+#define __load_i16M(from)	((__libelf_i32_t) \
+    (li(from,0,8) | lu(from,1,0)))
+
+#define __load_u32L(from)	((__libelf_u32_t) \
+    (lu(from,3,24) | lu(from,2,16) | lu(from,1,8) | lu(from,0,0)))
+#define __load_u32M(from)	((__libelf_u32_t) \
+    (lu(from,0,24) | lu(from,1,16) | lu(from,2,8) | lu(from,3,0)))
+#define __load_i32L(from)	((__libelf_i32_t) \
+    (li(from,3,24) | lu(from,2,16) | lu(from,1,8) | lu(from,0,0)))
+#define __load_i32M(from)	((__libelf_i32_t) \
+    (li(from,0,24) | lu(from,1,16) | lu(from,2,8) | lu(from,3,0)))
+
+#define su(to,i,v,s)	(((char*)(to))[i]=((__libelf_u32_t)(v)>>(s)))
+#define si(to,i,v,s)	(((char*)(to))[i]=((__libelf_i32_t)(v)>>(s)))
+
+#define __store_u16L(to,v)	\
+    (su(to,1,v,8), su(to,0,v,0))
+#define __store_u16M(to,v)	\
+    (su(to,0,v,8), su(to,1,v,0))
+#define __store_i16L(to,v)	\
+    (si(to,1,v,8), si(to,0,v,0))
+#define __store_i16M(to,v)	\
+    (si(to,0,v,8), si(to,1,v,0))
+
+#define __store_u32L(to,v)	\
+    (su(to,3,v,24), su(to,2,v,16), su(to,1,v,8), su(to,0,v,0))
+#define __store_u32M(to,v)	\
+    (su(to,0,v,24), su(to,1,v,16), su(to,2,v,8), su(to,3,v,0))
+#define __store_i32L(to,v)	\
+    (si(to,3,v,24), si(to,2,v,16), si(to,1,v,8), si(to,0,v,0))
+#define __store_i32M(to,v)	\
+    (si(to,0,v,24), si(to,1,v,16), si(to,2,v,8), si(to,3,v,0))
+
+#if __LIBELF64
+
+/*
+ * conversion functions from swap64.c
+ */
+extern __libelf_u64_t _elf_load_u64L(const unsigned char *from);
+extern __libelf_u64_t _elf_load_u64M(const unsigned char *from);
+extern __libelf_i64_t _elf_load_i64L(const unsigned char *from);
+extern __libelf_i64_t _elf_load_i64M(const unsigned char *from);
+extern void _elf_store_u64L(unsigned char *to, __libelf_u64_t v);
+extern void _elf_store_u64M(unsigned char *to, __libelf_u64_t v);
+extern void _elf_store_i64L(unsigned char *to, __libelf_u64_t v);
+extern void _elf_store_i64M(unsigned char *to, __libelf_u64_t v);
+
+/*
+ * aliases for existing conversion code
+ */
+#define __load_u64L	_elf_load_u64L
+#define __load_u64M	_elf_load_u64M
+#define __load_i64L	_elf_load_i64L
+#define __load_i64M	_elf_load_i64M
+#define __store_u64L	_elf_store_u64L
+#define __store_u64M	_elf_store_u64M
+#define __store_i64L	_elf_store_i64L
+#define __store_i64M	_elf_store_i64M
+
+#endif /* __LIBELF64 */
+
+#endif /* _BYTESWAP_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/checksum.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,178 @@
+/*
+checksum.c - implementation of the elf{32,64}_checksum(3) functions.
+Copyright (C) 1995 - 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: checksum.c,v 1.6 2005/05/21 15:39:20 michael Exp $";
+#endif /* lint */
+
+/*
+ * Compatibility note:
+ *
+ * The algorithm used in {elf32,elf64,gelf}_checksum() does not seem to
+ * be documented.  I hope I got it right.  My implementation does the
+ * following:
+ *
+ *   - skip sections that do not have the SHF_ALLOC flag set
+ *   - skip sections of type SHT_NULL, SHT_NOBITS, SHT_DYNSYM and
+ *     SHT_DYNAMIC
+ *   - add all data bytes from the remaining sections, modulo 2**32
+ *   - add upper and lower half of the result
+ *   - subtract 0xffff if the result is > 0xffff
+ *   - if any error occurs, return 0L
+ */
+
+static int
+skip_section(Elf_Scn *scn, unsigned cls) {
+    if (cls == ELFCLASS32) {
+	Elf32_Shdr *shdr = &scn->s_shdr32;
+
+	if (!(shdr->sh_flags & SHF_ALLOC)) {
+	    return 1;
+	}
+	switch (shdr->sh_type) {
+	    case SHT_NULL:
+	    case SHT_NOBITS:
+	    /* Solaris seems to ignore these, too */
+	    case SHT_DYNSYM:
+	    case SHT_DYNAMIC:
+		return 1;
+	}
+    }
+#if __LIBELF64
+    else if (cls == ELFCLASS64) {
+	Elf64_Shdr *shdr = &scn->s_shdr64;
+
+	if (!(shdr->sh_flags & SHF_ALLOC)) {
+	    return 1;
+	}
+	switch (shdr->sh_type) {
+	    case SHT_NULL:
+	    case SHT_NOBITS:
+	    /* Solaris seems to ignore these, too */
+	    case SHT_DYNSYM:
+	    case SHT_DYNAMIC:
+		return 1;
+	}
+    }
+#endif /* __LIBELF64 */
+    else {
+	seterr(ERROR_UNIMPLEMENTED);
+    }
+    return 0;
+}
+
+static long
+add_bytes(unsigned char *ptr, size_t len) {
+    long csum = 0;
+
+    while (len--) {
+	csum += *ptr++;
+    }
+    return csum;
+}
+
+static long
+_elf_csum(Elf *elf) {
+    long csum = 0;
+    Elf_Data *data;
+    Elf_Scn *scn;
+
+    if (!elf->e_ehdr && !_elf_cook(elf)) {
+	/* propagate errors from _elf_cook */
+	return 0L;
+    }
+    seterr(0);
+    for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+	if (scn->s_index == SHN_UNDEF || skip_section(scn, elf->e_class)) {
+	    continue;
+	}
+	data = NULL;
+	while ((data = elf_getdata(scn, data))) {
+	    if (data->d_size) {
+		if (data->d_buf == NULL) {
+		    seterr(ERROR_NULLBUF);
+		    return 0L;
+		}
+		csum += add_bytes(data->d_buf, data->d_size);
+	    }
+	}
+    }
+    if (_elf_errno) {
+	return 0L;
+    }
+    csum = (csum & 0xffff) + ((csum >> 16) & 0xffff);
+    if (csum > 0xffff) {
+	csum -= 0xffff;
+    }
+    return csum;
+}
+
+long
+elf32_checksum(Elf *elf) {
+    if (elf) {
+	if (elf->e_kind != ELF_K_ELF) {
+	    seterr(ERROR_NOTELF);
+	}
+	else if (elf->e_class != ELFCLASS32) {
+	    seterr(ERROR_CLASSMISMATCH);
+	}
+	else {
+	    return _elf_csum(elf);
+	}
+    }
+    return 0L;
+}
+
+#if __LIBELF64
+
+long
+elf64_checksum(Elf *elf) {
+    if (elf) {
+	if (elf->e_kind != ELF_K_ELF) {
+	    seterr(ERROR_NOTELF);
+	}
+	else if (elf->e_class != ELFCLASS64) {
+	    seterr(ERROR_CLASSMISMATCH);
+	}
+	else {
+	    return _elf_csum(elf);
+	}
+    }
+    return 0L;
+}
+
+long
+gelf_checksum(Elf *elf) {
+    if (elf) {
+	if (elf->e_kind != ELF_K_ELF) {
+	    seterr(ERROR_NOTELF);
+	}
+	else if (!valid_class(elf->e_class)) {
+	    seterr(ERROR_UNKNOWN_CLASS);
+	}
+	else {
+	    return _elf_csum(elf);
+	}
+    }
+    return 0L;
+}
+
+#endif /* __LIBELF64 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/cntl.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,71 @@
+/*
+cntl.c - implementation of the elf_cntl(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: cntl.c,v 1.6 2005/05/21 15:39:21 michael Exp $";
+#endif /* lint */
+
+int
+elf_cntl(Elf *elf, Elf_Cmd cmd) {
+    Elf_Scn *scn;
+    Elf *child;
+
+    if (!elf) {
+	return -1;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (cmd == ELF_C_FDREAD) {
+	if (!elf->e_readable) {
+	    seterr(ERROR_WRONLY);
+	    return -1;
+	}
+    }
+    else if (cmd != ELF_C_FDDONE) {
+	seterr(ERROR_INVALID_CMD);
+	return -1;
+    }
+    if (elf->e_disabled) {
+	return 0;
+    }
+    if (elf->e_kind == ELF_K_AR) {
+	for (child = elf->e_members; child; child = child->e_link) {
+	    elf_assert(elf == child->e_parent);
+	    if (elf_cntl(child, cmd)) {
+		return -1;
+	    }
+	}
+    }
+    else if (elf->e_kind == ELF_K_ELF && cmd == ELF_C_FDREAD) {
+	if (!elf->e_ehdr && !_elf_cook(elf)) {
+	    return -1;
+	}
+	for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+	    if (scn->s_index == SHN_UNDEF || scn->s_type == SHT_NULL) {
+		continue;
+	    }
+	    else if (!elf_getdata(scn, NULL)) {
+		return -1;
+	    }
+	}
+    }
+    elf->e_disabled = 1;
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/config.h.w32	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,161 @@
+/*
+ * lib/config.h.w32 - configuration file for W32 port
+ * Copyright (C) 2004 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @(#) $Id: config.h.w32,v 1.2 2006/09/07 15:55:42 michael Exp $
+ */
+
+/* Define to empty if the keyword does not work.  */
+#undef const
+
+/* Define if you have a working `mmap' system call.  */
+#undef HAVE_MMAP
+
+/* Define to `long' if <sys/types.h> doesn't define.  */
+#undef off_t
+
+/* Define to `unsigned' if <sys/types.h> doesn't define.  */
+#undef size_t
+
+/* Define if you have the ANSI C header files.  */
+#define STDC_HEADERS 1
+
+/* Define if you want to include extra debugging code */
+#define ENABLE_DEBUG 1
+
+/* Define if memmove() does not copy overlapping arrays correctly */
+#undef HAVE_BROKEN_MEMMOVE
+
+/* Define if you have the catgets function. */
+#undef HAVE_CATGETS
+
+/* Define if you have the dgettext function. */
+#undef HAVE_DGETTEXT
+
+/* Define if you have the memset function.  */
+#define HAVE_MEMSET 1
+
+/* Define if struct nlist is declared in <elf.h> or <sys/elf.h> */
+#undef HAVE_STRUCT_NLIST_DECLARATION
+
+/* Define if Elf32_Dyn is declared in <link.h> */
+#undef __LIBELF_NEED_LINK_H
+
+/* Define if Elf32_Dyn is declared in <sys/link.h> */
+#undef __LIBELF_NEED_SYS_LINK_H
+
+/* Define to `<elf.h>' or `<sys/elf.h>' if one of them is present */
+#undef __LIBELF_HEADER_ELF_H
+
+/* Define if you want 64-bit support (and your system supports it) */
+#define __LIBELF64 1
+
+/* Define if you want 64-bit support, and are running IRIX */
+#undef __LIBELF64_IRIX
+
+/* Define if you want 64-bit support, and are running Linux */
+#undef __LIBELF64_LINUX
+
+/* Define if you want symbol versioning (and your system supports it) */
+#define __LIBELF_SYMBOL_VERSIONS 1
+
+/* Define if symbol versioning uses Sun section type (SHT_SUNW_*) */
+#define __LIBELF_SUN_SYMBOL_VERSIONS 1
+
+/* Define if symbol versioning uses GNU section types (SHT_GNU_*) */
+#undef __LIBELF_GNU_SYMBOL_VERSIONS
+
+/* Define to a 64-bit signed integer type if one exists */
+#define __libelf_i64_t __int64
+
+/* Define to a 64-bit unsigned integer type if one exists */
+#define __libelf_u64_t unsigned __int64
+
+/* Define to a 32-bit signed integer type if one exists */
+#define __libelf_i32_t int
+
+/* Define to a 32-bit unsigned integer type if one exists */
+#define __libelf_u32_t unsigned int
+
+/* Define to a 16-bit signed integer type if one exists */
+#define __libelf_i16_t short int
+
+/* Define to a 16-bit unsigned integer type if one exists */
+#define __libelf_u16_t unsigned short int
+
+/* The number of bytes in a __int64.  */
+#define SIZEOF___INT64 8
+
+/* The number of bytes in a int.  */
+#define SIZEOF_INT 4
+
+/* The number of bytes in a long.  */
+#define SIZEOF_LONG 4
+
+/* The number of bytes in a long long.  */
+#define SIZEOF_LONG_LONG 0
+
+/* The number of bytes in a short.  */
+#define SIZEOF_SHORT 2
+
+/* Define if you have the ftruncate function.  */
+#undef HAVE_FTRUNCATE
+
+/* Define if you have the getpagesize function.  */
+#undef HAVE_GETPAGESIZE
+
+/* Define if you have the memcmp function.  */
+#define HAVE_MEMCMP 1
+
+/* Define if you have the memcpy function.  */
+#define HAVE_MEMCPY 1
+
+/* Define if you have the memmove function.  */
+#define HAVE_MEMMOVE 1
+
+/* Define if you have the memset function.  */
+#define HAVE_MEMSET 1
+
+/* Define if you have the <ar.h> header file.  */
+#undef HAVE_AR_H
+
+/* Define if you have the <elf.h> header file.  */
+#undef HAVE_ELF_H
+
+/* Define if you have the <fcntl.h> header file.  */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <gelf.h> header file.  */
+#undef HAVE_GELF_H
+
+/* Define if you have the <libelf.h> header file.  */
+#undef HAVE_LIBELF_H
+
+/* Define if you have the <link.h> header file.  */
+#undef HAVE_LINK_H
+
+/* Define if you have the <nlist.h> header file.  */
+#undef HAVE_NLIST_H
+
+/* Define if you have the <sys/elf.h> header file.  */
+#undef HAVE_SYS_ELF_H
+
+/* Define if you have the <sys/link.h> header file.  */
+#undef HAVE_SYS_LINK_H
+
+/* Define if you have the <unistd.h> header file.  */
+#undef HAVE_UNISTD_H
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/cook.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,501 @@
+/*
+ * cook.c - read and translate ELF files.
+ * Copyright (C) 1995 - 2006 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: cook.c,v 1.28 2006/07/07 22:15:50 michael Exp $";
+#endif /* lint */
+
+const Elf_Scn _elf_scn_init = INIT_SCN;
+const Scn_Data _elf_data_init = INIT_DATA;
+
+Elf_Type
+_elf_scn_type(unsigned t) {
+    switch (t) {
+	case SHT_DYNAMIC:       return ELF_T_DYN;
+	case SHT_DYNSYM:        return ELF_T_SYM;
+	case SHT_HASH:          return ELF_T_WORD;
+	case SHT_REL:           return ELF_T_REL;
+	case SHT_RELA:          return ELF_T_RELA;
+	case SHT_SYMTAB:        return ELF_T_SYM;
+	case SHT_SYMTAB_SHNDX:	return ELF_T_WORD;	/* XXX: really? */
+#if __LIBELF_SYMBOL_VERSIONS
+#if __LIBELF_SUN_SYMBOL_VERSIONS
+	case SHT_SUNW_verdef:   return ELF_T_VDEF;
+	case SHT_SUNW_verneed:  return ELF_T_VNEED;
+	case SHT_SUNW_versym:   return ELF_T_HALF;
+#else /* __LIBELF_SUN_SYMBOL_VERSIONS */
+	case SHT_GNU_verdef:    return ELF_T_VDEF;
+	case SHT_GNU_verneed:   return ELF_T_VNEED;
+	case SHT_GNU_versym:    return ELF_T_HALF;
+#endif /* __LIBELF_SUN_SYMBOL_VERSIONS */
+#endif /* __LIBELF_SYMBOL_VERSIONS */
+    }
+    return ELF_T_BYTE;
+}
+
+/*
+ * Check for overflow on 32-bit systems
+ */
+#define overflow(a,b,t)	(sizeof(a) < sizeof(t) && (t)(a) != (b))
+
+#define truncerr(t) ((t)==ELF_T_EHDR?ERROR_TRUNC_EHDR:	\
+		    ((t)==ELF_T_PHDR?ERROR_TRUNC_PHDR:	\
+		    ERROR_INTERNAL))
+#define memerr(t)   ((t)==ELF_T_EHDR?ERROR_MEM_EHDR:	\
+		    ((t)==ELF_T_PHDR?ERROR_MEM_PHDR:	\
+		    ERROR_INTERNAL))
+
+Elf_Data*
+_elf_xlatetom(const Elf *elf, Elf_Data *dst, const Elf_Data *src) {
+    if (elf->e_class == ELFCLASS32) {
+	return elf32_xlatetom(dst, src, elf->e_encoding);
+    }
+#if __LIBELF64
+    else if (elf->e_class == ELFCLASS64) {
+	return elf64_xlatetom(dst, src, elf->e_encoding);
+    }
+#endif /* __LIBELF64 */
+    seterr(ERROR_UNIMPLEMENTED);
+    return NULL;
+}
+
+static char*
+_elf_item(void *buf, Elf *elf, Elf_Type type, size_t off) {
+    Elf_Data src, dst;
+
+    elf_assert(valid_type(type));
+    if (off < 0 || off > elf->e_size) {
+	seterr(ERROR_OUTSIDE);
+	return NULL;
+    }
+
+    src.d_type = type;
+    src.d_version = elf->e_version;
+    src.d_size = _fsize(elf->e_class, src.d_version, type);
+    elf_assert(src.d_size);
+    if ((elf->e_size - off) < src.d_size) {
+	seterr(truncerr(type));
+	return NULL;
+    }
+
+    dst.d_version = _elf_version;
+    dst.d_size = _msize(elf->e_class, dst.d_version, type);
+    elf_assert(dst.d_size);
+
+    if (!(dst.d_buf = buf) && !(dst.d_buf = malloc(dst.d_size))) {
+	seterr(memerr(type));
+	return NULL;
+    }
+
+    elf_assert(elf->e_data);
+    if (elf->e_rawdata) {
+	src.d_buf = elf->e_rawdata + off;
+    }
+    else {
+	src.d_buf = elf->e_data + off;
+    }
+
+    if (_elf_xlatetom(elf, &dst, &src)) {
+	return (char*)dst.d_buf;
+    }
+    if (dst.d_buf != buf) {
+	free(dst.d_buf);
+    }
+    return NULL;
+}
+
+static int
+_elf_cook_phdr(Elf *elf) {
+    size_t num, off, entsz;
+
+    if (elf->e_class == ELFCLASS32) {
+	num = ((Elf32_Ehdr*)elf->e_ehdr)->e_phnum;
+	off = ((Elf32_Ehdr*)elf->e_ehdr)->e_phoff;
+	entsz = ((Elf32_Ehdr*)elf->e_ehdr)->e_phentsize;
+    }
+#if __LIBELF64
+    else if (elf->e_class == ELFCLASS64) {
+	num = ((Elf64_Ehdr*)elf->e_ehdr)->e_phnum;
+	off = ((Elf64_Ehdr*)elf->e_ehdr)->e_phoff;
+	entsz = ((Elf64_Ehdr*)elf->e_ehdr)->e_phentsize;
+	/*
+	 * Check for overflow on 32-bit systems
+	 */
+	if (overflow(off, ((Elf64_Ehdr*)elf->e_ehdr)->e_phoff, Elf64_Off)) {
+	    seterr(ERROR_OUTSIDE);
+	    return 0;
+	}
+    }
+#endif /* __LIBELF64 */
+    else {
+	seterr(ERROR_UNIMPLEMENTED);
+	return 0;
+    }
+    if (off) {
+	Elf_Scn *scn;
+	size_t size;
+	unsigned i;
+	char *p;
+
+	if (num == PN_XNUM) {
+	    /*
+	     * Overflow in ehdr->e_phnum.
+	     * Get real value from first SHDR.
+	     */
+	    if (!(scn = elf->e_scn_1)) {
+		seterr(ERROR_NOSUCHSCN);
+		return 0;
+	    }
+	    if (elf->e_class == ELFCLASS32) {
+		num = scn->s_shdr32.sh_info;
+	    }
+#if __LIBELF64
+	    else if (elf->e_class == ELFCLASS64) {
+		num = scn->s_shdr64.sh_info;
+	    }
+#endif /* __LIBELF64 */
+	    /* we already had this
+	    else {
+		seterr(ERROR_UNIMPLEMENTED);
+		return 0;
+	    }
+	    */
+	}
+
+	size = _fsize(elf->e_class, elf->e_version, ELF_T_PHDR);
+	elf_assert(size);
+#if ENABLE_EXTENDED_FORMAT
+	if (entsz < size) {
+#else /* ENABLE_EXTENDED_FORMAT */
+	if (entsz != size) {
+#endif /* ENABLE_EXTENDED_FORMAT */
+	    seterr(ERROR_EHDR_PHENTSIZE);
+	    return 0;
+	}
+	size = _msize(elf->e_class, _elf_version, ELF_T_PHDR);
+	elf_assert(size);
+	if (!(p = malloc(num * size))) {
+	    seterr(memerr(ELF_T_PHDR));
+	    return 0;
+	}
+	for (i = 0; i < num; i++) {
+	    if (!_elf_item(p + i * size, elf, ELF_T_PHDR, off + i * entsz)) {
+		free(p);
+		return 0;
+	    }
+	}
+	elf->e_phdr = p;
+	elf->e_phnum = num;
+    }
+    return 1;
+}
+
+static int
+_elf_cook_shdr(Elf *elf) {
+    size_t num, off, entsz;
+
+    if (elf->e_class == ELFCLASS32) {
+	num = ((Elf32_Ehdr*)elf->e_ehdr)->e_shnum;
+	off = ((Elf32_Ehdr*)elf->e_ehdr)->e_shoff;
+	entsz = ((Elf32_Ehdr*)elf->e_ehdr)->e_shentsize;
+    }
+#if __LIBELF64
+    else if (elf->e_class == ELFCLASS64) {
+	num = ((Elf64_Ehdr*)elf->e_ehdr)->e_shnum;
+	off = ((Elf64_Ehdr*)elf->e_ehdr)->e_shoff;
+	entsz = ((Elf64_Ehdr*)elf->e_ehdr)->e_shentsize;
+	/*
+	 * Check for overflow on 32-bit systems
+	 */
+	if (overflow(off, ((Elf64_Ehdr*)elf->e_ehdr)->e_shoff, Elf64_Off)) {
+	    seterr(ERROR_OUTSIDE);
+	    return 0;
+	}
+    }
+#endif /* __LIBELF64 */
+    else {
+	seterr(ERROR_UNIMPLEMENTED);
+	return 0;
+    }
+    if (off) {
+	struct tmp {
+	    Elf_Scn	scn;
+	    Scn_Data	data;
+	} *head;
+	Elf_Data src, dst;
+	Elf_Scn *scn;
+	Scn_Data *sd;
+	unsigned i;
+
+	if (off < 0 || off > elf->e_size) {
+	    seterr(ERROR_OUTSIDE);
+	    return 0;
+	}
+
+	src.d_type = ELF_T_SHDR;
+	src.d_version = elf->e_version;
+	src.d_size = _fsize(elf->e_class, src.d_version, ELF_T_SHDR);
+	elf_assert(src.d_size);
+#if ENABLE_EXTENDED_FORMAT
+	if (entsz < src.d_size) {
+#else /* ENABLE_EXTENDED_FORMAT */
+	if (entsz != src.d_size) {
+#endif /* ENABLE_EXTENDED_FORMAT */
+	    seterr(ERROR_EHDR_SHENTSIZE);
+	    return 0;
+	}
+	dst.d_version = EV_CURRENT;
+
+	if (num == 0) {
+	    union {
+		Elf32_Shdr sh32;
+#if __LIBELF64
+		Elf64_Shdr sh64;
+#endif /* __LIBELF64 */
+	    } u;
+
+	    /*
+	     * Overflow in ehdr->e_shnum.
+	     * Get real value from first SHDR.
+	     */
+	    if (elf->e_size - off < entsz) {
+		seterr(ERROR_TRUNC_SHDR);
+		return 0;
+	    }
+	    if (elf->e_rawdata) {
+		src.d_buf = elf->e_rawdata + off;
+	    }
+	    else {
+		src.d_buf = elf->e_data + off;
+	    }
+	    dst.d_buf = &u;
+	    dst.d_size = sizeof(u);
+	    if (!_elf_xlatetom(elf, &dst, &src)) {
+		return 0;
+	    }
+	    elf_assert(dst.d_size == _msize(elf->e_class, EV_CURRENT, ELF_T_SHDR));
+	    elf_assert(dst.d_type == ELF_T_SHDR);
+	    if (elf->e_class == ELFCLASS32) {
+		num = u.sh32.sh_size;
+	    }
+#if __LIBELF64
+	    else if (elf->e_class == ELFCLASS64) {
+		num = u.sh64.sh_size;
+		/*
+		 * Check for overflow on 32-bit systems
+		 */
+		if (overflow(num, u.sh64.sh_size, Elf64_Xword)) {
+		    seterr(ERROR_OUTSIDE);
+		    return 0;
+		}
+	    }
+#endif /* __LIBELF64 */
+	}
+
+	if ((elf->e_size - off) / entsz < num) {
+	    seterr(ERROR_TRUNC_SHDR);
+	    return 0;
+	}
+
+	if (!(head = (struct tmp*)malloc(num * sizeof(struct tmp)))) {
+	    seterr(ERROR_MEM_SCN);
+	    return 0;
+	}
+	for (scn = NULL, i = num; i-- > 0; ) {
+	    head[i].scn = _elf_scn_init;
+	    head[i].data = _elf_data_init;
+	    head[i].scn.s_link = scn;
+	    if (!scn) {
+		elf->e_scn_n = &head[i].scn;
+	    }
+	    scn = &head[i].scn;
+	    sd = &head[i].data;
+
+	    if (elf->e_rawdata) {
+		src.d_buf = elf->e_rawdata + off + i * entsz;
+	    }
+	    else {
+		src.d_buf = elf->e_data + off + i * entsz;
+	    }
+	    dst.d_buf = &scn->s_uhdr;
+	    dst.d_size = sizeof(scn->s_uhdr);
+	    if (!_elf_xlatetom(elf, &dst, &src)) {
+		elf->e_scn_n = NULL;
+		free(head);
+		return 0;
+	    }
+	    elf_assert(dst.d_size == _msize(elf->e_class, EV_CURRENT, ELF_T_SHDR));
+	    elf_assert(dst.d_type == ELF_T_SHDR);
+
+	    scn->s_elf = elf;
+	    scn->s_index = i;
+	    scn->s_data_1 = sd;
+	    scn->s_data_n = sd;
+
+	    sd->sd_scn = scn;
+
+	    if (elf->e_class == ELFCLASS32) {
+		Elf32_Shdr *shdr = &scn->s_shdr32;
+
+		scn->s_type = shdr->sh_type;
+		scn->s_size = shdr->sh_size;
+		scn->s_offset = shdr->sh_offset;
+		sd->sd_data.d_align = shdr->sh_addralign;
+		sd->sd_data.d_type = _elf_scn_type(scn->s_type);
+	    }
+#if __LIBELF64
+	    else if (elf->e_class == ELFCLASS64) {
+		Elf64_Shdr *shdr = &scn->s_shdr64;
+
+		scn->s_type = shdr->sh_type;
+		scn->s_size = shdr->sh_size;
+		scn->s_offset = shdr->sh_offset;
+		sd->sd_data.d_align = shdr->sh_addralign;
+		/*
+		 * Check for overflow on 32-bit systems
+		 */
+		if (overflow(scn->s_size, shdr->sh_size, Elf64_Xword)
+		 || overflow(scn->s_offset, shdr->sh_offset, Elf64_Off)
+		 || overflow(sd->sd_data.d_align, shdr->sh_addralign, Elf64_Xword)) {
+		    seterr(ERROR_OUTSIDE);
+		    return 0;
+		}
+		sd->sd_data.d_type = _elf_scn_type(scn->s_type);
+		/*
+		 * QUIRKS MODE:
+		 *
+		 * Some 64-bit architectures use 64-bit entries in the
+		 * .hash section. This violates the ELF standard, and
+		 * should be fixed. It's mostly harmless as long as the
+		 * binary and the machine running your program have the
+		 * same byte order, but you're in trouble if they don't,
+		 * and if the entry size is wrong.
+		 *
+		 * As a workaround, I let libelf guess the right size
+		 * for the binary. This relies pretty much on the fact
+		 * that the binary provides correct data in the section
+		 * headers. If it doesn't, it's probably broken anyway.
+		 * Therefore, libelf uses a standard conforming value
+		 * when it's not absolutely sure.
+		 */
+		if (scn->s_type == SHT_HASH) {
+		    int override = 0;
+
+		    /*
+		     * sh_entsize must reflect the entry size
+		     */
+		    if (shdr->sh_entsize == ELF64_FSZ_ADDR) {
+			override++;
+		    }
+		    /*
+		     * sh_size must be a multiple of sh_entsize
+		     */
+		    if (shdr->sh_size % ELF64_FSZ_ADDR == 0) {
+			override++;
+		    }
+		    /*
+		     * There must be room for at least 2 entries
+		     */
+		    if (shdr->sh_size >= 2 * ELF64_FSZ_ADDR) {
+			override++;
+		    }
+		    /*
+		     * sh_addralign must be correctly set
+		     */
+		    if (shdr->sh_addralign == ELF64_FSZ_ADDR) {
+			override++;
+		    }
+		    /*
+		     * The section must be properly aligned
+		     */
+		    if (shdr->sh_offset % ELF64_FSZ_ADDR == 0) {
+			override++;
+		    }
+		    /* XXX: also look at the data? */
+		    /*
+		     * Make a conservative decision...
+		     */
+		    if (override >= 5) {
+			sd->sd_data.d_type = ELF_T_ADDR;
+		    }
+		}
+		/*
+		 * END QUIRKS MODE.
+		 */
+	    }
+#endif /* __LIBELF64 */
+	    /* we already had this
+	    else {
+		seterr(ERROR_UNIMPLEMENTED);
+		return 0;
+	    }
+	    */
+
+	    sd->sd_data.d_size = scn->s_size;
+	    sd->sd_data.d_version = _elf_version;
+	}
+	elf_assert(scn == &head[0].scn);
+	elf->e_scn_1 = &head[0].scn;
+	head[0].scn.s_freeme = 1;
+    }
+    return 1;
+}
+
+static int
+_elf_cook_file(Elf *elf) {
+    elf->e_ehdr = _elf_item(NULL, elf, ELF_T_EHDR, 0);
+    if (!elf->e_ehdr) {
+	return 0;
+    }
+    /*
+     * Note: _elf_cook_phdr may require the first section header!
+     */
+    if (!_elf_cook_shdr(elf)) {
+	return 0;
+    }
+    if (!_elf_cook_phdr(elf)) {
+	return 0;
+    }
+    return 1;
+}
+
+int
+_elf_cook(Elf *elf) {
+    elf_assert(_elf_scn_init.s_magic == SCN_MAGIC);
+    elf_assert(_elf_data_init.sd_magic == DATA_MAGIC);
+    elf_assert(elf);
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    elf_assert(elf->e_kind == ELF_K_ELF);
+    elf_assert(!elf->e_ehdr);
+    if (!valid_version(elf->e_version)) {
+	seterr(ERROR_UNKNOWN_VERSION);
+    }
+    else if (!valid_encoding(elf->e_encoding)) {
+	seterr(ERROR_UNKNOWN_ENCODING);
+    }
+    else if (valid_class(elf->e_class)) {
+	return _elf_cook_file(elf);
+    }
+    else {
+	seterr(ERROR_UNKNOWN_CLASS);
+    }
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/data.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,36 @@
+/*
+ * data.c - libelf internal variables.
+ * Copyright (C) 1995 - 1998, 2007 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: data.c,v 1.7 2007/09/07 12:07:59 michael Exp $";
+#endif /* lint */
+
+unsigned _elf_version = EV_NONE;
+int _elf_errno = 0;
+int _elf_fill = 0;
+
+#if ENABLE_SANITY_CHECKS
+#define SANITY_CHECKS	-1
+#else
+#define SANITY_CHECKS	0
+#endif
+
+int _elf_sanity_checks = SANITY_CHECKS;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/elf_repl.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,992 @@
+/*
+ * elf_repl.h - public header file for systems that lack it.
+ * Copyright (C) 1995 - 2006 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* @(#) $Id: elf_repl.h,v 1.20 2006/07/07 22:16:15 michael Exp $ */
+
+/*
+ * NEVER INCLUDE THIS FILE DIRECTLY - USE <libelf.h> INSTEAD!
+ */
+
+#ifndef _ELF_REPL_H
+#define _ELF_REPL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * Scalar data types
+ */
+typedef __libelf_u32_t		Elf32_Addr;
+typedef __libelf_u16_t		Elf32_Half;
+typedef __libelf_u32_t		Elf32_Off;
+typedef __libelf_i32_t		Elf32_Sword;
+typedef __libelf_u32_t		Elf32_Word;
+
+#define ELF32_FSZ_ADDR		4
+#define ELF32_FSZ_HALF		2
+#define ELF32_FSZ_OFF		4
+#define ELF32_FSZ_SWORD		4
+#define ELF32_FSZ_WORD		4
+
+#if __LIBELF64
+
+typedef __libelf_u64_t		Elf64_Addr;
+typedef __libelf_u16_t		Elf64_Half;
+typedef __libelf_u64_t		Elf64_Off;
+typedef __libelf_i32_t		Elf64_Sword;
+typedef __libelf_u32_t		Elf64_Word;
+typedef __libelf_i64_t		Elf64_Sxword;
+typedef __libelf_u64_t		Elf64_Xword;
+
+#define ELF64_FSZ_ADDR		8
+#define ELF64_FSZ_HALF		2
+#define ELF64_FSZ_OFF		8
+#define ELF64_FSZ_SWORD		4
+#define ELF64_FSZ_WORD		4
+#define ELF64_FSZ_SXWORD	8
+#define ELF64_FSZ_XWORD		8
+
+/*
+ * Blame Sun for this...
+ */
+typedef __libelf_u64_t		Elf64_Lword;
+typedef __libelf_u64_t		Elf32_Lword;
+
+#endif /* __LIBELF64 */
+
+/*
+ * ELF header
+ */
+#define EI_NIDENT	16
+
+typedef struct {
+    unsigned char	e_ident[EI_NIDENT];
+    Elf32_Half		e_type;
+    Elf32_Half		e_machine;
+    Elf32_Word		e_version;
+    Elf32_Addr		e_entry;
+    Elf32_Off		e_phoff;
+    Elf32_Off		e_shoff;
+    Elf32_Word		e_flags;
+    Elf32_Half		e_ehsize;
+    Elf32_Half		e_phentsize;
+    Elf32_Half		e_phnum;
+    Elf32_Half		e_shentsize;
+    Elf32_Half		e_shnum;
+    Elf32_Half		e_shstrndx;
+} Elf32_Ehdr;
+
+#if __LIBELF64
+typedef struct {
+    unsigned char	e_ident[EI_NIDENT];
+    Elf64_Half		e_type;
+    Elf64_Half		e_machine;
+    Elf64_Word		e_version;
+    Elf64_Addr		e_entry;
+    Elf64_Off		e_phoff;
+    Elf64_Off		e_shoff;
+    Elf64_Word		e_flags;
+    Elf64_Half		e_ehsize;
+    Elf64_Half		e_phentsize;
+    Elf64_Half		e_phnum;
+    Elf64_Half		e_shentsize;
+    Elf64_Half		e_shnum;
+    Elf64_Half		e_shstrndx;
+} Elf64_Ehdr;
+#endif /* __LIBELF64 */
+
+/*
+ * e_ident
+ */
+#define EI_MAG0		0
+#define EI_MAG1		1
+#define EI_MAG2		2
+#define EI_MAG3		3
+#define EI_CLASS	4
+#define EI_DATA		5
+#define EI_VERSION	6
+#define EI_OSABI	7
+#define EI_ABIVERSION	8
+#define EI_PAD		9
+
+#define ELFMAG0		0x7f
+#define ELFMAG1		'E'
+#define ELFMAG2		'L'
+#define ELFMAG3		'F'
+#define ELFMAG		"\177ELF"
+#define SELFMAG		4
+
+/*
+ * e_ident[EI_CLASS]
+ */
+#define ELFCLASSNONE	0
+#define ELFCLASS32	1
+#define ELFCLASS64	2
+#define ELFCLASSNUM	3
+
+/*
+ * e_ident[EI_DATA]
+ */
+#define ELFDATANONE	0
+#define ELFDATA2LSB	1
+#define ELFDATA2MSB	2
+#define ELFDATANUM	3
+
+/*
+ * e_ident[EI_OSABI]
+ */
+#define ELFOSABI_NONE		0	/* No extensions or unspecified */
+#define ELFOSABI_SYSV		ELFOSABI_NONE
+#define ELFOSABI_HPUX		1	/* Hewlett-Packard HP-UX */
+#define ELFOSABI_NETBSD		2	/* NetBSD */
+#define ELFOSABI_LINUX		3	/* Linux */
+#define ELFOSABI_SOLARIS	6	/* Sun Solaris */
+#define ELFOSABI_AIX		7	/* AIX */
+#define ELFOSABI_IRIX		8	/* IRIX */
+#define ELFOSABI_FREEBSD	9	/* FreeBSD */
+#define ELFOSABI_TRU64		10	/* Compaq TRU64 UNIX */
+#define ELFOSABI_MODESTO	11	/* Novell Modesto */
+#define ELFOSABI_OPENBSD	12	/* Open BSD */
+#define ELFOSABI_OPENVMS	13	/* Open VMS */
+#define ELFOSABI_NSK		14	/* Hewlett-Packard Non-Stop Kernel */
+#define ELFOSABI_AROS	 	15 	/* Amiga Research OS */
+/* these are probably obsolete: */
+#define ELFOSABI_ARM		97	/* ARM */
+#define ELFOSABI_STANDALONE	255	/* standalone (embedded) application */
+
+
+/*
+ * e_type
+ */
+#define ET_NONE		0
+#define ET_REL		1
+#define ET_EXEC		2
+#define ET_DYN		3
+#define ET_CORE		4
+#define ET_NUM		5
+#define ET_LOOS		0xfe00
+#define ET_HIOS		0xfeff
+#define ET_LOPROC	0xff00
+#define ET_HIPROC	0xffff
+
+/*
+ * e_machine
+ */
+#define EM_NONE		0	/* No machine */
+#define EM_M32		1	/* AT&T WE 32100 */
+#define EM_SPARC	2	/* SPARC */
+#define EM_386		3	/* Intel 80386 */
+#define EM_68K		4	/* Motorola 68000 */
+#define EM_88K		5	/* Motorola 88000 */
+#define EM_486		6	/* Intel i486 (DO NOT USE THIS ONE) */
+#define EM_860		7	/* Intel 80860 */
+#define EM_MIPS		8	/* MIPS I Architecture */
+#define EM_S370		9	/* IBM System/370 Processor */
+#define EM_MIPS_RS3_LE	10	/* MIPS RS3000 Little-endian */
+#define EM_SPARC64	11	/* SPARC 64-bit */
+#define EM_PARISC	15	/* Hewlett-Packard PA-RISC */
+#define EM_VPP500	17	/* Fujitsu VPP500 */
+#define EM_SPARC32PLUS	18	/* Enhanced instruction set SPARC */
+#define EM_960		19	/* Intel 80960 */
+#define EM_PPC		20	/* PowerPC */
+#define EM_PPC64	21	/* 64-bit PowerPC */
+#define EM_S390		22	/* IBM System/390 Processor */
+#define EM_V800		36	/* NEC V800 */
+#define EM_FR20		37	/* Fujitsu FR20 */
+#define EM_RH32		38	/* TRW RH-32 */
+#define EM_RCE		39	/* Motorola RCE */
+#define EM_ARM		40	/* Advanced RISC Machines ARM */
+#define EM_ALPHA	41	/* Digital Alpha */
+#define EM_SH		42	/* Hitachi SH */
+#define EM_SPARCV9	43	/* SPARC Version 9 */
+#define EM_TRICORE	44	/* Siemens TriCore embedded processor */
+#define EM_ARC		45	/* Argonaut RISC Core, Argonaut Technologies Inc. */
+#define EM_H8_300	46	/* Hitachi H8/300 */
+#define EM_H8_300H	47	/* Hitachi H8/300H */
+#define EM_H8S		48	/* Hitachi H8S */
+#define EM_H8_500	49	/* Hitachi H8/500 */
+#define EM_IA_64	50	/* Intel IA-64 processor architecture */
+#define EM_MIPS_X	51	/* Stanford MIPS-X */
+#define EM_COLDFIRE	52	/* Motorola ColdFire */
+#define EM_68HC12	53	/* Motorola M68HC12 */
+#define EM_MMA		54	/* Fujitsu MMA Multimedia Accelerator */
+#define EM_PCP		55	/* Siemens PCP */
+#define EM_NCPU		56	/* Sony nCPU embedded RISC processor */
+#define EM_NDR1		57	/* Denso NDR1 microprocessor */
+#define EM_STARCORE	58	/* Motorola Star*Core processor */
+#define EM_ME16		59	/* Toyota ME16 processor */
+#define EM_ST100	60	/* STMicroelectronics ST100 processor */
+#define EM_TINYJ	61	/* Advanced Logic Corp. TinyJ embedded processor family */
+#define EM_X86_64	62	/* AMD x86-64 architecture */
+#define EM_AMD64	EM_X86_64
+#define EM_PDSP		63	/* Sony DSP Processor */
+#define EM_FX66		66	/* Siemens FX66 microcontroller */
+#define EM_ST9PLUS	67	/* STMicroelectronics ST9+ 8/16 bit microcontroller */
+#define EM_ST7		68	/* STMicroelectronics ST7 8-bit microcontroller */
+#define EM_68HC16	69	/* Motorola MC68HC16 Microcontroller */
+#define EM_68HC11	70	/* Motorola MC68HC11 Microcontroller */
+#define EM_68HC08	71	/* Motorola MC68HC08 Microcontroller */
+#define EM_68HC05	72	/* Motorola MC68HC05 Microcontroller */
+#define EM_SVX		73	/* Silicon Graphics SVx */
+#define EM_ST19		74	/* STMicroelectronics ST19 8-bit microcontroller */
+#define EM_VAX		75	/* Digital VAX */
+#define EM_CRIS		76	/* Axis Communications 32-bit embedded processor */
+#define EM_JAVELIN	77	/* Infineon Technologies 32-bit embedded processor */
+#define EM_FIREPATH	78	/* Element 14 64-bit DSP Processor */
+#define EM_ZSP		79	/* LSI Logic 16-bit DSP Processor */
+#define EM_MMIX		80	/* Donald Knuth's educational 64-bit processor */
+#define EM_HUANY	81	/* Harvard University machine-independent object files */
+#define EM_PRISM	82	/* SiTera Prism */
+#define EM_AVR		83	/* Atmel AVR 8-bit microcontroller */
+#define EM_FR30		84	/* Fujitsu FR30 */
+#define EM_D10V		85	/* Mitsubishi D10V */
+#define EM_D30V		86	/* Mitsubishi D30V */
+#define EM_V850		87	/* NEC v850 */
+#define EM_M32R		88	/* Mitsubishi M32R */
+#define EM_MN10300	89	/* Matsushita MN10300 */
+#define EM_MN10200	90	/* Matsushita MN10200 */
+#define EM_PJ		91	/* picoJava */
+#define EM_OPENRISC	92	/* OpenRISC 32-bit embedded processor */
+#define EM_ARC_A5	93	/* ARC Cores Tangent-A5 */
+#define EM_XTENSA	94	/* Tensilica Xtensa Architecture */
+#define EM_VIDEOCORE	95	/* Alphamosaic VideoCore processor */
+#define EM_TMM_GPP	96	/* Thompson Multimedia General Purpose Processor */
+#define EM_NS32K	97	/* National Semiconductor 32000 series */
+#define EM_TPC		98	/* Tenor Network TPC processor */
+#define EM_SNP1K	99	/* Trebia SNP 1000 processor */
+#define EM_ST200	100	/* STMicroelectronics (www.st.com) ST200 microcontroller */
+#define EM_IP2K 	101 	/* Ubicom IP2xxx microcontroller family */
+#define EM_MAX 		102 	/* MAX Processor */
+#define EM_CR 		103 	/* National Semiconductor CompactRISC microprocessor */
+#define EM_F2MC16 	104 	/* Fujitsu F2MC16 */
+#define EM_MSP430 	105 	/* Texas Instruments embedded microcontroller msp430 */
+#define EM_BLACKFIN	106 	/* Analog Devices Blackfin (DSP) processor */
+#define EM_SE_C33 	107 	/* S1C33 Family of Seiko Epson processors */
+#define EM_SEP 		108 	/* Sharp embedded microprocessor */
+#define EM_ARCA 	109 	/* Arca RISC Microprocessor */
+#define EM_UNICORE 	110 	/* Microprocessor series from PKU-Unity Ltd. and MPRC of Peking University */
+#define EM_NUM		111
+
+/*
+ * e_ident[EI_VERSION], e_version
+ */
+#define EV_NONE		0
+#define EV_CURRENT	1
+#define EV_NUM		2
+
+/*
+ * Section header
+ */
+typedef struct {
+    Elf32_Word		sh_name;
+    Elf32_Word		sh_type;
+    Elf32_Word		sh_flags;
+    Elf32_Addr		sh_addr;
+    Elf32_Off		sh_offset;
+    Elf32_Word		sh_size;
+    Elf32_Word		sh_link;
+    Elf32_Word		sh_info;
+    Elf32_Word		sh_addralign;
+    Elf32_Word		sh_entsize;
+} Elf32_Shdr;
+
+#if __LIBELF64
+typedef struct {
+    Elf64_Word		sh_name;
+    Elf64_Word		sh_type;
+    Elf64_Xword		sh_flags;
+    Elf64_Addr		sh_addr;
+    Elf64_Off		sh_offset;
+    Elf64_Xword		sh_size;
+    Elf64_Word		sh_link;
+    Elf64_Word		sh_info;
+    Elf64_Xword		sh_addralign;
+    Elf64_Xword		sh_entsize;
+} Elf64_Shdr;
+#endif /* __LIBELF64 */
+
+/*
+ * Special section indices
+ */
+#define SHN_UNDEF	0
+#define SHN_LORESERVE	0xff00
+#define SHN_LOPROC	0xff00
+#define SHN_HIPROC	0xff1f
+#define SHN_LOOS	0xff20
+#define SHN_HIOS	0xff3f
+#define SHN_ABS		0xfff1
+#define SHN_COMMON	0xfff2
+#define SHN_XINDEX	0xffff
+#define SHN_HIRESERVE	0xffff
+
+/*
+ * sh_type
+ */
+#define SHT_NULL		0
+#define SHT_PROGBITS		1
+#define SHT_SYMTAB		2
+#define SHT_STRTAB		3
+#define SHT_RELA		4
+#define SHT_HASH		5
+#define SHT_DYNAMIC		6
+#define SHT_NOTE		7
+#define SHT_NOBITS		8
+#define SHT_REL			9
+#define SHT_SHLIB		10
+#define SHT_DYNSYM		11
+#define SHT_INIT_ARRAY		14
+#define SHT_FINI_ARRAY		15
+#define SHT_PREINIT_ARRAY	16
+#define SHT_GROUP		17
+#define SHT_SYMTAB_SHNDX	18
+#define SHT_NUM			19
+#define SHT_LOOS		0x60000000
+#define SHT_HIOS		0x6fffffff
+#define SHT_LOPROC		0x70000000
+#define SHT_HIPROC		0x7fffffff
+#define SHT_LOUSER		0x80000000
+#define SHT_HIUSER		0xffffffff
+
+/*
+ * Solaris extensions
+ */
+#define SHT_LOSUNW		0x6ffffff4
+#define SHT_SUNW_dof		0x6ffffff4
+#define SHT_SUNW_cap		0x6ffffff5
+#define SHT_SUNW_SIGNATURE	0x6ffffff6
+#define SHT_SUNW_ANNOTATE	0x6ffffff7
+#define SHT_SUNW_DEBUGSTR	0x6ffffff8
+#define SHT_SUNW_DEBUG		0x6ffffff9
+#define SHT_SUNW_move		0x6ffffffa
+#define SHT_SUNW_COMDAT		0x6ffffffb
+#define SHT_SUNW_syminfo	0x6ffffffc
+#define SHT_SUNW_verdef		0x6ffffffd
+#define SHT_SUNW_verneed	0x6ffffffe
+#define SHT_SUNW_versym		0x6fffffff
+#define SHT_HISUNW		0x6fffffff
+
+#define SHT_SPARC_GOTDATA	0x70000000
+#define SHT_AMD64_UNWIND	0x70000001 
+
+/*
+ * GNU extensions
+ */
+#define SHT_GNU_verdef		0x6ffffffd
+#define SHT_GNU_verneed		0x6ffffffe
+#define SHT_GNU_versym		0x6fffffff
+
+/*
+ * sh_flags
+ */
+#define SHF_WRITE		0x1
+#define SHF_ALLOC		0x2
+#define SHF_EXECINSTR		0x4
+#define SHF_MERGE		0x10
+#define SHF_STRINGS		0x20
+#define SHF_INFO_LINK		0x40
+#define SHF_LINK_ORDER		0x80
+#define SHF_OS_NONCONFORMING	0x100
+#define SHF_GROUP		0x200
+#define SHF_TLS			0x400
+#define SHF_MASKOS		0x0ff00000
+#define SHF_MASKPROC		0xf0000000
+
+/*
+ * Solaris extensions
+ */
+#define SHF_AMD64_LARGE		0x10000000
+#define SHF_ORDERED		0x40000000
+#define SHF_EXCLUDE		0x80000000
+
+/*
+ * Section group flags
+ */
+#define GRP_COMDAT		0x1
+#define GRP_MASKOS		0x0ff00000
+#define GRP_MASKPROC		0xf0000000
+
+/*
+ * Symbol table
+ */
+typedef struct {
+    Elf32_Word		st_name;
+    Elf32_Addr		st_value;
+    Elf32_Word		st_size;
+    unsigned char	st_info;
+    unsigned char	st_other;
+    Elf32_Half		st_shndx;
+} Elf32_Sym;
+
+#if __LIBELF64
+typedef struct {
+    Elf64_Word		st_name;
+    unsigned char	st_info;
+    unsigned char	st_other;
+    Elf64_Half		st_shndx;
+    Elf64_Addr		st_value;
+    Elf64_Xword		st_size;
+} Elf64_Sym;
+#endif /* __LIBELF64 */
+
+/*
+ * Special symbol indices
+ */
+#define STN_UNDEF	0
+
+/*
+ * Macros for manipulating st_info
+ */
+#define ELF32_ST_BIND(i)	((i)>>4)
+#define ELF32_ST_TYPE(i)	((i)&0xf)
+#define ELF32_ST_INFO(b,t)	(((b)<<4)+((t)&0xf))
+
+#if __LIBELF64
+#define ELF64_ST_BIND(i)	((i)>>4)
+#define ELF64_ST_TYPE(i)	((i)&0xf)
+#define ELF64_ST_INFO(b,t)	(((b)<<4)+((t)&0xf))
+#endif /* __LIBELF64 */
+
+/*
+ * Symbol binding
+ */
+#define STB_LOCAL	0
+#define STB_GLOBAL	1
+#define STB_WEAK	2
+#define STB_NUM		3
+#define STB_LOOS	10
+#define STB_HIOS	12
+#define STB_LOPROC	13
+#define STB_HIPROC	15
+
+/*
+ * Symbol types
+ */
+#define STT_NOTYPE	0
+#define STT_OBJECT	1
+#define STT_FUNC	2
+#define STT_SECTION	3
+#define STT_FILE	4
+#define STT_COMMON	5
+#define STT_TLS		6
+#define STT_NUM		7
+#define STT_LOOS	10
+#define STT_HIOS	12
+#define STT_LOPROC	13
+#define STT_HIPROC	15
+
+/*
+ * Macros for manipulating st_other
+ */
+#define ELF32_ST_VISIBILITY(o)	((o)&0x3)
+#if __LIBELF64
+#define ELF64_ST_VISIBILITY(o)	((o)&0x3)
+#endif /* __LIBELF64 */
+
+/*
+ * Symbol visibility
+ */
+#define STV_DEFAULT	0
+#define STV_INTERNAL	1
+#define STV_HIDDEN	2
+#define STV_PROTECTED	3
+
+/*
+ * Relocation
+ */
+typedef struct {
+    Elf32_Addr		r_offset;
+    Elf32_Word		r_info;
+} Elf32_Rel;
+
+typedef struct {
+    Elf32_Addr		r_offset;
+    Elf32_Word		r_info;
+    Elf32_Sword		r_addend;
+} Elf32_Rela;
+
+#if __LIBELF64
+typedef struct {
+    Elf64_Addr		r_offset;
+    Elf64_Xword		r_info;
+} Elf64_Rel;
+
+typedef struct {
+    Elf64_Addr		r_offset;
+    Elf64_Xword		r_info;
+    Elf64_Sxword	r_addend;
+} Elf64_Rela;
+#endif /* __LIBELF64 */
+
+/*
+ * Macros for manipulating r_info
+ */
+#define ELF32_R_SYM(i)		((i)>>8)
+#define ELF32_R_TYPE(i)		((unsigned char)(i))
+#define ELF32_R_INFO(s,t)	(((s)<<8)+(unsigned char)(t))
+
+#if __LIBELF64
+#define ELF64_R_SYM(i)		((Elf64_Xword)(i)>>32)
+#define ELF64_R_TYPE(i)		((i)&0xffffffffL)
+#define ELF64_R_INFO(s,t)	(((Elf64_Xword)(s)<<32)+((t)&0xffffffffL))
+#endif /* __LIBELF64 */
+
+/*
+ * Note entry header
+ */
+typedef struct {
+    Elf32_Word		n_namesz;	/* name size */
+    Elf32_Word		n_descsz;	/* descriptor size */
+    Elf32_Word		n_type;		/* descriptor type */
+} Elf32_Nhdr;
+
+#if __LIBELF64
+/* Solaris and GNU use this layout.  Be compatible. */
+/* XXX: Latest ELF specs say it's 64-bit!!! */
+typedef struct {
+    Elf64_Word		n_namesz;	/* name size */
+    Elf64_Word		n_descsz;	/* descriptor size */
+    Elf64_Word		n_type;		/* descriptor type */
+} Elf64_Nhdr;
+#endif /* __LIBELF64 */
+
+/*
+ * Well-known descriptor types for ET_CORE files
+ */
+#define NT_PRSTATUS	1
+#define NT_PRFPREG	2
+#define NT_PRPSINFO	3
+
+/*
+ * Program header
+ */
+typedef struct {
+    Elf32_Word		p_type;
+    Elf32_Off		p_offset;
+    Elf32_Addr		p_vaddr;
+    Elf32_Addr		p_paddr;
+    Elf32_Word		p_filesz;
+    Elf32_Word		p_memsz;
+    Elf32_Word		p_flags;
+    Elf32_Word		p_align;
+} Elf32_Phdr;
+
+#if __LIBELF64
+typedef struct {
+    Elf64_Word		p_type;
+    Elf64_Word		p_flags;
+    Elf64_Off		p_offset;
+    Elf64_Addr		p_vaddr;
+    Elf64_Addr		p_paddr;
+    Elf64_Xword		p_filesz;
+    Elf64_Xword		p_memsz;
+    Elf64_Xword		p_align;
+} Elf64_Phdr;
+#endif /* __LIBELF64 */
+
+/*
+ * Special numbers
+ */
+#define PN_XNUM		0xffff
+
+/*
+ * p_type
+ */
+#define PT_NULL		0
+#define PT_LOAD		1
+#define PT_DYNAMIC	2
+#define PT_INTERP	3
+#define PT_NOTE		4
+#define PT_SHLIB	5
+#define PT_PHDR		6
+#define PT_TLS		7
+#define PT_NUM		8
+#define PT_LOOS		0x60000000
+#define PT_HIOS		0x6fffffff
+#define PT_LOPROC	0x70000000
+#define PT_HIPROC	0x7fffffff
+
+/*
+ * Solaris extensions
+ */
+
+#define PT_SUNW_UNWIND	0x6464e550
+#define PT_LOSUNW	0x6ffffffa
+#define PT_SUNWBSS	0x6ffffffa
+#define PT_SUNWSTACK	0x6ffffffb
+#define PT_SUNWDTRACE	0x6ffffffc
+#define PT_SUNWCAP	0x6ffffffd
+#define PT_HISUNW	0x6fffffff 
+
+/*
+ * p_flags
+ */
+#define PF_X		0x1
+#define PF_W		0x2
+#define PF_R		0x4
+#define PF_MASKOS	0x0ff00000
+#define PF_MASKPROC	0xf0000000
+
+/*
+ * Dynamic structure
+ */
+typedef struct {
+    Elf32_Sword		d_tag;
+    union {
+	Elf32_Word	d_val;
+	Elf32_Addr	d_ptr;
+    } d_un;
+} Elf32_Dyn;
+
+#if __LIBELF64
+typedef struct {
+    Elf64_Sxword	d_tag;
+    union {
+	Elf64_Xword	d_val;
+	Elf64_Addr	d_ptr;
+    } d_un;
+} Elf64_Dyn;
+#endif /* __LIBELF64 */
+
+/*
+ * Dynamic array tags
+ */
+					/* d_un   exec	 shared */
+#define DT_NULL			0	/* ign.   mand.	 mand. */
+#define DT_NEEDED		1	/* d_val  opt.	 opt.  */
+#define DT_PLTRELSZ		2	/* d_val  opt.	 opt.  */
+#define DT_PLTGOT		3	/* d_ptr  opt.	 opt.  */
+#define DT_HASH			4	/* d_ptr  mand.	 mand. */
+#define DT_STRTAB		5	/* d_ptr  mand.	 mand. */
+#define DT_SYMTAB		6	/* d_ptr  mand.	 mand. */
+#define DT_RELA			7	/* d_ptr  mand.	 opt.  */
+#define DT_RELASZ		8	/* d_val  mand.	 opt.  */
+#define DT_RELAENT		9	/* d_val  mand.	 opt.  */
+#define DT_STRSZ		10	/* d_val  mand.	 mand. */
+#define DT_SYMENT		11	/* d_val  mand.	 mand. */
+#define DT_INIT			12	/* d_ptr  opt.	 opt.  */
+#define DT_FINI			13	/* d_ptr  opt.	 opt.  */
+#define DT_SONAME		14	/* d_val  ign.	 opt.  */
+#define DT_RPATH		15	/* d_val  opt.	 ign.  */
+#define DT_SYMBOLIC		16	/* ign.   ign.	 opt.  */
+#define DT_REL			17	/* d_ptr  mand.	 opt.  */
+#define DT_RELSZ		18	/* d_val  mand.	 opt.  */
+#define DT_RELENT		19	/* d_val  mand.	 opt.  */
+#define DT_PLTREL		20	/* d_val  opt.	 opt.  */
+#define DT_DEBUG		21	/* d_ptr  opt.	 ign.  */
+#define DT_TEXTREL		22	/* ign.   opt.	 opt.  */
+#define DT_JMPREL		23	/* d_ptr  opt.	 opt.  */
+#define DT_BIND_NOW		24	/* ign.   opt.	 opt.  */
+#define DT_INIT_ARRAY		25	/* d_ptr  opt.	 opt.  */
+#define DT_FINI_ARRAY		26	/* d_ptr  opt.	 opt.  */
+#define DT_INIT_ARRAYSZ		27	/* d_val  opt.	 opt.  */
+#define DT_FINI_ARRAYSZ		28	/* d_val  opt.	 opt.  */
+#define DT_RUNPATH		29	/* d_val  opt.	 opt.  */
+#define DT_FLAGS		30	/* d_val  opt.	 opt.  */
+#define DT_ENCODING		32	/* odd/even encoding rule starts here */
+#define DT_PREINIT_ARRAY	32	/* d_ptr  opt.	 ign.  */
+#define DT_PREINIT_ARRAYSZ	33	/* d_val  opt.	 ign.  */
+#define DT_NUM			34
+#define DT_LOOS			0x6000000D
+#define DT_HIOS			0x6ffff000
+#define DT_LOPROC		0x70000000
+#define DT_HIPROC		0x7fffffff
+
+/*
+ * DT_FLAGS values
+ */
+#define DF_ORIGIN	0x1
+#define DF_SYMBOLIC	0x2
+#define DF_TEXTREL	0x4
+#define DF_BIND_NOW	0x8
+#define DF_STATIC_TLS	0x10
+
+/*
+ * Solaris extensions
+ */
+#define DT_VALRNGLO	0x6ffffd00
+#define DT_CHECKSUM	0x6ffffdf8
+#define DT_PLTPADSZ	0x6ffffdf9
+#define DT_MOVEENT	0x6ffffdfa
+#define DT_MOVESZ	0x6ffffdfb
+#define DT_FEATURE_1	0x6ffffdfc
+#define DT_POSFLAG_1	0x6ffffdfd
+#define DT_SYMINSZ	0x6ffffdfe
+#define DT_SYMINENT	0x6ffffdff
+#define DT_VALRNGHI	0x6ffffdff
+
+#define DT_ADDRRNGLO	0x6ffffe00
+#define DT_CONFIG	0x6ffffefa
+#define DT_DEPAUDIT	0x6ffffefb
+#define DT_AUDIT	0x6ffffefc
+#define DT_PLTPAD	0x6ffffefd
+#define DT_MOVETAB	0x6ffffefe
+#define DT_SYMINFO	0x6ffffeff
+#define DT_ADDRRNGHI	0x6ffffeff
+
+#define DT_RELACOUNT	0x6ffffff9
+#define DT_RELCOUNT	0x6ffffffa
+#define DT_FLAGS_1	0x6ffffffb
+#define DT_VERDEF	0x6ffffffc
+#define DT_VERDEFNUM	0x6ffffffd
+#define DT_VERNEED	0x6ffffffe
+#define DT_VERNEEDNUM	0x6fffffff
+
+#define DT_AUXILIARY	0x7ffffffd
+#define DT_USED		0x7ffffffe
+#define DT_FILTER	0x7fffffff
+
+/*
+ * GNU extensions
+ */
+#define DT_VERSYM	0x6ffffff0
+
+/*
+ * DT_FEATURE_1 values
+ */
+#define DTF_1_PARINIT	0x1
+#define DTF_1_CONFEXP	0x2
+
+/*
+ * DT_POSFLAG_1 values
+ */
+#define DF_P1_LAZYLOAD	0x1
+#define DF_P1_GROUPPERM	0x2
+
+/*
+ * DT_FLAGS_1 values
+ */
+#define DF_1_NOW	0x00000001
+#define DF_1_GLOBAL	0x00000002
+#define DF_1_GROUP	0x00000004
+#define DF_1_NODELETE	0x00000008
+#define DF_1_LOADFLTR	0x00000010
+#define DF_1_INITFIRST	0x00000020
+#define DF_1_NOOPEN	0x00000040
+#define DF_1_ORIGIN	0x00000080
+#define DF_1_DIRECT	0x00000100
+#define DF_1_TRANS	0x00000200
+#define DF_1_INTERPOSE	0x00000400
+#define DF_1_NODEFLIB	0x00000800
+#define DF_1_NODUMP	0x00001000
+#define DF_1_CONFALT	0x00002000
+#define DF_1_ENDFILTEE	0x00004000
+#define DF_1_DISPRELDNE	0x00008000
+#define DF_1_DISPRELPND	0x00010000
+
+/*
+ * Syminfo structure
+ */
+typedef struct {
+    Elf32_Half		si_boundto;
+    Elf32_Half		si_flags;
+} Elf32_Syminfo;
+
+#if __LIBELF64
+typedef struct {
+    Elf64_Half		si_boundto;
+    Elf64_Half		si_flags;
+} Elf64_Syminfo;
+#endif /* __LIBELF64 */
+
+/*
+ * Syminfo version (stored in unused first entry)
+ */
+#define SYMINFO_NONE	0
+#define SYMINFO_CURRENT	1
+#define SYMINFO_NUM	2
+
+/*
+ * si_boundto special values
+ */
+#define SYMINFO_BT_LOWRESERVE	0xff00
+#define SYMINFO_BT_PARENT	0xfffe	/* bound to parent */
+#define SYMINFO_BT_SELF		0xffff	/* bound to self */
+
+/*
+ * si_flags
+ */
+#define SYMINFO_FLG_DIRECT	0x01	/* bound to an object */
+#define SYMINFO_FLG_PASSTHRU	0x02	/* pass-thru symbol */
+#define SYMINFO_FLG_COPY	0x04	/* result of a copy relocation */
+#define SYMINFO_FLG_LAZYLOAD	0x08	/* bound to lazy-loaded object */
+
+/*
+ * Version definitions
+ */
+typedef struct {
+    Elf32_Half		vd_version;
+    Elf32_Half		vd_flags;
+    Elf32_Half		vd_ndx;
+    Elf32_Half		vd_cnt;
+    Elf32_Word		vd_hash;
+    Elf32_Word		vd_aux;
+    Elf32_Word		vd_next;
+} Elf32_Verdef;
+
+typedef struct {
+    Elf32_Word		vda_name;
+    Elf32_Word		vda_next;
+} Elf32_Verdaux;
+
+typedef struct {
+    Elf32_Half		vn_version;
+    Elf32_Half		vn_cnt;
+    Elf32_Word		vn_file;
+    Elf32_Word		vn_aux;
+    Elf32_Word		vn_next;
+} Elf32_Verneed;
+
+typedef struct {
+    Elf32_Word		vna_hash;
+    Elf32_Half		vna_flags;
+    Elf32_Half		vna_other;
+    Elf32_Word		vna_name;
+    Elf32_Word		vna_next;
+} Elf32_Vernaux;
+
+typedef Elf32_Half	Elf32_Versym;
+
+#if __LIBELF64
+
+typedef struct {
+    Elf64_Half		vd_version;
+    Elf64_Half		vd_flags;
+    Elf64_Half		vd_ndx;
+    Elf64_Half		vd_cnt;
+    Elf64_Word		vd_hash;
+    Elf64_Word		vd_aux;
+    Elf64_Word		vd_next;
+} Elf64_Verdef;
+
+typedef struct {
+    Elf64_Word		vda_name;
+    Elf64_Word		vda_next;
+} Elf64_Verdaux;
+
+typedef struct {
+    Elf64_Half		vn_version;
+    Elf64_Half		vn_cnt;
+    Elf64_Word		vn_file;
+    Elf64_Word		vn_aux;
+    Elf64_Word		vn_next;
+} Elf64_Verneed;
+
+typedef struct {
+    Elf64_Word		vna_hash;
+    Elf64_Half		vna_flags;
+    Elf64_Half		vna_other;
+    Elf64_Word		vna_name;
+    Elf64_Word		vna_next;
+} Elf64_Vernaux;
+
+typedef Elf64_Half	Elf64_Versym;
+
+#endif /* __LIBELF64 */
+
+/*
+ * vd_version
+ */
+#define VER_DEF_NONE	0
+#define VER_DEF_CURRENT	1
+#define VER_DEF_NUM	2
+
+/*
+ * vn_version
+ */
+#define VER_NEED_NONE		0
+#define VER_NEED_CURRENT	1
+#define VER_NEED_NUM		2
+
+/*
+ * vd_flags / vna_flags
+ */
+#define VER_FLG_BASE	0x1	/* vd_flags only */
+#define VER_FLG_WEAK	0x2
+
+/*
+ * Elf*_Versym special values
+ */
+#define VER_NDX_LOCAL	0
+#define VER_NDX_GLOBAL	1
+
+/*
+ * Solaris extensions
+ */
+
+/*
+ * Move section
+ */
+#if __LIBELF64
+
+typedef struct {
+    Elf32_Lword		m_value;
+    Elf32_Word		m_info;
+    Elf32_Word		m_poffset;
+    Elf32_Half		m_repeat;
+    Elf32_Half		m_stride;
+} Elf32_Move;
+
+typedef struct {
+    Elf64_Lword		m_value;
+    Elf64_Xword		m_info;
+    Elf64_Xword		m_poffset;
+    Elf64_Half		m_repeat;
+    Elf64_Half		m_stride;
+} Elf64_Move;
+
+#define ELF32_M_SYM(info)	((info)>>8)
+#define ELF32_M_SIZE(info)	((unsigned char)(info))
+#define ELF32_M_INFO(sym, sz)	(((sym)<<8)+(unsigned char)(sz))
+
+#define ELF64_M_SYM(info)	((Elf64_Xword)(info)>>8)
+#define ELF64_M_SIZE(info)	((unsigned char)(info))
+#define ELF64_M_INFO(sym, sz)	(((Elf64_Xword)(sym)<<8)+(unsigned char)(sz))
+
+#endif /* __LIBELF64 */
+
+/*
+ * Capabilities
+ */
+
+typedef struct {
+    Elf32_Word      	c_tag;
+    union {
+	Elf32_Word      c_val;
+	Elf32_Addr      c_ptr;
+    } c_un;
+} Elf32_Cap;
+
+typedef struct {
+    Elf64_Xword     	c_tag;
+    union {
+	Elf64_Xword     c_val;
+	Elf64_Addr      c_ptr;
+    } c_un;
+} Elf64_Cap;
+
+#define CA_SUNW_NULL	0	/* c_un ignored */
+#define CA_SUNW_HW_1	1	/* c_un.c_val */
+#define CA_SUNW_SF_1	2	/* c_un.c_val */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _ELF_REPL_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/end.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,118 @@
+/*
+ * end.c - implementation of the elf_end(3) function.
+ * Copyright (C) 1995 - 2004 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: end.c,v 1.11 2005/05/21 15:39:21 michael Exp $";
+#endif /* lint */
+
+#if HAVE_MMAP
+#include <sys/mman.h>
+#endif /* HAVE_MMAP */
+
+static void
+_elf_free(void *ptr) {
+    if (ptr) {
+	free(ptr);
+    }
+}
+
+static void
+_elf_free_scns(Elf *elf, Elf_Scn *scn) {
+    Scn_Data *sd, *tmp;
+    Elf_Scn *freescn;
+
+    for (freescn = NULL; scn; scn = scn->s_link) {
+	elf_assert(scn->s_magic == SCN_MAGIC);
+	elf_assert(scn->s_elf == elf);
+	for (sd = scn->s_data_1; sd; sd = tmp) {
+	    elf_assert(sd->sd_magic == DATA_MAGIC);
+	    elf_assert(sd->sd_scn == scn);
+	    tmp = sd->sd_link;
+	    if (sd->sd_free_data) {
+		_elf_free(sd->sd_memdata);
+	    }
+	    if (sd->sd_freeme) {
+		free(sd);
+	    }
+	}
+	if ((sd = scn->s_rawdata)) {
+	    elf_assert(sd->sd_magic == DATA_MAGIC);
+	    elf_assert(sd->sd_scn == scn);
+	    if (sd->sd_free_data) {
+		_elf_free(sd->sd_memdata);
+	    }
+	    if (sd->sd_freeme) {
+		free(sd);
+	    }
+	}
+	if (scn->s_freeme) {
+	    _elf_free(freescn);
+	    freescn = scn;
+	}
+    }
+    _elf_free(freescn);
+}
+
+int
+elf_end(Elf *elf) {
+    Elf **siblings;
+
+    if (!elf) {
+	return 0;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (--elf->e_count) {
+	return elf->e_count;
+    }
+    if (elf->e_parent) {
+	elf_assert(elf->e_parent->e_magic == ELF_MAGIC);
+	elf_assert(elf->e_parent->e_kind == ELF_K_AR);
+	siblings = &elf->e_parent->e_members;
+	while (*siblings) {
+	    if (*siblings == elf) {
+		*siblings = elf->e_link;
+		break;
+	    }
+	    siblings = &(*siblings)->e_link;
+	}
+	elf_end(elf->e_parent);
+	_elf_free(elf->e_arhdr);
+    }
+#if HAVE_MMAP
+    else if (elf->e_unmap_data) {
+	munmap(elf->e_data, elf->e_size);
+    }
+#endif /* HAVE_MMAP */
+    else if (!elf->e_memory) {
+	_elf_free(elf->e_data);
+    }
+    _elf_free_scns(elf, elf->e_scn_1);
+    if (elf->e_rawdata != elf->e_data) {
+	_elf_free(elf->e_rawdata);
+    }
+    if (elf->e_free_syms) {
+	_elf_free(elf->e_symtab);
+    }
+    _elf_free(elf->e_ehdr);
+    _elf_free(elf->e_phdr);
+    free(elf);
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/errmsg.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,77 @@
+/*
+ * errmsg.c - implementation of the elf_errmsg(3) function.
+ * Copyright (C) 1995 - 1999, 2004 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: errmsg.c,v 1.10 2005/05/21 15:39:21 michael Exp $";
+#endif /* lint */
+
+#if HAVE_DGETTEXT
+# undef HAVE_CATGETS
+# include <libintl.h>
+#else /* HAVE_DGETTEXT */
+# define dgettext(dom, str) str
+#endif /* HAVE_DGETTEXT */
+
+#if HAVE_CATGETS
+# include <nl_types.h>
+static nl_catd _libelf_cat = (nl_catd)0;
+#endif /* HAVE_CATGETS */
+
+#if HAVE_DGETTEXT || HAVE_CATGETS
+static const char domain[] = "libelf";
+#endif /* HAVE_DGETTEXT || HAVE_CATGETS */
+
+#if PIC
+static const char *_messages[] = {
+#else /* PIC */
+static const char *const _messages[] = {
+#endif /* PIC */
+#define __err__(a,b)	b,
+#include <errors.h>		/* include string tables from errors.h */
+#undef __err__
+};
+
+const char*
+elf_errmsg(int err) {
+    if (err == 0) {
+	err = _elf_errno;
+	if (err == 0) {
+	    return NULL;
+	}
+    }
+    else if (err == -1) {
+	err = _elf_errno;
+    }
+
+    if (err < 0 || err >= ERROR_NUM || _messages[err] == NULL) {
+	err = ERROR_UNKNOWN;
+    }
+
+#if HAVE_CATGETS
+    if (_libelf_cat == (nl_catd)0) {
+	_libelf_cat = catopen(domain, 0);
+    }
+    if (_libelf_cat != (nl_catd)-1) {
+	return catgets(_libelf_cat, 1, err + 1, _messages[err]);
+    }
+#endif /* HAVE_CATGETS */
+    return dgettext(domain, _messages[err]);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/errno.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,32 @@
+/*
+errno.c - implementation of the elf_errno(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: errno.c,v 1.6 2005/05/21 15:39:21 michael Exp $";
+#endif /* lint */
+
+int
+elf_errno(void) {
+    int tmp = _elf_errno;
+
+    _elf_errno = 0;
+    return tmp;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/errors.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,100 @@
+/*
+ * errors.h - exhaustive list of all error codes and messages for libelf.
+ * Copyright (C) 1995 - 2003, 2006 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* @(#) $Id: errors.h,v 1.17 2006/04/21 17:17:46 michael Exp $ */
+
+/* dummy for xgettext */
+#define _(str) str
+
+__err__(ERROR_OK,		_("no error"))
+__err__(ERROR_UNKNOWN,		_("unknown error"))
+__err__(ERROR_INTERNAL,		_("Internal error: unknown reason"))
+__err__(ERROR_UNIMPLEMENTED,	_("Internal error: not implemented"))
+__err__(ERROR_WRONLY,		_("Request error: cntl(ELF_C_FDREAD) on write-only file"))
+__err__(ERROR_INVALID_CMD,	_("Request error: invalid ELF_C_* argument"))
+__err__(ERROR_FDDISABLED,	_("Request error: file descriptor disabled"))
+__err__(ERROR_NOTARCHIVE,	_("Request error: not an archive"))
+__err__(ERROR_BADOFF,		_("Request error: offset out of range"))
+__err__(ERROR_UNKNOWN_VERSION,	_("Request error: unknown ELF version"))
+__err__(ERROR_CMDMISMATCH,	_("Request error: ELF_C_* argument does not match"))
+__err__(ERROR_MEMBERWRITE,	_("Request error: archive member begin() for writing"))
+__err__(ERROR_FDMISMATCH,	_("Request error: archive/member file descriptor mismatch"))
+__err__(ERROR_NOTELF,		_("Request error: not an ELF file"))
+__err__(ERROR_CLASSMISMATCH,	_("Request error: class file/memory mismatch"))
+__err__(ERROR_UNKNOWN_TYPE,	_("Request error: invalid ELF_T_* argument"))
+__err__(ERROR_UNKNOWN_ENCODING,	_("Request error: unknown data encoding"))
+__err__(ERROR_DST2SMALL,	_("Request error: destination buffer too small"))
+__err__(ERROR_NULLBUF,		_("Request error: d_buf is NULL"))
+__err__(ERROR_UNKNOWN_CLASS,	_("Request error: unknown ELF class"))
+__err__(ERROR_ELFSCNMISMATCH,	_("Request error: section does not belong to file"))
+__err__(ERROR_NOSUCHSCN,	_("Request error: no section at index"))
+__err__(ERROR_NULLSCN,		_("Request error: can't manipulate null section"))
+__err__(ERROR_SCNDATAMISMATCH,	_("Request error: data does not belong to section"))
+__err__(ERROR_NOSTRTAB,		_("Request error: no string table"))
+__err__(ERROR_BADSTROFF,	_("Request error: string table offset out of range"))
+__err__(ERROR_RDONLY,		_("Request error: update(ELF_C_WRITE) on read-only file"))
+__err__(ERROR_IO_SEEK,		_("I/O error: seek"))
+__err__(ERROR_IO_2BIG,		_("I/O error: file too big for memory"))
+__err__(ERROR_IO_READ,		_("I/O error: raw read"))
+__err__(ERROR_IO_GETSIZE,	_("I/O error: get file size"))
+__err__(ERROR_IO_WRITE,		_("I/O error: output write"))
+__err__(ERROR_IO_TRUNC,		_("I/O error: can't truncate output file"))
+__err__(ERROR_VERSION_UNSET,	_("Sequence error: must set ELF version first"))
+__err__(ERROR_NOEHDR,		_("Sequence error: must create ELF header first"))
+__err__(ERROR_OUTSIDE,		_("Format error: reference outside file"))
+__err__(ERROR_TRUNC_ARHDR,	_("Format error: archive header truncated"))
+__err__(ERROR_ARFMAG,		_("Format error: archive fmag"))
+__err__(ERROR_ARHDR,		_("Format error: archive header"))
+__err__(ERROR_TRUNC_MEMBER,	_("Format error: archive member truncated"))
+__err__(ERROR_SIZE_ARSYMTAB,	_("Format error: archive symbol table size"))
+__err__(ERROR_ARSTRTAB,		_("Format error: archive string table"))
+__err__(ERROR_ARSPECIAL,	_("Format error: archive special name unknown"))
+__err__(ERROR_TRUNC_EHDR,	_("Format error: ELF header truncated"))
+__err__(ERROR_TRUNC_PHDR,	_("Format error: program header table truncated"))
+__err__(ERROR_TRUNC_SHDR,	_("Format error: section header table truncated"))
+__err__(ERROR_TRUNC_SCN,	_("Format error: data region truncated"))
+__err__(ERROR_ALIGN_PHDR,	_("Format error: program header table alignment"))
+__err__(ERROR_ALIGN_SHDR,	_("Format error: section header table alignment"))
+__err__(ERROR_VERDEF_FORMAT,	_("Format error: bad parameter in Verdef record"))
+__err__(ERROR_VERDEF_VERSION,	_("Format error: unknown Verdef version"))
+__err__(ERROR_VERNEED_FORMAT,	_("Format error: bad parameter in Verneed record"))
+__err__(ERROR_VERNEED_VERSION,	_("Format error: unknown Verneed version"))
+__err__(ERROR_EHDR_SHNUM,	_("Format error: bad e_shnum value"))
+__err__(ERROR_EHDR_SHENTSIZE,	_("Format error: bad e_shentsize value"))
+__err__(ERROR_EHDR_PHENTSIZE,	_("Format error: bad e_phentsize value"))
+__err__(ERROR_UNTERM,		_("Format error: unterminated string in string table"))
+__err__(ERROR_SCN2SMALL,	_("Layout error: section size too small for data"))
+__err__(ERROR_SCN_OVERLAP,	_("Layout error: overlapping sections"))
+__err__(ERROR_MEM_ELF,		_("Memory error: elf descriptor"))
+__err__(ERROR_MEM_ARSYMTAB,	_("Memory error: archive symbol table"))
+__err__(ERROR_MEM_ARHDR,	_("Memory error: archive member header"))
+__err__(ERROR_MEM_EHDR,		_("Memory error: ELF header"))
+__err__(ERROR_MEM_PHDR,		_("Memory error: program header table"))
+__err__(ERROR_MEM_SHDR,		_("Memory error: section header table"))
+__err__(ERROR_MEM_SCN,		_("Memory error: section descriptor"))
+__err__(ERROR_MEM_SCNDATA,	_("Memory error: section data"))
+__err__(ERROR_MEM_OUTBUF,	_("Memory error: output file space"))
+__err__(ERROR_MEM_TEMPORARY,    _("Memory error: temporary buffer"))
+__err__(ERROR_BADVALUE,		_("GElf error: value out of range"))
+__err__(ERROR_BADINDEX,		_("GElf error: index out of range"))
+__err__(ERROR_BADTYPE,		_("GElf error: type mismatch"))
+__err__(ERROR_MEM_SYM,		_("GElf error: not enough memory for GElf_Sym"))
+__err__(ERROR_MEM_DYN,		_("GElf error: not enough memory for GElf_Dyn"))
+__err__(ERROR_MEM_RELA,		_("GElf error: not enough memory for GElf_Rela"))
+__err__(ERROR_MEM_REL,		_("GElf error: not enough memory for GElf_Rel"))
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/ext_types.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,334 @@
+/*
+ext_types.h - external representation of ELF data types.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+/* @(#) $Id: ext_types.h,v 1.8 2005/05/21 15:39:22 michael Exp $ */
+
+#ifndef _EXT_TYPES_H
+#define _EXT_TYPES_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/*
+ * Scalar data types
+ */
+typedef unsigned char __ext_Elf32_Addr  [ELF32_FSZ_ADDR];
+typedef unsigned char __ext_Elf32_Half  [ELF32_FSZ_HALF];
+typedef unsigned char __ext_Elf32_Off   [ELF32_FSZ_OFF];
+typedef unsigned char __ext_Elf32_Sword [ELF32_FSZ_SWORD];
+typedef unsigned char __ext_Elf32_Word  [ELF32_FSZ_WORD];
+
+#if __LIBELF64
+
+typedef unsigned char __ext_Elf32_Lword [8];
+
+typedef unsigned char __ext_Elf64_Addr  [ELF64_FSZ_ADDR];
+typedef unsigned char __ext_Elf64_Half  [ELF64_FSZ_HALF];
+typedef unsigned char __ext_Elf64_Off   [ELF64_FSZ_OFF];
+typedef unsigned char __ext_Elf64_Sword [ELF64_FSZ_SWORD];
+typedef unsigned char __ext_Elf64_Word  [ELF64_FSZ_WORD];
+typedef unsigned char __ext_Elf64_Sxword[ELF64_FSZ_SXWORD];
+typedef unsigned char __ext_Elf64_Xword [ELF64_FSZ_XWORD];
+
+typedef unsigned char __ext_Elf64_Lword [8];
+
+#endif /* __LIBELF64 */
+
+/*
+ * ELF header
+ */
+typedef struct {
+    unsigned char	e_ident[EI_NIDENT];
+    __ext_Elf32_Half	e_type;
+    __ext_Elf32_Half	e_machine;
+    __ext_Elf32_Word	e_version;
+    __ext_Elf32_Addr	e_entry;
+    __ext_Elf32_Off	e_phoff;
+    __ext_Elf32_Off	e_shoff;
+    __ext_Elf32_Word	e_flags;
+    __ext_Elf32_Half	e_ehsize;
+    __ext_Elf32_Half	e_phentsize;
+    __ext_Elf32_Half	e_phnum;
+    __ext_Elf32_Half	e_shentsize;
+    __ext_Elf32_Half	e_shnum;
+    __ext_Elf32_Half	e_shstrndx;
+} __ext_Elf32_Ehdr;
+
+#if __LIBELF64
+typedef struct {
+    unsigned char	e_ident[EI_NIDENT];
+    __ext_Elf64_Half	e_type;
+    __ext_Elf64_Half	e_machine;
+    __ext_Elf64_Word	e_version;
+    __ext_Elf64_Addr	e_entry;
+    __ext_Elf64_Off	e_phoff;
+    __ext_Elf64_Off	e_shoff;
+    __ext_Elf64_Word	e_flags;
+    __ext_Elf64_Half	e_ehsize;
+    __ext_Elf64_Half	e_phentsize;
+    __ext_Elf64_Half	e_phnum;
+    __ext_Elf64_Half	e_shentsize;
+    __ext_Elf64_Half	e_shnum;
+    __ext_Elf64_Half	e_shstrndx;
+} __ext_Elf64_Ehdr;
+#endif /* __LIBELF64 */
+
+/*
+ * Section header
+ */
+typedef struct {
+    __ext_Elf32_Word	sh_name;
+    __ext_Elf32_Word	sh_type;
+    __ext_Elf32_Word	sh_flags;
+    __ext_Elf32_Addr	sh_addr;
+    __ext_Elf32_Off	sh_offset;
+    __ext_Elf32_Word	sh_size;
+    __ext_Elf32_Word	sh_link;
+    __ext_Elf32_Word	sh_info;
+    __ext_Elf32_Word	sh_addralign;
+    __ext_Elf32_Word	sh_entsize;
+} __ext_Elf32_Shdr;
+
+#if __LIBELF64
+typedef struct {
+    __ext_Elf64_Word	sh_name;
+    __ext_Elf64_Word	sh_type;
+    __ext_Elf64_Xword	sh_flags;
+    __ext_Elf64_Addr	sh_addr;
+    __ext_Elf64_Off	sh_offset;
+    __ext_Elf64_Xword	sh_size;
+    __ext_Elf64_Word	sh_link;
+    __ext_Elf64_Word	sh_info;
+    __ext_Elf64_Xword	sh_addralign;
+    __ext_Elf64_Xword	sh_entsize;
+} __ext_Elf64_Shdr;
+#endif /* __LIBELF64 */
+
+/*
+ * Symbol table
+ */
+typedef struct {
+    __ext_Elf32_Word	st_name;
+    __ext_Elf32_Addr	st_value;
+    __ext_Elf32_Word	st_size;
+    unsigned char	st_info;
+    unsigned char	st_other;
+    __ext_Elf32_Half	st_shndx;
+} __ext_Elf32_Sym;
+
+#if __LIBELF64
+typedef struct {
+    __ext_Elf64_Word	st_name;
+    unsigned char	st_info;
+    unsigned char	st_other;
+    __ext_Elf64_Half	st_shndx;
+    __ext_Elf64_Addr	st_value;
+    __ext_Elf64_Xword	st_size;
+} __ext_Elf64_Sym;
+#endif /* __LIBELF64 */
+
+/*
+ * Relocation
+ */
+typedef struct {
+    __ext_Elf32_Addr	r_offset;
+    __ext_Elf32_Word	r_info;
+} __ext_Elf32_Rel;
+
+typedef struct {
+    __ext_Elf32_Addr	r_offset;
+    __ext_Elf32_Word	r_info;
+    __ext_Elf32_Sword	r_addend;
+} __ext_Elf32_Rela;
+
+#if __LIBELF64
+typedef struct {
+    __ext_Elf64_Addr	r_offset;
+#if __LIBELF64_IRIX
+    __ext_Elf64_Word	r_sym;
+    unsigned char	r_ssym;
+    unsigned char	r_type3;
+    unsigned char	r_type2;
+    unsigned char	r_type;
+#else /* __LIBELF64_IRIX */
+    __ext_Elf64_Xword	r_info;
+#endif /* __LIBELF64_IRIX */
+} __ext_Elf64_Rel;
+
+typedef struct {
+    __ext_Elf64_Addr	r_offset;
+#if __LIBELF64_IRIX
+    __ext_Elf64_Word	r_sym;
+    unsigned char	r_ssym;
+    unsigned char	r_type3;
+    unsigned char	r_type2;
+    unsigned char	r_type;
+#else /* __LIBELF64_IRIX */
+    __ext_Elf64_Xword	r_info;
+#endif /* __LIBELF64_IRIX */
+    __ext_Elf64_Sxword	r_addend;
+} __ext_Elf64_Rela;
+#endif /* __LIBELF64 */
+
+/*
+ * Program header
+ */
+typedef struct {
+    __ext_Elf32_Word	p_type;
+    __ext_Elf32_Off	p_offset;
+    __ext_Elf32_Addr	p_vaddr;
+    __ext_Elf32_Addr	p_paddr;
+    __ext_Elf32_Word	p_filesz;
+    __ext_Elf32_Word	p_memsz;
+    __ext_Elf32_Word	p_flags;
+    __ext_Elf32_Word	p_align;
+} __ext_Elf32_Phdr;
+
+#if __LIBELF64
+typedef struct {
+    __ext_Elf64_Word	p_type;
+    __ext_Elf64_Word	p_flags;
+    __ext_Elf64_Off	p_offset;
+    __ext_Elf64_Addr	p_vaddr;
+    __ext_Elf64_Addr	p_paddr;
+    __ext_Elf64_Xword	p_filesz;
+    __ext_Elf64_Xword	p_memsz;
+    __ext_Elf64_Xword	p_align;
+} __ext_Elf64_Phdr;
+#endif /* __LIBELF64 */
+
+/*
+ * Dynamic structure
+ */
+typedef struct {
+    __ext_Elf32_Sword	d_tag;
+    union {
+	__ext_Elf32_Word	d_val;
+	__ext_Elf32_Addr	d_ptr;
+    } d_un;
+} __ext_Elf32_Dyn;
+
+#if __LIBELF64
+typedef struct {
+    __ext_Elf64_Sxword	d_tag;
+    union {
+	__ext_Elf64_Xword	d_val;
+	__ext_Elf64_Addr	d_ptr;
+    } d_un;
+} __ext_Elf64_Dyn;
+#endif /* __LIBELF64 */
+
+/*
+ * Version definitions
+ */
+typedef struct {
+    __ext_Elf32_Half	vd_version;
+    __ext_Elf32_Half	vd_flags;
+    __ext_Elf32_Half	vd_ndx;
+    __ext_Elf32_Half	vd_cnt;
+    __ext_Elf32_Word	vd_hash;
+    __ext_Elf32_Word	vd_aux;
+    __ext_Elf32_Word	vd_next;
+} __ext_Elf32_Verdef;
+
+typedef struct {
+    __ext_Elf32_Word	vda_name;
+    __ext_Elf32_Word	vda_next;
+} __ext_Elf32_Verdaux;
+
+typedef struct {
+    __ext_Elf32_Half	vn_version;
+    __ext_Elf32_Half	vn_cnt;
+    __ext_Elf32_Word	vn_file;
+    __ext_Elf32_Word	vn_aux;
+    __ext_Elf32_Word	vn_next;
+} __ext_Elf32_Verneed;
+
+typedef struct {
+    __ext_Elf32_Word	vna_hash;
+    __ext_Elf32_Half	vna_flags;
+    __ext_Elf32_Half	vna_other;
+    __ext_Elf32_Word	vna_name;
+    __ext_Elf32_Word	vna_next;
+} __ext_Elf32_Vernaux;
+
+#if __LIBELF64
+
+typedef struct {
+    __ext_Elf64_Half	vd_version;
+    __ext_Elf64_Half	vd_flags;
+    __ext_Elf64_Half	vd_ndx;
+    __ext_Elf64_Half	vd_cnt;
+    __ext_Elf64_Word	vd_hash;
+    __ext_Elf64_Word	vd_aux;
+    __ext_Elf64_Word	vd_next;
+} __ext_Elf64_Verdef;
+
+typedef struct {
+    __ext_Elf64_Word	vda_name;
+    __ext_Elf64_Word	vda_next;
+} __ext_Elf64_Verdaux;
+
+typedef struct {
+    __ext_Elf64_Half	vn_version;
+    __ext_Elf64_Half	vn_cnt;
+    __ext_Elf64_Word	vn_file;
+    __ext_Elf64_Word	vn_aux;
+    __ext_Elf64_Word	vn_next;
+} __ext_Elf64_Verneed;
+
+typedef struct {
+    __ext_Elf64_Word	vna_hash;
+    __ext_Elf64_Half	vna_flags;
+    __ext_Elf64_Half	vna_other;
+    __ext_Elf64_Word	vna_name;
+    __ext_Elf64_Word	vna_next;
+} __ext_Elf64_Vernaux;
+
+#endif /* __LIBELF64 */
+
+/*
+ * Move section
+ */
+#if __LIBELF64
+
+typedef struct {
+    __ext_Elf32_Lword	m_value;
+    __ext_Elf32_Word	m_info;
+    __ext_Elf32_Word	m_poffset;
+    __ext_Elf32_Half	m_repeat;
+    __ext_Elf32_Half	m_stride;
+} __ext_Elf32_Move;
+
+typedef struct {
+    __ext_Elf64_Lword	m_value;
+    __ext_Elf64_Xword	m_info;
+    __ext_Elf64_Xword	m_poffset;
+    __ext_Elf64_Half	m_repeat;
+    __ext_Elf64_Half	m_stride;
+} __ext_Elf64_Move;
+
+#endif /* __LIBELF64 */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _EXT_TYPES_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/fill.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,29 @@
+/*
+fill.c - implementation of the elf_fill(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: fill.c,v 1.6 2005/05/21 15:39:22 michael Exp $";
+#endif /* lint */
+
+void
+elf_fill(int fill) {
+    _elf_fill = fill;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/flag.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,92 @@
+/*
+flag.c - implementation of the elf_flag*(3) functions.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: flag.c,v 1.6 2005/05/21 15:39:22 michael Exp $";
+#endif /* lint */
+
+static unsigned
+_elf_flag(unsigned *f, Elf_Cmd cmd, unsigned flags) {
+    if (cmd == ELF_C_SET) {
+	return *f |= flags;
+    }
+    if (cmd == ELF_C_CLR) {
+	return *f &= ~flags;
+    }
+    seterr(ERROR_INVALID_CMD);
+    return 0;
+}
+
+unsigned
+elf_flagdata(Elf_Data *data, Elf_Cmd cmd, unsigned flags) {
+    Scn_Data *sd = (Scn_Data*)data;
+
+    if (!sd) {
+	return 0;
+    }
+    elf_assert(sd->sd_magic == DATA_MAGIC);
+    return _elf_flag(&sd->sd_data_flags, cmd, flags);
+}
+
+unsigned
+elf_flagehdr(Elf *elf, Elf_Cmd cmd, unsigned flags) {
+    if (!elf) {
+	return 0;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    return _elf_flag(&elf->e_ehdr_flags, cmd, flags);
+}
+
+unsigned
+elf_flagelf(Elf *elf, Elf_Cmd cmd, unsigned flags) {
+    if (!elf) {
+	return 0;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    return _elf_flag(&elf->e_elf_flags, cmd, flags);
+}
+
+unsigned
+elf_flagphdr(Elf *elf, Elf_Cmd cmd, unsigned flags) {
+    if (!elf) {
+	return 0;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    return _elf_flag(&elf->e_phdr_flags, cmd, flags);
+}
+
+unsigned
+elf_flagscn(Elf_Scn *scn, Elf_Cmd cmd, unsigned flags) {
+    if (!scn) {
+	return 0;
+    }
+    elf_assert(scn->s_magic == SCN_MAGIC);
+    return _elf_flag(&scn->s_scn_flags, cmd, flags);
+}
+
+unsigned
+elf_flagshdr(Elf_Scn *scn, Elf_Cmd cmd, unsigned flags) {
+    if (!scn) {
+	return 0;
+    }
+    elf_assert(scn->s_magic == SCN_MAGIC);
+    return _elf_flag(&scn->s_shdr_flags, cmd, flags);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/gelf.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,155 @@
+/*
+ * gelf.h - public header file for libelf.
+ * Copyright (C) 2000 - 2006 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* @(#) $Id: gelf.h,v 1.15 2006/09/07 15:55:42 michael Exp $ */
+
+#ifndef _GELF_H
+#define _GELF_H
+
+#if __LIBELF_INTERNAL__
+#include <libelf.h>
+#else /* __LIBELF_INTERNAL__ */
+#include <libelf/libelf.h>
+#endif /* __LIBELF_INTERNAL__ */
+
+#if __LIBELF_NEED_LINK_H
+#include <link.h>
+#elif __LIBELF_NEED_SYS_LINK_H
+#include <sys/link.h>
+#endif /* __LIBELF_NEED_LINK_H */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifndef __P
+# if (__STDC__ + 0) || defined(__cplusplus) || defined(_WIN32)
+#  define __P(args) args
+# else /* __STDC__ || defined(__cplusplus) */
+#  define __P(args) ()
+# endif /* __STDC__ || defined(__cplusplus) */
+#endif /* __P */
+
+#if !__LIBELF64
+
+#error "GElf is not supported on this system."
+
+#else /* __LIBELF64 */
+
+typedef Elf64_Addr	GElf_Addr;
+typedef Elf64_Half	GElf_Half;
+typedef Elf64_Off	GElf_Off;
+typedef Elf64_Sword	GElf_Sword;
+typedef Elf64_Word	GElf_Word;
+typedef Elf64_Sxword	GElf_Sxword;
+typedef Elf64_Xword	GElf_Xword;
+
+typedef Elf64_Ehdr	GElf_Ehdr;
+typedef Elf64_Phdr	GElf_Phdr;
+typedef Elf64_Shdr	GElf_Shdr;
+typedef Elf64_Dyn	GElf_Dyn;
+typedef Elf64_Rel	GElf_Rel;
+typedef Elf64_Rela	GElf_Rela;
+typedef Elf64_Sym	GElf_Sym;
+
+/*
+ * Symbol versioning
+ */
+#if __LIBELF_SYMBOL_VERSIONS
+typedef Elf64_Verdef	GElf_Verdef;
+typedef Elf64_Verneed	GElf_Verneed;
+typedef Elf64_Verdaux	GElf_Verdaux;
+typedef Elf64_Vernaux	GElf_Vernaux;
+#endif /* __LIBELF_SYMBOL_VERSIONS */
+
+/*
+ * These types aren't implemented (yet)
+ *
+typedef Elf64_Move    GElf_Move;
+typedef Elf64_Syminfo GElf_Syminfo;
+ */
+
+/*
+ * Generic macros
+ */
+#define GELF_ST_BIND	ELF64_ST_BIND
+#define GELF_ST_TYPE	ELF64_ST_TYPE
+#define GELF_ST_INFO	ELF64_ST_INFO
+
+#define GELF_R_TYPE	ELF64_R_TYPE
+#define GELF_R_SYM	ELF64_R_SYM
+#define GELF_R_INFO	ELF64_R_INFO
+
+/*
+ * Function declarations
+ */
+extern int             gelf_getclass __P((Elf *__elf));
+
+extern size_t             gelf_fsize __P((Elf *__elf, Elf_Type __type, size_t __count, unsigned __ver));
+
+extern Elf_Data       *gelf_xlatetof __P((Elf *__elf, Elf_Data *__dst, const Elf_Data *__src, unsigned __encode));
+extern Elf_Data       *gelf_xlatetom __P((Elf *__elf, Elf_Data *__dst, const Elf_Data *__src, unsigned __encode));
+
+extern GElf_Ehdr       *gelf_getehdr __P((Elf *__elf, GElf_Ehdr *__dst));
+extern int          gelf_update_ehdr __P((Elf *__elf, GElf_Ehdr *__src));
+extern unsigned long    gelf_newehdr __P((Elf *__elf, int __elfclass));
+
+extern GElf_Phdr       *gelf_getphdr __P((Elf *__elf, int ndx, GElf_Phdr *__dst));
+extern int          gelf_update_phdr __P((Elf *__elf, int ndx, GElf_Phdr *__src));
+extern unsigned long    gelf_newphdr __P((Elf *__elf, size_t __phnum));
+
+extern GElf_Shdr       *gelf_getshdr __P((Elf_Scn *__scn, GElf_Shdr *__dst));
+extern int          gelf_update_shdr __P((Elf_Scn *__scn, GElf_Shdr *__src));
+
+extern GElf_Dyn         *gelf_getdyn __P((Elf_Data *__src, int __ndx, GElf_Dyn *__dst));
+extern int           gelf_update_dyn __P((Elf_Data *__dst, int __ndx, GElf_Dyn *__src));
+
+extern GElf_Rel         *gelf_getrel __P((Elf_Data *__src, int __ndx, GElf_Rel *__dst));
+extern int           gelf_update_rel __P((Elf_Data *__dst, int __ndx, GElf_Rel *__src));
+
+extern GElf_Rela       *gelf_getrela __P((Elf_Data *__src, int __ndx, GElf_Rela *__dst));
+extern int          gelf_update_rela __P((Elf_Data *__dst, int __ndx, GElf_Rela *__src));
+
+extern GElf_Sym         *gelf_getsym __P((Elf_Data *__src, int __ndx, GElf_Sym *__dst));
+extern int           gelf_update_sym __P((Elf_Data *__dst, int __ndx, GElf_Sym *__src));
+
+extern long            gelf_checksum __P((Elf *__elf));
+
+/*
+ * These functions aren't implemented (yet)
+ *
+extern GElf_Move       *gelf_getmove __P((Elf_Data *__src, int __ndx, GElf_Move *__src));
+extern int          gelf_update_move __P((Elf_Data *__dst, int __ndx, GElf_Move *__src));
+ *
+extern GElf_Syminfo* gelf_getsyminfo __P((Elf_Data *__src, int __ndx, GElf_Syminfo *__dst));
+extern int       gelf_update_syminfo __P((Elf_Data *__dst, int __ndx, GElf_Syminfo *__src));
+ */
+
+/*
+ * Extensions (not available in other versions of libelf)
+ */
+extern size_t             gelf_msize __P((Elf *__elf, Elf_Type __type, size_t __count, unsigned __ver));
+
+#endif /* __LIBELF64 */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _GELF_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/gelfehdr.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,140 @@
+/*
+ * gelfehdr.c - gelf_* translation functions.
+ * Copyright (C) 2000 - 2006 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+
+#if __LIBELF64
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: gelfehdr.c,v 1.8 2006/07/07 22:16:43 michael Exp $";
+#endif /* lint */
+
+#define check_and_copy(type, d, s, name, eret)		\
+    do {						\
+	if (sizeof((d)->name) < sizeof((s)->name)	\
+	 && (type)(s)->name != (s)->name) {		\
+	    seterr(ERROR_BADVALUE);			\
+	    return (eret);				\
+	}						\
+	(d)->name = (type)(s)->name;			\
+    } while (0)
+
+GElf_Ehdr*
+gelf_getehdr(Elf *elf, GElf_Ehdr *dst) {
+    GElf_Ehdr buf;
+    char *tmp;
+
+    if (!elf) {
+	return NULL;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    tmp = _elf_getehdr(elf, elf->e_class);
+    if (!tmp) {
+	return NULL;
+    }
+    if (!dst) {
+	dst = &buf;
+    }
+    if (elf->e_class == ELFCLASS64) {
+	*dst = *(Elf64_Ehdr*)tmp;
+    }
+    else if (elf->e_class == ELFCLASS32) {
+	Elf32_Ehdr *src = (Elf32_Ehdr*)tmp;
+
+	memcpy(dst->e_ident, src->e_ident, EI_NIDENT);
+	check_and_copy(GElf_Half, dst, src, e_type,      NULL);
+	check_and_copy(GElf_Half, dst, src, e_machine,   NULL);
+	check_and_copy(GElf_Word, dst, src, e_version,   NULL);
+	check_and_copy(GElf_Addr, dst, src, e_entry,     NULL);
+	check_and_copy(GElf_Off,  dst, src, e_phoff,     NULL);
+	check_and_copy(GElf_Off,  dst, src, e_shoff,     NULL);
+	check_and_copy(GElf_Word, dst, src, e_flags,     NULL);
+	check_and_copy(GElf_Half, dst, src, e_ehsize,    NULL);
+	check_and_copy(GElf_Half, dst, src, e_phentsize, NULL);
+	check_and_copy(GElf_Half, dst, src, e_phnum,     NULL);
+	check_and_copy(GElf_Half, dst, src, e_shentsize, NULL);
+	check_and_copy(GElf_Half, dst, src, e_shnum,     NULL);
+	check_and_copy(GElf_Half, dst, src, e_shstrndx,  NULL);
+    }
+    else {
+	if (valid_class(elf->e_class)) {
+	    seterr(ERROR_UNIMPLEMENTED);
+	}
+	else {
+	    seterr(ERROR_UNKNOWN_CLASS);
+	}
+	return NULL;
+    }
+    if (dst == &buf) {
+	dst = (GElf_Ehdr*)malloc(sizeof(GElf_Ehdr));
+	if (!dst) {
+	    seterr(ERROR_MEM_EHDR);
+	    return NULL;
+	}
+	*dst = buf;
+    }
+    return dst;
+}
+
+int
+gelf_update_ehdr(Elf *elf, GElf_Ehdr *src) {
+    char *tmp;
+
+    if (!elf || !src) {
+	return 0;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    tmp = _elf_getehdr(elf, elf->e_class);
+    if (!tmp) {
+	return 0;
+    }
+    if (elf->e_class == ELFCLASS64) {
+	*(Elf64_Ehdr*)tmp = *src;
+    }
+    else if (elf->e_class == ELFCLASS32) {
+	Elf32_Ehdr *dst = (Elf32_Ehdr*)tmp;
+
+	memcpy(dst->e_ident, src->e_ident, EI_NIDENT);
+	check_and_copy(Elf32_Half, dst, src, e_type,      0);
+	check_and_copy(Elf32_Half, dst, src, e_machine,   0);
+	check_and_copy(Elf32_Word, dst, src, e_version,   0);
+	check_and_copy(Elf32_Addr, dst, src, e_entry,     0);
+	check_and_copy(Elf32_Off,  dst, src, e_phoff,     0);
+	check_and_copy(Elf32_Off,  dst, src, e_shoff,     0);
+	check_and_copy(Elf32_Word, dst, src, e_flags,     0);
+	check_and_copy(Elf32_Half, dst, src, e_ehsize,    0);
+	check_and_copy(Elf32_Half, dst, src, e_phentsize, 0);
+	check_and_copy(Elf32_Half, dst, src, e_phnum,     0);
+	check_and_copy(Elf32_Half, dst, src, e_shentsize, 0);
+	check_and_copy(Elf32_Half, dst, src, e_shnum,     0);
+	check_and_copy(Elf32_Half, dst, src, e_shstrndx,  0);
+    }
+    else {
+	if (valid_class(elf->e_class)) {
+	    seterr(ERROR_UNIMPLEMENTED);
+	}
+	else {
+	    seterr(ERROR_UNKNOWN_CLASS);
+	}
+	return 0;
+    }
+    return 1;
+}
+
+#endif /* __LIBELF64 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/gelfphdr.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,148 @@
+/*
+ * gelfphdr.c - gelf_* translation functions.
+ * Copyright (C) 2000 - 2006 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+
+#if __LIBELF64
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: gelfphdr.c,v 1.8 2006/07/07 22:16:43 michael Exp $";
+#endif /* lint */
+
+#define check_and_copy(type, d, s, name, eret)		\
+    do {						\
+	if (sizeof((d)->name) < sizeof((s)->name)	\
+	 && (type)(s)->name != (s)->name) {		\
+	    seterr(ERROR_BADVALUE);			\
+	    return (eret);				\
+	}						\
+	(d)->name = (type)(s)->name;			\
+    } while (0)
+
+GElf_Phdr*
+gelf_getphdr(Elf *elf, int ndx, GElf_Phdr *dst) {
+    GElf_Phdr buf;
+    char *tmp;
+    size_t n;
+
+    if (!elf) {
+	return NULL;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    tmp = _elf_getphdr(elf, elf->e_class);
+    if (!tmp) {
+	return NULL;
+    }
+    if (ndx < 0 || ndx >= elf->e_phnum) {
+	seterr(ERROR_BADINDEX);
+	return NULL;
+    }
+    n = _msize(elf->e_class, _elf_version, ELF_T_PHDR);
+    if (n == 0) {
+	seterr(ERROR_UNIMPLEMENTED);
+	return NULL;
+    }
+    if (!dst) {
+	dst = &buf;
+    }
+    if (elf->e_class == ELFCLASS64) {
+	*dst = *(Elf64_Phdr*)(tmp + ndx * n);
+    }
+    else if (elf->e_class == ELFCLASS32) {
+	Elf32_Phdr *src = (Elf32_Phdr*)(tmp + ndx * n);
+
+	check_and_copy(GElf_Word,  dst, src, p_type,   NULL);
+	check_and_copy(GElf_Word,  dst, src, p_flags,  NULL);
+	check_and_copy(GElf_Off,   dst, src, p_offset, NULL);
+	check_and_copy(GElf_Addr,  dst, src, p_vaddr,  NULL);
+	check_and_copy(GElf_Addr,  dst, src, p_paddr,  NULL);
+	check_and_copy(GElf_Xword, dst, src, p_filesz, NULL);
+	check_and_copy(GElf_Xword, dst, src, p_memsz,  NULL);
+	check_and_copy(GElf_Xword, dst, src, p_align,  NULL);
+    }
+    else {
+	if (valid_class(elf->e_class)) {
+	    seterr(ERROR_UNIMPLEMENTED);
+	}
+	else {
+	    seterr(ERROR_UNKNOWN_CLASS);
+	}
+	return NULL;
+    }
+    if (dst == &buf) {
+	dst = (GElf_Phdr*)malloc(sizeof(GElf_Phdr));
+	if (!dst) {
+	    seterr(ERROR_MEM_PHDR);
+	    return NULL;
+	}
+	*dst = buf;
+    }
+    return dst;
+}
+
+int
+gelf_update_phdr(Elf *elf, int ndx, GElf_Phdr *src) {
+    char *tmp;
+    size_t n;
+
+    if (!elf || !src) {
+	return 0;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    tmp = _elf_getphdr(elf, elf->e_class);
+    if (!tmp) {
+	return 0;
+    }
+    if (ndx < 0 || ndx >= elf->e_phnum) {
+	seterr(ERROR_BADINDEX);
+	return 0;
+    }
+    n = _msize(elf->e_class, _elf_version, ELF_T_PHDR);
+    if (n == 0) {
+	seterr(ERROR_UNIMPLEMENTED);
+	return 0;
+    }
+    if (elf->e_class == ELFCLASS64) {
+	*(Elf64_Phdr*)(tmp + ndx * n) = *src;
+    }
+    else if (elf->e_class == ELFCLASS32) {
+	Elf32_Phdr *dst = (Elf32_Phdr*)(tmp + ndx * n);
+
+	check_and_copy(Elf32_Word, dst, src, p_type,   0);
+	check_and_copy(Elf32_Off,  dst, src, p_offset, 0);
+	check_and_copy(Elf32_Addr, dst, src, p_vaddr,  0);
+	check_and_copy(Elf32_Addr, dst, src, p_paddr,  0);
+	check_and_copy(Elf32_Word, dst, src, p_filesz, 0);
+	check_and_copy(Elf32_Word, dst, src, p_memsz,  0);
+	check_and_copy(Elf32_Word, dst, src, p_flags,  0);
+	check_and_copy(Elf32_Word, dst, src, p_align,  0);
+    }
+    else {
+	if (valid_class(elf->e_class)) {
+	    seterr(ERROR_UNIMPLEMENTED);
+	}
+	else {
+	    seterr(ERROR_UNKNOWN_CLASS);
+	}
+	return 0;
+    }
+    return 1;
+}
+
+#endif /* __LIBELF64 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/gelfshdr.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,125 @@
+/*
+ * gelfshdr.c - gelf_* translation functions.
+ * Copyright (C) 2000 - 2006 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+
+#if __LIBELF64
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: gelfshdr.c,v 1.9 2006/07/07 22:16:43 michael Exp $";
+#endif /* lint */
+
+#define check_and_copy(type, d, s, name, eret)		\
+    do {						\
+	if (sizeof((d)->name) < sizeof((s)->name)	\
+	 && (type)(s)->name != (s)->name) {		\
+	    seterr(ERROR_BADVALUE);			\
+	    return (eret);				\
+	}						\
+	(d)->name = (type)(s)->name;			\
+    } while (0)
+
+GElf_Shdr*
+gelf_getshdr(Elf_Scn *scn, GElf_Shdr *dst) {
+    GElf_Shdr buf;
+
+    if (!scn) {
+	return NULL;
+    }
+    elf_assert(scn->s_magic == SCN_MAGIC);
+    elf_assert(scn->s_elf);
+    elf_assert(scn->s_elf->e_magic == ELF_MAGIC);
+    if (!dst) {
+	dst = &buf;
+    }
+    if (scn->s_elf->e_class == ELFCLASS64) {
+	*dst = scn->s_shdr64;
+    }
+    else if (scn->s_elf->e_class == ELFCLASS32) {
+	Elf32_Shdr *src = &scn->s_shdr32;
+
+	check_and_copy(GElf_Word,  dst, src, sh_name,      NULL);
+	check_and_copy(GElf_Word,  dst, src, sh_type,      NULL);
+	check_and_copy(GElf_Xword, dst, src, sh_flags,     NULL);
+	check_and_copy(GElf_Addr,  dst, src, sh_addr,      NULL);
+	check_and_copy(GElf_Off,   dst, src, sh_offset,    NULL);
+	check_and_copy(GElf_Xword, dst, src, sh_size,      NULL);
+	check_and_copy(GElf_Word,  dst, src, sh_link,      NULL);
+	check_and_copy(GElf_Word,  dst, src, sh_info,      NULL);
+	check_and_copy(GElf_Xword, dst, src, sh_addralign, NULL);
+	check_and_copy(GElf_Xword, dst, src, sh_entsize,   NULL);
+    }
+    else {
+	if (valid_class(scn->s_elf->e_class)) {
+	    seterr(ERROR_UNIMPLEMENTED);
+	}
+	else {
+	    seterr(ERROR_UNKNOWN_CLASS);
+	}
+	return NULL;
+    }
+    if (dst == &buf) {
+	dst = (GElf_Shdr*)malloc(sizeof(GElf_Shdr));
+	if (!dst) {
+	    seterr(ERROR_MEM_SHDR);
+	    return NULL;
+	}
+	*dst = buf;
+    }
+    return dst;
+}
+
+int
+gelf_update_shdr(Elf_Scn *scn, GElf_Shdr *src) {
+    if (!scn || !src) {
+	return 0;
+    }
+    elf_assert(scn->s_magic == SCN_MAGIC);
+    elf_assert(scn->s_elf);
+    elf_assert(scn->s_elf->e_magic == ELF_MAGIC);
+    if (scn->s_elf->e_class == ELFCLASS64) {
+	scn->s_shdr64 = *src;
+    }
+    else if (scn->s_elf->e_class == ELFCLASS32) {
+	Elf32_Shdr *dst = &scn->s_shdr32;
+
+	check_and_copy(Elf32_Word, dst, src, sh_name,      0);
+	check_and_copy(Elf32_Word, dst, src, sh_type,      0);
+	check_and_copy(Elf32_Word, dst, src, sh_flags,     0);
+	check_and_copy(Elf32_Addr, dst, src, sh_addr,      0);
+	check_and_copy(Elf32_Off,  dst, src, sh_offset,    0);
+	check_and_copy(Elf32_Word, dst, src, sh_size,      0);
+	check_and_copy(Elf32_Word, dst, src, sh_link,      0);
+	check_and_copy(Elf32_Word, dst, src, sh_info,      0);
+	check_and_copy(Elf32_Word, dst, src, sh_addralign, 0);
+	check_and_copy(Elf32_Word, dst, src, sh_entsize,   0);
+    }
+    else {
+	if (valid_class(scn->s_elf->e_class)) {
+	    seterr(ERROR_UNIMPLEMENTED);
+	}
+	else {
+	    seterr(ERROR_UNKNOWN_CLASS);
+	}
+	return 0;
+    }
+    return 1;
+}
+
+#endif /* __LIBELF64 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/gelftrans.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,407 @@
+/*
+gelftrans.c - gelf_* translation functions.
+Copyright (C) 2000 - 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#if __LIBELF64
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: gelftrans.c,v 1.9 2005/05/21 15:39:23 michael Exp $";
+#endif /* lint */
+
+#define check_and_copy(type, d, s, name, eret)		\
+    do {						\
+	if (sizeof((d)->name) < sizeof((s)->name)	\
+	 && (type)(s)->name != (s)->name) {		\
+	    seterr(ERROR_BADVALUE);			\
+	    return (eret);				\
+	}						\
+	(d)->name = (type)(s)->name;			\
+    } while (0)
+
+/*
+ * These macros are missing on some Linux systems
+ */
+#if !defined(ELF32_R_SYM) || !defined(ELF32_R_TYPE) || !defined(ELF32_R_INFO)
+# undef ELF32_R_SYM
+# undef ELF32_R_TYPE
+# undef ELF32_R_INFO
+# define ELF32_R_SYM(i)		((i)>>8)
+# define ELF32_R_TYPE(i)	((unsigned char)(i))
+# define ELF32_R_INFO(s,t)	(((s)<<8)+(unsigned char)(t))
+#endif /* !defined(...) */
+
+#if !defined(ELF64_R_SYM) || !defined(ELF64_R_TYPE) || !defined(ELF64_R_INFO)
+# undef ELF64_R_SYM
+# undef ELF64_R_TYPE
+# undef ELF64_R_INFO
+# define ELF64_R_SYM(i)		((i)>>32)
+# define ELF64_R_TYPE(i)	((i)&0xffffffffL)
+# define ELF64_R_INFO(s,t)	(((Elf64_Xword)(s)<<32)+((t)&0xffffffffL))
+#endif /* !defined(...) */
+
+static char*
+get_addr_and_class(const Elf_Data *data, int ndx, Elf_Type type, unsigned *cls) {
+    Scn_Data *sd = (Scn_Data*)data;
+    Elf_Scn *scn;
+    Elf *elf;
+    size_t n;
+
+    if (!sd) {
+	return NULL;
+    }
+    elf_assert(sd->sd_magic == DATA_MAGIC);
+    scn = sd->sd_scn;
+    elf_assert(scn);
+    elf_assert(scn->s_magic == SCN_MAGIC);
+    elf = scn->s_elf;
+    elf_assert(elf);
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (elf->e_kind != ELF_K_ELF) {
+	seterr(ERROR_NOTELF);
+	return NULL;
+    }
+    if (!valid_class(elf->e_class)) {
+	seterr(ERROR_UNKNOWN_CLASS);
+	return NULL;
+    }
+    if (data->d_type != type) {
+	seterr(ERROR_BADTYPE);
+	return NULL;
+    }
+    n = _msize(elf->e_class, data->d_version, type);
+    if (n == 0) {
+	seterr(ERROR_UNIMPLEMENTED);
+	return NULL;
+    }
+    if (ndx < 0 || data->d_size < (ndx + 1) * n) {
+	seterr(ERROR_BADINDEX);
+	return NULL;
+    }
+    if (!data->d_buf) {
+	seterr(ERROR_NULLBUF);
+	return NULL;
+    }
+    if (cls) {
+	*cls = elf->e_class;
+    }
+    return (char*)data->d_buf + n * ndx;
+}
+
+GElf_Sym*
+gelf_getsym(Elf_Data *src, int ndx, GElf_Sym *dst) {
+    GElf_Sym buf;
+    unsigned cls;
+    char *tmp;
+
+    if (!dst) {
+	dst = &buf;
+    }
+    tmp = get_addr_and_class(src, ndx, ELF_T_SYM, &cls);
+    if (!tmp) {
+	return NULL;
+    }
+    if (cls == ELFCLASS64) {
+	*dst = *(Elf64_Sym*)tmp;
+    }
+    else if (cls == ELFCLASS32) {
+	Elf32_Sym *src = (Elf32_Sym*)tmp;
+
+	check_and_copy(GElf_Word,     dst, src, st_name,  NULL);
+	check_and_copy(unsigned char, dst, src, st_info,  NULL);
+	check_and_copy(unsigned char, dst, src, st_other, NULL);
+	check_and_copy(GElf_Half,     dst, src, st_shndx, NULL);
+	check_and_copy(GElf_Addr,     dst, src, st_value, NULL);
+	check_and_copy(GElf_Xword,    dst, src, st_size,  NULL);
+    }
+    else {
+	seterr(ERROR_UNIMPLEMENTED);
+	return NULL;
+    }
+    if (dst == &buf) {
+	dst = (GElf_Sym*)malloc(sizeof(GElf_Sym));
+	if (!dst) {
+	    seterr(ERROR_MEM_SYM);
+	    return NULL;
+	}
+	*dst = buf;
+    }
+    return dst;
+}
+
+int
+gelf_update_sym(Elf_Data *dst, int ndx, GElf_Sym *src) {
+    unsigned cls;
+    char *tmp;
+
+    tmp = get_addr_and_class(dst, ndx, ELF_T_SYM, &cls);
+    if (!tmp) {
+	return 0;
+    }
+    if (cls == ELFCLASS64) {
+	*(Elf64_Sym*)tmp = *src;
+    }
+    else if (cls == ELFCLASS32) {
+	Elf32_Sym *dst = (Elf32_Sym*)tmp;
+
+	check_and_copy(Elf32_Word,    dst, src, st_name,  0);
+	check_and_copy(Elf32_Addr,    dst, src, st_value, 0);
+	check_and_copy(Elf32_Word,    dst, src, st_size,  0);
+	check_and_copy(unsigned char, dst, src, st_info,  0);
+	check_and_copy(unsigned char, dst, src, st_other, 0);
+	check_and_copy(Elf32_Half,    dst, src, st_shndx, 0);
+    }
+    else {
+	seterr(ERROR_UNIMPLEMENTED);
+	return 0;
+    }
+    return 1;
+}
+
+GElf_Dyn*
+gelf_getdyn(Elf_Data *src, int ndx, GElf_Dyn *dst) {
+    GElf_Dyn buf;
+    unsigned cls;
+    char *tmp;
+
+    if (!dst) {
+	dst = &buf;
+    }
+    tmp = get_addr_and_class(src, ndx, ELF_T_DYN, &cls);
+    if (!tmp) {
+	return NULL;
+    }
+    if (cls == ELFCLASS64) {
+	*dst = *(Elf64_Dyn*)tmp;
+    }
+    else if (cls == ELFCLASS32) {
+	Elf32_Dyn *src = (Elf32_Dyn*)tmp;
+
+	check_and_copy(GElf_Sxword, dst, src, d_tag,      NULL);
+	check_and_copy(GElf_Xword,  dst, src, d_un.d_val, NULL);
+    }
+    else {
+	seterr(ERROR_UNIMPLEMENTED);
+	return NULL;
+    }
+    if (dst == &buf) {
+	dst = (GElf_Dyn*)malloc(sizeof(GElf_Dyn));
+	if (!dst) {
+	    seterr(ERROR_MEM_DYN);
+	    return NULL;
+	}
+	*dst = buf;
+    }
+    return dst;
+}
+
+int
+gelf_update_dyn(Elf_Data *dst, int ndx, GElf_Dyn *src) {
+    unsigned cls;
+    char *tmp;
+
+    tmp = get_addr_and_class(dst, ndx, ELF_T_DYN, &cls);
+    if (!tmp) {
+	return 0;
+    }
+    if (cls == ELFCLASS64) {
+	*(Elf64_Dyn*)tmp = *src;
+    }
+    else if (cls == ELFCLASS32) {
+	Elf32_Dyn *dst = (Elf32_Dyn*)tmp;
+
+	check_and_copy(Elf32_Sword, dst, src, d_tag,      0);
+	check_and_copy(Elf32_Word,  dst, src, d_un.d_val, 0);
+    }
+    else {
+	seterr(ERROR_UNIMPLEMENTED);
+	return 0;
+    }
+    return 1;
+}
+
+GElf_Rela*
+gelf_getrela(Elf_Data *src, int ndx, GElf_Rela *dst) {
+    GElf_Rela buf;
+    unsigned cls;
+    char *tmp;
+
+    if (!dst) {
+	dst = &buf;
+    }
+    tmp = get_addr_and_class(src, ndx, ELF_T_RELA, &cls);
+    if (!tmp) {
+	return NULL;
+    }
+    if (cls == ELFCLASS64) {
+	*dst = *(Elf64_Rela*)tmp;
+    }
+    else if (cls == ELFCLASS32) {
+	Elf32_Rela *src = (Elf32_Rela*)tmp;
+
+	check_and_copy(GElf_Addr,   dst, src, r_offset, NULL);
+	dst->r_info = ELF64_R_INFO((Elf64_Xword)ELF32_R_SYM(src->r_info),
+				   (Elf64_Xword)ELF32_R_TYPE(src->r_info));
+	check_and_copy(GElf_Sxword, dst, src, r_addend, NULL);
+    }
+    else {
+	seterr(ERROR_UNIMPLEMENTED);
+	return NULL;
+    }
+    if (dst == &buf) {
+	dst = (GElf_Rela*)malloc(sizeof(GElf_Rela));
+	if (!dst) {
+	    seterr(ERROR_MEM_RELA);
+	    return NULL;
+	}
+	*dst = buf;
+    }
+    return dst;
+}
+
+int
+gelf_update_rela(Elf_Data *dst, int ndx, GElf_Rela *src) {
+    unsigned cls;
+    char *tmp;
+
+    tmp = get_addr_and_class(dst, ndx, ELF_T_RELA, &cls);
+    if (!tmp) {
+	return 0;
+    }
+    if (cls == ELFCLASS64) {
+	*(Elf64_Rela*)tmp = *src;
+    }
+    else if (cls == ELFCLASS32) {
+	Elf32_Rela *dst = (Elf32_Rela*)tmp;
+
+	check_and_copy(Elf32_Addr,  dst, src, r_offset, 0);
+	if (ELF64_R_SYM(src->r_info) > 0xffffffUL
+	 || ELF64_R_TYPE(src->r_info) > 0xffUL) {
+	    seterr(ERROR_BADVALUE);
+	    return 0;
+	}
+	dst->r_info = ELF32_R_INFO((Elf32_Word)ELF64_R_SYM(src->r_info),
+				  (Elf32_Word)ELF64_R_TYPE(src->r_info));
+	check_and_copy(Elf32_Sword, dst, src, r_addend, 0);
+    }
+    else {
+	seterr(ERROR_UNIMPLEMENTED);
+	return 0;
+    }
+    return 1;
+}
+
+GElf_Rel*
+gelf_getrel(Elf_Data *src, int ndx, GElf_Rel *dst) {
+    GElf_Rel buf;
+    unsigned cls;
+    char *tmp;
+
+    if (!dst) {
+	dst = &buf;
+    }
+    tmp = get_addr_and_class(src, ndx, ELF_T_REL, &cls);
+    if (!tmp) {
+	return NULL;
+    }
+    if (cls == ELFCLASS64) {
+	*dst = *(Elf64_Rel*)tmp;
+    }
+    else if (cls == ELFCLASS32) {
+	Elf32_Rel *src = (Elf32_Rel*)tmp;
+
+	check_and_copy(GElf_Addr, dst, src, r_offset, NULL);
+	dst->r_info = ELF64_R_INFO((Elf64_Xword)ELF32_R_SYM(src->r_info),
+				   (Elf64_Xword)ELF32_R_TYPE(src->r_info));
+    }
+    else {
+	seterr(ERROR_UNIMPLEMENTED);
+	return NULL;
+    }
+    if (dst == &buf) {
+	dst = (GElf_Rel*)malloc(sizeof(GElf_Rel));
+	if (!dst) {
+	    seterr(ERROR_MEM_REL);
+	    return NULL;
+	}
+	*dst = buf;
+    }
+    return dst;
+}
+
+int
+gelf_update_rel(Elf_Data *dst, int ndx, GElf_Rel *src) {
+    unsigned cls;
+    char *tmp;
+
+    tmp = get_addr_and_class(dst, ndx, ELF_T_REL, &cls);
+    if (!tmp) {
+	return 0;
+    }
+    if (cls == ELFCLASS64) {
+	*(Elf64_Rel*)tmp = *src;
+    }
+    else if (cls == ELFCLASS32) {
+	Elf32_Rel *dst = (Elf32_Rel*)tmp;
+
+	check_and_copy(Elf32_Addr, dst, src, r_offset, 0);
+	if (ELF64_R_SYM(src->r_info) > 0xffffffUL
+	 || ELF64_R_TYPE(src->r_info) > 0xffUL) {
+	    seterr(ERROR_BADVALUE);
+	    return 0;
+	}
+	dst->r_info = ELF32_R_INFO((Elf32_Word)ELF64_R_SYM(src->r_info),
+				   (Elf32_Word)ELF64_R_TYPE(src->r_info));
+    }
+    else {
+	seterr(ERROR_UNIMPLEMENTED);
+	return 0;
+    }
+    return 1;
+}
+
+#if 0
+
+GElf_Syminfo*
+gelf_getsyminfo(Elf_Data *src, int ndx, GElf_Syminfo *dst) {
+    seterr(ERROR_UNIMPLEMENTED);
+    return NULL;
+}
+
+int
+gelf_update_syminfo(Elf_Data *dst, int ndx, GElf_Syminfo *src) {
+    seterr(ERROR_UNIMPLEMENTED);
+    return 0;
+}
+
+GElf_Move*
+gelf_getmove(Elf_Data *src, int ndx, GElf_Move *src) {
+    seterr(ERROR_UNIMPLEMENTED);
+    return NULL;
+}
+
+int
+gelf_update_move(Elf_Data *dst, int ndx, GElf_Move *src) {
+    seterr(ERROR_UNIMPLEMENTED);
+    return 0;
+}
+
+#endif
+
+#endif /* __LIBELF64 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/getarhdr.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,37 @@
+/*
+getarhdr.c - implementation of the elf_getarhdr(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: getarhdr.c,v 1.6 2005/05/21 15:39:23 michael Exp $";
+#endif /* lint */
+
+Elf_Arhdr*
+elf_getarhdr(Elf *elf) {
+    if (!elf) {
+	return NULL;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (elf->e_arhdr) {
+	return elf->e_arhdr;
+    }
+    seterr(ERROR_NOTARCHIVE);
+    return NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/getarsym.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,87 @@
+/*
+ * getarsym.c - implementation of the elf_getarsym(3) function.
+ * Copyright (C) 1995 - 1998, 2004 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+#include <byteswap.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: getarsym.c,v 1.8 2005/05/21 15:39:23 michael Exp $";
+#endif /* lint */
+
+Elf_Arsym*
+elf_getarsym(Elf *elf, size_t *ptr) {
+    Elf_Arsym *syms;
+    size_t count;
+    size_t tmp;
+    size_t i;
+    char *s;
+    char *e;
+
+    if (!ptr) {
+	ptr = &tmp;
+    }
+    *ptr = 0;
+    if (!elf) {
+	return NULL;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (elf->e_kind != ELF_K_AR) {
+	seterr(ERROR_NOTARCHIVE);
+	return NULL;
+    }
+    if (elf->e_symtab && !elf->e_free_syms) {
+	if (elf->e_symlen < 4) {
+	    seterr(ERROR_SIZE_ARSYMTAB);
+	    return NULL;
+	}
+	count = __load_u32M(elf->e_symtab);
+	if (elf->e_symlen < 4 * (count + 1)) {
+	    seterr(ERROR_SIZE_ARSYMTAB);
+	    return NULL;
+	}
+	if (!(syms = (Elf_Arsym*)malloc((count + 1) * sizeof(*syms)))) {
+	    seterr(ERROR_MEM_ARSYMTAB);
+	    return NULL;
+	}
+	s = elf->e_symtab + 4 * (count + 1);
+	e = elf->e_symtab + elf->e_symlen;
+	for (i = 0; i < count; i++, s++) {
+	    syms[i].as_name = s;
+	    while (s < e && *s) {
+		s++;
+	    }
+	    if (s >= e) {
+		seterr(ERROR_SIZE_ARSYMTAB);
+		free(syms);
+		return NULL;
+	    }
+	    elf_assert(!*s);
+	    syms[i].as_hash = elf_hash((unsigned char*)syms[i].as_name);
+	    syms[i].as_off = __load_u32M(elf->e_symtab + 4 * (i + 1));
+	}
+	syms[count].as_name = NULL;
+	syms[count].as_hash = ~0UL;
+	syms[count].as_off = 0;
+	elf->e_symtab = (char*)syms;
+	elf->e_symlen = count + 1;
+	elf->e_free_syms = 1;
+    }
+    *ptr = elf->e_symlen;
+    return (Elf_Arsym*)elf->e_symtab;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/getbase.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,33 @@
+/*
+getbase.c - implementation of the elf_getbase(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: getbase.c,v 1.6 2005/05/21 15:39:23 michael Exp $";
+#endif /* lint */
+
+off_t
+elf_getbase(Elf *elf) {
+    if (!elf) {
+	return -1;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    return (off_t)elf->e_base;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/getdata.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,157 @@
+/*
+getdata.c - implementation of the elf_getdata(3) function.
+Copyright (C) 1995 - 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: getdata.c,v 1.12 2005/05/21 15:39:23 michael Exp $";
+#endif /* lint */
+
+static Elf_Data*
+_elf_cook_scn(Elf *elf, Elf_Scn *scn, Scn_Data *sd) {
+    Elf_Data dst;
+    Elf_Data src;
+    int flag = 0;
+    size_t dlen;
+
+    elf_assert(elf->e_data);
+
+    /*
+     * Prepare source
+     */
+    src = sd->sd_data;
+    src.d_version = elf->e_version;
+    if (elf->e_rawdata) {
+	src.d_buf = elf->e_rawdata + scn->s_offset;
+    }
+    else {
+	src.d_buf = elf->e_data + scn->s_offset;
+    }
+
+    /*
+     * Prepare destination (needs prepared source!)
+     */
+    dst = sd->sd_data;
+    if (elf->e_class == ELFCLASS32) {
+	dlen = _elf32_xltsize(&src, dst.d_version, elf->e_encoding, 0);
+    }
+#if __LIBELF64
+    else if (elf->e_class == ELFCLASS64) {
+	dlen = _elf64_xltsize(&src, dst.d_version, elf->e_encoding, 0);
+    }
+#endif /* __LIBELF64 */
+    else {
+	elf_assert(valid_class(elf->e_class));
+	seterr(ERROR_UNIMPLEMENTED);
+	return NULL;
+    }
+    if (dlen == (size_t)-1) {
+	return NULL;
+    }
+    dst.d_size = dlen;
+    if (elf->e_rawdata != elf->e_data && dst.d_size <= src.d_size) {
+	dst.d_buf = elf->e_data + scn->s_offset;
+    }
+    else if (!(dst.d_buf = malloc(dst.d_size))) {
+	seterr(ERROR_MEM_SCNDATA);
+	return NULL;
+    }
+    else {
+	flag = 1;
+    }
+
+    /*
+     * Translate data
+     */
+    if (_elf_xlatetom(elf, &dst, &src)) {
+	sd->sd_memdata = (char*)dst.d_buf;
+	sd->sd_data = dst;
+	if (!(sd->sd_free_data = flag)) {
+	    elf->e_cooked = 1;
+	}
+	return &sd->sd_data;
+    }
+
+    if (flag) {
+	free(dst.d_buf);
+    }
+    return NULL;
+}
+
+Elf_Data*
+elf_getdata(Elf_Scn *scn, Elf_Data *data) {
+    Scn_Data *sd;
+    Elf *elf;
+
+    if (!scn) {
+	return NULL;
+    }
+    elf_assert(scn->s_magic == SCN_MAGIC);
+    if (scn->s_index == SHN_UNDEF) {
+	seterr(ERROR_NULLSCN);
+    }
+    else if (data) {
+	for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
+	    elf_assert(sd->sd_magic == DATA_MAGIC);
+	    elf_assert(sd->sd_scn == scn);
+	    if (data == &sd->sd_data) {
+		/*
+		 * sd_link allocated by elf_newdata().
+		 */
+		return &sd->sd_link->sd_data;
+	    }
+	}
+	seterr(ERROR_SCNDATAMISMATCH);
+    }
+    else if ((sd = scn->s_data_1)) {
+	elf_assert(sd->sd_magic == DATA_MAGIC);
+	elf_assert(sd->sd_scn == scn);
+	elf = scn->s_elf;
+	elf_assert(elf);
+	elf_assert(elf->e_magic == ELF_MAGIC);
+	if (sd->sd_freeme) {
+	    /* allocated by elf_newdata() */
+	    return &sd->sd_data;
+	}
+	else if (scn->s_type == SHT_NULL) {
+	    seterr(ERROR_NULLSCN);
+	}
+	else if (sd->sd_memdata) {
+	    /* already cooked */
+	    return &sd->sd_data;
+	}
+	else if (scn->s_offset < 0 || scn->s_offset > elf->e_size) {
+	    seterr(ERROR_OUTSIDE);
+	}
+	else if (scn->s_type == SHT_NOBITS || !scn->s_size) {
+	    /* no data to read */
+	    return &sd->sd_data;
+	}
+	else if (scn->s_offset + scn->s_size > elf->e_size) {
+	    seterr(ERROR_TRUNC_SCN);
+	}
+	else if (valid_class(elf->e_class)) {
+	    return _elf_cook_scn(elf, scn, sd);
+	}
+	else {
+	    seterr(ERROR_UNKNOWN_CLASS);
+	}
+    }
+    return NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/getident.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,48 @@
+/*
+getident.c - implementation of the elf_getident(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: getident.c,v 1.6 2005/05/21 15:39:23 michael Exp $";
+#endif /* lint */
+
+char*
+elf_getident(Elf *elf, size_t *ptr) {
+    size_t tmp;
+
+    if (!ptr) {
+	ptr = &tmp;
+    }
+    if (!elf) {
+	*ptr = 0;
+	return NULL;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (elf->e_kind != ELF_K_ELF) {
+	*ptr = elf->e_idlen;
+	return elf->e_data;
+    }
+    if (elf->e_ehdr || _elf_cook(elf)) {
+	*ptr = elf->e_idlen;
+	return elf->e_ehdr;
+    }
+    *ptr = 0;
+    return NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/getscn.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,48 @@
+/*
+getscn.c - implementation of the elf_getscn(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: getscn.c,v 1.6 2005/05/21 15:39:23 michael Exp $";
+#endif /* lint */
+
+Elf_Scn*
+elf_getscn(Elf *elf, size_t index) {
+    Elf_Scn *scn;
+
+    if (!elf) {
+	return NULL;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (elf->e_kind != ELF_K_ELF) {
+	seterr(ERROR_NOTELF);
+    }
+    else if (elf->e_ehdr || _elf_cook(elf)) {
+	for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+	    elf_assert(scn->s_magic == SCN_MAGIC);
+	    elf_assert(scn->s_elf == elf);
+	    if (scn->s_index == index) {
+		return scn;
+	    }
+	}
+	seterr(ERROR_NOSUCHSCN);
+    }
+    return NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/hash.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,38 @@
+/*
+hash.c - implementation of the elf_hash(3) function.
+Copyright (C) 1995 - 2002 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: hash.c,v 1.9 2005/05/21 15:39:23 michael Exp $";
+#endif /* lint */
+
+unsigned long
+elf_hash(const unsigned char *name) {
+    unsigned long hash = 0;
+    unsigned long tmp;
+
+    while (*name) {
+	hash = (hash << 4) + (unsigned char)*name++;
+	if ((tmp = hash & 0xf0000000)) {
+	    hash ^= tmp | (tmp >> 24);
+	}
+    }
+    return hash;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/input.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,106 @@
+/*
+ * input.c - low-level input for libelf.
+ * Copyright (C) 1995 - 2001, 2005 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: input.c,v 1.10 2005/10/20 21:08:02 michael Exp $";
+#endif /* lint */
+
+#include <errno.h>
+
+#if HAVE_MMAP
+#include <sys/mman.h>
+#endif /* HAVE_MMAP */
+
+static int
+xread(int fd, char *buffer, size_t len) {
+    size_t done = 0;
+    size_t n;
+
+    while (done < len) {
+	n = read(fd, buffer + done, len - done);
+	if (n == 0) {
+	    /* premature end of file */
+	    return -1;
+	}
+	else if (n != (size_t)-1) {
+	    /* some bytes read, continue */
+	    done += n;
+	}
+	else if (errno != EAGAIN && errno != EINTR) {
+	    /* real error */
+	    return -1;
+	}
+    }
+    return 0;
+}
+
+void*
+_elf_read(Elf *elf, void *buffer, size_t off, size_t len) {
+    void *tmp;
+
+    elf_assert(elf);
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    elf_assert(off >= 0 && off + len <= elf->e_size);
+    if (elf->e_disabled) {
+	seterr(ERROR_FDDISABLED);
+    }
+    else if (len) {
+	off += elf->e_base;
+	if (lseek(elf->e_fd, (off_t)off, SEEK_SET) != (off_t)off) {
+	    seterr(ERROR_IO_SEEK);
+	}
+	else if (!(tmp = buffer) && !(tmp = malloc(len))) {
+	    seterr(ERROR_IO_2BIG);
+	}
+	else if (xread(elf->e_fd, tmp, len)) {
+	    seterr(ERROR_IO_READ);
+	    if (tmp != buffer) {
+		free(tmp);
+	    }
+	}
+	else {
+	    return tmp;
+	}
+    }
+    return NULL;
+}
+
+void*
+_elf_mmap(Elf *elf) {
+#if HAVE_MMAP
+    void *tmp;
+
+    elf_assert(elf);
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    elf_assert(elf->e_base == 0);
+    if (elf->e_disabled) {
+	seterr(ERROR_FDDISABLED);
+    }
+    else if (elf->e_size) {
+	tmp = (void*)mmap(0, elf->e_size, PROT_READ | PROT_WRITE,
+			  MAP_PRIVATE, elf->e_fd, 0);
+	if (tmp != (void*)-1) {
+	    return tmp;
+	}
+    }
+#endif /* HAVE_MMAP */
+    return NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/kind.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,33 @@
+/*
+kind.c - implementation of the elf_kind(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: kind.c,v 1.6 2005/05/21 15:39:24 michael Exp $";
+#endif /* lint */
+
+Elf_Kind
+elf_kind(Elf *elf) {
+    if (!elf) {
+	return ELF_K_NONE;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    return elf->e_kind;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/libelf.def	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,82 @@
+LIBRARY libelf
+VERSION 0.8
+EXPORTS
+	elf_begin
+	elf_cntl
+	elf_delscn
+	elf_end
+	elf_errmsg
+	elf_errno
+	elf_fill
+	elf_flagdata
+	elf_flagehdr
+	elf_flagelf
+	elf_flagphdr
+	elf_flagscn
+	elf_flagshdr
+	elf_getarhdr
+	elf_getarsym
+	elf_getbase
+	elf_getdata
+	elf_getident
+	elf_getscn
+	elf_hash
+	elf_kind
+	elf_memory
+	elf_ndxscn
+	elf_newdata
+	elf_newscn
+	elf_next
+	elf_nextscn
+	elf_rand
+	elf_rawdata
+	elf_rawfile
+	elf_strptr
+	elf_update
+	elf_version
+	elf32_checksum
+	elf32_fsize
+	elf32_getehdr
+	elf32_getphdr
+	elf32_getshdr
+	elf32_newehdr
+	elf32_newphdr
+	elf32_xlatetof
+	elf32_xlatetom
+	elf64_checksum
+	elf64_fsize
+	elf64_getehdr
+	elf64_getphdr
+	elf64_getshdr
+	elf64_newehdr
+	elf64_newphdr
+	elf64_xlatetof
+	elf64_xlatetom
+	elfx_movscn
+	elfx_remscn
+	gelf_checksum
+	gelf_fsize
+	gelf_getclass
+	gelf_getdyn
+	gelf_getehdr
+	gelf_getphdr
+	gelf_getrel
+	gelf_getrela
+	gelf_getshdr
+	gelf_getsym
+	gelf_msize
+	gelf_newehdr
+	gelf_newphdr
+	gelf_update_dyn
+	gelf_update_ehdr
+	gelf_update_phdr
+	gelf_update_rel
+	gelf_update_rela
+	gelf_update_shdr
+	gelf_update_sym
+	gelf_xlatetof
+	gelf_xlatetom
+	elf_getphnum
+	elf_getshnum
+	elf_getshstrndx
+	elfx_update_shstrndx
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/libelf.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,284 @@
+/*
+ * libelf.h - public header file for libelf.
+ * Copyright (C) 1995 - 2006 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* @(#) $Id: libelf.h,v 1.26 2006/09/02 14:11:48 michael Exp $ */
+
+#ifndef _LIBELF_H
+#define _LIBELF_H
+
+#include <stddef.h>	/* for size_t */
+#include <sys/types.h>
+
+#if __LIBELF_INTERNAL__
+#include <sys_elf.h>
+#else /* __LIBELF_INTERNAL__ */
+#include <libelf/sys_elf.h>
+#endif /* __LIBELF_INTERNAL__ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#ifndef __P
+# if (__STDC__ + 0) || defined(__cplusplus) || defined(_WIN32)
+#  define __P(args) args
+# else /* __STDC__ || defined(__cplusplus) */
+#  define __P(args) ()
+# endif /* __STDC__ || defined(__cplusplus) */
+#endif /* __P */
+
+/*
+ * Commands
+ */
+typedef enum {
+    ELF_C_NULL = 0,	/* must be first, 0 */
+    ELF_C_READ,
+    ELF_C_WRITE,
+    ELF_C_CLR,
+    ELF_C_SET,
+    ELF_C_FDDONE,
+    ELF_C_FDREAD,
+    ELF_C_RDWR,
+    ELF_C_NUM		/* must be last */
+} Elf_Cmd;
+
+/*
+ * Flags
+ */
+#define ELF_F_DIRTY	0x1
+#define ELF_F_LAYOUT	0x4
+
+/*
+ * File types
+ */
+typedef enum {
+    ELF_K_NONE = 0,	/* must be first, 0 */
+    ELF_K_AR,
+    ELF_K_COFF,
+    ELF_K_ELF,
+    ELF_K_NUM		/* must be last */
+} Elf_Kind;
+
+/*
+ * Data types
+ */
+typedef enum {
+    ELF_T_BYTE = 0,	/* must be first, 0 */
+    ELF_T_ADDR,
+    ELF_T_DYN,
+    ELF_T_EHDR,
+    ELF_T_HALF,
+    ELF_T_OFF,
+    ELF_T_PHDR,
+    ELF_T_RELA,
+    ELF_T_REL,
+    ELF_T_SHDR,
+    ELF_T_SWORD,
+    ELF_T_SYM,
+    ELF_T_WORD,
+    /*
+     * New stuff for 64-bit.
+     *
+     * Most implementations add ELF_T_SXWORD after ELF_T_SWORD
+     * which breaks binary compatibility with earlier versions.
+     * If this causes problems for you, contact me.
+     */
+    ELF_T_SXWORD,
+    ELF_T_XWORD,
+    /*
+     * Symbol versioning.  Sun broke binary compatibility (again!),
+     * but I won't.
+     */
+    ELF_T_VDEF,
+    ELF_T_VNEED,
+    ELF_T_NUM		/* must be last */
+} Elf_Type;
+
+/*
+ * Elf descriptor
+ */
+typedef struct Elf	Elf;
+
+/*
+ * Section descriptor
+ */
+typedef struct Elf_Scn	Elf_Scn;
+
+/*
+ * Archive member header
+ */
+typedef struct {
+    char*		ar_name;
+    time_t		ar_date;
+    long		ar_uid;
+    long 		ar_gid;
+    unsigned long	ar_mode;
+    off_t		ar_size;
+    char*		ar_rawname;
+} Elf_Arhdr;
+
+/*
+ * Archive symbol table
+ */
+typedef struct {
+    char*		as_name;
+    size_t		as_off;
+    unsigned long	as_hash;
+} Elf_Arsym;
+
+/*
+ * Data descriptor
+ */
+typedef struct {
+    void*		d_buf;
+    Elf_Type		d_type;
+    size_t		d_size;
+    off_t		d_off;
+    size_t		d_align;
+    unsigned		d_version;
+} Elf_Data;
+
+/*
+ * Function declarations
+ */
+extern Elf *elf_begin __P((int __fd, Elf_Cmd __cmd, Elf *__ref));
+extern Elf *elf_memory __P((char *__image, size_t __size));
+extern int elf_cntl __P((Elf *__elf, Elf_Cmd __cmd));
+extern int elf_end __P((Elf *__elf));
+extern const char *elf_errmsg __P((int __err));
+extern int elf_errno __P((void));
+extern void elf_fill __P((int __fill));
+extern unsigned elf_flagdata __P((Elf_Data *__data, Elf_Cmd __cmd,
+	unsigned __flags));
+extern unsigned elf_flagehdr __P((Elf *__elf, Elf_Cmd __cmd,
+	unsigned __flags));
+extern unsigned elf_flagelf __P((Elf *__elf, Elf_Cmd __cmd,
+	unsigned __flags));
+extern unsigned elf_flagphdr __P((Elf *__elf, Elf_Cmd __cmd,
+	unsigned __flags));
+extern unsigned elf_flagscn __P((Elf_Scn *__scn, Elf_Cmd __cmd,
+	unsigned __flags));
+extern unsigned elf_flagshdr __P((Elf_Scn *__scn, Elf_Cmd __cmd,
+	unsigned __flags));
+extern size_t elf32_fsize __P((Elf_Type __type, size_t __count,
+	unsigned __ver));
+extern Elf_Arhdr *elf_getarhdr __P((Elf *__elf));
+extern Elf_Arsym *elf_getarsym __P((Elf *__elf, size_t *__ptr));
+extern off_t elf_getbase __P((Elf *__elf));
+extern Elf_Data *elf_getdata __P((Elf_Scn *__scn, Elf_Data *__data));
+extern Elf32_Ehdr *elf32_getehdr __P((Elf *__elf));
+extern char *elf_getident __P((Elf *__elf, size_t *__ptr));
+extern Elf32_Phdr *elf32_getphdr __P((Elf *__elf));
+extern Elf_Scn *elf_getscn __P((Elf *__elf, size_t __index));
+extern Elf32_Shdr *elf32_getshdr __P((Elf_Scn *__scn));
+extern unsigned long elf_hash __P((const unsigned char *__name));
+extern Elf_Kind elf_kind __P((Elf *__elf));
+extern size_t elf_ndxscn __P((Elf_Scn *__scn));
+extern Elf_Data *elf_newdata __P((Elf_Scn *__scn));
+extern Elf32_Ehdr *elf32_newehdr __P((Elf *__elf));
+extern Elf32_Phdr *elf32_newphdr __P((Elf *__elf, size_t __count));
+extern Elf_Scn *elf_newscn __P((Elf *__elf));
+extern Elf_Cmd elf_next __P((Elf *__elf));
+extern Elf_Scn *elf_nextscn __P((Elf *__elf, Elf_Scn *__scn));
+extern size_t elf_rand __P((Elf *__elf, size_t __offset));
+extern Elf_Data *elf_rawdata __P((Elf_Scn *__scn, Elf_Data *__data));
+extern char *elf_rawfile __P((Elf *__elf, size_t *__ptr));
+extern char *elf_strptr __P((Elf *__elf, size_t __section, size_t __offset));
+extern off_t elf_update __P((Elf *__elf, Elf_Cmd __cmd));
+extern unsigned elf_version __P((unsigned __ver));
+extern Elf_Data *elf32_xlatetof __P((Elf_Data *__dst, const Elf_Data *__src,
+	unsigned __encode));
+extern Elf_Data *elf32_xlatetom __P((Elf_Data *__dst, const Elf_Data *__src,
+	unsigned __encode));
+
+/*
+ * Additional functions found on Solaris
+ */
+extern long elf32_checksum __P((Elf *__elf));
+
+#if __LIBELF64
+/*
+ * 64-bit ELF functions
+ * Not available on all platforms
+ */
+extern Elf64_Ehdr *elf64_getehdr __P((Elf *__elf));
+extern Elf64_Ehdr *elf64_newehdr __P((Elf *__elf));
+extern Elf64_Phdr *elf64_getphdr __P((Elf *__elf));
+extern Elf64_Phdr *elf64_newphdr __P((Elf *__elf, size_t __count));
+extern Elf64_Shdr *elf64_getshdr __P((Elf_Scn *__scn));
+extern size_t elf64_fsize __P((Elf_Type __type, size_t __count,
+	unsigned __ver));
+extern Elf_Data *elf64_xlatetof __P((Elf_Data *__dst, const Elf_Data *__src,
+	unsigned __encode));
+extern Elf_Data *elf64_xlatetom __P((Elf_Data *__dst, const Elf_Data *__src,
+	unsigned __encode));
+
+/*
+ * Additional functions found on Solaris
+ */
+extern long elf64_checksum __P((Elf *__elf));
+
+#endif /* __LIBELF64 */
+
+/*
+ * ELF format extensions
+ *
+ * These functions return 0 on failure, 1 on success.
+ */
+extern int elf_getphnum __P((Elf *__elf, size_t *__resultp));
+extern int elf_getshnum __P((Elf *__elf, size_t *__resultp));
+extern int elf_getshstrndx __P((Elf *__elf, size_t *__resultp));
+
+/*
+ * Convenience functions
+ *
+ * elfx_update_shstrndx is elf_getshstrndx's counterpart.
+ * It should be used to set the e_shstrndx member.
+ * There is no update function for e_shnum or e_phnum
+ * because libelf handles them internally.
+ */
+extern int elfx_update_shstrndx __P((Elf *__elf, size_t __index));
+
+/*
+ * Experimental extensions:
+ *
+ * elfx_movscn() moves section `__scn' directly after section `__after'.
+ * elfx_remscn() removes section `__scn'.  Both functions update
+ * the section indices; elfx_remscn() also adjusts the ELF header's
+ * e_shnum member.  The application is responsible for updating other
+ * data (in particular, e_shstrndx and the section headers' sh_link and
+ * sh_info members).
+ *
+ * elfx_movscn() returns the new index of the moved section.
+ * elfx_remscn() returns the original index of the removed section.
+ * A return value of zero indicates an error.
+ */
+extern size_t elfx_movscn __P((Elf *__elf, Elf_Scn *__scn, Elf_Scn *__after));
+extern size_t elfx_remscn __P((Elf *__elf, Elf_Scn *__scn));
+
+/*
+ * elf_delscn() is obsolete.  Please use elfx_remscn() instead.
+ */
+extern size_t elf_delscn __P((Elf *__elf, Elf_Scn *__scn));
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _LIBELF_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/memset.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,53 @@
+/*
+ * memset.c - replacement for memset(3), using duff's device.
+ * Copyright (C) 1995 - 2004 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: memset.c,v 1.10 2005/05/21 15:39:24 michael Exp $";
+#endif /* lint */
+
+#include <stddef.h>	/* for size_t */
+#include <sys/types.h>
+
+void*
+_elf_memset(void *s, int c, size_t n) {
+    char *t = (char*)s;
+
+    if (n) {
+	switch (n % 8u) {
+	    do {
+		n -= 8;
+		default:
+		case 0: *t++ = (char)c;
+		case 7: *t++ = (char)c;
+		case 6: *t++ = (char)c;
+		case 5: *t++ = (char)c;
+		case 4: *t++ = (char)c;
+		case 3: *t++ = (char)c;
+		case 2: *t++ = (char)c;
+		case 1: *t++ = (char)c;
+	    }
+	    while (n > 8);
+	}
+    }
+    return s;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/ndxscn.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,33 @@
+/*
+ndxscn.c - implementation of the elf_ndxscn(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: ndxscn.c,v 1.6 2005/05/21 15:39:24 michael Exp $";
+#endif /* lint */
+
+size_t
+elf_ndxscn(Elf_Scn *scn) {
+    if (!scn) {
+	return SHN_UNDEF;
+    }
+    elf_assert(scn->s_magic == SCN_MAGIC);
+    return scn->s_index;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/newdata.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,56 @@
+/*
+newdata.c - implementation of the elf_newdata(3) function.
+Copyright (C) 1995 - 2000 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: newdata.c,v 1.9 2005/05/21 15:39:24 michael Exp $";
+#endif /* lint */
+
+Elf_Data*
+elf_newdata(Elf_Scn *scn) {
+    Scn_Data *sd;
+
+    if (!scn) {
+	return NULL;
+    }
+    elf_assert(scn->s_magic == SCN_MAGIC);
+    if (scn->s_index == SHN_UNDEF) {
+	seterr(ERROR_NULLSCN);
+    }
+    else if (!(sd = (Scn_Data*)malloc(sizeof(*sd)))) {
+	seterr(ERROR_MEM_SCNDATA);
+    }
+    else {
+	*sd = _elf_data_init;
+	sd->sd_scn = scn;
+	sd->sd_data_flags = ELF_F_DIRTY;
+	sd->sd_freeme = 1;
+	sd->sd_data.d_version = _elf_version;
+	if (scn->s_data_n) {
+	    scn->s_data_n->sd_link = sd;
+	}
+	else {
+	    scn->s_data_1 = sd;
+	}
+	scn->s_data_n = sd;
+	return &sd->sd_data;
+    }
+    return NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/newscn.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,145 @@
+/*
+ * newscn.c - implementation of the elf_newscn(3) function.
+ * Copyright (C) 1995 - 2006 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: newscn.c,v 1.12 2006/07/07 22:17:01 michael Exp $";
+#endif /* lint */
+
+int
+_elf_update_shnum(Elf *elf, size_t shnum) {
+    size_t extshnum = 0;
+    Elf_Scn *scn;
+
+    elf_assert(elf);
+    elf_assert(elf->e_ehdr);
+    scn = elf->e_scn_1;
+    elf_assert(scn);
+    elf_assert(scn->s_index == 0);
+    if (shnum >= SHN_LORESERVE) {
+	extshnum = shnum;
+	shnum = 0;
+    }
+    if (elf->e_class == ELFCLASS32) {
+	((Elf32_Ehdr*)elf->e_ehdr)->e_shnum = shnum;
+	scn->s_shdr32.sh_size = extshnum;
+    }
+#if __LIBELF64
+    else if (elf->e_class == ELFCLASS64) {
+	((Elf64_Ehdr*)elf->e_ehdr)->e_shnum = shnum;
+	scn->s_shdr64.sh_size = extshnum;
+    }
+#endif /* __LIBELF64 */
+    else {
+	if (valid_class(elf->e_class)) {
+	    seterr(ERROR_UNIMPLEMENTED);
+	}
+	else {
+	    seterr(ERROR_UNKNOWN_CLASS);
+	}
+	return -1;
+    }
+    elf->e_ehdr_flags |= ELF_F_DIRTY;
+    scn->s_shdr_flags |= ELF_F_DIRTY;
+    return 0;
+}
+
+static Elf_Scn*
+_makescn(Elf *elf, size_t index) {
+    Elf_Scn *scn;
+
+    elf_assert(elf);
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    elf_assert(elf->e_ehdr);
+    elf_assert(_elf_scn_init.s_magic == SCN_MAGIC);
+    if (!(scn = (Elf_Scn*)malloc(sizeof(*scn)))) {
+	seterr(ERROR_MEM_SCN);
+	return NULL;
+    }
+    *scn = _elf_scn_init;
+    scn->s_elf = elf;
+    scn->s_scn_flags = ELF_F_DIRTY;
+    scn->s_shdr_flags = ELF_F_DIRTY;
+    scn->s_freeme = 1;
+    scn->s_index = index;
+    return scn;
+}
+
+Elf_Scn*
+_elf_first_scn(Elf *elf) {
+    Elf_Scn *scn;
+
+    elf_assert(elf);
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if ((scn = elf->e_scn_1)) {
+	return scn;
+    }
+    if ((scn = _makescn(elf, 0))) {
+	elf->e_scn_1 = elf->e_scn_n = scn;
+	if (_elf_update_shnum(elf, 1)) {
+	    free(scn);
+	    elf->e_scn_1 = elf->e_scn_n = scn = NULL;
+	}
+    }
+    return scn;
+}
+
+static Elf_Scn*
+_buildscn(Elf *elf) {
+    Elf_Scn *scn;
+
+    if (!_elf_first_scn(elf)) {
+	return NULL;
+    }
+    scn = elf->e_scn_n;
+    elf_assert(scn);
+    if (!(scn = _makescn(elf, scn->s_index + 1))) {
+	return NULL;
+    }
+    if (_elf_update_shnum(elf, scn->s_index + 1)) {
+	free(scn);
+	return NULL;
+    }
+    elf->e_scn_n = elf->e_scn_n->s_link = scn;
+    return scn;
+}
+
+Elf_Scn*
+elf_newscn(Elf *elf) {
+    Elf_Scn *scn;
+
+    if (!elf) {
+	return NULL;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (!elf->e_readable && !elf->e_ehdr) {
+	seterr(ERROR_NOEHDR);
+    }
+    else if (elf->e_kind != ELF_K_ELF) {
+	seterr(ERROR_NOTELF);
+    }
+    else if (!elf->e_ehdr && !_elf_cook(elf)) {
+	return NULL;
+    }
+    else if ((scn = _buildscn(elf))) {
+	return scn;
+    }
+    return NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/next.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,42 @@
+/*
+next.c - implementation of the elf_next(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: next.c,v 1.6 2005/05/21 15:39:25 michael Exp $";
+#endif /* lint */
+
+Elf_Cmd
+elf_next(Elf *elf) {
+    if (!elf) {
+	return ELF_C_NULL;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (!elf->e_parent) {
+	return ELF_C_NULL;
+    }
+    elf_assert(elf->e_parent->e_magic == ELF_MAGIC);
+    elf_assert(elf->e_parent->e_kind == ELF_K_AR);
+    elf->e_parent->e_off = elf->e_next;
+    if (elf->e_next == elf->e_parent->e_size) {
+	return ELF_C_NULL;
+    }
+    return ELF_C_READ;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/nextscn.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,54 @@
+/*
+nextscn.c - implementation of the elf_nextscn(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: nextscn.c,v 1.6 2005/05/21 15:39:25 michael Exp $";
+#endif /* lint */
+
+Elf_Scn*
+elf_nextscn(Elf *elf, Elf_Scn *scn) {
+    if (!elf) {
+	return NULL;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (scn) {
+	elf_assert(scn->s_magic == SCN_MAGIC);
+	if (scn->s_elf == elf) {
+	    return scn->s_link;
+	}
+	seterr(ERROR_ELFSCNMISMATCH);
+    }
+    else if (elf->e_kind != ELF_K_ELF) {
+	seterr(ERROR_NOTELF);
+    }
+    else if (elf->e_ehdr || _elf_cook(elf)) {
+	elf_assert(elf->e_ehdr);
+	for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+	    elf_assert(scn->s_magic == SCN_MAGIC);
+	    elf_assert(scn->s_elf == elf);
+	    if (scn->s_index == 1) {
+		return scn;
+	    }
+	}
+	seterr(ERROR_NOSUCHSCN);
+    }
+    return NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/nlist.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,253 @@
+/*
+ * nlist.c - implementation of the nlist(3) function.
+ * Copyright (C) 1995 - 2004 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+#include <nlist.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: nlist.c,v 1.14 2006/08/18 00:01:07 michael Exp $";
+#endif /* lint */
+
+#if !defined(_WIN32)
+#if HAVE_FCNTL_H
+#include <fcntl.h>
+#else
+extern int open();
+#endif /* HAVE_FCNTL_H */
+#endif /* defined(_WIN32) */
+
+#ifndef O_RDONLY
+#define O_RDONLY	0
+#endif /* O_RDONLY */
+
+#ifndef O_BINARY
+#define O_BINARY	0
+#endif /* O_BINARY */
+
+#define FILE_OPEN_MODE	(O_RDONLY | O_BINARY)
+
+#define PRIME	217
+
+struct hash {
+    const char*		name;
+    unsigned long	hash;
+    unsigned		next;
+};
+
+static const char*
+symbol_name(Elf *elf, const void *syms, const char *names, size_t nlimit, size_t index) {
+    size_t off;
+
+    if (elf->e_class == ELFCLASS32) {
+	off = ((Elf32_Sym*)syms)[index].st_name;
+    }
+#if __LIBELF64
+    else if (elf->e_class == ELFCLASS64) {
+	off = ((Elf64_Sym*)syms)[index].st_name;
+    }
+#endif /* __LIBELF64 */
+    else {
+	return NULL;
+    }
+    if (off >= 0 && off < nlimit) {
+	return &names[off];
+    }
+    return NULL;
+}
+
+static void
+copy_symbol(Elf *elf, struct nlist *np, const void *syms, size_t index) {
+    if (elf->e_class == ELFCLASS32) {
+	np->n_value = ((Elf32_Sym*)syms)[index].st_value;
+	np->n_scnum = ((Elf32_Sym*)syms)[index].st_shndx;
+    }
+#if __LIBELF64
+    else if (elf->e_class == ELFCLASS64) {
+	np->n_value = ((Elf64_Sym*)syms)[index].st_value;
+	np->n_scnum = ((Elf64_Sym*)syms)[index].st_shndx;
+    }
+#endif /* __LIBELF64 */
+    /*
+     * this needs more work
+     */
+    np->n_type = 0;
+    np->n_sclass = 0;
+    np->n_numaux = 0;
+}
+
+static int
+_elf_nlist(Elf *elf, struct nlist *nl) {
+    unsigned first[PRIME];
+    Elf_Scn *symtab = NULL;
+    Elf_Scn *strtab = NULL;
+    Elf_Data *symdata;
+    Elf_Data *strdata;
+    size_t symsize;
+    size_t nsymbols;
+    const char *name;
+    struct hash *table;
+    unsigned long hash;
+    unsigned i;
+    struct nlist *np;
+
+    /*
+     * Get and translate ELF header, section table and so on.
+     * Must be class independent, so don't use elf32_get*().
+     */
+    if (elf->e_kind != ELF_K_ELF) {
+	return -1;
+    }
+    if (!elf->e_ehdr && !_elf_cook(elf)) {
+	return -1;
+    }
+
+    /*
+     * Find symbol table. If there is none, try dynamic symbols.
+     */
+    for (symtab = elf->e_scn_1; symtab; symtab = symtab->s_link) {
+	if (symtab->s_type == SHT_SYMTAB) {
+	    break;
+	}
+	if (symtab->s_type == SHT_DYNSYM) {
+	    strtab = symtab;
+	}
+    }
+    if (!symtab && !(symtab = strtab)) {
+	return -1;
+    }
+
+    /*
+     * Get associated string table.
+     */
+    i = 0;
+    if (elf->e_class == ELFCLASS32) {
+	i = symtab->s_shdr32.sh_link;
+    }
+#if __LIBELF64
+    else if (elf->e_class == ELFCLASS64) {
+	i = symtab->s_shdr64.sh_link;
+    }
+#endif /* __LIBELF64 */
+    if (i == 0) {
+	return -1;
+    }
+    for (strtab = elf->e_scn_1; strtab; strtab = strtab->s_link) {
+	if (strtab->s_index == i) {
+	    break;
+	}
+    }
+    if (!strtab || strtab->s_type != SHT_STRTAB) {
+	return -1;
+    }
+
+    /*
+     * Get and translate section data.
+     */
+    symdata = elf_getdata(symtab, NULL);
+    strdata = elf_getdata(strtab, NULL);
+    if (!symdata || !strdata) {
+	return -1;
+    }
+    symsize = _msize(elf->e_class, _elf_version, ELF_T_SYM);
+    elf_assert(symsize);
+    nsymbols = symdata->d_size / symsize;
+    if (!symdata->d_buf || !strdata->d_buf || !nsymbols || !strdata->d_size) {
+	return -1;
+    }
+
+    /*
+     * Build a simple hash table.
+     */
+    if (!(table = (struct hash*)malloc(nsymbols * sizeof(*table)))) {
+	return -1;
+    }
+    for (i = 0; i < PRIME; i++) {
+	first[i] = 0;
+    }
+    for (i = 0; i < nsymbols; i++) {
+	table[i].name = NULL;
+	table[i].hash = 0;
+	table[i].next = 0;
+    }
+    for (i = 1; i < nsymbols; i++) {
+	name = symbol_name(elf, symdata->d_buf, strdata->d_buf,
+			   strdata->d_size, i);
+	if (name == NULL) {
+	    free(table);
+	    return -1;
+	}
+	if (*name != '\0') {
+	    table[i].name = name;
+	    table[i].hash = elf_hash((unsigned char*)name);
+	    hash = table[i].hash % PRIME;
+	    table[i].next = first[hash];
+	    first[hash] = i;
+	}
+    }
+
+    /*
+     * Lookup symbols, one by one.
+     */
+    for (np = nl; (name = np->n_name) && *name; np++) {
+	hash = elf_hash((unsigned char*)name);
+	for (i = first[hash % PRIME]; i; i = table[i].next) {
+	    if (table[i].hash == hash && !strcmp(table[i].name, name)) {
+		break;
+	    }
+	}
+	if (i) {
+	    copy_symbol(elf, np, symdata->d_buf, i);
+	}
+	else {
+	    np->n_value = 0;
+	    np->n_scnum = 0;
+	    np->n_type = 0;
+	    np->n_sclass = 0;
+	    np->n_numaux = 0;
+	}
+    }
+    free(table);
+    return 0;
+}
+
+int
+nlist(const char *filename, struct nlist *nl) {
+    int result = -1;
+    unsigned oldver;
+    Elf *elf;
+    int fd;
+
+    if ((oldver = elf_version(EV_CURRENT)) != EV_NONE) {
+	if ((fd = open(filename, FILE_OPEN_MODE)) != -1) {
+	    if ((elf = elf_begin(fd, ELF_C_READ, NULL))) {
+		result = _elf_nlist(elf, nl);
+		elf_end(elf);
+	    }
+	    close(fd);
+	}
+	elf_version(oldver);
+    }
+    if (result) {
+	while (nl->n_name && *nl->n_name) {
+	    nl->n_value = 0;
+	    nl++;
+	}
+    }
+    return result;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/nlist.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,48 @@
+/*
+ * nlist.h - public header file for nlist(3).
+ * Copyright (C) 1995 - 2006 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* @(#) $Id: nlist.h,v 1.9 2006/04/25 16:26:39 michael Exp $ */
+
+#ifndef _NLIST_H
+#define _NLIST_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+struct nlist {
+    char*		n_name;
+    long		n_value;
+    short		n_scnum;
+    unsigned short	n_type;
+    char		n_sclass;
+    char		n_numaux;
+};
+
+#if (__STDC__ + 0) || defined(__cplusplus) || defined(_WIN32)
+extern int nlist(const char *__filename, struct nlist *__nl);
+#else /* __STDC__ || defined(__cplusplus) */
+extern int nlist();
+#endif /* __STDC__ || defined(__cplusplus) */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* _NLIST_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/opt.delscn.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,205 @@
+/*
+opt.delscn.c - implementation of the elf_delscn(3) function.
+Copyright (C) 1995 - 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: opt.delscn.c,v 1.11 2005/05/21 15:39:25 michael Exp $";
+#endif /* lint */
+
+static size_t
+_newindex(size_t old, size_t index) {
+    return old == index ? SHN_UNDEF : (old > index ? old - 1 : old);
+}
+
+static void
+_elf32_update_shdr(Elf *elf, size_t index) {
+    Elf32_Shdr *shdr;
+    Elf_Scn *scn;
+
+    ((Elf32_Ehdr*)elf->e_ehdr)->e_shnum = elf->e_scn_n->s_index + 1;
+    for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+	shdr = &scn->s_shdr32;
+	switch (shdr->sh_type) {
+	    case SHT_REL:
+	    case SHT_RELA:
+		shdr->sh_info = _newindex(shdr->sh_info, index);
+		/* fall through */
+	    case SHT_DYNSYM:
+	    case SHT_DYNAMIC:
+	    case SHT_HASH:
+	    case SHT_SYMTAB:
+#if __LIBELF_SYMBOL_VERSIONS
+#if __LIBELF_SUN_SYMBOL_VERSIONS
+	    case SHT_SUNW_verdef:
+	    case SHT_SUNW_verneed:
+	    case SHT_SUNW_versym:
+#else /* __LIBELF_SUN_SYMBOL_VERSIONS */
+	    case SHT_GNU_verdef:
+	    case SHT_GNU_verneed:
+	    case SHT_GNU_versym:
+#endif /* __LIBELF_SUN_SYMBOL_VERSIONS */
+#endif /* __LIBELF_SYMBOL_VERSIONS */
+		shdr->sh_link = _newindex(shdr->sh_link, index);
+		/* fall through */
+	    default:
+		break;
+	}
+    }
+}
+
+#if __LIBELF64
+
+static void
+_elf64_update_shdr(Elf *elf, size_t index) {
+    Elf64_Shdr *shdr;
+    Elf_Scn *scn;
+
+    ((Elf64_Ehdr*)elf->e_ehdr)->e_shnum = elf->e_scn_n->s_index + 1;
+    for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+	shdr = &scn->s_shdr64;
+	switch (shdr->sh_type) {
+	    case SHT_REL:
+	    case SHT_RELA:
+		shdr->sh_info = _newindex(shdr->sh_info, index);
+		/* fall through */
+	    case SHT_DYNSYM:
+	    case SHT_DYNAMIC:
+	    case SHT_HASH:
+	    case SHT_SYMTAB:
+#if __LIBELF_SYMBOL_VERSIONS
+#if __LIBELF_SUN_SYMBOL_VERSIONS
+	    case SHT_SUNW_verdef:
+	    case SHT_SUNW_verneed:
+	    case SHT_SUNW_versym:
+#else /* __LIBELF_SUN_SYMBOL_VERSIONS */
+	    case SHT_GNU_verdef:
+	    case SHT_GNU_verneed:
+	    case SHT_GNU_versym:
+#endif /* __LIBELF_SUN_SYMBOL_VERSIONS */
+#endif /* __LIBELF_SYMBOL_VERSIONS */
+		shdr->sh_link = _newindex(shdr->sh_link, index);
+		/* fall through */
+	    default:
+		break;
+	}
+    }
+}
+
+#endif /* __LIBELF64 */
+
+size_t
+elf_delscn(Elf *elf, Elf_Scn *scn) {
+    Elf_Scn *pscn;
+    Scn_Data *sd;
+    Scn_Data *tmp;
+    size_t index;
+
+    if (!elf || !scn) {
+	return SHN_UNDEF;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    elf_assert(scn->s_magic == SCN_MAGIC);
+    elf_assert(elf->e_ehdr);
+    if (scn->s_elf != elf) {
+	seterr(ERROR_ELFSCNMISMATCH);
+	return SHN_UNDEF;
+    }
+    elf_assert(elf->e_scn_1);
+    if (scn == elf->e_scn_1) {
+	seterr(ERROR_NULLSCN);
+	return SHN_UNDEF;
+    }
+
+    /*
+     * Find previous section.
+     */
+    for (pscn = elf->e_scn_1; pscn->s_link; pscn = pscn->s_link) {
+	if (pscn->s_link == scn) {
+	    break;
+	}
+    }
+    if (pscn->s_link != scn) {
+	seterr(ERROR_ELFSCNMISMATCH);
+	return SHN_UNDEF;
+    }
+    /*
+     * Unlink section.
+     */
+    if (elf->e_scn_n == scn) {
+	elf->e_scn_n = pscn;
+    }
+    pscn->s_link = scn->s_link;
+    index = scn->s_index;
+    /*
+     * Free section descriptor and data.
+     */
+    for (sd = scn->s_data_1; sd; sd = tmp) {
+	elf_assert(sd->sd_magic == DATA_MAGIC);
+	elf_assert(sd->sd_scn == scn);
+	tmp = sd->sd_link;
+	if (sd->sd_free_data && sd->sd_memdata) {
+	    free(sd->sd_memdata);
+	}
+	if (sd->sd_freeme) {
+	    free(sd);
+	}
+    }
+    if ((sd = scn->s_rawdata)) {
+	elf_assert(sd->sd_magic == DATA_MAGIC);
+	elf_assert(sd->sd_scn == scn);
+	if (sd->sd_free_data && sd->sd_memdata) {
+	    free(sd->sd_memdata);
+	}
+	if (sd->sd_freeme) {
+	    free(sd);
+	}
+    }
+    if (scn->s_freeme) {
+	elf_assert(scn->s_index > 0);
+	free(scn);
+    }
+    /*
+     * Adjust section indices.
+     */
+    for (scn = pscn->s_link; scn; scn = scn->s_link) {
+	elf_assert(scn->s_index > index);
+	scn->s_index--;
+    }
+    /*
+     * Adjust ELF header and well-known section headers.
+     */
+    if (elf->e_class == ELFCLASS32) {
+	_elf32_update_shdr(elf, index);
+	return index;
+    }
+#if __LIBELF64
+    else if (elf->e_class == ELFCLASS64) {
+	_elf64_update_shdr(elf, index);
+	return index;
+    }
+#endif /* __LIBELF64 */
+    else if (valid_class(elf->e_class)) {
+	seterr(ERROR_UNIMPLEMENTED);
+    }
+    else {
+	seterr(ERROR_UNKNOWN_CLASS);
+    }
+    return SHN_UNDEF;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/private.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,425 @@
+/*
+ * private.h - private definitions for libelf.
+ * Copyright (C) 1995 - 2007 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* @(#) $Id: private.h,v 1.38 2007/09/07 12:07:59 michael Exp $ */
+
+#ifndef _PRIVATE_H
+#define _PRIVATE_H
+
+#define __LIBELF_INTERNAL__ 1
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+/*
+ * Workaround for GLIBC bug:
+ * include <stdint.h> before <sys/types.h>
+ */
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#include <sys/types.h>
+
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#else /* STDC_HEADERS */
+extern void *malloc(), *realloc();
+extern void free(), bcopy(), abort();
+extern int strcmp(), strncmp(), memcmp();
+extern void *memcpy(), *memmove(), *memset();
+#endif /* STDC_HEADERS */
+
+#if defined(_WIN32)
+#include <io.h>
+#else
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#else /* HAVE_UNISTD_H */
+extern int read(), write(), close();
+extern off_t lseek();
+#if HAVE_FTRUNCATE
+extern int ftruncate();
+#endif /* HAVE_FTRUNCATE */
+#endif /* HAVE_UNISTD_H */
+#endif /* defined(_WIN32) */
+
+#ifndef SEEK_SET
+#define SEEK_SET	0
+#endif /* SEEK_SET */
+#ifndef SEEK_CUR
+#define SEEK_CUR	1
+#endif /* SEEK_CUR */
+#ifndef SEEK_END
+#define SEEK_END	2
+#endif /* SEEK_END */
+
+#if !HAVE_MEMCMP
+# define memcmp	strncmp
+#endif /* !HAVE_MEMCMP */
+#if !HAVE_MEMCPY
+# define memcpy(d,s,n)	bcopy(s,d,n)
+#endif /* !HAVE_MEMCPY */
+#if !HAVE_MEMMOVE
+# define memmove(d,s,n)	bcopy(s,d,n)
+#endif /* !HAVE_MEMMOVE */
+
+#if !HAVE_MEMSET
+# define memset _elf_memset
+extern void *_elf_memset();
+#endif /* !HAVE_MEMSET */
+
+#if HAVE_STRUCT_NLIST_DECLARATION
+# define nlist __override_nlist_declaration
+#endif /* HAVE_STRUCT_NLIST_DECLARATION */
+
+#if __LIBELF_NEED_LINK_H
+# include <link.h>
+#elif __LIBELF_NEED_SYS_LINK_H
+# include <sys/link.h>
+#endif /* __LIBELF_NEED_LINK_H */
+
+#include <libelf.h>
+
+#if HAVE_STRUCT_NLIST_DECLARATION
+# undef nlist
+#endif /* HAVE_STRUCT_NLIST_DECLARATION */
+
+#if __LIBELF64
+#include <gelf.h>
+#endif /* __LIBELF64 */
+
+typedef struct Scn_Data Scn_Data;
+
+/*
+ * ELF descriptor
+ */
+struct Elf {
+    /* common */
+    size_t	e_size;			/* file/member size */
+    size_t	e_dsize;		/* size of memory image */
+    Elf_Kind	e_kind;			/* kind of file */
+    char*	e_data;			/* file/member data */
+    char*	e_rawdata;		/* file/member raw data */
+    size_t	e_idlen;		/* identifier size */
+    int		e_fd;			/* file descriptor */
+    unsigned	e_count;		/* activation count */
+    /* archive members (still common) */
+    Elf*	e_parent;		/* NULL if not an archive member */
+    size_t	e_next;			/* 0 if not an archive member */
+    size_t	e_base;			/* 0 if not an archive member */
+    Elf*	e_link;			/* next archive member or NULL */
+    Elf_Arhdr*	e_arhdr;		/* archive member header or NULL */
+    /* archives */
+    size_t	e_off;			/* current member offset (for elf_begin) */
+    Elf*	e_members;		/* linked list of active archive members */
+    char*	e_symtab;		/* archive symbol table */
+    size_t	e_symlen;		/* length of archive symbol table */
+    char*	e_strtab;		/* archive string table */
+    size_t	e_strlen;		/* length of archive string table */
+    /* ELF files */
+    unsigned	e_class;		/* ELF class */
+    unsigned	e_encoding;		/* ELF data encoding */
+    unsigned	e_version;		/* ELF version */
+    char*	e_ehdr;			/* ELF header */
+    char*	e_phdr;			/* ELF program header table */
+    size_t	e_phnum;		/* size of program header table */
+    Elf_Scn*	e_scn_1;		/* first section */
+    Elf_Scn*	e_scn_n;		/* last section */
+    unsigned	e_elf_flags;		/* elf flags (ELF_F_*) */
+    unsigned	e_ehdr_flags;		/* ehdr flags (ELF_F_*) */
+    unsigned	e_phdr_flags;		/* phdr flags (ELF_F_*) */
+    /* misc flags */
+    unsigned	e_readable : 1;		/* file is readable */
+    unsigned	e_writable : 1;		/* file is writable */
+    unsigned	e_disabled : 1;		/* e_fd has been disabled */
+    unsigned	e_cooked : 1;		/* e_data was modified */
+    unsigned	e_free_syms : 1;	/* e_symtab is malloc'ed */
+    unsigned	e_unmap_data : 1;	/* e_data is mmap'ed */
+    unsigned	e_memory : 1;		/* created by elf_memory() */
+    /* magic number for debugging */
+    long	e_magic;
+};
+
+#define ELF_MAGIC	0x012b649e
+
+#define INIT_ELF	{\
+    /* e_size */	0,\
+    /* e_dsize */	0,\
+    /* e_kind */	ELF_K_NONE,\
+    /* e_data */	NULL,\
+    /* e_rawdata */	NULL,\
+    /* e_idlen */	0,\
+    /* e_fd */		-1,\
+    /* e_count */	1,\
+    /* e_parent */	NULL,\
+    /* e_next */	0,\
+    /* e_base */	0,\
+    /* e_link */	NULL,\
+    /* e_arhdr */	NULL,\
+    /* e_off */		0,\
+    /* e_members */	NULL,\
+    /* e_symtab */	NULL,\
+    /* e_symlen */	0,\
+    /* e_strtab */	NULL,\
+    /* e_strlen */	0,\
+    /* e_class */	ELFCLASSNONE,\
+    /* e_encoding */	ELFDATANONE,\
+    /* e_version */	EV_NONE,\
+    /* e_ehdr */	NULL,\
+    /* e_phdr */	NULL,\
+    /* e_phnum */	0,\
+    /* e_scn_1 */	NULL,\
+    /* e_scn_n */	NULL,\
+    /* e_elf_flags */	0,\
+    /* e_ehdr_flags */	0,\
+    /* e_phdr_flags */	0,\
+    /* e_readable */	0,\
+    /* e_writable */	0,\
+    /* e_disabled */	0,\
+    /* e_cooked */	0,\
+    /* e_free_syms */	0,\
+    /* e_unmap_data */	0,\
+    /* e_memory */	0,\
+    /* e_magic */	ELF_MAGIC\
+}
+
+/*
+ * Section descriptor
+ */
+struct Elf_Scn {
+    Elf_Scn*	s_link;			/* pointer to next Elf_Scn */
+    Elf*	s_elf;			/* pointer to elf descriptor */
+    size_t	s_index;		/* number of this section */
+    unsigned	s_scn_flags;		/* section flags (ELF_F_*) */
+    unsigned	s_shdr_flags;		/* shdr flags (ELF_F_*) */
+    Scn_Data*	s_data_1;		/* first data buffer */
+    Scn_Data*	s_data_n;		/* last data buffer */
+    Scn_Data*	s_rawdata;		/* raw data buffer */
+    /* data copied from shdr */
+    unsigned	s_type;			/* section type */
+    size_t	s_offset;		/* section offset */
+    size_t	s_size;			/* section size */
+    /* misc flags */
+    unsigned	s_freeme : 1;		/* this Elf_Scn was malloc'ed */
+    /* section header */
+    union {
+#if __LIBELF64
+	Elf64_Shdr	u_shdr64;
+#endif /* __LIBELF64 */
+	Elf32_Shdr	u_shdr32;
+    }		s_uhdr;
+    /* magic number for debugging */
+    long	s_magic;
+};
+#define s_shdr32	s_uhdr.u_shdr32
+#define s_shdr64	s_uhdr.u_shdr64
+
+#define SCN_MAGIC	0x012c747d
+
+#define INIT_SCN	{\
+    /* s_link */	NULL,\
+    /* s_elf */		NULL,\
+    /* s_index */	0,\
+    /* s_scn_flags */	0,\
+    /* s_shdr_flags */	0,\
+    /* s_data_1 */	NULL,\
+    /* s_data_n */	NULL,\
+    /* s_rawdata */	NULL,\
+    /* s_type */	SHT_NULL,\
+    /* s_offset */	0,\
+    /* s_size */	0,\
+    /* s_freeme */	0,\
+    /* s_uhdr */	{{0,}},\
+    /* s_magic */	SCN_MAGIC\
+}
+
+/*
+ * Data descriptor
+ */
+struct Scn_Data {
+    Elf_Data	sd_data;		/* must be first! */
+    Scn_Data*	sd_link;		/* pointer to next Scn_Data */
+    Elf_Scn*	sd_scn;			/* pointer to section */
+    char*	sd_memdata;		/* memory image of section */
+    unsigned	sd_data_flags;		/* data flags (ELF_F_*) */
+    /* misc flags */
+    unsigned	sd_freeme : 1;		/* this Scn_Data was malloc'ed */
+    unsigned	sd_free_data : 1;	/* sd_memdata is malloc'ed */
+    /* magic number for debugging */
+    long	sd_magic;
+};
+
+#define DATA_MAGIC	0x01072639
+
+#define INIT_DATA	{\
+    {\
+    /* d_buf */		NULL,\
+    /* d_type */	ELF_T_BYTE,\
+    /* d_size */	0,\
+    /* d_off */		0,\
+    /* d_align */	0,\
+    /* d_version */	EV_NONE\
+    },\
+    /* sd_link */	NULL,\
+    /* sd_scn */	NULL,\
+    /* sd_memdata */	NULL,\
+    /* sd_data_flags */	0,\
+    /* sd_freeme */	0,\
+    /* sd_free_data */	0,\
+    /* sd_magic */	DATA_MAGIC\
+}
+
+/*
+ * Private status variables
+ */
+extern unsigned _elf_version;
+extern int _elf_errno;
+extern int _elf_fill;
+extern int _elf_sanity_checks;
+#define SANITY_CHECK_STRPTR	(1u << 0)
+
+/*
+ * Private functions
+ */
+extern void *_elf_read __P((Elf*, void*, size_t, size_t));
+extern void *_elf_mmap __P((Elf*));
+extern int _elf_cook __P((Elf*));
+extern char *_elf_getehdr __P((Elf*, unsigned));
+extern char *_elf_getphdr __P((Elf*, unsigned));
+extern Elf_Data *_elf_xlatetom __P((const Elf*, Elf_Data*, const Elf_Data*));
+extern Elf_Type _elf_scn_type __P((unsigned));
+extern size_t _elf32_xltsize __P((const Elf_Data *__src, unsigned __dv, unsigned __encode, int __tof));
+extern size_t _elf64_xltsize __P((const Elf_Data *__src, unsigned __dv, unsigned __encode, int __tof));
+extern int _elf_update_shnum(Elf *__elf, size_t __shnum);
+extern Elf_Scn *_elf_first_scn(Elf *__elf);
+
+/*
+ * Special translators
+ */
+extern size_t _elf_verdef_32L11_tof __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verdef_32L11_tom __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verdef_32M11_tof __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verdef_32M11_tom __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verdef_64L11_tof __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verdef_64L11_tom __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verdef_64M11_tof __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verdef_64M11_tom __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verneed_32L11_tof __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verneed_32L11_tom __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verneed_32M11_tof __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verneed_32M11_tom __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verneed_64L11_tof __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verneed_64L11_tom __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verneed_64M11_tof __P((unsigned char *dst, const unsigned char *src, size_t n));
+extern size_t _elf_verneed_64M11_tom __P((unsigned char *dst, const unsigned char *src, size_t n));
+
+/*
+ * Private data
+ */
+extern const Elf_Scn _elf_scn_init;
+extern const Scn_Data _elf_data_init;
+extern const size_t _elf_fmsize[2][EV_CURRENT - EV_NONE][ELF_T_NUM][2];
+
+/*
+ * Access macros for _elf_fmsize[]
+ */
+#define _fmsize(c,v,t,w)	\
+	(_elf_fmsize[(c)-ELFCLASS32][(v)-EV_NONE-1][(t)-ELF_T_BYTE][(w)])
+#define _fsize(c,v,t)		_fmsize((c),(v),(t),1)
+#define _msize(c,v,t)		_fmsize((c),(v),(t),0)
+
+/*
+ * Various checks
+ */
+#define valid_class(c)		((c) >= ELFCLASS32 && (c) <= ELFCLASS64)
+#define valid_encoding(e)	((e) >= ELFDATA2LSB && (e) <= ELFDATA2MSB)
+#define valid_version(v)	((v) > EV_NONE && (v) <= EV_CURRENT)
+#define valid_type(t)		((unsigned)(t) < ELF_T_NUM)
+
+/*
+ * Error codes
+ */
+enum {
+#define __err__(a,b)	a,
+#include <errors.h>		/* include constants from errors.h */
+#undef __err__
+ERROR_NUM
+};
+
+#define seterr(err)	(_elf_errno = (err))
+
+/*
+ * Sizes of data types (external representation)
+ * These definitions should be in <elf.h>, but...
+ */
+#ifndef ELF32_FSZ_ADDR
+# define ELF32_FSZ_ADDR		4
+# define ELF32_FSZ_HALF		2
+# define ELF32_FSZ_OFF		4
+# define ELF32_FSZ_SWORD	4
+# define ELF32_FSZ_WORD		4
+#endif /* ELF32_FSZ_ADDR */
+#ifndef ELF64_FSZ_ADDR
+# define ELF64_FSZ_ADDR		8
+# define ELF64_FSZ_HALF		2
+# define ELF64_FSZ_OFF		8
+# define ELF64_FSZ_SWORD	4
+# define ELF64_FSZ_SXWORD	8
+# define ELF64_FSZ_WORD		4
+# define ELF64_FSZ_XWORD	8
+#endif /* ELF64_FSZ_ADDR */
+
+/*
+ * More missing pieces, in no particular order
+ */
+#ifndef SHT_SYMTAB_SHNDX
+#define SHT_SYMTAB_SHNDX	18
+#endif /* SHT_SYMTAB_SHNDX */
+
+#ifndef SHN_XINDEX
+#define SHN_XINDEX		0xffff
+#endif /* SHN_XINDEX */
+
+#ifndef PN_XNUM
+#define PN_XNUM			0xffff
+#endif /* PN_XNUM */
+
+/*
+ * Debugging
+ */
+#if ENABLE_DEBUG
+extern void __elf_assert __P((const char*, unsigned, const char*));
+# if (__STDC__ + 0)
+#  define elf_assert(x)	do{if(!(x))__elf_assert(__FILE__,__LINE__,#x);}while(0)
+# else /* __STDC__ */
+#  define elf_assert(x)	do{if(!(x))__elf_assert(__FILE__,__LINE__,"x");}while(0)
+# endif /* __STDC__ */
+#else /* ENABLE_DEBUG */
+# define elf_assert(x)	do{}while(0)
+#endif /* ENABLE_DEBUG */
+
+/*
+ * Return values for certain functions
+ */
+#define LIBELF_SUCCESS	1
+#define LIBELF_FAILURE	0
+
+#endif /* _PRIVATE_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/rand.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,43 @@
+/*
+rand.c - implementation of the elf_rand(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: rand.c,v 1.6 2005/05/21 15:39:25 michael Exp $";
+#endif /* lint */
+
+size_t
+elf_rand(Elf *elf, size_t offset) {
+    if (!elf) {
+	return 0;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (elf->e_kind != ELF_K_AR) {
+	seterr(ERROR_NOTARCHIVE);
+    }
+    else if (offset <= 0 || offset > elf->e_size) {
+	seterr(ERROR_BADOFF);
+    }
+    else {
+	elf->e_off = offset;
+	return offset;
+    }
+    return 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/rawdata.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,89 @@
+/*
+rawdata.c - implementation of the elf_rawdata(3) function.
+Copyright (C) 1995 - 2000 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: rawdata.c,v 1.9 2005/05/21 15:39:26 michael Exp $";
+#endif /* lint */
+
+Elf_Data*
+elf_rawdata(Elf_Scn *scn, Elf_Data *data) {
+    Scn_Data *sd;
+    Elf *elf;
+
+    if (!scn) {
+	return NULL;
+    }
+    elf_assert(scn->s_magic == SCN_MAGIC);
+    elf = scn->s_elf;
+    elf_assert(elf);
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (!elf->e_readable) {
+	return NULL;
+    }
+    else if (scn->s_index == SHN_UNDEF || scn->s_type == SHT_NULL) {
+	seterr(ERROR_NULLSCN);
+    }
+    else if (data) {
+	return NULL;
+    }
+    else if ((sd = scn->s_rawdata)) {
+	elf_assert(sd->sd_magic == DATA_MAGIC);
+	elf_assert(sd->sd_scn == scn);
+	return &sd->sd_data;
+    }
+    else if (scn->s_offset < 0 || scn->s_offset > elf->e_size) {
+	seterr(ERROR_OUTSIDE);
+    }
+    else if (scn->s_type != SHT_NOBITS
+	    && scn->s_offset + scn->s_size > elf->e_size) {
+	seterr(ERROR_TRUNC_SCN);
+    }
+    else if (!(sd = (Scn_Data*)malloc(sizeof(*sd)))) {
+	seterr(ERROR_MEM_SCNDATA);
+    }
+    else {
+	*sd = _elf_data_init;
+	sd->sd_scn = scn;
+	sd->sd_freeme = 1;
+	sd->sd_data.d_size = scn->s_size;
+	sd->sd_data.d_version = _elf_version;
+	if (scn->s_type != SHT_NOBITS && scn->s_size) {
+	    if (!(sd->sd_memdata = (char*)malloc(scn->s_size))) {
+		seterr(ERROR_IO_2BIG);
+		free(sd);
+		return NULL;
+	    }
+	    else if (elf->e_rawdata) {
+		memcpy(sd->sd_memdata, elf->e_rawdata + scn->s_offset, scn->s_size);
+	    }
+	    else if (!_elf_read(elf, sd->sd_memdata, scn->s_offset, scn->s_size)) {
+		free(sd->sd_memdata);
+		free(sd);
+		return NULL;
+	    }
+	    sd->sd_data.d_buf = sd->sd_memdata;
+	    sd->sd_free_data = 1;
+	}
+	scn->s_rawdata = sd;
+	return &sd->sd_data;
+    }
+    return NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/rawfile.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,52 @@
+/*
+rawfile.c - implementation of the elf_rawfile(3) function.
+Copyright (C) 1995 - 1998 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: rawfile.c,v 1.6 2005/05/21 15:39:26 michael Exp $";
+#endif /* lint */
+
+char*
+elf_rawfile(Elf *elf, size_t *ptr) {
+    size_t tmp;
+
+    if (!ptr) {
+	ptr = &tmp;
+    }
+    *ptr = 0;
+    if (!elf) {
+	return NULL;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (!elf->e_readable) {
+	return NULL;
+    }
+    else if (elf->e_size && !elf->e_rawdata) {
+	elf_assert(elf->e_data);
+	if (!elf->e_cooked) {
+	    elf->e_rawdata = elf->e_data;
+	}
+	else if (!(elf->e_rawdata = _elf_read(elf, NULL, 0, elf->e_size))) {
+	    return NULL;
+	}
+	*ptr = elf->e_size;
+    }
+    return elf->e_rawdata;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/strptr.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,150 @@
+/*
+ * strptr.c - implementation of the elf_strptr(3) function.
+ * Copyright (C) 1995 - 2007 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: strptr.c,v 1.11 2007/09/07 12:07:59 michael Exp $";
+#endif /* lint */
+
+char*
+elf_strptr(Elf *elf, size_t section, size_t offset) {
+    Elf_Data *data;
+    Elf_Scn *scn;
+    size_t n;
+    char *s;
+
+    if (!elf) {
+	return NULL;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (!(scn = elf_getscn(elf, section))) {
+	return NULL;
+    }
+    if (scn->s_index == SHN_UNDEF) {
+	seterr(ERROR_NOSTRTAB);
+	return NULL;
+    }
+    /*
+     * checking the section header is more appropriate
+     */
+    if (elf->e_class == ELFCLASS32) {
+	if (scn->s_shdr32.sh_type != SHT_STRTAB) {
+	    seterr(ERROR_NOSTRTAB);
+	    return NULL;
+	}
+    }
+#if __LIBELF64
+    else if (elf->e_class == ELFCLASS64) {
+	if (scn->s_shdr64.sh_type != SHT_STRTAB) {
+	    seterr(ERROR_NOSTRTAB);
+	    return NULL;
+	}
+    }
+#endif /* __LIBELF64 */
+    else if (valid_class(elf->e_class)) {
+	seterr(ERROR_UNIMPLEMENTED);
+	return NULL;
+    }
+    else {
+	seterr(ERROR_UNKNOWN_CLASS);
+	return NULL;
+    }
+    /*
+     * Find matching buffer
+     */
+    n = 0;
+    data = NULL;
+    if (elf->e_elf_flags & ELF_F_LAYOUT) {
+	/*
+	 * Programmer is responsible for d_off
+	 * Note: buffers may be in any order!
+	 */
+	while ((data = elf_getdata(scn, data))) {
+	    n = data->d_off;
+	    if (offset >= n && offset - n < data->d_size) {
+		/*
+		 * Found it
+		 */
+		break;
+	    }
+	}
+    }
+    else {
+	/*
+	 * Calculate offsets myself
+	 */
+	while ((data = elf_getdata(scn, data))) {
+	    if (data->d_align > 1) {
+		n += data->d_align - 1;
+		n -= n % data->d_align;
+	    }
+	    if (offset < n) {
+		/*
+		 * Invalid offset: points into a hole
+		 */
+		seterr(ERROR_BADSTROFF);
+		return NULL;
+	    }
+	    if (offset - n < data->d_size) {
+		/*
+		 * Found it
+		 */
+		break;
+	    }
+	    n += data->d_size;
+	}
+    }
+    if (data == NULL) {
+	/*
+	 * Not found
+	 */
+	seterr(ERROR_BADSTROFF);
+	return NULL;
+    }
+    if (data->d_buf == NULL) {
+	/*
+	 * Buffer is NULL (usually the programmers' fault)
+	 */
+	seterr(ERROR_NULLBUF);
+	return NULL;
+    }
+    offset -= n;
+    s = (char*)data->d_buf;
+    if (!(_elf_sanity_checks & SANITY_CHECK_STRPTR)) {
+	return s + offset;
+    }
+    /*
+     * Perform extra sanity check
+     */
+    for (n = offset; n < data->d_size; n++) {
+	if (s[n] == '\0') {
+	    /*
+	     * Return properly NUL terminated string
+	     */
+	    return s + offset;
+	}
+    }
+    /*
+     * String is not NUL terminated
+     * Return error to avoid SEGV in application
+     */
+    seterr(ERROR_UNTERM);
+    return NULL;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/swap64.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,81 @@
+/*
+swap64.c - 64-bit byte swapping functions.
+Copyright (C) 1995 - 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+#include <byteswap.h>
+
+#if __LIBELF64
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: swap64.c,v 1.5 2005/05/21 15:39:26 michael Exp $";
+#endif /* lint */
+
+__libelf_u64_t
+_elf_load_u64L(const unsigned char *from) {
+    return ((__libelf_u64_t)__load_u32L(from + 4) << 32)
+	 | (__libelf_u64_t)__load_u32L(from);
+}
+
+__libelf_u64_t
+_elf_load_u64M(const unsigned char *from) {
+    return ((__libelf_u64_t)__load_u32M(from) << 32)
+	 | (__libelf_u64_t)__load_u32M(from + 4);
+}
+
+__libelf_i64_t
+_elf_load_i64L(const unsigned char *from) {
+    return ((__libelf_i64_t)__load_i32L(from + 4) << 32)
+	 | (__libelf_u64_t)__load_u32L(from);
+}
+
+__libelf_i64_t
+_elf_load_i64M(const unsigned char *from) {
+    return ((__libelf_i64_t)__load_i32M(from) << 32)
+	 | (__libelf_u64_t)__load_u32M(from + 4);
+}
+
+void
+_elf_store_u64L(unsigned char *to, __libelf_u64_t v) {
+    __store_u32L(to, (__libelf_u32_t)v);
+    v >>= 32;
+    __store_u32L(to + 4, (__libelf_u32_t)v);
+}
+
+void
+_elf_store_u64M(unsigned char *to, __libelf_u64_t v) {
+    __store_u32M(to + 4, (__libelf_u32_t)v);
+    v >>= 32;
+    __store_u32M(to, (__libelf_u32_t)v);
+}
+
+void
+_elf_store_i64L(unsigned char *to, __libelf_u64_t v) {
+    __store_u32L(to, (__libelf_u32_t)v);
+    v >>= 32;
+    __store_i32L(to + 4, (__libelf_u32_t)v);
+}
+
+void
+_elf_store_i64M(unsigned char *to, __libelf_u64_t v) {
+    __store_u32M(to + 4, (__libelf_u32_t)v);
+    v >>= 32;
+    __store_i32M(to, (__libelf_u32_t)v);
+}
+
+#endif /* __LIBELF64 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/sys_elf.h.in	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,130 @@
+/*
+sys_elf.h.in - configure template for private "switch" file.
+Copyright (C) 1998 - 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+/* @(#) $Id: sys_elf.h.in,v 1.12 2006/09/07 15:55:42 michael Exp $ */
+
+/*
+ * DO NOT USE THIS IN APPLICATIONS - #include <libelf.h> INSTEAD!
+ */
+
+/* Define to `<elf.h>' or `<sys/elf.h>' if one of them is present */
+#undef __LIBELF_HEADER_ELF_H
+
+/* Define if Elf32_Dyn is declared in <link.h> */
+#undef __LIBELF_NEED_LINK_H
+
+/* Define if Elf32_Dyn is declared in <sys/link.h> */
+#undef __LIBELF_NEED_SYS_LINK_H
+
+/* Define if you want 64-bit support (and your system supports it) */
+#undef __LIBELF64
+
+/* Define if you want 64-bit support, and are running IRIX */
+#undef __LIBELF64_IRIX
+
+/* Define if you want 64-bit support, and are running Linux */
+#undef __LIBELF64_LINUX
+
+/* Define if you want symbol versioning (and your system supports it) */
+#undef __LIBELF_SYMBOL_VERSIONS
+
+/* Define to a 64-bit signed integer type if one exists */
+#undef __libelf_i64_t
+
+/* Define to a 64-bit unsigned integer type if one exists */
+#undef __libelf_u64_t
+
+/* Define to a 32-bit signed integer type if one exists */
+#undef __libelf_i32_t
+
+/* Define to a 32-bit unsigned integer type if one exists */
+#undef __libelf_u32_t
+
+/* Define to a 16-bit signed integer type if one exists */
+#undef __libelf_i16_t
+
+/* Define to a 16-bit unsigned integer type if one exists */
+#undef __libelf_u16_t
+
+/*
+ * Ok, now get the correct instance of elf.h...
+ */
+#ifdef __LIBELF_HEADER_ELF_H
+# include __LIBELF_HEADER_ELF_H
+#else /* __LIBELF_HEADER_ELF_H */
+# if __LIBELF_INTERNAL__
+#  include <elf_repl.h>
+# else /* __LIBELF_INTERNAL__ */
+#  include <libelf/elf_repl.h>
+# endif /* __LIBELF_INTERNAL__ */
+#endif /* __LIBELF_HEADER_ELF_H */
+
+/*
+ * On some systems, <elf.h> is severely broken.  Try to fix it.
+ */
+#ifdef __LIBELF_HEADER_ELF_H
+
+# ifndef ELF32_FSZ_ADDR
+#  define ELF32_FSZ_ADDR	4
+#  define ELF32_FSZ_HALF	2
+#  define ELF32_FSZ_OFF		4
+#  define ELF32_FSZ_SWORD	4
+#  define ELF32_FSZ_WORD	4
+# endif /* ELF32_FSZ_ADDR */
+
+# ifndef STN_UNDEF
+#  define STN_UNDEF	0
+# endif /* STN_UNDEF */
+
+# if __LIBELF64
+
+#  ifndef ELF64_FSZ_ADDR
+#   define ELF64_FSZ_ADDR	8
+#   define ELF64_FSZ_HALF	2
+#   define ELF64_FSZ_OFF	8
+#   define ELF64_FSZ_SWORD	4
+#   define ELF64_FSZ_WORD	4
+#   define ELF64_FSZ_SXWORD	8
+#   define ELF64_FSZ_XWORD	8
+#  endif /* ELF64_FSZ_ADDR */
+
+#  ifndef ELF64_ST_BIND
+#   define ELF64_ST_BIND(i)	((i)>>4)
+#   define ELF64_ST_TYPE(i)	((i)&0xf)
+#   define ELF64_ST_INFO(b,t)	(((b)<<4)+((t)&0xf))
+#  endif /* ELF64_ST_BIND */
+
+#  ifndef ELF64_R_SYM
+#   define ELF64_R_SYM(i)	((Elf64_Xword)(i)>>32)
+#   define ELF64_R_TYPE(i)	((i)&0xffffffffL)
+#   define ELF64_R_INFO(s,t)	(((Elf64_Xword)(s)<<32)+((t)&0xffffffffL))
+#  endif /* ELF64_R_SYM */
+
+#  if __LIBELF64_LINUX
+typedef __libelf_u64_t	Elf64_Addr;
+typedef __libelf_u16_t	Elf64_Half;
+typedef __libelf_u64_t	Elf64_Off;
+typedef __libelf_i32_t	Elf64_Sword;
+typedef __libelf_u32_t	Elf64_Word;
+typedef __libelf_i64_t	Elf64_Sxword;
+typedef __libelf_u64_t	Elf64_Xword;
+#  endif /* __LIBELF64_LINUX */
+
+# endif /* __LIBELF64 */
+#endif /* __LIBELF_HEADER_ELF_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/sys_elf.h.w32	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,130 @@
+/*
+ * lib/sys_elf.h.w32 - internal configuration file for W32 port
+ * Copyright (C) 2004 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * @(#) $Id: sys_elf.h.w32,v 1.2 2006/09/07 15:55:42 michael Exp $
+ */
+
+/*
+ * DO NOT USE THIS IN APPLICATIONS - #include <libelf.h> INSTEAD!
+ */
+
+/* Define to `<elf.h>' or `<sys/elf.h>' if one of them is present */
+#undef __LIBELF_HEADER_ELF_H
+
+/* Define if Elf32_Dyn is declared in <link.h> */
+#undef __LIBELF_NEED_LINK_H
+
+/* Define if Elf32_Dyn is declared in <sys/link.h> */
+#undef __LIBELF_NEED_SYS_LINK_H
+
+/* Define if you want 64-bit support (and your system supports it) */
+#define __LIBELF64 1
+
+/* Define if you want 64-bit support, and are running IRIX */
+#undef __LIBELF64_IRIX
+
+/* Define if you want 64-bit support, and are running Linux */
+#undef __LIBELF64_LINUX
+
+/* Define if you want symbol versioning (and your system supports it) */
+#define __LIBELF_SYMBOL_VERSIONS 1
+
+/* Define to a 64-bit signed integer type if one exists */
+#define __libelf_i64_t __int64
+
+/* Define to a 64-bit unsigned integer type if one exists */
+#define __libelf_u64_t unsigned __int64
+
+/* Define to a 32-bit signed integer type if one exists */
+#define __libelf_i32_t int
+
+/* Define to a 32-bit unsigned integer type if one exists */
+#define __libelf_u32_t unsigned int
+
+/* Define to a 16-bit signed integer type if one exists */
+#define __libelf_i16_t short int
+
+/* Define to a 16-bit unsigned integer type if one exists */
+#define __libelf_u16_t unsigned short int
+
+/*
+ * Ok, now get the correct instance of elf.h...
+ */
+#ifdef __LIBELF_HEADER_ELF_H
+# include __LIBELF_HEADER_ELF_H
+#else /* __LIBELF_HEADER_ELF_H */
+# if __LIBELF_INTERNAL__
+#  include <elf_repl.h>
+# else /* __LIBELF_INTERNAL__ */
+#  include <libelf/elf_repl.h>
+# endif /* __LIBELF_INTERNAL__ */
+#endif /* __LIBELF_HEADER_ELF_H */
+
+/*
+ * On some systems, <elf.h> is severely broken.  Try to fix it.
+ */
+#ifdef __LIBELF_HEADER_ELF_H
+
+# ifndef ELF32_FSZ_ADDR
+#  define ELF32_FSZ_ADDR	4
+#  define ELF32_FSZ_HALF	2
+#  define ELF32_FSZ_OFF		4
+#  define ELF32_FSZ_SWORD	4
+#  define ELF32_FSZ_WORD	4
+# endif /* ELF32_FSZ_ADDR */
+
+# ifndef STN_UNDEF
+#  define STN_UNDEF	0
+# endif /* STN_UNDEF */
+
+# if __LIBELF64
+
+#  ifndef ELF64_FSZ_ADDR
+#   define ELF64_FSZ_ADDR	8
+#   define ELF64_FSZ_HALF	2
+#   define ELF64_FSZ_OFF	8
+#   define ELF64_FSZ_SWORD	4
+#   define ELF64_FSZ_WORD	4
+#   define ELF64_FSZ_SXWORD	8
+#   define ELF64_FSZ_XWORD	8
+#  endif /* ELF64_FSZ_ADDR */
+
+#  ifndef ELF64_ST_BIND
+#   define ELF64_ST_BIND(i)	((i)>>4)
+#   define ELF64_ST_TYPE(i)	((i)&0xf)
+#   define ELF64_ST_INFO(b,t)	(((b)<<4)+((t)&0xf))
+#  endif /* ELF64_ST_BIND */
+
+#  ifndef ELF64_R_SYM
+#   define ELF64_R_SYM(i)	((Elf64_Xword)(i)>>32)
+#   define ELF64_R_TYPE(i)	((i)&0xffffffffL)
+#   define ELF64_R_INFO(s,t)	(((Elf64_Xword)(s)<<32)+((t)&0xffffffffL))
+#  endif /* ELF64_R_SYM */
+
+#  if __LIBELF64_LINUX
+typedef __libelf_u64_t	Elf64_Addr;
+typedef __libelf_u16_t	Elf64_Half;
+typedef __libelf_u64_t	Elf64_Off;
+typedef __libelf_i32_t	Elf64_Sword;
+typedef __libelf_u32_t	Elf64_Word;
+typedef __libelf_i64_t	Elf64_Sxword;
+typedef __libelf_u64_t	Elf64_Xword;
+#  endif /* __LIBELF64_LINUX */
+
+# endif /* __LIBELF64 */
+#endif /* __LIBELF_HEADER_ELF_H */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/update.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1019 @@
+/*
+ * update.c - implementation of the elf_update(3) function.
+ * Copyright (C) 1995 - 2006 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: update.c,v 1.32 2006/07/07 22:15:50 michael Exp $";
+#endif /* lint */
+
+#include <errno.h>
+
+#if HAVE_MMAP
+#include <sys/mman.h>
+#endif /* HAVE_MMAP */
+
+static const unsigned short __encoding = ELFDATA2LSB + (ELFDATA2MSB << 8);
+#define native_encoding (*(unsigned char*)&__encoding)
+
+#define rewrite(var,val,f)	\
+    do{if((var)!=(val)){(var)=(val);(f)|=ELF_F_DIRTY;}}while(0)
+
+#define align(var,val)		\
+    do{if((val)>1){(var)+=(val)-1;(var)-=(var)%(val);}}while(0)
+
+#undef max
+#define max(a,b)		((a)>(b)?(a):(b))
+
+static off_t
+scn_data_layout(Elf_Scn *scn, unsigned v, unsigned type, size_t *algn, unsigned *flag) {
+    Elf *elf = scn->s_elf;
+    Elf_Data *data;
+    int layout = (elf->e_elf_flags & ELF_F_LAYOUT) == 0;
+    size_t scn_align = 1;
+    size_t len = 0;
+    Scn_Data *sd;
+    size_t fsize;
+
+    if (!(sd = scn->s_data_1)) {
+	/* no data in section */
+	*algn = scn_align;
+	return (off_t)len;
+    }
+    /* load data from file, if any */
+    if (!(data = elf_getdata(scn, NULL))) {
+	return (off_t)-1;
+    }
+    elf_assert(data == &sd->sd_data);
+    for (; sd; sd = sd->sd_link) {
+	elf_assert(sd->sd_magic == DATA_MAGIC);
+	elf_assert(sd->sd_scn == scn);
+
+	if (!valid_version(sd->sd_data.d_version)) {
+	    return (off_t)-1;
+	}
+
+	fsize = sd->sd_data.d_size;
+	if (fsize && type != SHT_NOBITS && valid_type(sd->sd_data.d_type)) {
+	    if (elf->e_class == ELFCLASS32) {
+		fsize = _elf32_xltsize(&sd->sd_data, v, ELFDATA2LSB, 1);
+	    }
+#if __LIBELF64
+	    else if (elf->e_class == ELFCLASS64) {
+		fsize = _elf64_xltsize(&sd->sd_data, v, ELFDATA2LSB, 1);
+	    }
+#endif /* __LIBELF64 */
+	    else {
+		elf_assert(valid_class(elf->e_class));
+		seterr(ERROR_UNIMPLEMENTED);
+		return (off_t)-1;
+	    }
+	    if (fsize == (size_t)-1) {
+		return (off_t)-1;
+	    }
+	}
+
+	if (layout) {
+	    align(len, sd->sd_data.d_align);
+	    scn_align = max(scn_align, sd->sd_data.d_align);
+	    rewrite(sd->sd_data.d_off, (off_t)len, sd->sd_data_flags);
+	    len += fsize;
+	}
+	else {
+	    len = max(len, sd->sd_data.d_off + fsize);
+	}
+
+	*flag |= sd->sd_data_flags;
+    }
+    *algn = scn_align;
+    return (off_t)len;
+}
+
+static size_t
+scn_entsize(const Elf *elf, unsigned version, unsigned stype) {
+    Elf_Type type;
+
+    switch ((type = _elf_scn_type(stype))) {
+	case ELF_T_BYTE:
+	    return 0;
+	case ELF_T_VDEF:
+	case ELF_T_VNEED:
+	    return 0;	/* What else can I do?  Thank you, Sun! */
+	default:
+	    return _fsize(elf->e_class, version, type);
+    }
+}
+
+static off_t
+_elf32_layout(Elf *elf, unsigned *flag) {
+    int layout = (elf->e_elf_flags & ELF_F_LAYOUT) == 0;
+    Elf32_Ehdr *ehdr = (Elf32_Ehdr*)elf->e_ehdr;
+    size_t off = 0;
+    unsigned version;
+    unsigned encoding;
+    size_t align_addr;
+    size_t entsize;
+    unsigned phnum;
+    unsigned shnum;
+    Elf_Scn *scn;
+
+    *flag = elf->e_elf_flags | elf->e_phdr_flags;
+
+    if ((version = ehdr->e_version) == EV_NONE) {
+	version = EV_CURRENT;
+    }
+    if (!valid_version(version)) {
+	seterr(ERROR_UNKNOWN_VERSION);
+	return -1;
+    }
+    if ((encoding = ehdr->e_ident[EI_DATA]) == ELFDATANONE) {
+	encoding = native_encoding;
+    }
+    if (!valid_encoding(encoding)) {
+	seterr(ERROR_UNKNOWN_ENCODING);
+	return -1;
+    }
+    entsize = _fsize(ELFCLASS32, version, ELF_T_EHDR);
+    elf_assert(entsize);
+    rewrite(ehdr->e_ehsize, entsize, elf->e_ehdr_flags);
+    off = entsize;
+
+    align_addr = _fsize(ELFCLASS32, version, ELF_T_ADDR);
+    elf_assert(align_addr);
+
+    if ((phnum = elf->e_phnum)) {
+	entsize = _fsize(ELFCLASS32, version, ELF_T_PHDR);
+	elf_assert(entsize);
+	if (layout) {
+	    align(off, align_addr);
+	    rewrite(ehdr->e_phoff, off, elf->e_ehdr_flags);
+	    off += phnum * entsize;
+	}
+	else {
+	    off = max(off, ehdr->e_phoff + phnum * entsize);
+	}
+    }
+    else {
+	entsize = 0;
+	if (layout) {
+	    rewrite(ehdr->e_phoff, 0, elf->e_ehdr_flags);
+	}
+    }
+    if (phnum >= PN_XNUM) {
+	Elf_Scn *scn = elf->e_scn_1;
+	Elf32_Shdr *shdr = &scn->s_shdr32;
+
+	elf_assert(scn);
+	elf_assert(scn->s_index == 0);
+	rewrite(shdr->sh_info, phnum, scn->s_shdr_flags);
+	*flag |= scn->s_shdr_flags;
+	phnum = PN_XNUM;
+    }
+    rewrite(ehdr->e_phnum, phnum, elf->e_ehdr_flags);
+    rewrite(ehdr->e_phentsize, entsize, elf->e_ehdr_flags);
+
+    for (scn = elf->e_scn_1, shnum = 0; scn; scn = scn->s_link, ++shnum) {
+	Elf32_Shdr *shdr = &scn->s_shdr32;
+	size_t scn_align = 1;
+	off_t len;
+
+	elf_assert(scn->s_index == shnum);
+
+	*flag |= scn->s_scn_flags;
+
+	if (scn->s_index == SHN_UNDEF) {
+	    rewrite(shdr->sh_entsize, 0, scn->s_shdr_flags);
+	    if (layout) {
+		rewrite(shdr->sh_offset, 0, scn->s_shdr_flags);
+		rewrite(shdr->sh_size, 0, scn->s_shdr_flags);
+		rewrite(shdr->sh_addralign, 0, scn->s_shdr_flags);
+	    }
+	    *flag |= scn->s_shdr_flags;
+	    continue;
+	}
+	if (shdr->sh_type == SHT_NULL) {
+	    *flag |= scn->s_shdr_flags;
+	    continue;
+	}
+
+	len = scn_data_layout(scn, version, shdr->sh_type, &scn_align, flag);
+	if (len == -1) {
+	    return -1;
+	}
+
+	/*
+	 * Never override the program's choice.
+	 */
+	if (shdr->sh_entsize == 0) {
+	    entsize = scn_entsize(elf, version, shdr->sh_type);
+	    if (entsize > 1) {
+		rewrite(shdr->sh_entsize, entsize, scn->s_shdr_flags);
+	    }
+	}
+
+	if (layout) {
+	    align(off, scn_align);
+	    rewrite(shdr->sh_offset, off, scn->s_shdr_flags);
+	    rewrite(shdr->sh_size, (size_t)len, scn->s_shdr_flags);
+	    rewrite(shdr->sh_addralign, scn_align, scn->s_shdr_flags);
+
+	    if (shdr->sh_type != SHT_NOBITS) {
+		off += (size_t)len;
+	    }
+	}
+	else if ((size_t)len > shdr->sh_size) {
+	    seterr(ERROR_SCN2SMALL);
+	    return -1;
+	}
+	else {
+	    Elf_Scn *scn2;
+	    size_t end1, end2;
+
+	    end1 = shdr->sh_offset;
+	    if (shdr->sh_type != SHT_NOBITS) {
+		end1 += shdr->sh_size;
+	    }
+	    if (shdr->sh_offset < off) {
+		/*
+		 * check for overlapping sections
+		 */
+		for (scn2 = elf->e_scn_1; scn2; scn2 = scn2->s_link) {
+		    if (scn2 == scn) {
+			break;
+		    }
+		    end2 = scn2->s_shdr32.sh_offset;
+		    if (scn2->s_shdr32.sh_type != SHT_NOBITS) {
+			end2 += scn2->s_shdr32.sh_size;
+		    }
+		    if (end1 > scn2->s_shdr32.sh_offset
+		     && end2 > shdr->sh_offset) {
+			seterr(ERROR_SCN_OVERLAP);
+			return -1;
+		    }
+		}
+	    }
+	    if (off < end1) {
+		off = end1;
+	    }
+	}
+	*flag |= scn->s_shdr_flags;
+    }
+
+    if (shnum) {
+	entsize = _fsize(ELFCLASS32, version, ELF_T_SHDR);
+	elf_assert(entsize);
+	if (layout) {
+	    align(off, align_addr);
+	    rewrite(ehdr->e_shoff, off, elf->e_ehdr_flags);
+	    off += shnum * entsize;
+	}
+	else {
+	    off = max(off, ehdr->e_shoff + shnum * entsize);
+	}
+    }
+    else {
+	entsize = 0;
+	if (layout) {
+	    rewrite(ehdr->e_shoff, 0, elf->e_ehdr_flags);
+	}
+    }
+    if (shnum >= SHN_LORESERVE) {
+	Elf_Scn *scn = elf->e_scn_1;
+	Elf32_Shdr *shdr = &scn->s_shdr32;
+
+	elf_assert(scn->s_index == 0);
+	rewrite(shdr->sh_size, shnum, scn->s_shdr_flags);
+	*flag |= scn->s_shdr_flags;
+	shnum = 0;
+    }
+    rewrite(ehdr->e_shnum, shnum, elf->e_ehdr_flags);
+    rewrite(ehdr->e_shentsize, entsize, elf->e_ehdr_flags);
+
+    rewrite(ehdr->e_ident[EI_MAG0], ELFMAG0, elf->e_ehdr_flags);
+    rewrite(ehdr->e_ident[EI_MAG1], ELFMAG1, elf->e_ehdr_flags);
+    rewrite(ehdr->e_ident[EI_MAG2], ELFMAG2, elf->e_ehdr_flags);
+    rewrite(ehdr->e_ident[EI_MAG3], ELFMAG3, elf->e_ehdr_flags);
+    rewrite(ehdr->e_ident[EI_CLASS], ELFCLASS32, elf->e_ehdr_flags);
+    rewrite(ehdr->e_ident[EI_DATA], encoding, elf->e_ehdr_flags);
+    rewrite(ehdr->e_ident[EI_VERSION], version, elf->e_ehdr_flags);
+    rewrite(ehdr->e_version, version, elf->e_ehdr_flags);
+
+    *flag |= elf->e_ehdr_flags;
+
+    return off;
+}
+
+#if __LIBELF64
+
+static off_t
+_elf64_layout(Elf *elf, unsigned *flag) {
+    int layout = (elf->e_elf_flags & ELF_F_LAYOUT) == 0;
+    Elf64_Ehdr *ehdr = (Elf64_Ehdr*)elf->e_ehdr;
+    size_t off = 0;
+    unsigned version;
+    unsigned encoding;
+    size_t align_addr;
+    size_t entsize;
+    unsigned phnum;
+    unsigned shnum;
+    Elf_Scn *scn;
+
+    *flag = elf->e_elf_flags | elf->e_phdr_flags;
+
+    if ((version = ehdr->e_version) == EV_NONE) {
+	version = EV_CURRENT;
+    }
+    if (!valid_version(version)) {
+	seterr(ERROR_UNKNOWN_VERSION);
+	return -1;
+    }
+    if ((encoding = ehdr->e_ident[EI_DATA]) == ELFDATANONE) {
+	encoding = native_encoding;
+    }
+    if (!valid_encoding(encoding)) {
+	seterr(ERROR_UNKNOWN_ENCODING);
+	return -1;
+    }
+    entsize = _fsize(ELFCLASS64, version, ELF_T_EHDR);
+    elf_assert(entsize);
+    rewrite(ehdr->e_ehsize, entsize, elf->e_ehdr_flags);
+    off = entsize;
+
+    align_addr = _fsize(ELFCLASS64, version, ELF_T_ADDR);
+    elf_assert(align_addr);
+
+    if ((phnum = elf->e_phnum)) {
+	entsize = _fsize(ELFCLASS64, version, ELF_T_PHDR);
+	elf_assert(entsize);
+	if (layout) {
+	    align(off, align_addr);
+	    rewrite(ehdr->e_phoff, off, elf->e_ehdr_flags);
+	    off += phnum * entsize;
+	}
+	else {
+	    off = max(off, ehdr->e_phoff + phnum * entsize);
+	}
+    }
+    else {
+	entsize = 0;
+	if (layout) {
+	    rewrite(ehdr->e_phoff, 0, elf->e_ehdr_flags);
+	}
+    }
+    if (phnum >= PN_XNUM) {
+	Elf_Scn *scn = elf->e_scn_1;
+	Elf32_Shdr *shdr = &scn->s_shdr32;
+
+	/* modify first section header, too! */
+	elf_assert(scn);
+	elf_assert(scn->s_index == 0);
+	rewrite(shdr->sh_info, phnum, scn->s_shdr_flags);
+	*flag |= scn->s_shdr_flags;
+	phnum = PN_XNUM;
+    }
+    rewrite(ehdr->e_phnum, phnum, elf->e_ehdr_flags);
+    rewrite(ehdr->e_phentsize, entsize, elf->e_ehdr_flags);
+
+    for (scn = elf->e_scn_1, shnum = 0; scn; scn = scn->s_link, ++shnum) {
+	Elf64_Shdr *shdr = &scn->s_shdr64;
+	size_t scn_align = 1;
+	off_t len;
+
+	elf_assert(scn->s_index == shnum);
+
+	*flag |= scn->s_scn_flags;
+
+	if (scn->s_index == SHN_UNDEF) {
+	    rewrite(shdr->sh_entsize, 0, scn->s_shdr_flags);
+	    if (layout) {
+		rewrite(shdr->sh_offset, 0, scn->s_shdr_flags);
+		rewrite(shdr->sh_size, 0, scn->s_shdr_flags);
+		rewrite(shdr->sh_addralign, 0, scn->s_shdr_flags);
+	    }
+	    *flag |= scn->s_shdr_flags;
+	    continue;
+	}
+	if (shdr->sh_type == SHT_NULL) {
+	    *flag |= scn->s_shdr_flags;
+	    continue;
+	}
+
+	len = scn_data_layout(scn, version, shdr->sh_type, &scn_align, flag);
+	if (len == -1) {
+	    return -1;
+	}
+
+	/*
+	 * Never override the program's choice.
+	 */
+	if (shdr->sh_entsize == 0) {
+	    entsize = scn_entsize(elf, version, shdr->sh_type);
+	    if (entsize > 1) {
+		rewrite(shdr->sh_entsize, entsize, scn->s_shdr_flags);
+	    }
+	}
+
+	if (layout) {
+	    align(off, scn_align);
+	    rewrite(shdr->sh_offset, off, scn->s_shdr_flags);
+	    rewrite(shdr->sh_size, (size_t)len, scn->s_shdr_flags);
+	    rewrite(shdr->sh_addralign, scn_align, scn->s_shdr_flags);
+
+	    if (shdr->sh_type != SHT_NOBITS) {
+		off += (size_t)len;
+	    }
+	}
+	else if ((size_t)len > shdr->sh_size) {
+	    seterr(ERROR_SCN2SMALL);
+	    return -1;
+	}
+	else {
+	    Elf_Scn *scn2;
+	    size_t end1, end2;
+
+	    end1 = shdr->sh_offset;
+	    if (shdr->sh_type != SHT_NOBITS) {
+		end1 += shdr->sh_size;
+	    }
+	    if (shdr->sh_offset < off) {
+		/*
+		 * check for overlapping sections
+		 */
+		for (scn2 = elf->e_scn_1; scn2; scn2 = scn2->s_link) {
+		    if (scn2 == scn) {
+			break;
+		    }
+		    end2 = scn2->s_shdr64.sh_offset;
+		    if (scn2->s_shdr64.sh_type != SHT_NOBITS) {
+			end2 += scn2->s_shdr64.sh_size;
+		    }
+		    if (end1 > scn2->s_shdr64.sh_offset
+		     && end2 > shdr->sh_offset) {
+			seterr(ERROR_SCN_OVERLAP);
+			return -1;
+		    }
+		}
+	    }
+	    if (off < end1) {
+		off = end1;
+	    }
+	}
+	*flag |= scn->s_shdr_flags;
+    }
+
+    if (shnum) {
+	entsize = _fsize(ELFCLASS64, version, ELF_T_SHDR);
+	elf_assert(entsize);
+	if (layout) {
+	    align(off, align_addr);
+	    rewrite(ehdr->e_shoff, off, elf->e_ehdr_flags);
+	    off += shnum * entsize;
+	}
+	else {
+	    off = max(off, ehdr->e_shoff + shnum * entsize);
+	}
+    }
+    else {
+	entsize = 0;
+	if (layout) {
+	    rewrite(ehdr->e_shoff, 0, elf->e_ehdr_flags);
+	}
+    }
+    if (shnum >= SHN_LORESERVE) {
+	Elf_Scn *scn = elf->e_scn_1;
+	Elf64_Shdr *shdr = &scn->s_shdr64;
+
+	elf_assert(scn->s_index == 0);
+	rewrite(shdr->sh_size, shnum, scn->s_shdr_flags);
+	*flag |= scn->s_shdr_flags;
+	shnum = 0;
+    }
+    rewrite(ehdr->e_shnum, shnum, elf->e_ehdr_flags);
+    rewrite(ehdr->e_shentsize, entsize, elf->e_ehdr_flags);
+
+    rewrite(ehdr->e_ident[EI_MAG0], ELFMAG0, elf->e_ehdr_flags);
+    rewrite(ehdr->e_ident[EI_MAG1], ELFMAG1, elf->e_ehdr_flags);
+    rewrite(ehdr->e_ident[EI_MAG2], ELFMAG2, elf->e_ehdr_flags);
+    rewrite(ehdr->e_ident[EI_MAG3], ELFMAG3, elf->e_ehdr_flags);
+    rewrite(ehdr->e_ident[EI_CLASS], ELFCLASS64, elf->e_ehdr_flags);
+    rewrite(ehdr->e_ident[EI_DATA], encoding, elf->e_ehdr_flags);
+    rewrite(ehdr->e_ident[EI_VERSION], version, elf->e_ehdr_flags);
+    rewrite(ehdr->e_version, version, elf->e_ehdr_flags);
+
+    *flag |= elf->e_ehdr_flags;
+
+    return off;
+}
+
+#endif /* __LIBELF64 */
+
+#define ptrinside(p,a,l)	((p)>=(a)&&(p)<(a)+(l))
+#define newptr(p,o,n)		((p)=((p)-(o))+(n))
+
+static int
+_elf_update_pointers(Elf *elf, char *outbuf, size_t len) {
+    Elf_Scn *scn;
+    Scn_Data *sd;
+    char *data, *rawdata;
+
+    elf_assert(elf);
+    elf_assert(elf->e_data);
+    elf_assert(!elf->e_parent);
+    elf_assert(!elf->e_unmap_data);
+    elf_assert(elf->e_kind == ELF_K_ELF);
+    elf_assert(len >= EI_NIDENT);
+
+    /* resize memory images */
+    if (len <= elf->e_dsize) {
+	/* don't shorten the memory image */
+	data = elf->e_data;
+    }
+    else if ((data = (char*)realloc(elf->e_data, len))) {
+	elf->e_dsize = len;
+    }
+    else {
+	seterr(ERROR_IO_2BIG);
+	return -1;
+    }
+    if (elf->e_rawdata == elf->e_data) {
+	/* update frozen raw image */
+	memcpy(data, outbuf, len);
+	elf->e_data = elf->e_rawdata = data;
+	/* cooked data is stored outside the raw image */
+	return 0;
+    }
+    if (elf->e_rawdata) {
+	/* update raw image */
+	if (!(rawdata = (char*)realloc(elf->e_rawdata, len))) {
+	    seterr(ERROR_IO_2BIG);
+	    return -1;
+	}
+	memcpy(rawdata, outbuf, len);
+	elf->e_rawdata = rawdata;
+    }
+    if (data == elf->e_data) {
+	/* nothing more to do */
+	return 0;
+    }
+    /* adjust internal pointers */
+    for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+	elf_assert(scn->s_magic == SCN_MAGIC);
+	elf_assert(scn->s_elf == elf);
+	if ((sd = scn->s_data_1)) {
+	    elf_assert(sd->sd_magic == DATA_MAGIC);
+	    elf_assert(sd->sd_scn == scn);
+	    if (sd->sd_memdata && !sd->sd_free_data) {
+		elf_assert(ptrinside(sd->sd_memdata, elf->e_data, elf->e_dsize));
+		if (sd->sd_data.d_buf == sd->sd_memdata) {
+		    newptr(sd->sd_memdata, elf->e_data, data);
+		    sd->sd_data.d_buf = sd->sd_memdata;
+		}
+		else {
+		    newptr(sd->sd_memdata, elf->e_data, data);
+		}
+	    }
+	}
+	if ((sd = scn->s_rawdata)) {
+	    elf_assert(sd->sd_magic == DATA_MAGIC);
+	    elf_assert(sd->sd_scn == scn);
+	    if (sd->sd_memdata && sd->sd_free_data) {
+		size_t off, len;
+
+		if (elf->e_class == ELFCLASS32) {
+		    off = scn->s_shdr32.sh_offset;
+		    len = scn->s_shdr32.sh_size;
+		}
+#if __LIBELF64
+		else if (elf->e_class == ELFCLASS64) {
+		    off = scn->s_shdr64.sh_offset;
+		    len = scn->s_shdr64.sh_size;
+		}
+#endif /* __LIBELF64 */
+		else {
+		    seterr(ERROR_UNIMPLEMENTED);
+		    return -1;
+		}
+		if (!(rawdata = (char*)realloc(sd->sd_memdata, len))) {
+		    seterr(ERROR_IO_2BIG);
+		    return -1;
+		}
+		memcpy(rawdata, outbuf + off, len);
+		if (sd->sd_data.d_buf == sd->sd_memdata) {
+		    sd->sd_data.d_buf = rawdata;
+		}
+		sd->sd_memdata = rawdata;
+	    }
+	}
+    }
+    elf->e_data = data;
+    return 0;
+}
+
+#undef ptrinside
+#undef newptr
+
+static off_t
+_elf32_write(Elf *elf, char *outbuf, size_t len) {
+    Elf32_Ehdr *ehdr;
+    Elf32_Shdr *shdr;
+    Elf_Scn *scn;
+    Scn_Data *sd;
+    Elf_Data src;
+    Elf_Data dst;
+    unsigned encode;
+
+    elf_assert(len);
+    elf_assert(elf->e_ehdr);
+    ehdr = (Elf32_Ehdr*)elf->e_ehdr;
+    encode = ehdr->e_ident[EI_DATA];
+
+    src.d_buf = ehdr;
+    src.d_type = ELF_T_EHDR;
+    src.d_size = _msize(ELFCLASS32, _elf_version, ELF_T_EHDR);
+    src.d_version = _elf_version;
+    dst.d_buf = outbuf;
+    dst.d_size = ehdr->e_ehsize;
+    dst.d_version = ehdr->e_version;
+    if (!elf32_xlatetof(&dst, &src, encode)) {
+	return -1;
+    }
+
+    if (elf->e_phnum) {
+	src.d_buf = elf->e_phdr;
+	src.d_type = ELF_T_PHDR;
+	src.d_size = elf->e_phnum * _msize(ELFCLASS32, _elf_version, ELF_T_PHDR);
+	src.d_version = _elf_version;
+	dst.d_buf = outbuf + ehdr->e_phoff;
+	dst.d_size = elf->e_phnum * ehdr->e_phentsize;
+	dst.d_version = ehdr->e_version;
+	if (!elf32_xlatetof(&dst, &src, encode)) {
+	    return -1;
+	}
+    }
+
+    for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+	elf_assert(scn->s_magic == SCN_MAGIC);
+	elf_assert(scn->s_elf == elf);
+
+	src.d_buf = &scn->s_uhdr;
+	src.d_type = ELF_T_SHDR;
+	src.d_size = _msize(ELFCLASS32, EV_CURRENT, ELF_T_SHDR);
+	src.d_version = EV_CURRENT;
+	dst.d_buf = outbuf + ehdr->e_shoff + scn->s_index * ehdr->e_shentsize;
+	dst.d_size = ehdr->e_shentsize;
+	dst.d_version = ehdr->e_version;
+	if (!elf32_xlatetof(&dst, &src, encode)) {
+	    return -1;
+	}
+
+	if (scn->s_index == SHN_UNDEF) {
+	    continue;
+	}
+	shdr = &scn->s_shdr32;
+	if (shdr->sh_type == SHT_NULL || shdr->sh_type == SHT_NOBITS) {
+	    continue;
+	}
+	/* XXX: this is probably no longer necessary */
+	if (scn->s_data_1 && !elf_getdata(scn, NULL)) {
+	    return -1;
+	}
+	for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
+	    elf_assert(sd->sd_magic == DATA_MAGIC);
+	    elf_assert(sd->sd_scn == scn);
+	    src = sd->sd_data;
+	    if (!src.d_size) {
+		continue;
+	    }
+	    if (!src.d_buf) {
+		seterr(ERROR_NULLBUF);
+		return -1;
+	    }
+	    dst.d_buf = outbuf + shdr->sh_offset + src.d_off;
+	    dst.d_size = src.d_size;
+	    dst.d_version = ehdr->e_version;
+	    if (valid_type(src.d_type)) {
+		size_t tmp;
+
+		tmp = _elf32_xltsize(&src, dst.d_version, ELFDATA2LSB, 1);
+		if (tmp == (size_t)-1) {
+		    return -1;
+		}
+		dst.d_size = tmp;
+	    }
+	    else {
+		src.d_type = ELF_T_BYTE;
+	    }
+	    if (!elf32_xlatetof(&dst, &src, encode)) {
+		return -1;
+	    }
+	}
+    }
+
+    /* cleanup */
+    if (elf->e_readable && _elf_update_pointers(elf, outbuf, len)) {
+	return -1;
+    }
+    /* NOTE: ehdr is no longer valid! */
+    ehdr = (Elf32_Ehdr*)elf->e_ehdr; elf_assert(ehdr);
+    elf->e_encoding = ehdr->e_ident[EI_DATA];
+    elf->e_version = ehdr->e_ident[EI_VERSION];
+    elf->e_elf_flags &= ~ELF_F_DIRTY;
+    elf->e_ehdr_flags &= ~ELF_F_DIRTY;
+    elf->e_phdr_flags &= ~ELF_F_DIRTY;
+    for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+	scn->s_scn_flags &= ~ELF_F_DIRTY;
+	scn->s_shdr_flags &= ~ELF_F_DIRTY;
+	for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
+	    sd->sd_data_flags &= ~ELF_F_DIRTY;
+	}
+	if (elf->e_readable) {
+	    shdr = &scn->s_shdr32;
+	    scn->s_type = shdr->sh_type;
+	    scn->s_size = shdr->sh_size;
+	    scn->s_offset = shdr->sh_offset;
+	}
+    }
+    elf->e_size = len;
+    return len;
+}
+
+#if __LIBELF64
+
+static off_t
+_elf64_write(Elf *elf, char *outbuf, size_t len) {
+    Elf64_Ehdr *ehdr;
+    Elf64_Shdr *shdr;
+    Elf_Scn *scn;
+    Scn_Data *sd;
+    Elf_Data src;
+    Elf_Data dst;
+    unsigned encode;
+
+    elf_assert(len);
+    elf_assert(elf->e_ehdr);
+    ehdr = (Elf64_Ehdr*)elf->e_ehdr;
+    encode = ehdr->e_ident[EI_DATA];
+
+    src.d_buf = ehdr;
+    src.d_type = ELF_T_EHDR;
+    src.d_size = _msize(ELFCLASS64, _elf_version, ELF_T_EHDR);
+    src.d_version = _elf_version;
+    dst.d_buf = outbuf;
+    dst.d_size = ehdr->e_ehsize;
+    dst.d_version = ehdr->e_version;
+    if (!elf64_xlatetof(&dst, &src, encode)) {
+	return -1;
+    }
+
+    if (elf->e_phnum) {
+	src.d_buf = elf->e_phdr;
+	src.d_type = ELF_T_PHDR;
+	src.d_size = elf->e_phnum * _msize(ELFCLASS64, _elf_version, ELF_T_PHDR);
+	src.d_version = _elf_version;
+	dst.d_buf = outbuf + ehdr->e_phoff;
+	dst.d_size = elf->e_phnum * ehdr->e_phentsize;
+	dst.d_version = ehdr->e_version;
+	if (!elf64_xlatetof(&dst, &src, encode)) {
+	    return -1;
+	}
+    }
+
+    for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+	elf_assert(scn->s_magic == SCN_MAGIC);
+	elf_assert(scn->s_elf == elf);
+
+	src.d_buf = &scn->s_uhdr;
+	src.d_type = ELF_T_SHDR;
+	src.d_size = _msize(ELFCLASS64, EV_CURRENT, ELF_T_SHDR);
+	src.d_version = EV_CURRENT;
+	dst.d_buf = outbuf + ehdr->e_shoff + scn->s_index * ehdr->e_shentsize;
+	dst.d_size = ehdr->e_shentsize;
+	dst.d_version = ehdr->e_version;
+	if (!elf64_xlatetof(&dst, &src, encode)) {
+	    return -1;
+	}
+
+	if (scn->s_index == SHN_UNDEF) {
+	    continue;
+	}
+	shdr = &scn->s_shdr64;
+	if (shdr->sh_type == SHT_NULL || shdr->sh_type == SHT_NOBITS) {
+	    continue;
+	}
+	/* XXX: this is probably no longer necessary */
+	if (scn->s_data_1 && !elf_getdata(scn, NULL)) {
+	    return -1;
+	}
+	for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
+	    elf_assert(sd->sd_magic == DATA_MAGIC);
+	    elf_assert(sd->sd_scn == scn);
+	    src = sd->sd_data;
+	    if (!src.d_size) {
+		continue;
+	    }
+	    if (!src.d_buf) {
+		seterr(ERROR_NULLBUF);
+		return -1;
+	    }
+	    dst.d_buf = outbuf + shdr->sh_offset + src.d_off;
+	    dst.d_size = src.d_size;
+	    dst.d_version = ehdr->e_version;
+	    if (valid_type(src.d_type)) {
+		size_t tmp;
+
+		tmp = _elf64_xltsize(&src, dst.d_version, ELFDATA2LSB, 1);
+		if (tmp == (size_t)-1) {
+		    return -1;
+		}
+		dst.d_size = tmp;
+	    }
+	    else {
+		src.d_type = ELF_T_BYTE;
+	    }
+	    if (!elf64_xlatetof(&dst, &src, encode)) {
+		return -1;
+	    }
+	}
+    }
+
+    /* cleanup */
+    if (elf->e_readable && _elf_update_pointers(elf, outbuf, len)) {
+	return -1;
+    }
+    /* NOTE: ehdr is no longer valid! */
+    ehdr = (Elf64_Ehdr*)elf->e_ehdr; elf_assert(ehdr);
+    elf->e_encoding = ehdr->e_ident[EI_DATA];
+    elf->e_version = ehdr->e_ident[EI_VERSION];
+    elf->e_elf_flags &= ~ELF_F_DIRTY;
+    elf->e_ehdr_flags &= ~ELF_F_DIRTY;
+    elf->e_phdr_flags &= ~ELF_F_DIRTY;
+    for (scn = elf->e_scn_1; scn; scn = scn->s_link) {
+	scn->s_scn_flags &= ~ELF_F_DIRTY;
+	scn->s_shdr_flags &= ~ELF_F_DIRTY;
+	for (sd = scn->s_data_1; sd; sd = sd->sd_link) {
+	    sd->sd_data_flags &= ~ELF_F_DIRTY;
+	}
+	if (elf->e_readable) {
+	    shdr = &scn->s_shdr64;
+	    scn->s_type = shdr->sh_type;
+	    scn->s_size = shdr->sh_size;
+	    scn->s_offset = shdr->sh_offset;
+	}
+    }
+    elf->e_size = len;
+    return len;
+}
+
+#endif /* __LIBELF64 */
+
+static int
+xwrite(int fd, char *buffer, size_t len) {
+    size_t done = 0;
+    size_t n;
+
+    while (done < len) {
+	n = write(fd, buffer + done, len - done);
+	if (n == 0) {
+	    /* file system full */
+	    return -1;
+	}
+	else if (n != (size_t)-1) {
+	    /* some bytes written, continue */
+	    done += n;
+	}
+	else if (errno != EAGAIN && errno != EINTR) {
+	    /* real error */
+	    return -1;
+	}
+    }
+    return 0;
+}
+
+static off_t
+_elf_output(Elf *elf, int fd, size_t len, off_t (*_elf_write)(Elf*, char*, size_t)) {
+    char *buf;
+    off_t err;
+
+    elf_assert(len);
+#if HAVE_FTRUNCATE
+    ftruncate(fd, 0);
+#endif /* HAVE_FTRUNCATE */
+#if HAVE_MMAP
+    /*
+     * Make sure the file is (at least) len bytes long
+     */
+#if HAVE_FTRUNCATE
+    lseek(fd, (off_t)len, SEEK_SET);
+    if (ftruncate(fd, len)) {
+#else /* HAVE_FTRUNCATE */
+    {
+#endif /* HAVE_FTRUNCATE */
+	if (lseek(fd, (off_t)len - 1, SEEK_SET) != (off_t)len - 1) {
+	    seterr(ERROR_IO_SEEK);
+	    return -1;
+	}
+	if (xwrite(fd, "", 1)) {
+	    seterr(ERROR_IO_WRITE);
+	    return -1;
+	}
+    }
+    buf = (void*)mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+    if (buf != (char*)-1) {
+	if ((char)_elf_fill && !(elf->e_elf_flags & ELF_F_LAYOUT)) {
+	    memset(buf, _elf_fill, len);
+	}
+	err = _elf_write(elf, buf, len);
+	munmap(buf, len);
+	return err;
+    }
+#endif /* HAVE_MMAP */
+    if (!(buf = (char*)malloc(len))) {
+	seterr(ERROR_MEM_OUTBUF);
+	return -1;
+    }
+    memset(buf, _elf_fill, len);
+    err = _elf_write(elf, buf, len);
+    if (err != -1 && (size_t)err == len) {
+	if (lseek(fd, (off_t)0, SEEK_SET)) {
+	    seterr(ERROR_IO_SEEK);
+	    err = -1;
+	}
+	else if (xwrite(fd, buf, len)) {
+	    seterr(ERROR_IO_WRITE);
+	    err = -1;
+	}
+    }
+    free(buf);
+    return err;
+}
+
+off_t
+elf_update(Elf *elf, Elf_Cmd cmd) {
+    unsigned flag;
+    off_t len;
+
+    if (!elf) {
+	return -1;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (cmd == ELF_C_WRITE) {
+	if (!elf->e_writable) {
+	    seterr(ERROR_RDONLY);
+	    return -1;
+	}
+	if (elf->e_disabled) {
+	    seterr(ERROR_FDDISABLED);
+	    return -1;
+	}
+    }
+    else if (cmd != ELF_C_NULL) {
+	seterr(ERROR_INVALID_CMD);
+	return -1;
+    }
+
+    if (!elf->e_ehdr) {
+	seterr(ERROR_NOEHDR);
+    }
+    else if (elf->e_kind != ELF_K_ELF) {
+	seterr(ERROR_NOTELF);
+    }
+    else if (elf->e_class == ELFCLASS32) {
+	len = _elf32_layout(elf, &flag);
+	if (len != -1 && cmd == ELF_C_WRITE && (flag & ELF_F_DIRTY)) {
+	    len = _elf_output(elf, elf->e_fd, (size_t)len, _elf32_write);
+	}
+	return len;
+    }
+#if __LIBELF64
+    else if (elf->e_class == ELFCLASS64) {
+	len = _elf64_layout(elf, &flag);
+	if (len != -1 && cmd == ELF_C_WRITE && (flag & ELF_F_DIRTY)) {
+	    len = _elf_output(elf, elf->e_fd, (size_t)len, _elf64_write);
+	}
+	return len;
+    }
+#endif /* __LIBELF64 */
+    else if (valid_class(elf->e_class)) {
+	seterr(ERROR_UNIMPLEMENTED);
+    }
+    else {
+	seterr(ERROR_UNKNOWN_CLASS);
+    }
+    return -1;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/verdef.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,241 @@
+/*
+ * verdef.h - copy versioning information.
+ * Copyright (C) 2001 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef lint
+static const char verdef_h_rcsid[] = "@(#) $Id: verdef.h,v 1.12 2006/07/27 22:56:11 michael Exp $";
+#endif /* lint */
+
+#if VER_DEF_CURRENT != 1
+#error libelf currently does not support VER_DEF_CURRENT != 1
+#endif /* VER_DEF_CURRENT != 1 */
+
+#if TOFILE
+
+static void
+__store_verdaux(verdaux_ftype *dst, const verdaux_mtype *src, unsigned enc) {
+    if (enc == ELFDATA2LSB) {
+	__store_u32L(dst->vda_name, src->vda_name);
+	__store_u32L(dst->vda_next, src->vda_next);
+    }
+    else {
+	__store_u32M(dst->vda_name, src->vda_name);
+	__store_u32M(dst->vda_next, src->vda_next);
+    }
+}
+
+static void
+__store_verdef(verdef_ftype *dst, const verdef_mtype *src, unsigned enc) {
+    if (enc == ELFDATA2LSB) {
+	__store_u16L(dst->vd_version, src->vd_version);
+	__store_u16L(dst->vd_flags,   src->vd_flags);
+	__store_u16L(dst->vd_ndx,     src->vd_ndx);
+	__store_u16L(dst->vd_cnt,     src->vd_cnt);
+	__store_u32L(dst->vd_hash,    src->vd_hash);
+	__store_u32L(dst->vd_aux,     src->vd_aux);
+	__store_u32L(dst->vd_next,    src->vd_next);
+    }
+    else {
+	__store_u16M(dst->vd_version, src->vd_version);
+	__store_u16M(dst->vd_flags,   src->vd_flags);
+	__store_u16M(dst->vd_ndx,     src->vd_ndx);
+	__store_u16M(dst->vd_cnt,     src->vd_cnt);
+	__store_u32M(dst->vd_hash,    src->vd_hash);
+	__store_u32M(dst->vd_aux,     src->vd_aux);
+	__store_u32M(dst->vd_next,    src->vd_next);
+    }
+}
+
+typedef verdaux_mtype		verdaux_stype;
+typedef verdaux_ftype		verdaux_dtype;
+typedef verdef_mtype		verdef_stype;
+typedef verdef_ftype		verdef_dtype;
+typedef align_mtype		verdef_atype;
+
+#define copy_verdaux_srctotmp(d, s, e)	(*(d) = *(s))
+#define copy_verdaux_tmptodst(d, s, e)	__store_verdaux((d), (s), (e))
+#define copy_verdef_srctotmp(d, s, e)	(*(d) = *(s))
+#define copy_verdef_tmptodst(d, s, e)	__store_verdef((d), (s), (e))
+
+#define translator_suffix	_tof
+
+#else /* TOFILE */
+
+static void
+__load_verdaux(verdaux_mtype *dst, const verdaux_ftype *src, unsigned enc) {
+    if (enc == ELFDATA2LSB) {
+	dst->vda_name = __load_u32L(src->vda_name);
+	dst->vda_next = __load_u32L(src->vda_next);
+    }
+    else {
+	dst->vda_name = __load_u32M(src->vda_name);
+	dst->vda_next = __load_u32M(src->vda_next);
+    }
+}
+
+static void
+__load_verdef(verdef_mtype *dst, const verdef_ftype *src, unsigned enc) {
+    if (enc == ELFDATA2LSB) {
+	dst->vd_version = __load_u16L(src->vd_version);
+	dst->vd_flags   = __load_u16L(src->vd_flags);
+	dst->vd_ndx     = __load_u16L(src->vd_ndx);
+	dst->vd_cnt     = __load_u16L(src->vd_cnt);
+	dst->vd_hash    = __load_u32L(src->vd_hash);
+	dst->vd_aux     = __load_u32L(src->vd_aux);
+	dst->vd_next    = __load_u32L(src->vd_next);
+    }
+    else {
+	dst->vd_version = __load_u16M(src->vd_version);
+	dst->vd_flags   = __load_u16M(src->vd_flags);
+	dst->vd_ndx     = __load_u16M(src->vd_ndx);
+	dst->vd_cnt     = __load_u16M(src->vd_cnt);
+	dst->vd_hash    = __load_u32M(src->vd_hash);
+	dst->vd_aux     = __load_u32M(src->vd_aux);
+	dst->vd_next    = __load_u32M(src->vd_next);
+    }
+}
+
+typedef verdaux_ftype		verdaux_stype;
+typedef verdaux_mtype		verdaux_dtype;
+typedef verdef_ftype		verdef_stype;
+typedef verdef_mtype		verdef_dtype;
+typedef align_ftype		verdef_atype;
+
+#define copy_verdaux_srctotmp(d, s, e)	__load_verdaux((d), (s), (e))
+#define copy_verdaux_tmptodst(d, s, e)	(*(d) = *(s))
+#define copy_verdef_srctotmp(d, s, e)	__load_verdef((d), (s), (e))
+#define copy_verdef_tmptodst(d, s, e)	(*(d) = *(s))
+
+#define translator_suffix	_tom
+
+#endif /* TOFILE */
+
+#define cat3(a,b,c)	a##b##c
+#define xlt3(p,e,s)	cat3(p,e,s)
+#define xltprefix(x)	xlt3(x,_,class_suffix)
+#define translator(x,e)	xlt3(xltprefix(_elf_##x),e,translator_suffix)
+
+static size_t
+xlt_verdef(unsigned char *dst, const unsigned char *src, size_t n, unsigned enc) {
+    size_t off;
+
+    if (sizeof(verdef_stype) != sizeof(verdef_dtype)
+     || sizeof(verdaux_stype) != sizeof(verdaux_dtype)) {
+	/* never happens for ELF v1 and Verneed v1 */
+	seterr(ERROR_UNIMPLEMENTED);
+	return (size_t)-1;
+    }
+    /* size translation shortcut */
+    if (dst == NULL) {
+	return n;
+    }
+    if (src == NULL) {
+	seterr(ERROR_NULLBUF);
+	return (size_t)-1;
+    }
+    off = 0;
+    while (off + sizeof(verdef_stype) <= n) {
+	const verdef_stype *svd;
+	verdef_dtype *dvd;
+	verdef_mtype vd;
+	size_t acount;
+	size_t aoff;
+
+	/*
+	 * check for proper alignment
+	 */
+	if (off % sizeof(verdef_atype)) {
+	    seterr(ERROR_VERDEF_FORMAT);
+	    return (size_t)-1;
+	}
+	/*
+	 * copy and check src
+	 */
+	svd = (verdef_stype*)(src + off);
+	dvd = (verdef_dtype*)(dst + off);
+	copy_verdef_srctotmp(&vd, svd, enc);
+	if (vd.vd_version < 1
+	 || vd.vd_version > VER_DEF_CURRENT) {
+	    seterr(ERROR_VERDEF_VERSION);
+	    return (size_t)-1;
+	}
+	if (vd.vd_cnt < 1
+	 || vd.vd_aux == 0) {
+	    seterr(ERROR_VERDEF_FORMAT);
+	    return (size_t)-1;
+	}
+	copy_verdef_tmptodst(dvd, &vd, enc);
+	/*
+	 * copy aux array
+	 */
+	aoff = off + vd.vd_aux;
+	for (acount = 0; acount < vd.vd_cnt; acount++) {
+	    const verdaux_stype *svda;
+	    verdaux_dtype *dvda;
+	    verdaux_mtype vda;
+
+	    /*
+	     * are we still inside the buffer limits?
+	     */
+	    if (aoff + sizeof(verdaux_stype) > n) {
+		break;
+	    }
+	    /*
+	     * check for proper alignment
+	     */
+	    if (aoff % sizeof(verdef_atype)) {
+		seterr(ERROR_VERDEF_FORMAT);
+		return (size_t)-1;
+	    }
+	    /*
+	     * copy and check src
+	     */
+	    svda = (verdaux_stype*)(src + aoff);
+	    dvda = (verdaux_dtype*)(dst + aoff);
+	    copy_verdaux_srctotmp(&vda, svda, enc);
+	    copy_verdaux_tmptodst(dvda, &vda, enc);
+	    /*
+	     * advance to next verdaux
+	     */
+	    if (vda.vda_next == 0) {
+		/* end of list */
+		break;
+	    }
+	    aoff += vda.vda_next;
+	}
+	/*
+	 * advance to next verdef
+	 */
+	if (vd.vd_next == 0) {
+	    /* end of list */
+	    break;
+	}
+	off += vd.vd_next;
+    }
+    return n;
+}
+
+size_t
+translator(verdef,L11)(unsigned char *dst, const unsigned char *src, size_t n) {
+    return xlt_verdef(dst, src, n, ELFDATA2LSB);
+}
+
+size_t
+translator(verdef,M11)(unsigned char *dst, const unsigned char *src, size_t n) {
+    return xlt_verdef(dst, src, n, ELFDATA2MSB);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/verdef_32_tof.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,53 @@
+/*
+verdef_32_tof.c - copy 32-bit versioning information.
+Copyright (C) 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+#include <ext_types.h>
+#include <byteswap.h>
+
+#if __LIBELF_SYMBOL_VERSIONS
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: verdef_32_tof.c,v 1.4 2005/05/21 15:39:26 michael Exp $";
+#endif /* lint */
+
+typedef Elf32_Verdaux		verdaux_mtype;
+typedef Elf32_Verdef		verdef_mtype;
+typedef Elf32_Vernaux		vernaux_mtype;
+typedef Elf32_Verneed		verneed_mtype;
+typedef Elf32_Word		align_mtype;
+
+typedef __ext_Elf32_Verdaux	verdaux_ftype;
+typedef __ext_Elf32_Verdef	verdef_ftype;
+typedef __ext_Elf32_Vernaux	vernaux_ftype;
+typedef __ext_Elf32_Verneed	verneed_ftype;
+typedef __ext_Elf32_Word	align_ftype;
+
+#define class_suffix		32
+
+#undef TOFILE
+#define TOFILE 1
+
+/*
+ * Include shared code
+ */
+#include "verdef.h"
+#include "verneed.h"
+
+#endif /* __LIBELF_SYMBOL_VERSIONS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/verdef_32_tom.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,53 @@
+/*
+verdef_32_tom.c - copy 32-bit versioning information.
+Copyright (C) 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+#include <ext_types.h>
+#include <byteswap.h>
+
+#if __LIBELF_SYMBOL_VERSIONS
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: verdef_32_tom.c,v 1.4 2005/05/21 15:39:27 michael Exp $";
+#endif /* lint */
+
+typedef Elf32_Verdaux		verdaux_mtype;
+typedef Elf32_Verdef		verdef_mtype;
+typedef Elf32_Vernaux		vernaux_mtype;
+typedef Elf32_Verneed		verneed_mtype;
+typedef Elf32_Word		align_mtype;
+
+typedef __ext_Elf32_Verdaux	verdaux_ftype;
+typedef __ext_Elf32_Verdef	verdef_ftype;
+typedef __ext_Elf32_Vernaux	vernaux_ftype;
+typedef __ext_Elf32_Verneed	verneed_ftype;
+typedef __ext_Elf32_Word	align_ftype;
+
+#define class_suffix		32
+
+#undef TOFILE
+#define TOFILE 0
+
+/*
+ * Include shared code
+ */
+#include "verdef.h"
+#include "verneed.h"
+
+#endif /* __LIBELF_SYMBOL_VERSIONS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/verdef_64_tof.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,53 @@
+/*
+verdef_64_tof.c - copy 64-bit versioning information.
+Copyright (C) 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+#include <ext_types.h>
+#include <byteswap.h>
+
+#if __LIBELF64 && __LIBELF_SYMBOL_VERSIONS
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: verdef_64_tof.c,v 1.4 2005/05/21 15:39:27 michael Exp $";
+#endif /* lint */
+
+typedef Elf64_Verdaux		verdaux_mtype;
+typedef Elf64_Verdef		verdef_mtype;
+typedef Elf64_Vernaux		vernaux_mtype;
+typedef Elf64_Verneed		verneed_mtype;
+typedef Elf64_Word		align_mtype;
+
+typedef __ext_Elf64_Verdaux	verdaux_ftype;
+typedef __ext_Elf64_Verdef	verdef_ftype;
+typedef __ext_Elf64_Vernaux	vernaux_ftype;
+typedef __ext_Elf64_Verneed	verneed_ftype;
+typedef __ext_Elf64_Word	align_ftype;
+
+#define class_suffix		64
+
+#undef TOFILE
+#define TOFILE 1
+
+/*
+ * Include shared code
+ */
+#include "verdef.h"
+#include "verneed.h"
+
+#endif /* __LIBELF64 && __LIBELF_SYMBOL_VERSIONS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/verdef_64_tom.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,53 @@
+/*
+verdef_64_tom.c - copy 64-bit versioning information.
+Copyright (C) 2001 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+#include <ext_types.h>
+#include <byteswap.h>
+
+#if __LIBELF64 && __LIBELF_SYMBOL_VERSIONS
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: verdef_64_tom.c,v 1.4 2005/05/21 15:39:27 michael Exp $";
+#endif /* lint */
+
+typedef Elf64_Verdaux		verdaux_mtype;
+typedef Elf64_Verdef		verdef_mtype;
+typedef Elf64_Vernaux		vernaux_mtype;
+typedef Elf64_Verneed		verneed_mtype;
+typedef Elf64_Word		align_mtype;
+
+typedef __ext_Elf64_Verdaux	verdaux_ftype;
+typedef __ext_Elf64_Verdef	verdef_ftype;
+typedef __ext_Elf64_Vernaux	vernaux_ftype;
+typedef __ext_Elf64_Verneed	verneed_ftype;
+typedef __ext_Elf64_Word	align_ftype;
+
+#define class_suffix		64
+
+#undef TOFILE
+#define TOFILE 0
+
+/*
+ * Include shared code
+ */
+#include "verdef.h"
+#include "verneed.h"
+
+#endif /* __LIBELF64 && __LIBELF_SYMBOL_VERSIONS */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/verneed.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,245 @@
+/*
+ * verneed.h - copy versioning information.
+ * Copyright (C) 2001 - 2006 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef lint
+static const char verneed_h_rcsid[] = "@(#) $Id: verneed.h,v 1.12 2006/07/27 22:40:03 michael Exp $";
+#endif /* lint */
+
+#if VER_NEED_CURRENT != 1
+#error libelf currently does not support VER_NEED_CURRENT != 1
+#endif /* VER_NEED_CURRENT != 1 */
+
+#if TOFILE
+
+static void
+__store_vernaux(vernaux_ftype *dst, const vernaux_mtype *src, unsigned enc) {
+    if (enc == ELFDATA2LSB) {
+	__store_u32L(dst->vna_hash,  src->vna_hash);
+	__store_u16L(dst->vna_flags, src->vna_flags);
+	__store_u16L(dst->vna_other, src->vna_other);
+	__store_u32L(dst->vna_name,  src->vna_name);
+	__store_u32L(dst->vna_next,  src->vna_next);
+    }
+    else {
+	__store_u32M(dst->vna_hash,  src->vna_hash);
+	__store_u16M(dst->vna_flags, src->vna_flags);
+	__store_u16M(dst->vna_other, src->vna_other);
+	__store_u32M(dst->vna_name,  src->vna_name);
+	__store_u32M(dst->vna_next,  src->vna_next);
+    }
+}
+
+static void
+__store_verneed(verneed_ftype *dst, const verneed_mtype *src, unsigned enc) {
+    if (enc == ELFDATA2LSB) {
+	__store_u16L(dst->vn_version, src->vn_version);
+	__store_u16L(dst->vn_cnt,     src->vn_cnt);
+	__store_u32L(dst->vn_file,    src->vn_file);
+	__store_u32L(dst->vn_aux,     src->vn_aux);
+	__store_u32L(dst->vn_next,    src->vn_next);
+    }
+    else {
+	__store_u16M(dst->vn_version, src->vn_version);
+	__store_u16M(dst->vn_cnt,     src->vn_cnt);
+	__store_u32M(dst->vn_file,    src->vn_file);
+	__store_u32M(dst->vn_aux,     src->vn_aux);
+	__store_u32M(dst->vn_next,    src->vn_next);
+    }
+}
+
+typedef vernaux_mtype		vernaux_stype;
+typedef vernaux_ftype		vernaux_dtype;
+typedef verneed_mtype		verneed_stype;
+typedef verneed_ftype		verneed_dtype;
+typedef align_mtype		verneed_atype;
+
+#define copy_vernaux_srctotmp(d, s, e)	(*(d) = *(s))
+#define copy_vernaux_tmptodst(d, s, e)	__store_vernaux((d), (s), (e))
+#define copy_verneed_srctotmp(d, s, e)	(*(d) = *(s))
+#define copy_verneed_tmptodst(d, s, e)	__store_verneed((d), (s), (e))
+
+#define translator_suffix	_tof
+
+#else /* TOFILE */
+
+static void
+__load_vernaux(vernaux_mtype *dst, const vernaux_ftype *src, unsigned enc) {
+    if (enc == ELFDATA2LSB) {
+	dst->vna_hash  = __load_u32L(src->vna_hash);
+	dst->vna_flags = __load_u16L(src->vna_flags);
+	dst->vna_other = __load_u16L(src->vna_other);
+	dst->vna_name  = __load_u32L(src->vna_name);
+	dst->vna_next  = __load_u32L(src->vna_next);
+    }
+    else {
+	dst->vna_hash  = __load_u32M(src->vna_hash);
+	dst->vna_flags = __load_u16M(src->vna_flags);
+	dst->vna_other = __load_u16M(src->vna_other);
+	dst->vna_name  = __load_u32M(src->vna_name);
+	dst->vna_next  = __load_u32M(src->vna_next);
+    }
+}
+
+static void
+__load_verneed(verneed_mtype *dst, const verneed_ftype *src, unsigned enc) {
+    if (enc == ELFDATA2LSB) {
+	dst->vn_version = __load_u16L(src->vn_version);
+	dst->vn_cnt     = __load_u16L(src->vn_cnt);
+	dst->vn_file    = __load_u32L(src->vn_file);
+	dst->vn_aux     = __load_u32L(src->vn_aux);
+	dst->vn_next    = __load_u32L(src->vn_next);
+    }
+    else {
+	dst->vn_version = __load_u16M(src->vn_version);
+	dst->vn_cnt     = __load_u16M(src->vn_cnt);
+	dst->vn_file    = __load_u32M(src->vn_file);
+	dst->vn_aux     = __load_u32M(src->vn_aux);
+	dst->vn_next    = __load_u32M(src->vn_next);
+    }
+}
+
+typedef vernaux_ftype		vernaux_stype;
+typedef vernaux_mtype		vernaux_dtype;
+typedef verneed_ftype		verneed_stype;
+typedef verneed_mtype		verneed_dtype;
+typedef align_ftype		verneed_atype;
+
+#define copy_vernaux_srctotmp(d, s, e)	__load_vernaux((d), (s), (e))
+#define copy_vernaux_tmptodst(d, s, e)	(*(d) = *(s))
+#define copy_verneed_srctotmp(d, s, e)	__load_verneed((d), (s), (e))
+#define copy_verneed_tmptodst(d, s, e)	(*(d) = *(s))
+
+#define translator_suffix	_tom
+
+#endif /* TOFILE */
+
+#define cat3(a,b,c)	a##b##c
+#define xlt3(p,e,s)	cat3(p,e,s)
+#define xltprefix(x)	xlt3(x,_,class_suffix)
+#define translator(x,e)	xlt3(xltprefix(_elf_##x),e,translator_suffix)
+
+static size_t
+xlt_verneed(unsigned char *dst, const unsigned char *src, size_t n, unsigned enc) {
+    size_t off;
+
+    if (sizeof(verneed_stype) != sizeof(verneed_dtype)
+     || sizeof(vernaux_stype) != sizeof(vernaux_dtype)) {
+	/* never happens for ELF v1 and Verneed v1 */
+	seterr(ERROR_UNIMPLEMENTED);
+	return (size_t)-1;
+    }
+    /* size translation shortcut */
+    if (dst == NULL) {
+	return n;
+    }
+    if (src == NULL) {
+	seterr(ERROR_NULLBUF);
+	return (size_t)-1;
+    }
+    off = 0;
+    while (off + sizeof(verneed_stype) <= n) {
+	const verneed_stype *svn;
+	verneed_dtype *dvn;
+	verneed_mtype vn;
+	size_t acount;
+	size_t aoff;
+
+	/*
+	 * check for proper alignment
+	 */
+	if (off % sizeof(verneed_atype)) {
+	    seterr(ERROR_VERNEED_FORMAT);
+	    return (size_t)-1;
+	}
+	/*
+	 * copy and check src
+	 */
+	svn = (verneed_stype*)(src + off);
+	dvn = (verneed_dtype*)(dst + off);
+	copy_verneed_srctotmp(&vn, svn, enc);
+	if (vn.vn_version < 1
+	 || vn.vn_version > VER_NEED_CURRENT) {
+	    seterr(ERROR_VERNEED_VERSION);
+	    return (size_t)-1;
+	}
+	if (vn.vn_cnt < 1
+	 || vn.vn_aux == 0) {
+	    seterr(ERROR_VERNEED_FORMAT);
+	    return (size_t)-1;
+	}
+	copy_verneed_tmptodst(dvn, &vn, enc);
+	/*
+	 * copy aux array
+	 */
+	aoff = off + vn.vn_aux;
+	for (acount = 0; acount < vn.vn_cnt; acount++) {
+	    const vernaux_stype *svna;
+	    vernaux_dtype *dvna;
+	    vernaux_mtype vna;
+
+	    /*
+	     * are we still inside the buffer limits?
+	     */
+	    if (aoff + sizeof(vernaux_stype) > n) {
+		break;
+	    }
+	    /*
+	     * check for proper alignment
+	     */
+	    if (aoff % sizeof(verneed_atype)) {
+		seterr(ERROR_VERNEED_FORMAT);
+		return (size_t)-1;
+	    }
+	    /*
+	     * copy and check src
+	     */
+	    svna = (vernaux_stype*)(src + aoff);
+	    dvna = (vernaux_dtype*)(dst + aoff);
+	    copy_vernaux_srctotmp(&vna, svna, enc);
+	    copy_vernaux_tmptodst(dvna, &vna, enc);
+	    /*
+	     * advance to next vernaux
+	     */
+	    if (vna.vna_next == 0) {
+		/* end of list */
+		break;
+	    }
+	    aoff += vna.vna_next;
+	}
+	/*
+	 * advance to next verneed
+	 */
+	if (vn.vn_next == 0) {
+	    /* end of list */
+	    break;
+	}
+	off += vn.vn_next;
+    }
+    return n;
+}
+
+size_t
+translator(verneed,L11)(unsigned char *dst, const unsigned char *src, size_t n) {
+    return xlt_verneed(dst, src, n, ELFDATA2LSB);
+}
+
+size_t
+translator(verneed,M11)(unsigned char *dst, const unsigned char *src, size_t n) {
+    return xlt_verneed(dst, src, n, ELFDATA2MSB);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/version.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,44 @@
+/*
+ * version.c - implementation of the elf_version(3) function.
+ * Copyright (C) 1995 - 1998, 2007 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: version.c,v 1.7 2007/09/07 12:07:59 michael Exp $";
+#endif /* lint */
+
+unsigned
+elf_version(unsigned ver) {
+    const char *s;
+    unsigned tmp;
+
+    if ((s = getenv("LIBELF_SANITY_CHECKS"))) {
+	_elf_sanity_checks = (int)strtol(s, (char**)NULL, 0);
+    }
+    if (ver == EV_NONE) {
+	return EV_CURRENT;
+    }
+    if (!valid_version(ver)) {
+	seterr(ERROR_UNKNOWN_VERSION);
+	return EV_NONE;
+    }
+    tmp = _elf_version == EV_NONE ? EV_CURRENT : _elf_version;
+    _elf_version = ver;
+    return tmp;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/x.elfext.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,175 @@
+/*
+ * x.elfext.c -- handle ELF format extensions
+ * Copyright (C) 2002 - 2006 Michael Riepe
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Library General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: x.elfext.c,v 1.3 2006/07/07 22:17:50 michael Exp $";
+#endif /* lint */
+
+int
+elf_getphnum(Elf *elf, size_t *resultp) {
+    if (!elf) {
+	return LIBELF_FAILURE;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (elf->e_kind != ELF_K_ELF) {
+	seterr(ERROR_NOTELF);
+	return LIBELF_FAILURE;
+    }
+    if (!elf->e_ehdr && !_elf_cook(elf)) {
+	return LIBELF_FAILURE;
+    }
+    if (resultp) {
+	*resultp = elf->e_phnum;
+    }
+    return LIBELF_SUCCESS;
+}
+
+int
+elf_getshnum(Elf *elf, size_t *resultp) {
+    size_t num = 0;
+    Elf_Scn *scn;
+
+    if (!elf) {
+	return LIBELF_FAILURE;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (elf->e_kind != ELF_K_ELF) {
+	seterr(ERROR_NOTELF);
+	return LIBELF_FAILURE;
+    }
+    if (!elf->e_ehdr && !_elf_cook(elf)) {
+	return LIBELF_FAILURE;
+    }
+    if ((scn = elf->e_scn_n)) {
+	num = scn->s_index + 1;
+    }
+    if (resultp) {
+	*resultp = num;
+    }
+    return LIBELF_SUCCESS;
+}
+
+int
+elf_getshstrndx(Elf *elf, size_t *resultp) {
+    size_t num = 0;
+    size_t dummy;
+    Elf_Scn *scn;
+
+    if (!elf) {
+	return LIBELF_FAILURE;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (resultp == NULL) {
+	resultp = &dummy;	/* handle NULL pointer gracefully */
+    }
+    if (elf->e_kind != ELF_K_ELF) {
+	seterr(ERROR_NOTELF);
+	return LIBELF_FAILURE;
+    }
+    if (!elf->e_ehdr && !_elf_cook(elf)) {
+	return LIBELF_FAILURE;
+    }
+    if (elf->e_class == ELFCLASS32) {
+	num = ((Elf32_Ehdr*)elf->e_ehdr)->e_shstrndx;
+    }
+#if __LIBELF64
+    else if (elf->e_class == ELFCLASS64) {
+	num = ((Elf64_Ehdr*)elf->e_ehdr)->e_shstrndx;
+    }
+#endif /* __LIBELF64 */
+    else {
+	if (valid_class(elf->e_class)) {
+	    seterr(ERROR_UNIMPLEMENTED);
+	}
+	else {
+	    seterr(ERROR_UNKNOWN_CLASS);
+	}
+	return LIBELF_FAILURE;
+    }
+    if (num != SHN_XINDEX) {
+	*resultp = num;
+	return LIBELF_SUCCESS;
+    }
+    /*
+     * look at first section header
+     */
+    if (!(scn = elf->e_scn_1)) {
+	seterr(ERROR_NOSUCHSCN);
+	return LIBELF_FAILURE;
+    }
+    elf_assert(scn->s_magic == SCN_MAGIC);
+#if __LIBELF64
+    if (elf->e_class == ELFCLASS64) {
+	*resultp = scn->s_shdr64.sh_link;
+	return LIBELF_SUCCESS;
+    }
+#endif /* __LIBELF64 */
+    *resultp = scn->s_shdr32.sh_link;
+    return LIBELF_SUCCESS;
+}
+
+int
+elfx_update_shstrndx(Elf *elf, size_t value) {
+    size_t extvalue = 0;
+    Elf_Scn *scn;
+
+    if (!elf) {
+	return LIBELF_FAILURE;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (value >= SHN_LORESERVE) {
+	extvalue = value;
+	value = SHN_XINDEX;
+    }
+    if (elf->e_kind != ELF_K_ELF) {
+	seterr(ERROR_NOTELF);
+	return LIBELF_FAILURE;
+    }
+    if (!elf->e_ehdr && !_elf_cook(elf)) {
+	return LIBELF_FAILURE;
+    }
+    if (!(scn = _elf_first_scn(elf))) {
+	return LIBELF_FAILURE;
+    }
+    elf_assert(scn->s_magic == SCN_MAGIC);
+    if (elf->e_class == ELFCLASS32) {
+	((Elf32_Ehdr*)elf->e_ehdr)->e_shstrndx = value;
+	scn->s_shdr32.sh_link = extvalue;
+    }
+#if __LIBELF64
+    else if (elf->e_class == ELFCLASS64) {
+	((Elf64_Ehdr*)elf->e_ehdr)->e_shstrndx = value;
+	scn->s_shdr64.sh_link = extvalue;
+    }
+#endif /* __LIBELF64 */
+    else {
+	if (valid_class(elf->e_class)) {
+	    seterr(ERROR_UNIMPLEMENTED);
+	}
+	else {
+	    seterr(ERROR_UNKNOWN_CLASS);
+	}
+	return LIBELF_FAILURE;
+    }
+    elf->e_ehdr_flags |= ELF_F_DIRTY;
+    scn->s_shdr_flags |= ELF_F_DIRTY;
+    return LIBELF_SUCCESS;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/x.movscn.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,112 @@
+/*
+x.movscn.c - implementation of the elfx_movscn(3) function.
+Copyright (C) 1995 - 2001, 2003 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: x.movscn.c,v 1.13 2005/05/21 15:39:27 michael Exp $";
+#endif /* lint */
+
+size_t
+elfx_movscn(Elf *elf, Elf_Scn *scn, Elf_Scn *after) {
+    Elf_Scn *prev;
+    Elf_Scn *tmp;
+    int off;
+
+    if (!elf || !scn || !after) {
+	return SHN_UNDEF;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (elf->e_kind != ELF_K_ELF) {
+	seterr(ERROR_NOTELF);
+	return SHN_UNDEF;
+    }
+    elf_assert(scn->s_magic == SCN_MAGIC);
+    elf_assert(after->s_magic == SCN_MAGIC);
+    if (scn->s_elf != elf || after->s_elf != elf) {
+	seterr(ERROR_ELFSCNMISMATCH);
+	return SHN_UNDEF;
+    }
+    elf_assert(elf->e_scn_1);
+    if (scn == elf->e_scn_1) {
+	seterr(ERROR_NULLSCN);
+	return SHN_UNDEF;
+    }
+    if (scn == after || scn == after->s_link) {
+	/* nothing to do */
+	return scn->s_index;
+    }
+
+    /*
+     * Find previous section.
+     */
+    prev = NULL;
+    for (tmp = elf->e_scn_1; tmp->s_link; tmp = tmp->s_link) {
+	if (tmp->s_link == scn) {
+	    prev = tmp;
+	    break;
+	}
+    }
+    elf_assert(prev != NULL);
+
+    /*
+     * Update section indices
+     */
+    off = 0;
+    for (tmp = elf->e_scn_1; tmp; tmp = tmp->s_link) {
+	if (off) {
+	    tmp->s_index += off;
+	}
+	if (tmp == after) {
+	    off++;
+	}
+	else if (tmp == scn) {
+	    off--;
+	}
+    }
+    elf_assert(off == 0);
+
+    /*
+     * Move section.
+     */
+    prev->s_link = scn->s_link;
+    scn->s_link = after->s_link;
+    after->s_link = scn;
+    scn->s_index = after->s_index + 1;
+    if (elf->e_scn_n == scn) {
+	elf->e_scn_n = prev;
+    }
+    else if (elf->e_scn_n == after) {
+	elf->e_scn_n = scn;
+    }
+
+#if ENABLE_DEBUG
+    /*
+     * Check section indices
+     */
+    tmp = elf->e_scn_1;
+    elf_assert(tmp->s_index == 0);
+    while (tmp->s_link) {
+	elf_assert(tmp->s_link->s_index == tmp->s_index + 1);
+	tmp = tmp->s_link;
+    }
+#endif /* ENABLE_DEBUG */
+
+    return scn->s_index;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/lib/x.remscn.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,119 @@
+/*
+x.remscn.c - implementation of the elfx_remscn(3) function.
+Copyright (C) 1995 - 2001, 2003 Michael Riepe
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+This library 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
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+*/
+
+#include <private.h>
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: x.remscn.c,v 1.14 2005/05/21 15:39:27 michael Exp $";
+#endif /* lint */
+
+size_t
+elfx_remscn(Elf *elf, Elf_Scn *scn) {
+    Elf_Scn *pscn;
+    Scn_Data *sd;
+    Scn_Data *tmp;
+    size_t index;
+
+    if (!elf || !scn) {
+	return SHN_UNDEF;
+    }
+    elf_assert(elf->e_magic == ELF_MAGIC);
+    if (elf->e_kind != ELF_K_ELF) {
+	seterr(ERROR_NOTELF);
+	return SHN_UNDEF;
+    }
+    elf_assert(scn->s_magic == SCN_MAGIC);
+    elf_assert(elf->e_ehdr);
+    if (scn->s_elf != elf) {
+	seterr(ERROR_ELFSCNMISMATCH);
+	return SHN_UNDEF;
+    }
+    elf_assert(elf->e_scn_1);
+    if (scn == elf->e_scn_1) {
+	seterr(ERROR_NULLSCN);
+	return SHN_UNDEF;
+    }
+
+    /*
+     * Find previous section.
+     */
+    for (pscn = elf->e_scn_1; pscn->s_link; pscn = pscn->s_link) {
+	if (pscn->s_link == scn) {
+	    break;
+	}
+    }
+    if (pscn->s_link != scn) {
+	seterr(ERROR_ELFSCNMISMATCH);
+	return SHN_UNDEF;
+    }
+
+    /*
+     * Unlink section.
+     */
+    if (elf->e_scn_n == scn) {
+	elf->e_scn_n = pscn;
+    }
+    pscn->s_link = scn->s_link;
+    index = scn->s_index;
+
+    /*
+     * Free section descriptor and data.
+     */
+    for (sd = scn->s_data_1; sd; sd = tmp) {
+	elf_assert(sd->sd_magic == DATA_MAGIC);
+	elf_assert(sd->sd_scn == scn);
+	tmp = sd->sd_link;
+	if (sd->sd_free_data && sd->sd_memdata) {
+	    free(sd->sd_memdata);
+	}
+	if (sd->sd_freeme) {
+	    free(sd);
+	}
+    }
+    if ((sd = scn->s_rawdata)) {
+	elf_assert(sd->sd_magic == DATA_MAGIC);
+	elf_assert(sd->sd_scn == scn);
+	if (sd->sd_free_data && sd->sd_memdata) {
+	    free(sd->sd_memdata);
+	}
+	if (sd->sd_freeme) {
+	    free(sd);
+	}
+    }
+    if (scn->s_freeme) {
+	elf_assert(scn->s_index > 0);
+	free(scn);
+    }
+
+    /*
+     * Adjust section indices.
+     */
+    for (scn = pscn->s_link; scn; scn = scn->s_link) {
+	elf_assert(scn->s_index > index);
+	scn->s_index--;
+    }
+
+    /*
+     * Adjust section count in ELF header
+     */
+    if (_elf_update_shnum(elf, elf->e_scn_n->s_index + 1)) {
+	return SHN_UNDEF;
+    }
+    return index;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/libelf.pc.in	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: @PACKAGE@
+Description: ELF object file access library
+Version: @VERSION@
+Requires:
+Conflicts:
+Libs: -L${libdir} -lelf
+Cflags: -I${includedir}/libelf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/mkinstalldirs	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,35 @@
+#!/bin/sh
+# Make directory hierarchy. 
+# Written by Noah Friedman <friedman@prep.ai.mit.edu>
+# Public domain.
+
+defaultIFS=' 	
+'
+IFS="${IFS-${defaultIFS}}"
+
+errstatus=0
+
+for file in ${1+"$@"} ; do 
+   oIFS="${IFS}"
+   # Some sh's can't handle IFS=/ for some reason.
+   IFS='%'
+   set - `echo ${file} | sed -e 's@/@%@g' -e 's@^%@/@'`
+   IFS="${oIFS}"
+
+   pathcomp=''
+
+   for d in ${1+"$@"} ; do
+     pathcomp="${pathcomp}${d}"
+
+     if test ! -d "${pathcomp}"; then
+        echo "mkdir $pathcomp" 1>&2
+        mkdir "${pathcomp}" || errstatus=$?
+     fi
+
+     pathcomp="${pathcomp}/"
+   done
+done
+
+exit $errstatus
+
+# eof
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/po/Makefile.in	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,184 @@
+# po/Makefile for libelf.
+# Copyright (C) 1995 - 2006 Michael Riepe
+# 
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+# 
+# This library 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
+# Library General Public License for more details.
+# 
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+# @(#) $Id: Makefile.in,v 1.17 2006/04/21 17:16:51 michael Exp $
+
+instroot =
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+localedir = @localedir@
+
+CC = @CC@
+RM = rm -f
+MV = mv -f
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+
+GENCAT = @GENCAT@
+GMSGFMT = @GMSGFMT@
+MSGFMT = @MSGFMT@
+XGETTEXT = @XGETTEXT@
+MSGMERGE = @MSGMERGE@
+
+CFLAGS = @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+DEFS = -DHAVE_CONFIG_H
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+LIBINTL = @LIBINTL@
+
+# no user serviceable parts below
+
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+@SET_MAKE@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+
+topdir = ..
+subdir = po
+
+.SUFFIXES:
+.SUFFIXES: .po .mo .gmo .msg .cat
+
+.po.mo:
+	@$(RM) $@
+	$(MSGFMT) -o $@ $<
+
+.po.gmo:
+	file=$(srcdir)/`echo $*|sed 's,.*/,,'`.gmo; \
+	  $(RM) $$file && $(GMSGFMT) -o $$file $<
+
+.msg.cat:
+	@$(RM) $@
+	$(GENCAT) $@ $<
+
+POFILES = @POFILES@
+GMOFILES = @GMOFILES@
+MSGFILES = @MSGFILES@
+
+DISTFILES = \
+	gmo2msg.c Makefile.in $(PACKAGE).pot stamp-po \
+	$(POFILES) $(GMOFILES) $(MSGFILES)
+
+POTFILES = $(top_srcdir)/lib/errors.h
+
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
+INSTOBJEXT = @INSTOBJEXT@
+
+all: $(CATALOGS)
+
+check:
+
+install: all install-data
+
+install-data: $(top_srcdir)/mkinstalldirs
+	catalogs="$(CATALOGS)"; for cat in $$catalogs; do \
+	  lang=`echo $$cat | sed 's,$(CATOBJEXT)$$,,'`; \
+	  dir=$(localedir)/$$lang/LC_MESSAGES; \
+	  $(SHELL) $(top_srcdir)/mkinstalldirs $(instroot)$$dir; \
+	  if test -r $$cat; then \
+	    $(INSTALL_DATA) $$cat $(instroot)$$dir/$(PACKAGE)$(INSTOBJEXT); \
+	  else \
+	    $(INSTALL_DATA) $(srcdir)/$$cat $(instroot)$$dir/$(PACKAGE)$(INSTOBJEXT); \
+	  fi; \
+	done
+
+uninstall:
+	catalogs="$(CATALOGS)"; for cat in $$catalogs; do \
+	  lang=`echo $$cat | sed 's,$(CATOBJEXT)$$,,'`; \
+	  $(RM) $(instroot)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \
+	done
+
+mostlyclean:
+	$(RM) core core.* $(PACKAGE).po *.po.tmp
+
+clean: mostlyclean
+
+distclean: clean
+	$(RM) gmo2msg *.mo *.cat
+	$(RM) Makefile
+
+maintainer-clean: distclean
+	$(RM) stamp-po
+
+$(PACKAGE).pot: $(POTFILES)
+	$(XGETTEXT) -c -d$(PACKAGE) -k_ $(POTFILES)
+	if cmp -s $(PACKAGE).po $(srcdir)/$(PACKAGE).pot; then \
+	  $(RM) $(PACKAGE).po; \
+	else \
+	  $(RM) $(srcdir)/$(PACKAGE).pot && \
+	    $(MV) $(PACKAGE).po $(srcdir)/$(PACKAGE).pot; \
+	fi
+
+update-po: stamp-po
+stamp-po: $(PACKAGE).pot
+	pofiles="$(POFILES)"; cd $(srcdir) && for po in $$pofiles; do \
+	  $(RM) $$po.tmp; \
+	  if $(MSGMERGE) $$po $(PACKAGE).pot > $$po.tmp; then \
+	    $(RM) $$po; \
+	    $(MV) $$po.tmp $$po; \
+	  else \
+	    echo "update for $$po failed!"; \
+	    $(RM) $$po.tmp; \
+	  fi; \
+	done
+	$(RM) $@ && echo timestamp > $@
+
+# Create X/Open message catalog sources from .gmo files.
+
+.gmo.msg:
+	$(MAKE) $(srcdir)/gmo2msg
+	cd $(srcdir) && ./gmo2msg `echo $*|sed 's,.*/,,'`
+
+.SUFFIXES: .c
+
+.c:
+	@$(RM) $@
+	$(CC) $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) \
+	  $(LDFLAGS) $*.c $(LIBS) $(LIBINTL) -o $@
+
+INCLUDES = -I$(topdir) -I. -I$(topdir)/lib -I$(srcdir) -I$(top_srcdir)/lib
+
+# maintainer only
+
+MAINT = @MAINT@
+
+distdir = $(PACKAGE)-$(VERSION)
+distsubdir = $(topdir)/$(distdir)/$(subdir)
+$(MAINT)dist: update-po $(DISTFILES)
+	if test -d $(distsubdir); then true; else mkdir $(distsubdir); fi
+	files="$(DISTFILES)"; for file in $$files; do \
+	  ln $(srcdir)/$$file $(distsubdir) >/dev/null 2>&1 || \
+	    cp -p $(srcdir)/$$file $(distsubdir) || exit 1; \
+	done
+
+# For the justification of the following Makefile rules, see node
+# `Automatic Remaking' in GNU Autoconf documentation.
+
+$(MAINT)Makefile: Makefile.in $(topdir)/config.status
+	cd $(topdir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= ./config.status
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
Binary file tools/elf4rom/libs/libelf-0.8.10/po/de.gmo has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/po/de.msg	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1 @@
+$set 1 Automatically created from de.gmo by gmo2msg
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/po/de.po	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,345 @@
+# po/de.po - German messages for libelf.
+# Copyright (C) 1999 - 2003 Michael Riepe
+# 
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Library General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+# 
+# This library 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
+# Library General Public License for more details.
+# 
+# You should have received a copy of the GNU Library General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+#
+# @(#) $Id: de.po,v 1.16 2006/04/24 16:24:32 michael Exp $
+#
+msgid ""
+msgstr ""
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2006-04-21 19:18+0200\n"
+"Content-Type: text/plain; charset=iso-8859-1\n"
+"Date: 2001-10-06 20:40:10+0200\n"
+"From: Michael Riepe <michael@thrai>\n"
+"Xgettext-Options: -c -dlibelf -k_\n"
+"Files: ../lib/errors.h\n"
+
+#: ../lib/errors.h:25
+msgid "no error"
+msgstr "Kein Fehler"
+
+#: ../lib/errors.h:26
+msgid "unknown error"
+msgstr "Unbekannter Fehler"
+
+#: ../lib/errors.h:27
+msgid "Internal error: unknown reason"
+msgstr "Interner Fehler: Ursache unbekannt"
+
+#: ../lib/errors.h:28
+msgid "Internal error: not implemented"
+msgstr "Interner Fehler: Diese Funktion ist nicht implementiert"
+
+#: ../lib/errors.h:29
+msgid "Request error: cntl(ELF_C_FDREAD) on write-only file"
+msgstr "Aufruffehler: cntl(ELF_C_FDREAD) ohne Leseberechtigung"
+
+#: ../lib/errors.h:30
+msgid "Request error: invalid ELF_C_* argument"
+msgstr "Aufruffehler: Das ELF_C_*-Argument ist ungültig"
+
+#: ../lib/errors.h:31
+msgid "Request error: file descriptor disabled"
+msgstr "Aufruffehler: Der Zugriff auf diese Datei ist nicht mehr möglich"
+
+#: ../lib/errors.h:32
+msgid "Request error: not an archive"
+msgstr "Aufruffehler: Die bearbeitete Datei ist kein Archiv (.a)"
+
+#: ../lib/errors.h:33
+msgid "Request error: offset out of range"
+msgstr "Aufruffehler: Die gewünschte Byteposition liegt außerhalb der Datei"
+
+#: ../lib/errors.h:34
+msgid "Request error: unknown ELF version"
+msgstr "Aufruffehler: unbekannte ELF-Version"
+
+#: ../lib/errors.h:35
+msgid "Request error: ELF_C_* argument does not match"
+msgstr "Aufruffehler: Das ELF_C_*-Argument paßt nicht zu den Zugriffsrechten"
+
+#: ../lib/errors.h:36
+msgid "Request error: archive member begin() for writing"
+msgstr "Aufruffehler: Der Archivinhalt ist nicht schreibbar"
+
+#: ../lib/errors.h:37
+msgid "Request error: archive/member file descriptor mismatch"
+msgstr "Aufruffehler: Die Datei- und Archiv-Deskriptoren passen nicht zusammen"
+
+#: ../lib/errors.h:38
+msgid "Request error: not an ELF file"
+msgstr "Aufruffehler: Dies ist keine ELF-Datei"
+
+#: ../lib/errors.h:39
+msgid "Request error: class file/memory mismatch"
+msgstr "Aufruffehler: Die Datei gehört zur falschen ELF-Klasse (32/64 Bit)"
+
+#: ../lib/errors.h:40
+msgid "Request error: invalid ELF_T_* argument"
+msgstr "Aufruffehler: Das ELF_T_*-Argument ist ungültig"
+
+#: ../lib/errors.h:41
+msgid "Request error: unknown data encoding"
+msgstr "Aufruffehler: unbekannte Datenrepräsentation (big/little endian)"
+
+#: ../lib/errors.h:42
+msgid "Request error: destination buffer too small"
+msgstr "Aufruffehler: Der Zielpuffer ist zu klein"
+
+#: ../lib/errors.h:43
+msgid "Request error: d_buf is NULL"
+msgstr "Aufruffehler: d_buf ist NULL"
+
+#: ../lib/errors.h:44
+msgid "Request error: unknown ELF class"
+msgstr "Aufruffehler: unbekannte ELF-Klasse (32/64 Bit)"
+
+#: ../lib/errors.h:45
+msgid "Request error: section does not belong to file"
+msgstr "Aufruffehler: Der Dateiabschnitt gehört nicht zu dieser Datei"
+
+#: ../lib/errors.h:46
+msgid "Request error: no section at index"
+msgstr "Aufruffehler: Ein Abschnitt mit dieser Nummer existiert nicht"
+
+#: ../lib/errors.h:47
+msgid "Request error: can't manipulate null section"
+msgstr "Aufruffehler: Sie versuchen, den \"Null\"-Abschnitt zu bearbeiten"
+
+#: ../lib/errors.h:48
+msgid "Request error: data does not belong to section"
+msgstr ""
+"Aufruffehler: Dieser Datenblock gehört nicht zum angegebenen Dateiabschnitt"
+
+#: ../lib/errors.h:49
+msgid "Request error: no string table"
+msgstr "Aufruffehler: Die Namenliste fehlt"
+
+#: ../lib/errors.h:50
+msgid "Request error: string table offset out of range"
+msgstr "Aufruffehler: Die gewünschte Position liegt außerhalb der Namenliste"
+
+#: ../lib/errors.h:51
+msgid "Request error: update(ELF_C_WRITE) on read-only file"
+msgstr "Aufruffehler: update(ELF_C_WRITE) ohne Schreibberechtigung"
+
+#: ../lib/errors.h:52
+msgid "I/O error: seek"
+msgstr "Ein-/Ausgabefehler: Das Positionieren innerhalb der Datei schlug fehl"
+
+#: ../lib/errors.h:53
+msgid "I/O error: file too big for memory"
+msgstr "Ein-/Ausgabefehler: Die Datei ist zu groß"
+
+#: ../lib/errors.h:54
+msgid "I/O error: raw read"
+msgstr "Ein-/Ausgabefehler: Lesefehler"
+
+#: ../lib/errors.h:55
+msgid "I/O error: get file size"
+msgstr "Ein-/Ausgabefehler: Die Dateigröße ist nicht zu ermitteln"
+
+#: ../lib/errors.h:56
+msgid "I/O error: output write"
+msgstr "Ein-/Ausgabefehler: Schreibfehler"
+
+#: ../lib/errors.h:57
+msgid "I/O error: can't truncate output file"
+msgstr "Ein-/Ausgabefehler: Das Verkürzen der Datei schlug fehl"
+
+#: ../lib/errors.h:58
+msgid "Sequence error: must set ELF version first"
+msgstr "Falsche Reihenfolge: Sie müssen zuerst elf_version() aufrufen"
+
+#: ../lib/errors.h:59
+msgid "Sequence error: must create ELF header first"
+msgstr "Falsche Reihenfolge: Sie müssen zuerst elf{32,64}_newehdr() aufrufen"
+
+#: ../lib/errors.h:60
+msgid "Format error: reference outside file"
+msgstr ""
+"Fehler in der Datei: Eine Positionsangabe zeigt auf einen Punkt außerhalb "
+"der Datei"
+
+#: ../lib/errors.h:61
+msgid "Format error: archive header truncated"
+msgstr "Fehler in der Datei: Der Archiv-Header ist unvollständig"
+
+#: ../lib/errors.h:62
+msgid "Format error: archive fmag"
+msgstr "Fehler in der Datei: Die Archiv-Kennung ist falsch"
+
+#: ../lib/errors.h:63
+msgid "Format error: archive header"
+msgstr "Fehler in der Datei: Der Archiv-Header ist fehlerhaft"
+
+#: ../lib/errors.h:64
+msgid "Format error: archive member truncated"
+msgstr "Fehler in der Datei: Der Archivinhalt ist unvollständig"
+
+#: ../lib/errors.h:65
+msgid "Format error: archive symbol table size"
+msgstr "Fehler in der Datei: Die Größe der Archiv-Symboltabelle ist falsch"
+
+#: ../lib/errors.h:66
+msgid "Format error: archive string table"
+msgstr "Fehler in der Datei: Die Archiv-Namenliste ist defekt"
+
+#: ../lib/errors.h:67
+msgid "Format error: archive special name unknown"
+msgstr ""
+"Fehler in der Datei: Es existiert ein internes Archiv-Objekt mit unbekanntem "
+"Namen"
+
+#: ../lib/errors.h:68
+msgid "Format error: ELF header truncated"
+msgstr "Fehler in der Datei: Der ELF-Header ist unvollständig"
+
+#: ../lib/errors.h:69
+msgid "Format error: program header table truncated"
+msgstr "Fehler in der Datei: Die ELF Program Header Table ist unvollständig"
+
+#: ../lib/errors.h:70
+msgid "Format error: section header table truncated"
+msgstr "Fehler in der Datei: Die ELF Section Header Table ist unvollständig"
+
+#: ../lib/errors.h:71
+msgid "Format error: data region truncated"
+msgstr "Fehler in der Datei: Ein Datenblock ist unvollständig"
+
+#: ../lib/errors.h:72
+msgid "Format error: program header table alignment"
+msgstr ""
+"Fehler in der Datei: Die ELF Program Header Table liegt nicht auf einer "
+"Wortgrenze"
+
+#: ../lib/errors.h:73
+msgid "Format error: section header table alignment"
+msgstr ""
+"Fehler in der Datei: Die ELF Section Header Table liegt nicht auf einer "
+"Wortgrenze"
+
+#: ../lib/errors.h:74
+msgid "Format error: bad parameter in Verdef record"
+msgstr "Fehler in der Datei: Verdef-Datensatz enthält ungültige Parameter"
+
+#: ../lib/errors.h:75
+msgid "Format error: unknown Verdef version"
+msgstr "Fehler in der Datei: libelf unterstützt die Verdef-Version nicht"
+
+#: ../lib/errors.h:76
+msgid "Format error: bad parameter in Verneed record"
+msgstr "Fehler in der Datei: Verneed-Datensatz enthält ungültige Parameter"
+
+#: ../lib/errors.h:77
+msgid "Format error: unknown Verneed version"
+msgstr "Fehler in der Datei: libelf unterstützt die Verneed-Version nicht"
+
+#: ../lib/errors.h:78
+msgid "Format error: bad e_shnum value"
+msgstr "Fehler in der Datei: e_shnum enthält einen ungültigen Wert"
+
+#: ../lib/errors.h:79
+#, fuzzy
+msgid "Format error: bad e_shentsize value"
+msgstr "Fehler in der Datei: e_shentsize enthält einen ungültigen Wert"
+
+#: ../lib/errors.h:80
+#, fuzzy
+msgid "Format error: bad e_phentsize value"
+msgstr "Fehler in der Datei: e_phentsize enthält einen ungültigen Wert"
+
+#: ../lib/errors.h:81
+msgid "Format error: unterminated string in string table"
+msgstr ""
+"Fehler in der Datei: Der Eintrag in der String-Tabelle ist nicht terminiert"
+
+#: ../lib/errors.h:82
+msgid "Layout error: section size too small for data"
+msgstr ""
+"Layout-Fehler: Ein Dateiabschnitt ist zu kurz für die darin enthaltenen Daten"
+
+#: ../lib/errors.h:83
+msgid "Layout error: overlapping sections"
+msgstr "Layout-Fehler: Zwei (oder mehr) Dateiabschnitte überlappen sich"
+
+#: ../lib/errors.h:84
+msgid "Memory error: elf descriptor"
+msgstr "Zu wenig Speicher: für den Elf-Deskriptor"
+
+#: ../lib/errors.h:85
+msgid "Memory error: archive symbol table"
+msgstr "Zu wenig Speicher: für die Archiv-Symboltabelle"
+
+#: ../lib/errors.h:86
+msgid "Memory error: archive member header"
+msgstr "Zu wenig Speicher: für die Archiv-Verwaltungsinformationen"
+
+#: ../lib/errors.h:87
+msgid "Memory error: ELF header"
+msgstr "Zu wenig Speicher: für den ELF-Header"
+
+#: ../lib/errors.h:88
+msgid "Memory error: program header table"
+msgstr "Zu wenig Speicher: für die Program Header Table"
+
+#: ../lib/errors.h:89
+msgid "Memory error: section header table"
+msgstr "Zu wenig Speicher: für die Section Header Table"
+
+#: ../lib/errors.h:90
+msgid "Memory error: section descriptor"
+msgstr "Zu wenig Speicher: für den Elf_Scn-Deskriptor"
+
+#: ../lib/errors.h:91
+msgid "Memory error: section data"
+msgstr "Zu wenig Speicher: für die Daten dieses Abschnitts"
+
+#: ../lib/errors.h:92
+msgid "Memory error: output file space"
+msgstr "Zu wenig Speicher: für die Ausgabe"
+
+#: ../lib/errors.h:93
+msgid "Memory error: temporary buffer"
+msgstr "Zu wenig Speicher: für einen temporären Puffer"
+
+#: ../lib/errors.h:94
+msgid "GElf error: value out of range"
+msgstr "GElf-Fehler: eine Zahl ist außerhalb des darstellbaren Bereichs"
+
+#: ../lib/errors.h:95
+msgid "GElf error: index out of range"
+msgstr "GElf-Fehler: Index außerhalb des erlaubten Bereichs"
+
+#: ../lib/errors.h:96
+msgid "GElf error: type mismatch"
+msgstr "GElf-Fehler: Typfehler"
+
+#: ../lib/errors.h:97
+msgid "GElf error: not enough memory for GElf_Sym"
+msgstr "GElf-Fehler: zu wenig Speicher für eine Variable vom Typ GElf_Sym"
+
+#: ../lib/errors.h:98
+msgid "GElf error: not enough memory for GElf_Dyn"
+msgstr "GElf-Fehler: zu wenig Speicher für eine Variable vom Typ GElf_Dyn"
+
+#: ../lib/errors.h:99
+msgid "GElf error: not enough memory for GElf_Rela"
+msgstr "GElf-Fehler: zu wenig Speicher für eine Variable vom Typ GElf_Rela"
+
+#: ../lib/errors.h:100
+msgid "GElf error: not enough memory for GElf_Rel"
+msgstr "GElf-Fehler: zu wenig Speicher für eine Variable vom Typ GElf_Rel"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/po/gmo2msg.c	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,121 @@
+/*
+ * gmo2msg.c - create X/Open message source file for libelf.
+ * Copyright (C) 1996 - 2005 Michael Riepe
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef lint
+static const char rcsid[] = "@(#) $Id: gmo2msg.c,v 1.10 2005/05/21 15:39:28 michael Exp $";
+#endif /* lint */
+
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <libintl.h>
+
+#define DOMAIN	"libelf"
+
+static const char *msgs[] = {
+#define __err__(a,b)	b,
+#include <errors.h>
+#undef __err__
+};
+
+int
+main(int argc, char **argv) {
+    char buf[1024], *lang, *progname, *s;
+    unsigned i;
+    FILE *fp;
+
+    setlocale(LC_ALL, "");
+
+    if (*argv && (progname = strrchr(argv[0], '/'))) {
+	progname++;
+    }
+    else if (!(progname = *argv)) {
+	progname = "gmo2msg";
+    }
+
+    if (argc <= 1 || !(lang = argv[1])) {
+	fprintf(stderr, "Usage: gmo2msg <language>\n");
+	exit(1);
+    }
+
+    /*
+     * Fool gettext...
+     */
+    unlink(DOMAIN ".mo");
+    unlink("LC_MESSAGES");
+    unlink(lang);
+    sprintf(buf, "%s.gmo", lang);
+    if (link(buf, DOMAIN ".mo") == -1) {
+	fprintf(stderr, "Cannot link %s to " DOMAIN ".mo\n", buf);
+	perror("");
+	exit(1);
+    }
+    symlink(".", "LC_MESSAGES");
+    symlink(".", lang);
+    textdomain(DOMAIN);
+    getcwd(buf, sizeof(buf));
+    bindtextdomain(DOMAIN, buf);
+
+    sprintf(buf, "%s.msg", lang);
+    unlink(buf);
+    if (!(fp = fopen(buf, "w"))) {
+	perror(buf);
+	exit(1);
+    }
+
+    fprintf(fp, "$set 1 Automatically created from %s.gmo by %s\n", lang, progname);
+
+    /*
+     * Translate messages.
+     */
+    setlocale(LC_MESSAGES, lang);
+    if ((s = gettext("")) && (s = strdup(s))) {
+	s = strtok(s, "\n");
+	while (s) {
+	    fprintf(fp, "$ %s\n", s);
+	    s = strtok(NULL, "\n");
+	}
+    }
+    /*
+     * Assume that messages contain printable ASCII characters ONLY.
+     * That means no tabs, linefeeds etc.
+     */
+    for (i = 0; i < sizeof(msgs)/sizeof(*msgs); i++) {
+	s = gettext(msgs[i]);
+	if (s != msgs[i] && strcmp(s, msgs[i]) != 0) {
+	    fprintf(fp, "$ \n$ Original message: %s\n", msgs[i]);
+	    fprintf(fp, "%u %s\n", i + 1, s);
+	}
+    }
+    setlocale(LC_MESSAGES, "");
+
+    if (fclose(fp)) {
+	perror("writing output file");
+	exit(1);
+    }
+
+    /*
+     * Cleanup.
+     */
+    unlink(DOMAIN ".mo");
+    unlink("LC_MESSAGES");
+    unlink(lang);
+    exit(0);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/po/libelf.pot	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,321 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2006-04-21 19:18+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../lib/errors.h:25
+msgid "no error"
+msgstr ""
+
+#: ../lib/errors.h:26
+msgid "unknown error"
+msgstr ""
+
+#: ../lib/errors.h:27
+msgid "Internal error: unknown reason"
+msgstr ""
+
+#: ../lib/errors.h:28
+msgid "Internal error: not implemented"
+msgstr ""
+
+#: ../lib/errors.h:29
+msgid "Request error: cntl(ELF_C_FDREAD) on write-only file"
+msgstr ""
+
+#: ../lib/errors.h:30
+msgid "Request error: invalid ELF_C_* argument"
+msgstr ""
+
+#: ../lib/errors.h:31
+msgid "Request error: file descriptor disabled"
+msgstr ""
+
+#: ../lib/errors.h:32
+msgid "Request error: not an archive"
+msgstr ""
+
+#: ../lib/errors.h:33
+msgid "Request error: offset out of range"
+msgstr ""
+
+#: ../lib/errors.h:34
+msgid "Request error: unknown ELF version"
+msgstr ""
+
+#: ../lib/errors.h:35
+msgid "Request error: ELF_C_* argument does not match"
+msgstr ""
+
+#: ../lib/errors.h:36
+msgid "Request error: archive member begin() for writing"
+msgstr ""
+
+#: ../lib/errors.h:37
+msgid "Request error: archive/member file descriptor mismatch"
+msgstr ""
+
+#: ../lib/errors.h:38
+msgid "Request error: not an ELF file"
+msgstr ""
+
+#: ../lib/errors.h:39
+msgid "Request error: class file/memory mismatch"
+msgstr ""
+
+#: ../lib/errors.h:40
+msgid "Request error: invalid ELF_T_* argument"
+msgstr ""
+
+#: ../lib/errors.h:41
+msgid "Request error: unknown data encoding"
+msgstr ""
+
+#: ../lib/errors.h:42
+msgid "Request error: destination buffer too small"
+msgstr ""
+
+#: ../lib/errors.h:43
+msgid "Request error: d_buf is NULL"
+msgstr ""
+
+#: ../lib/errors.h:44
+msgid "Request error: unknown ELF class"
+msgstr ""
+
+#: ../lib/errors.h:45
+msgid "Request error: section does not belong to file"
+msgstr ""
+
+#: ../lib/errors.h:46
+msgid "Request error: no section at index"
+msgstr ""
+
+#: ../lib/errors.h:47
+msgid "Request error: can't manipulate null section"
+msgstr ""
+
+#: ../lib/errors.h:48
+msgid "Request error: data does not belong to section"
+msgstr ""
+
+#: ../lib/errors.h:49
+msgid "Request error: no string table"
+msgstr ""
+
+#: ../lib/errors.h:50
+msgid "Request error: string table offset out of range"
+msgstr ""
+
+#: ../lib/errors.h:51
+msgid "Request error: update(ELF_C_WRITE) on read-only file"
+msgstr ""
+
+#: ../lib/errors.h:52
+msgid "I/O error: seek"
+msgstr ""
+
+#: ../lib/errors.h:53
+msgid "I/O error: file too big for memory"
+msgstr ""
+
+#: ../lib/errors.h:54
+msgid "I/O error: raw read"
+msgstr ""
+
+#: ../lib/errors.h:55
+msgid "I/O error: get file size"
+msgstr ""
+
+#: ../lib/errors.h:56
+msgid "I/O error: output write"
+msgstr ""
+
+#: ../lib/errors.h:57
+msgid "I/O error: can't truncate output file"
+msgstr ""
+
+#: ../lib/errors.h:58
+msgid "Sequence error: must set ELF version first"
+msgstr ""
+
+#: ../lib/errors.h:59
+msgid "Sequence error: must create ELF header first"
+msgstr ""
+
+#: ../lib/errors.h:60
+msgid "Format error: reference outside file"
+msgstr ""
+
+#: ../lib/errors.h:61
+msgid "Format error: archive header truncated"
+msgstr ""
+
+#: ../lib/errors.h:62
+msgid "Format error: archive fmag"
+msgstr ""
+
+#: ../lib/errors.h:63
+msgid "Format error: archive header"
+msgstr ""
+
+#: ../lib/errors.h:64
+msgid "Format error: archive member truncated"
+msgstr ""
+
+#: ../lib/errors.h:65
+msgid "Format error: archive symbol table size"
+msgstr ""
+
+#: ../lib/errors.h:66
+msgid "Format error: archive string table"
+msgstr ""
+
+#: ../lib/errors.h:67
+msgid "Format error: archive special name unknown"
+msgstr ""
+
+#: ../lib/errors.h:68
+msgid "Format error: ELF header truncated"
+msgstr ""
+
+#: ../lib/errors.h:69
+msgid "Format error: program header table truncated"
+msgstr ""
+
+#: ../lib/errors.h:70
+msgid "Format error: section header table truncated"
+msgstr ""
+
+#: ../lib/errors.h:71
+msgid "Format error: data region truncated"
+msgstr ""
+
+#: ../lib/errors.h:72
+msgid "Format error: program header table alignment"
+msgstr ""
+
+#: ../lib/errors.h:73
+msgid "Format error: section header table alignment"
+msgstr ""
+
+#: ../lib/errors.h:74
+msgid "Format error: bad parameter in Verdef record"
+msgstr ""
+
+#: ../lib/errors.h:75
+msgid "Format error: unknown Verdef version"
+msgstr ""
+
+#: ../lib/errors.h:76
+msgid "Format error: bad parameter in Verneed record"
+msgstr ""
+
+#: ../lib/errors.h:77
+msgid "Format error: unknown Verneed version"
+msgstr ""
+
+#: ../lib/errors.h:78
+msgid "Format error: bad e_shnum value"
+msgstr ""
+
+#: ../lib/errors.h:79
+msgid "Format error: bad e_shentsize value"
+msgstr ""
+
+#: ../lib/errors.h:80
+msgid "Format error: bad e_phentsize value"
+msgstr ""
+
+#: ../lib/errors.h:81
+msgid "Format error: unterminated string in string table"
+msgstr ""
+
+#: ../lib/errors.h:82
+msgid "Layout error: section size too small for data"
+msgstr ""
+
+#: ../lib/errors.h:83
+msgid "Layout error: overlapping sections"
+msgstr ""
+
+#: ../lib/errors.h:84
+msgid "Memory error: elf descriptor"
+msgstr ""
+
+#: ../lib/errors.h:85
+msgid "Memory error: archive symbol table"
+msgstr ""
+
+#: ../lib/errors.h:86
+msgid "Memory error: archive member header"
+msgstr ""
+
+#: ../lib/errors.h:87
+msgid "Memory error: ELF header"
+msgstr ""
+
+#: ../lib/errors.h:88
+msgid "Memory error: program header table"
+msgstr ""
+
+#: ../lib/errors.h:89
+msgid "Memory error: section header table"
+msgstr ""
+
+#: ../lib/errors.h:90
+msgid "Memory error: section descriptor"
+msgstr ""
+
+#: ../lib/errors.h:91
+msgid "Memory error: section data"
+msgstr ""
+
+#: ../lib/errors.h:92
+msgid "Memory error: output file space"
+msgstr ""
+
+#: ../lib/errors.h:93
+msgid "Memory error: temporary buffer"
+msgstr ""
+
+#: ../lib/errors.h:94
+msgid "GElf error: value out of range"
+msgstr ""
+
+#: ../lib/errors.h:95
+msgid "GElf error: index out of range"
+msgstr ""
+
+#: ../lib/errors.h:96
+msgid "GElf error: type mismatch"
+msgstr ""
+
+#: ../lib/errors.h:97
+msgid "GElf error: not enough memory for GElf_Sym"
+msgstr ""
+
+#: ../lib/errors.h:98
+msgid "GElf error: not enough memory for GElf_Dyn"
+msgstr ""
+
+#: ../lib/errors.h:99
+msgid "GElf error: not enough memory for GElf_Rela"
+msgstr ""
+
+#: ../lib/errors.h:100
+msgid "GElf error: not enough memory for GElf_Rel"
+msgstr ""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/po/stamp-po	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1 @@
+timestamp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/libs/libelf-0.8.10/stamp-h.in	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,1 @@
+timestamp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/COPYING	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program 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, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/COPYING.LESSER	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,165 @@
+		   GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions.
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version.
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+  Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/Makefile	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,59 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program 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 Lesser General Public License for more details.
+# 
+# You should have received a copy of the GNU Lesser General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+CC=g++
+CFLAGS=-Wall -O3 -g3
+CPPFLAGS=-I. -I.. -I$/include/boost
+BASE_CFLAGS=
+LDFLAGS=-g -L$(MINGW_HOME)/local/lib
+LIBS=-lelf -lboost_program_options -lboost_regex -lboost_filesystem
+ELF4ROM=elf4rom.exe
+
+OBJS=dwarfabbrevmanager.o
+OBJS+=dwarfarangesmanager.o
+OBJS+=dwarfframemanager.o
+OBJS+=dwarfinfomanager.o
+OBJS+=dwarflinemanager.o
+OBJS+=dwarflocexpr.o
+OBJS+=dwarflocmanager.o
+OBJS+=dwarfmanager.o
+OBJS+=dwarfnamemanager.o
+OBJS+=dwarfrangesmanager.o
+OBJS+=dwarfutils.o
+OBJS+=e32romimage.o
+OBJS+=elfheader.o
+OBJS+=elfphdr.o
+OBJS+=elfrom.o
+OBJS+=elfromerror.o
+OBJS+=elfsection.o
+OBJS+=elfsectionmanager.o
+OBJS+=elfstringtable.o
+OBJS+=elfsymboltablemanager.o
+OBJS+=filefragment.o
+OBJS+=inputfile.o
+OBJS+=main.o
+OBJS+=outputfile.o
+OBJS+=processoptions.o
+
+%.o: %.cpp
+	$(CC) $(CFLAGS) $(CPPFLAGS) $(BASE_CFLAGS) -c -o $@ $<
+
+$(ELF4ROM): $(OBJS)
+	$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
+
+clean:
+	rm -f $(OBJS) $(ELF4ROM)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/defs.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,42 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef DEFS_H_
+#define DEFS_H_
+
+#include <string>
+typedef std::string String;
+
+#if 0
+typedef char * PathName;
+#endif
+
+typedef String PathName;
+
+typedef unsigned long LinearAddr;
+typedef unsigned long VirtualAddr;
+
+#define ALIGN4(x) (((x)+ 3) & ~3)
+
+typedef unsigned long Uint32;
+typedef long Int32;
+
+typedef char Byte;
+typedef char * Byteptr;
+
+#endif /*DEFS_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/dwarfabbrevmanager.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,161 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <iostream>
+#include "dwarfmanager.h"
+#include "inputfile.h"
+
+const string DwarfAbbrevManager::iAbbrevSectionName(".debug_abbrev");
+void InfoContext::SetAbbrevOffset(size_t offset){
+	if (!iContextValid){
+		cerr << "Error: runtime error - SetAbbrevOffset called on invalid InfoContext\n";
+		exit(EXIT_FAILURE);
+	}
+	
+	if (iAbbrevOffset == offset)
+			return;
+	// Save current entry (in particular the cursor value
+	if (iAbbrevOffset != 0xffffffff){
+		AbbrevOffsetMap::iterator old = iMap.find(iAbbrevOffset);
+		if (old != iMap.end())
+			old->second.iCursor = iAbbrevMapEntry.iCursor;
+		else
+			iMap[iAbbrevOffset] = iAbbrevMapEntry;
+	}
+	
+	AbbrevOffsetMap::iterator i = iMap.find(offset);
+	if (i != iMap.end()){
+		iAbbrevMapEntry = i->second;
+	} else {
+		AbbrevMap * newMap = new AbbrevMap;
+		new (&iAbbrevMapEntry) AbbrevMapEntry(iSectionStart + offset, newMap);
+		iMap[offset] = iAbbrevMapEntry;
+	}
+	iAbbrevOffset = offset;
+}
+
+DebugAbbrev & InfoContext::GetAbbrev(Dwarf_Word aCode){
+	AbbrevMap::iterator i = iAbbrevMapEntry.iMap->find(aCode);
+	if (i != iAbbrevMapEntry.iMap->end()){
+			return i->second;
+	} else {
+		return FindAbbrev(aCode);
+	}
+}
+
+DebugAbbrev & InfoContext::FindAbbrev(Dwarf_Word aCode){
+	// retrieve cursor for where we've scanned so far.
+	Dwarf_Byte_Ptr p = iAbbrevMapEntry.iCursor;
+	// NB. error if we don't find the code before section end
+	Dwarf_Byte_Ptr lim = iSectionEnd;
+	bool error = false;
+	bool found = false;
+	size_t leb128_length;
+
+	while (!found && (p < lim)){
+		
+#define CHECK_ABBREV_LIM(p,l,e) { if ((p)>(l)){ e = true; break;} }
+#define CHECK_DECODE_ULEB128(v,p,n,l,e) \
+			DECODE_ULEB128(v,p,n)\
+			CHECK_ABBREV_LIM(p,l,e);
+		
+		size_t count = 0;
+		//CHECK_DECODE_ULEB128(abbrev_code,p,leb128_length,lim, error);
+		Dwarf_Word abbrev_code = DwarfSectionManager::DecodeUnsignedLeb128(p, leb128_length);
+		p += leb128_length;
+		if (p>lim){ 
+			error = true; 
+			break;
+		}
+		// Might as well error here since either we've found the NULL abbrev
+	    if (abbrev_code == 0) {
+	    	DebugAbbrev abbr(0, 0, 0, NULL, NULL);
+	    	(*iAbbrevMapEntry.iMap)[0] = abbr;
+	    	if (aCode == 0) // ??? why would it
+	    		found = true;
+	    }
+
+		CHECK_DECODE_ULEB128(tag,p,leb128_length,lim, error);
+		// don't care about 'has child'
+	    p++;
+	    CHECK_ABBREV_LIM(p,lim,error);
+	    Dwarf_Byte_Ptr raw_attr_ptr = p;
+	    Dwarf_Word attr;
+	    Dwarf_Word attr_form;
+	    do {
+	    	CHECK_DECODE_ULEB128(a,p,leb128_length,lim, error);
+	    	attr = a;
+	    	CHECK_DECODE_ULEB128(f,p,leb128_length,lim, error);
+	    	attr_form = f;
+
+	    	if (attr != 0)
+	    		count++;
+
+	    } while (attr != 0 || attr_form != 0);
+	    
+		DebugAbbrevAttrForm * list = new DebugAbbrevAttrForm[count];
+		Dwarf_Byte_Ptr q=raw_attr_ptr;
+		for (size_t i=0 ; i < count ; i++){
+			list[i].iAttr = ULEB128(q,leb128_length);
+			list[i].iForm = ULEB128(q,leb128_length);
+		}
+	    DebugAbbrev abbr(abbrev_code, tag, count, raw_attr_ptr, list);
+	    (*iAbbrevMapEntry.iMap)[abbrev_code] = abbr;
+	    if (abbrev_code == aCode)
+	    	found = true;
+	}
+	if (error){
+		cerr << "Error: corrupt .debug_abbrev section\n";
+		exit(EXIT_FAILURE);
+	}
+	if (!found){
+		cerr << "Error: abbrev code not found in .debug_abbrev section\n";
+		exit(EXIT_FAILURE);
+	}
+	// record where we scanned to
+	iAbbrevMapEntry.iCursor = p;
+	// get the 
+	AbbrevMap::iterator i = iAbbrevMapEntry.iMap->find(aCode);
+	if (i == iAbbrevMapEntry.iMap->end()){
+		cerr << "Error: Runtime error processing .debug_abbrev section\n";
+		exit(EXIT_FAILURE);
+	} 
+
+	return i->second;
+}
+
+void DwarfAbbrevManager::StartContext(PathName & aName){
+	Dwarf_Byte_Ptr section = GetSection(aName);
+	iInfoContext.Init(section, section + GetSectionSize(aName), GetSectionOffset(aName));
+}
+
+void DwarfAbbrevManager::EndContext(){
+	iInfoContext.Reset();
+}
+
+void DwarfAbbrevManager::SetContextAbbrevOffset(Uint32 offset){
+	iInfoContext.SetAbbrevOffset(offset);
+}
+
+size_t DwarfAbbrevManager::GetContextSectionOffset(){
+	return iInfoContext.GetSectionOffset();
+}
+
+DebugAbbrev & DwarfAbbrevManager::GetAbbrev(Dwarf_Word aCode){
+	return iInfoContext.GetAbbrev(aCode);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/dwarfarangesmanager.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,94 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <iostream>
+#include "dwarfmanager.h"
+#include "inputfile.h"
+
+const string DwarfArangesManager::iArangesSectionName(".debug_aranges");
+
+void DwarfArangesManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end){
+	while (start < end){
+		Dwarf_Byte_Ptr data = start;		
+		size_t offset_size, initial_length_size;
+		
+		Dwarf_Word length = READ_UNALIGNED4(data); 
+		data += 4;
+
+		if (length >= 0xfffffff0u) {
+			cerr << "Error: 64 bit DWARF not supported\n";
+			exit(EXIT_FAILURE);
+		} else {	
+			offset_size = 4;
+			initial_length_size = 4;
+		}
+		
+		start += length + initial_length_size;
+
+		Dwarf_Half version = READ_UNALIGNED2(data);
+		data += 2;
+
+		Dwarf_Word offset = GetValue(data, offset_size); 
+		Dwarf_Word newOffset = CheckNewOffset(iDwarfInfoManager.GetSectionOffset(aPair.iXIPFileDetails.iElfFile), offset);
+		if (offset != newOffset)
+			WriteValue(data, offset, offset_size);
+		data += offset_size;
+
+
+		size_t pointer_size = *data++;
+
+		size_t segment_size = *data++;
+		
+		if (version != 2 && version != 3){
+			static bool warned = false;
+			if (!warned){
+				cerr << "Only DWARF 2 and 3 aranges are currently supported\n";
+				warned = true;
+			}
+			continue;
+		}
+
+		size_t address_size = pointer_size + segment_size;
+
+		if (address_size > 4){
+			static bool warned2 = false;
+			if (!warned2){
+				cerr << "64 bit DWARF not currently supported\n";
+				warned2 = true;
+			}
+			continue;		
+		}
+
+		Dwarf_Byte_Ptr ranges = data;
+
+		/* Must pad to an alignment boundary that is twice the address size.  */
+		size_t excess = (data - start) % (2 * address_size);
+		if (excess)
+			ranges += (2 * address_size) - excess;
+
+		while (ranges + 2 * address_size <= start){
+			LinearAddr addr = GetValue(ranges, address_size);
+			LinearAddr relocatedAddress = aPair.iXIPFileDetails.Relocate(addr);
+			if (addr != relocatedAddress)
+				WriteValue(ranges, relocatedAddress, address_size);
+			ranges += address_size;
+			// skip length field
+			ranges += address_size;
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/dwarfdefs.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,142 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef DWARFDEFS_H_
+#define DWARFDEFS_H_
+
+//#include <libdwarf.h>
+/* to identify a cie */
+
+
+#define DW_CIE_ID 		~(0x0)
+#define DW_CIE_VERSION		1 /* DWARF2 */
+#define DW_CIE_VERSION3		3 /* DWARF3 */
+#define ABBREV_HASH_TABLE_SIZE	10
+
+typedef int                 Dwarf_Bool;     /* boolean type */
+//
+// Copyright (c) 2008 Symbian Software Ltd. All rights reserved.
+//
+
+typedef unsigned long long  Dwarf_Off;      /* 8 byte file offset */
+typedef unsigned long long  Dwarf_Unsigned; /* 8 byte unsigned value*/
+typedef unsigned short      Dwarf_Half;     /* 2 byte unsigned value */
+typedef unsigned char       Dwarf_Small;    /* 1 byte unsigned value */
+typedef signed   long long  Dwarf_Signed;   /* 8 byte signed value */
+typedef unsigned long long  Dwarf_Addr;     /* target memory address */
+
+typedef void*		Dwarf_Ptr;          /* host machine pointer */
+
+typedef unsigned long Dwarf_Word;
+typedef signed long Dwarf_Sword;
+
+typedef signed char Dwarf_Sbyte;
+typedef unsigned char Dwarf_Ubyte;
+typedef signed short Dwarf_Shalf;
+typedef Dwarf_Ubyte *Dwarf_Byte_Ptr;
+
+/* these 2 are fixed sizes which must not vary with the
+** ILP32/LP64 model. Between these two, stay at 32 bit.
+*/
+typedef unsigned int Dwarf_ufixed;
+typedef int Dwarf_sfixed;
+
+/*
+        In various places the code mistakenly associates
+        forms 8 bytes long with Dwarf_Signed or Dwarf_Unsigned
+	This is not a very portable assumption.
+        The following should be used instead for 64 bit integers.
+*/
+typedef unsigned long long Dwarf_ufixed64;
+typedef long long Dwarf_sfixed64;
+
+char * GetDwarfTag(Dwarf_Unsigned aTag);
+char * GetDwarfAttr(Dwarf_Half attr);
+char * GetDwarfForm(Dwarf_Half form);
+
+#define READ_UNALIGNED2(aPtr)ReadUnaligned2(aPtr)
+static inline Dwarf_Word ReadUnaligned2(Dwarf_Byte_Ptr aPtr){
+	Dwarf_Byte_Ptr p = aPtr;
+	return p[0] | (p[1] << 8); 
+}
+#define READ_UNALIGNED4(aPtr)ReadUnaligned4(aPtr)
+static inline Dwarf_Word ReadUnaligned4(Dwarf_Byte_Ptr aPtr){
+	Dwarf_Byte_Ptr p = aPtr;
+	return p[0] | (p[1] << 8) | (p[2] << 16) | (p[3] << 24); 
+}
+#define WRITE_UNALIGNED2(aPtr, val)WriteUnaligned2(aPtr, val)
+static inline void WriteUnaligned2(Dwarf_Byte_Ptr aPtr, Dwarf_Word val){
+	Dwarf_Byte_Ptr p = aPtr;
+	p[0] = val & 0xff;
+	p[1] = (val >> 8) & 0xff;
+}
+
+#define WRITE_UNALIGNED4(aPtr, val)WriteUnaligned4(aPtr, val)
+static inline void WriteUnaligned4(Dwarf_Byte_Ptr aPtr, Dwarf_Word val){
+	Dwarf_Byte_Ptr p = aPtr;
+	p[0] = val & 0xff;
+	p[1] = (val >> 8) & 0xff;
+	p[2] = (val >> 16) & 0xff;
+	p[3] = (val >> 24) & 0xff;
+}
+
+#include <iostream>
+static inline Dwarf_Word GetValue(Dwarf_Byte_Ptr start, size_t size){
+	switch (size){
+	default:
+	case 0: {
+		std::cerr << "Error: size of " << size << " not allowed\n";
+		exit(EXIT_FAILURE);
+		}
+	case 2:
+		return READ_UNALIGNED2(start);
+	case 4:
+		return READ_UNALIGNED4(start);
+	case 8: {
+		std::cerr << "Error: 64 bit values not support yet\n";
+		exit(EXIT_FAILURE);		
+		}
+	}	
+}
+
+static inline void WriteValue(Dwarf_Byte_Ptr start, Dwarf_Word val, size_t size){
+	switch (size){
+	default:
+	case 0: {
+		std::cerr << "Error: size of " << size << " not allowed\n";
+		exit(EXIT_FAILURE);
+		}
+	case 2:
+		WRITE_UNALIGNED2(start, val);
+		break;
+	case 4:
+		WRITE_UNALIGNED4(start, val);
+		break;
+	case 8: {
+		std::cerr << "Error: 64 bit values not support yet\n";
+		exit(EXIT_FAILURE);		
+		}
+	}
+	
+}
+
+// TODO: for the moment just say 4 - we are dealing with 32 bit ARM for the foreseeable future
+// in the future we need to figure out where to get this from...
+#define ENCODED_POINTER_SIZE 4
+
+#endif /*DWARFDEFS_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/dwarfframemanager.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,283 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <iostream>
+#include "dwarfmanager.h"
+#include "inputfile.h"
+
+const string DwarfFrameManager::iFrameSectionName(".debug_frame");
+
+static inline size_t SizeOfEncodedValue (int encoding)
+{
+  switch (encoding & 0x7)
+    {
+    default:	/* ??? */
+    case 0:	return ENCODED_POINTER_SIZE;
+    case 2:	return 2;
+    case 3:	return 4;
+    case 4:	return 8;
+    }
+}
+
+static inline bool ValueFitsSize(Dwarf_Word val, size_t size){
+	switch (size){
+	default:
+	case 0: {
+		cerr << "Error: size of " << size << " not allowed\n";
+		exit(EXIT_FAILURE);
+		}
+	case 2:
+		return val <= 0xffff;
+	case 4:
+		return val <= 0xffffffff;
+	case 8:
+		return true;
+	}
+}
+
+
+void DwarfFrameManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr aStart, Dwarf_Byte_Ptr aEnd){
+	CiePtrEncodingMap ptrEncodingMap;
+	CieAugmentationMap augmentationMap;
+	size_t encoded_ptr_size = ENCODED_POINTER_SIZE;
+	size_t bytes_read;
+	Dwarf_Byte_Ptr start = aStart;
+	Dwarf_Byte_Ptr section_start = start;
+	Dwarf_Byte_Ptr end = aEnd;
+	while (start < end) {
+		unsigned char *augmentation_data = NULL;
+		unsigned long augmentation_data_len = 0;
+		size_t offset_size;
+		size_t initial_length_size;
+
+		Dwarf_Byte_Ptr saved_start = start;
+		Dwarf_Word length = READ_UNALIGNED4(start); 
+		start += 4;
+
+		if (length == 0){ // ZERO terminator - shouldn't see this
+			continue;
+		}	
+
+		if (length >= 0xfffffff0u) {
+			cerr << "Error: 64 bit DWARF not supported\n";
+			exit(EXIT_FAILURE);
+		} else {	
+			offset_size = 4;
+			initial_length_size = 4;
+		}
+
+		Dwarf_Byte_Ptr block_end = saved_start + length + initial_length_size;
+		if (block_end > end) {
+			cerr << "Warning: Invalid length " << length << " in FDE at 0x" 
+				<< (unsigned long)(saved_start - section_start) << " in file " << aPair.iXIPFileDetails.iElfFile << "\n";
+			block_end = end;
+		}	
+		Dwarf_Word cie_id = READ_UNALIGNED4(start); 
+		if (cie_id != (Dwarf_Word)DW_CIE_ID)
+			WRITE_UNALIGNED4(start, cie_id + GetSectionOffset(aPair.iXIPFileDetails.iElfFile));
+		start += offset_size;
+
+		if (cie_id == (Dwarf_Word)DW_CIE_ID) {
+			Dwarf_Ubyte version = *start++;
+
+			char * augmentation = (char *) start;
+			augmentation_data = NULL;
+			start = (Dwarf_Byte_Ptr) strchr ((char *) start, '\0') + 1;
+
+			if (augmentation[0] == 'z'){
+				ULEB128(start, bytes_read);
+				ULEB128(start, bytes_read);
+
+				if (version == 1){
+					// fc->ra = GET (1);
+					start++;
+				} else {
+					// fc->ra = LEB ();
+					ULEB128(start, bytes_read);
+				}
+				augmentation_data_len = ULEB128(start, bytes_read);
+				augmentation_data = start;
+				augmentationMap[saved_start] = augmentation_data_len;
+				start += augmentation_data_len;
+			} else if (strcmp (augmentation, "eh") == 0){
+				//start += eh_addr_size;
+				start += 4;
+				// fc->code_factor = LEB ();
+				// fc->data_factor = SLEB ();
+				ULEB128(start, bytes_read);
+				ULEB128(start, bytes_read);
+				if (version == 1){
+					//c->ra = GET (1);
+					start++;
+				} else {
+					// fc->ra = LEB ();
+					ULEB128(start, bytes_read);
+				}
+			} else {
+				ULEB128(start, bytes_read);
+				ULEB128(start, bytes_read);
+
+				if (version == 1){
+					// fc->ra = GET (1);
+					start++;
+				} else {
+					// fc->ra = LEB ();
+					ULEB128(start, bytes_read);
+				}
+			}
+
+			if (augmentation_data_len){
+				unsigned char *p, *q;
+				p = (unsigned char *) augmentation + 1;
+				q = augmentation_data;
+				Dwarf_Ubyte encoding = 0;
+				while (1){
+					if (*p == 'L')
+						q++;
+					else if (*p == 'P')
+						q += 1 + SizeOfEncodedValue(*q);
+					else if (*p == 'R')
+						encoding = *q++;
+					else
+						break;
+					p++;
+				}
+				if (encoding)
+					ptrEncodingMap[saved_start] = encoding;
+			}
+	  
+		} else {
+			Dwarf_Byte_Ptr look_for = section_start + cie_id;
+			Dwarf_Ubyte encoding = 0;
+			CiePtrEncodingMap::iterator iE = ptrEncodingMap.find(look_for);
+			if (iE != ptrEncodingMap.end()){
+				encoding = iE->second;
+				encoded_ptr_size = SizeOfEncodedValue(encoding);
+			}
+			if ((encoding & 0x70) != DW_EH_PE_pcrel){
+				// do the nasty
+				LinearAddr addr = GetValue(start, encoded_ptr_size);
+				LinearAddr relocatedAddr = aPair.iXIPFileDetails.Relocate(addr);
+				if (ValueFitsSize(relocatedAddr, encoded_ptr_size)){
+					WriteValue(start, relocatedAddr, encoded_ptr_size);
+				} else {
+					cerr << "Warning: relocated addresses in " << GetSectionName().c_str() 
+					<< " section of " << aPair.iXIPFileDetails.iElfFile.c_str() 
+					<< " too large for encoding. Backtraces may be misleading.\n";
+					}
+			}
+			start += encoded_ptr_size;
+			// skip the range size
+			start += encoded_ptr_size;
+
+			CieAugmentationMap::iterator iP =  augmentationMap.find(look_for);
+			if (iP != augmentationMap.end()){
+				ULEB128(start, bytes_read);
+				start += bytes_read;
+			}
+		}
+		
+		Dwarf_Word tmp = 0;
+		while (start < block_end){
+			unsigned op, opa;
+			op = *start++;
+			opa = op & 0x3f;
+			if (op & 0xc0)
+				op &= 0xc0;
+			switch (op){
+			case DW_CFA_advance_loc:
+				break;
+			case DW_CFA_offset:
+				ULEB128(start, bytes_read);
+				break;
+			case DW_CFA_restore:
+				break;
+			case DW_CFA_set_loc:
+				start += encoded_ptr_size;
+				break;
+			case DW_CFA_advance_loc1:
+				start += 1;
+				break;
+			case DW_CFA_advance_loc2:
+				start += 2;
+				break;
+			case DW_CFA_advance_loc4:
+				start += 4;
+				break;
+			case DW_CFA_offset_extended:
+			case DW_CFA_val_offset:
+				ULEB128(start, bytes_read);
+				ULEB128(start, bytes_read);
+				break;
+			case DW_CFA_restore_extended:
+			case DW_CFA_undefined:
+			case DW_CFA_same_value:
+				ULEB128(start, bytes_read);
+				break;
+			case DW_CFA_register:
+			case DW_CFA_def_cfa:
+				ULEB128(start, bytes_read);
+				ULEB128(start, bytes_read);
+				break;
+			case DW_CFA_def_cfa_register:
+			case DW_CFA_def_cfa_offset:
+				ULEB128(start, bytes_read);
+				break;
+			case DW_CFA_def_cfa_expression:
+				tmp = ULEB128(start, bytes_read);
+				EditLocationExpression (start, encoded_ptr_size, tmp, aPair);
+				start += tmp;
+				break;
+			case DW_CFA_expression: 
+			case DW_CFA_val_expression: 
+				ULEB128(start, bytes_read);
+				tmp = ULEB128(start, bytes_read);
+				EditLocationExpression (start, encoded_ptr_size, tmp, aPair);
+				start += tmp;
+				break;
+#ifndef DW_CFA_offset_extended_sf
+// seems to be type in dwarf.h
+#define DW_CFA_offset_extended_sf 0x11
+				//DW_CFA_cfa_offset_extended_sf
+#endif
+			case DW_CFA_offset_extended_sf:
+			case DW_CFA_val_offset_sf:
+			case DW_CFA_def_cfa_sf:
+				ULEB128(start, bytes_read);
+				ULEB128(start, bytes_read);
+				break;
+			case DW_CFA_def_cfa_offset_sf:
+				ULEB128(start, bytes_read);
+				break;
+			case DW_CFA_MIPS_advance_loc8:
+				start += 8;
+				break;
+			case DW_CFA_GNU_args_size:
+				ULEB128(start, bytes_read);
+				break;
+			case DW_CFA_GNU_negative_offset_extended:
+				ULEB128(start, bytes_read);
+				ULEB128(start, bytes_read);
+				break;
+			default:
+				break;
+			}
+		}
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/dwarfinfomanager.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,566 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <string.h>
+#include <iostream>
+#include <cassert>
+
+#include "dwarfmanager.h"
+#include "inputfile.h"
+
+const string DwarfInfoManager::iInfoSectionName(".debug_info");
+
+void DwarfInfoManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr aStart, Dwarf_Byte_Ptr aEnd){
+	iDwarfAbbrevManager.StartContext(aPair.iXIPFileDetails.iElfFile);
+	Dwarf_Byte_Ptr p = aStart;
+	Dwarf_Byte_Ptr e = aEnd;
+	while (p < e) {
+		p = ProcessCU(aPair, p, e);
+	}
+	iDwarfAbbrevManager.EndContext();
+}
+
+#define READ_DWARF_VAL(v,t,p) t v = *((t *)p); p += sizeof(t);
+Dwarf_Byte_Ptr DwarfInfoManager::ProcessCU(FileShdrPair & aPair, Dwarf_Byte_Ptr s, Dwarf_Byte_Ptr e){
+	Dwarf_Byte_Ptr p = s;
+	//Read the CU header info
+	// first check whether we're dealing with 32bit or 64 bit DWARF
+	
+	// TODO: must abstract over base types e.g uint32 etc.
+	// TODO: this might not be 4 byte aligned and so could cause problems on some
+	// architectures
+	READ_DWARF_VAL(len, Uint32, p);
+	if (len >= 0xfffffff0u){
+		cerr << "Error: 64 bit DWARF not supported\n";
+		exit(EXIT_FAILURE);
+	}
+	iLocalLength = len;
+	Dwarf_Byte_Ptr end = p + len;
+	// TODO: make sensitive to dwarf version number?
+	READ_DWARF_VAL(version, Dwarf_Half, p);
+	Uint32 abbrevOffset = *((Uint32 *)p);
+	// update the offset into the abbrev table
+	*((Uint32 *)p) = (Uint32)(abbrevOffset + iDwarfAbbrevManager.GetContextSectionOffset());
+	p += sizeof(Uint32);
+	READ_DWARF_VAL(address_size, Byte, p);
+	
+	// TODO: if this isn't 4 we're doomed aren't we?
+	iAddressSize = address_size;
+	
+	iDwarfAbbrevManager.SetContextAbbrevOffset(abbrevOffset);
+	
+	// now process each DIE until end.
+	while (p < end) {
+		p = ProcessDIE(aPair, p, end);
+	}
+
+	return p;
+}
+
+void NoteProducer(FileShdrPair & aPair, Dwarf_Byte_Ptr aPtr, Dwarf_Unsigned aForm){
+
+	switch (aForm){
+	case DW_FORM_string:{
+		const char * producer = (const char *)aPtr;
+		const char * RvctProducer = "ARM/Thumb C/C++ Compiler, RVCT";
+		const size_t RvctProducerLength = strlen(RvctProducer);
+		const char * GccProducer = "GNU C++";
+		const size_t GccProducerLength = strlen(GccProducer);
+		if (!strncmp(producer, RvctProducer, RvctProducerLength))
+			aPair.iXIPFileDetails.iRVCTProduced = true;
+		if (!strncmp(producer, GccProducer, GccProducerLength))
+			aPair.iXIPFileDetails.iGCCProduced = true;		
+		return;
+	}
+    case DW_FORM_indirect: {
+	    size_t indir_len = 0;
+	    Dwarf_Unsigned form_indirect = DwarfSectionManager::DecodeUnsignedLeb128(aPtr, indir_len);
+	    if (form_indirect == DW_FORM_indirect) {
+			/* 	Eek, should never happen, will get warned later */
+	    	return;
+	    }
+	    return NoteProducer(aPair, aPtr+indir_len, form_indirect);
+		}
+    case DW_FORM_strp:
+    	// TODO - We need to get the string table for this -- 
+    	return;
+	}
+}
+
+Dwarf_Byte_Ptr DwarfInfoManager::ProcessDIE(FileShdrPair & aPair, Dwarf_Byte_Ptr s, Dwarf_Byte_Ptr e){
+	Dwarf_Byte_Ptr info_ptr = s;
+    size_t leb128_length;
+    
+    Dwarf_Word abbrev_code = DecodeUnsignedLeb128(info_ptr, leb128_length);
+    info_ptr += leb128_length;
+    if (abbrev_code == 0) {
+    	return info_ptr;
+    }
+
+    DebugAbbrev & abbrev = iDwarfAbbrevManager.GetAbbrev(abbrev_code);
+ 
+    //cout << "Tag = " << GetDwarfTag(abbrev.iTag) << " Code = " << abbrev_code <<  " num attrs = " << abbrev.iCount << endl;
+   
+    for (size_t i = 0; i < abbrev.iCount; i++){
+    	size_t attr = abbrev.iParsed[i].iAttr;
+    	Dwarf_Unsigned form = abbrev.iParsed[i].iForm;
+    	//cout << "\tAttr " << GetDwarfAttr(attr) << " Form " << GetDwarfForm(form) << "\n";
+    	
+    	// record anything interesting about the producer here.
+    	if (attr == DW_AT_producer)
+    		NoteProducer(aPair, info_ptr, form);
+
+    	if (attr > DW_AT_recursive)
+    		info_ptr = DefaultInfoEditFn(*this, info_ptr, form, aPair);
+    	else
+    		info_ptr = iInfoEditFn[attr](*this, info_ptr, form, aPair);
+    }
+    
+	return info_ptr;
+}
+
+
+size_t DwarfInfoManager::SizeOfDieValue(Dwarf_Half aForm, Dwarf_Byte_Ptr aPtr){
+    Dwarf_Unsigned length = 0;
+    size_t leb128_length = 0;
+    size_t ret_value = 0;
+
+    switch (aForm) {
+
+    default:			/* Handles form = 0. */
+    	return (aForm);
+
+    case DW_FORM_addr:
+    	return iAddressSize;
+
+    case DW_FORM_ref_addr:
+    	// TODO: sort this out
+    	return 4;  // this is a 4 byte relocatable in 32 bit dwarf and 8-byte in 64 bit dwarf
+
+    case DW_FORM_block1:
+    	return (*aPtr) + 1;
+
+    case DW_FORM_block2:
+    	ret_value = READ_UNALIGNED2(aPtr) + 2;
+		return ret_value;
+
+    case DW_FORM_block4:
+    	ret_value = READ_UNALIGNED4(aPtr) + 4;
+    	return ret_value;
+
+    case DW_FORM_data1:
+	return 1;
+
+    case DW_FORM_data2:
+	return 2;
+
+    case DW_FORM_data4:
+	return 4;
+
+    case DW_FORM_data8:
+	return 8;
+
+    case DW_FORM_string:
+	return (strlen((char *) aPtr) + 1);
+
+    case DW_FORM_block:
+    	length = DecodeUnsignedLeb128(aPtr, leb128_length);
+    	return length + leb128_length;
+
+    case DW_FORM_flag:
+	return 1;
+
+    case DW_FORM_ref_udata:
+    	DecodeUnsignedLeb128(aPtr, leb128_length);
+	return leb128_length;
+
+    case DW_FORM_indirect: {
+	    size_t indir_len = 0;
+	    Dwarf_Unsigned form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
+	    if (form_indirect == DW_FORM_indirect) {
+			/* 	Eek, should never happen */
+	    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
+	    }
+	    return indir_len + SizeOfDieValue(form_indirect, aPtr+indir_len);
+	}
+
+    case DW_FORM_ref1:
+    	return 1;
+
+    case DW_FORM_ref2:
+    	return 2;
+
+    case DW_FORM_ref4:
+    	return 4;
+
+    case DW_FORM_ref8:
+    	return 8;
+
+    case DW_FORM_sdata:
+    	DecodeSignedLeb128(aPtr, leb128_length);
+    	return leb128_length;
+
+    case DW_FORM_strp:
+    	// TODO: sort this out
+    	return 4;  // this is a 4 byte relocatable in 32 bit dwarf and 8-byte in 64 bit dwarf
+
+    case DW_FORM_udata:
+    	DecodeUnsignedLeb128(aPtr, leb128_length);
+    	return leb128_length;
+    }
+}
+
+Dwarf_Byte_Ptr DwarfInfoManager::DefaultInfoEditFn(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
+	return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
+}
+
+Dwarf_Byte_Ptr DwarfInfoManager::ErrorInfoEditFn(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
+	cerr << "Error: Undefined DW_FORM value: " << aForm << "\n" ;
+	exit(EXIT_FAILURE);
+	return aPtr;
+}
+
+// TODO: implicitly only deals with 32-bit DWARF
+// Called from other edit functions to deal with blocks that contain location expressions.
+Dwarf_Byte_Ptr DwarfInfoManager::InfoEditLocExpr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
+	Dwarf_Unsigned length = 0;
+	bool locExpr = false;
+	Dwarf_Byte_Ptr block = aPtr;
+	if (aForm == DW_FORM_block1) {
+		locExpr = true;
+		length = block[0];
+		block++;
+		aPtr += (length + 1); 
+	} else if (aForm == DW_FORM_block2) {
+		locExpr = true;
+		length = READ_UNALIGNED2(block);
+		block += 2;
+		aPtr += (length + 2); 
+	} else if (aForm == DW_FORM_block4) {
+		locExpr = true;
+		length = READ_UNALIGNED4(block);
+		block += 4;
+		aPtr += (length + 4); 
+	} else if (aForm == DW_FORM_block) {
+		locExpr = true;
+		size_t leb_length = 0;
+		length = DecodeUnsignedLeb128(block, leb_length);
+		block += leb_length;
+		aPtr += (length + leb_length); 
+	}
+
+	if (locExpr){		
+		EditLocationExpression (block, aManager.iAddressSize, length, aPair);
+		return aPtr;
+	} else if (aForm == DW_FORM_indirect){
+	    size_t indir_len = 0;
+	    Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
+	    if (form_indirect == DW_FORM_indirect) {
+			/* 	Eek, should never happen */
+	    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
+	    }
+	    return InfoEditLocExpr(aManager, aPtr+indir_len, form_indirect, aPair);
+	
+	} else
+		return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
+}
+// TODO: implicitly only deals with 32-bit DWARF
+Dwarf_Byte_Ptr DwarfInfoManager::InfoEditAddress(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
+	if (aForm == DW_FORM_addr){
+		LinearAddr addr = READ_UNALIGNED4(aPtr);
+		LinearAddr relocatedAddr = aPair.iXIPFileDetails.Relocate(addr);
+		WRITE_UNALIGNED4(aPtr, relocatedAddr);
+		return aPtr + 4;
+	} else if (aForm == DW_FORM_indirect){
+	    size_t indir_len = 0;
+	    Dwarf_Unsigned form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
+	    if (form_indirect == DW_FORM_indirect) {
+			/* 	Eek, should never happen */
+	    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
+	    }
+	    return InfoEditAddress(aManager, aPtr+indir_len, form_indirect, aPair);
+	
+	} else
+		return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
+}
+
+// TODO: implicitly only deals with 32-bit DWARF
+Dwarf_Byte_Ptr DwarfInfoManager::InfoEditLinePtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
+	if (aForm == DW_FORM_data4){
+		size_t offset = READ_UNALIGNED4(aPtr);
+		size_t newOffset = aManager.iDwarfManager.GetLineSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset;
+		if (offset != newOffset)
+			WRITE_UNALIGNED4(aPtr, newOffset);
+		return aPtr + 4;
+	} else if (aForm == DW_FORM_indirect){
+	    size_t indir_len = 0;
+	    Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
+	    if (form_indirect == DW_FORM_indirect) {
+			/* 	Eek, should never happen */
+	    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
+	    }
+	    return InfoEditLinePtr(aManager, aPtr+indir_len, form_indirect, aPair);
+	
+	} else
+		return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
+}
+
+// TODO: implicitly only deals with 32-bit DWARF
+Dwarf_Byte_Ptr DwarfInfoManager::InfoEditLocListPtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
+	if (aForm == DW_FORM_data4){
+		size_t offset = READ_UNALIGNED4(aPtr);
+		size_t newOffset = aManager.iDwarfManager.GetLocListSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset;
+		if (offset != newOffset)
+			WRITE_UNALIGNED4(aPtr, newOffset);
+		return aPtr + 4;
+	} else if (aForm == DW_FORM_indirect){
+	    size_t indir_len = 0;
+	    Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
+	    if (form_indirect == DW_FORM_indirect) {
+			/* 	Eek, should never happen */
+	    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
+	    }
+	    return InfoEditLocListPtr(aManager, aPtr+indir_len, form_indirect, aPair);
+	
+	} else
+		//return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
+		return InfoEditLocExpr(aManager, aPtr, aForm, aPair);
+}
+
+
+
+
+
+// TODO: implicitly only deals with 32-bit DWARF
+Dwarf_Byte_Ptr DwarfInfoManager::InfoEditMacInfoPtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
+	if (aForm == DW_FORM_data4){
+		size_t offset = READ_UNALIGNED4(aPtr);
+		size_t newOffset = aManager.iDwarfManager.GetMacInfoSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset;
+		if (offset != newOffset)
+			WRITE_UNALIGNED4(aPtr, newOffset);
+		return aPtr + 4;
+	} else if (aForm == DW_FORM_indirect){
+	    size_t indir_len = 0;
+	    Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
+	    if (form_indirect == DW_FORM_indirect) {
+			/* 	Eek, should never happen */
+	    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
+	    }
+	    return InfoEditMacInfoPtr(aManager, aPtr+indir_len, form_indirect, aPair);
+	
+	} else
+		return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
+}
+
+// TODO: implicitly only deals with 32-bit DWARF
+Dwarf_Byte_Ptr DwarfInfoManager::InfoEditRangeListPtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
+	if (aForm == DW_FORM_data4){
+		size_t offset = READ_UNALIGNED4(aPtr);
+		size_t newOffset = aManager.iDwarfManager.GetRangesSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset;
+		if (offset != newOffset)
+			WRITE_UNALIGNED4(aPtr, newOffset);
+		return aPtr + 4;
+	} else if (aForm == DW_FORM_indirect){
+	    size_t indir_len = 0;
+	    Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
+	    if (form_indirect == DW_FORM_indirect) {
+			/* 	Eek, should never happen */
+	    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
+	    }
+	    return InfoEditRangeListPtr(aManager, aPtr+indir_len, form_indirect, aPair);
+	
+	} else
+		return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
+}
+
+// TODO: implicitly only deals with 32-bit DWARF
+Dwarf_Byte_Ptr DwarfInfoManager::InfoEditString(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
+	
+	if (aForm == DW_FORM_strp){
+		size_t offset = READ_UNALIGNED4(aPtr);
+		size_t newOffset = aManager.iDwarfManager.GetStrSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset;
+		if (offset != newOffset)
+			WRITE_UNALIGNED4(aPtr, newOffset);
+		return aPtr + 4;
+	} else if (aForm == DW_FORM_indirect){
+	    size_t indir_len = 0;
+	    Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
+	    if (form_indirect == DW_FORM_indirect) {
+			/* 	Eek, should never happen */
+	    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
+	    }
+	    return InfoEditString(aManager, aPtr+indir_len, form_indirect, aPair);
+	
+	} else
+		return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
+}
+
+// TODO: implicitly only deals with 32-bit DWARF
+Dwarf_Byte_Ptr DwarfInfoManager::InfoEditReference(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
+	if (aForm == DW_FORM_ref_addr){
+		size_t offset = READ_UNALIGNED4(aPtr);
+		size_t newOffset = aManager.CheckNewOffset(aManager.GetSectionOffset(aPair.iXIPFileDetails.iElfFile), offset);
+		if (offset != newOffset)
+			WRITE_UNALIGNED4(aPtr, newOffset);
+		return aPtr + 4;
+	} else if (aForm == DW_FORM_indirect){
+	    size_t indir_len = 0;
+	    Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
+	    if (form_indirect == DW_FORM_indirect) {
+			/* 	Eek, should never happen */
+	    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
+	    }
+	    return InfoEditReference(aManager, aPtr+indir_len, form_indirect, aPair);
+	
+	} else
+		//return aPtr + aManager.SizeOfDieValue(aForm, aPtr);
+		return InfoEditLocExpr(aManager, aPtr, aForm, aPair);
+}
+
+// TODO: implicitly only deals with 32-bit DWARF
+// Explicitly check for *_address and *_strp then let the reference handler deal with the flag possiblity as s 'else'. 
+Dwarf_Byte_Ptr DwarfInfoManager::InfoEditTrampoline(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){
+	if (aForm == DW_FORM_addr)
+		return InfoEditAddress(aManager, aPtr, aForm, aPair);
+	else if (aForm = DW_FORM_strp)
+		return InfoEditString(aManager, aPtr, aForm, aPair);
+	else if (aForm == DW_FORM_indirect){
+		    size_t indir_len = 0;
+		    Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len);
+		    if (form_indirect == DW_FORM_indirect) {
+				/* 	Eek, should never happen */
+		    	cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n";
+		    }
+		    return InfoEditTrampoline(aManager, aPtr+indir_len, form_indirect, aPair);
+		
+		} 
+	else
+		return InfoEditReference(aManager, aPtr, aForm, aPair);
+}
+
+
+DwarfInfoManager::InfoEditFn DwarfInfoManager::iInfoEditFn [] = {
+	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0 so this should never be called
+	DwarfInfoManager::InfoEditReference, 	// DW_AT_sibling                           0x01
+	DwarfInfoManager::InfoEditLocListPtr, 	// DW_AT_location                          0x02
+	DwarfInfoManager::InfoEditString, 		// DW_AT_name                              0x03
+	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  4 so this should never be called
+	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  5 so this should never be called
+	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  6 so this should never be called
+	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  7 so this should never be called
+	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  8 so this should never be called
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_ordering                          0x09
+    // TODO: This doesn't appear in the DWARF 3 spec of 2005/12/05 :-( so just defualt it for now
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_subscr_data                       0x0a
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_byte_size                         0x0b
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_bit_offset                        0x0c
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_bit_size                          0x0d
+	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x0e so this should never be called
+    // TODO: This doesn't appear in the DWARF 3 spec of 2005/12/05 :-( so just defualt it for now
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_element_list                      0x0f
+    DwarfInfoManager::InfoEditLinePtr, 		// DW_AT_stmt_list                         0x10
+    DwarfInfoManager::InfoEditAddress, 		// DW_AT_low_pc                            0x11
+    DwarfInfoManager::InfoEditAddress, 		// DW_AT_high_pc                           0x12
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_language                          0x13
+    // TODO: This doesn't appear in the DWARF 3 spec of 2005/12/05 :-( so just defualt it for now
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_member                            0x14
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_discr                             0x15
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_discr_value                       0x16
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_visibility                        0x17
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_import                            0x18
+    DwarfInfoManager::InfoEditLocListPtr, 	// DW_AT_string_length                     0x19
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_common_reference                  0x1a
+    DwarfInfoManager::InfoEditString, 		// DW_AT_comp_dir                          0x1b
+    DwarfInfoManager::InfoEditString, 		// DW_AT_const_value                       0x1c
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_containing_type                   0x1d
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_default_value                     0x1e
+	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x1f so this should never be called
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_inline                            0x20
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_is_optional                       0x21
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_lower_bound                       0x22
+	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x23 so this should never be called
+	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x24 so this should never be called
+    DwarfInfoManager::InfoEditString, 		// DW_AT_producer                          0x25
+	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x26 so this should never be called
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_prototyped                        0x27
+	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x28 so this should never be called
+	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x29 so this should never be called
+    DwarfInfoManager::InfoEditLocListPtr, 	// DW_AT_return_addr                       0x2a
+	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x2b so this should never be called
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_start_scope                       0x2c
+	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x2d so this should never be called
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_bit_stride                        0x2e /* DWARF3 name */
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_upper_bound                       0x2f
+	DwarfInfoManager::ErrorInfoEditFn, 		// There is no DW_FORM  0x30 so this should never be called
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_abstract_origin                   0x31
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_accessibility                     0x32
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_address_class                     0x33
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_artificial                        0x34
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_base_types                        0x35
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_calling_convention                0x36
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_count                             0x37
+    DwarfInfoManager::InfoEditLocListPtr, 	// DW_AT_data_member_location              0x38
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_decl_column                       0x39
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_decl_file                         0x3a
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_decl_line                         0x3b
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_declaration                       0x3c
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_discr_list                        0x3d
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_encoding                          0x3e
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_external                          0x3f
+    DwarfInfoManager::InfoEditLocListPtr, 	// DW_AT_frame_base                        0x40
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_friend                            0x41
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_identifier_case                   0x42
+    DwarfInfoManager::InfoEditMacInfoPtr, 	// DW_AT_macro_info                        0x43
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_namelist_item                     0x44
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_priority                          0x45
+    DwarfInfoManager::InfoEditLocListPtr, 	// DW_AT_segment                           0x46
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_specification                     0x47
+    DwarfInfoManager::InfoEditLocListPtr, 	// DW_AT_static_link                       0x48
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_type                              0x49
+    DwarfInfoManager::InfoEditLocListPtr, 	// DW_AT_use_location                      0x4a
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_variable_parameter                0x4b
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_virtuality                        0x4c
+    DwarfInfoManager::InfoEditLocListPtr, 	// DW_AT_vtable_elem_location              0x4d
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_allocated                         0x4e /* DWARF3 */
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_associated                        0x4f /* DWARF3 */
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_data_location                     0x50 /* DWARF3 */
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_byte_stride                       0x51 /* DWARF3f */
+    DwarfInfoManager::InfoEditAddress, 		// DW_AT_entry_pc                          0x52 /* DWARF3 */
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_use_UTF8                          0x53 /* DWARF3 */
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_extension                         0x54 /* DWARF3 */
+    DwarfInfoManager::InfoEditRangeListPtr, // DW_AT_ranges                            0x55 /* DWARF3 */
+    DwarfInfoManager::InfoEditTrampoline, 	// DW_AT_trampoline                        0x56 /* DWARF3 */
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_call_column                       0x57 /* DWARF3 */
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_call_file                         0x58 /* DWARF3 */
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_call_line                         0x59 /* DWARF3 */
+    DwarfInfoManager::InfoEditString, 		// DW_AT_description                       0x5a /* DWARF3 */
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_binary_scale                      0x5b /* DWARF3f */
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_decimal_scale                     0x5c /* DWARF3f */
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_small                             0x5d /* DWARF3f */
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_decimal_sign                      0x5e /* DWARF3f */
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_digit_count                       0x5f /* DWARF3f */
+    DwarfInfoManager::InfoEditString, 		// DW_AT_picture_string                    0x60 /* DWARF3f */
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_mutable                           0x61 /* DWARF3f */
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_threads_scaled                    0x62 /* DWARF3f */
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_explicit                          0x63 /* DWARF3f */
+    DwarfInfoManager::InfoEditReference, 	// DW_AT_object_pointer                    0x64 /* DWARF3f */
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_endianity                         0x65 /* DWARF3f */
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_elemental                         0x66 /* DWARF3f */
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_pure                              0x67 /* DWARF3f */
+    DwarfInfoManager::DefaultInfoEditFn, 	// DW_AT_recursive                         0x68 /* DWARF3f */
+};
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/dwarflinemanager.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,185 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <iostream>
+#include "dwarfmanager.h"
+#include "inputfile.h"
+
+const string DwarfLineManager::iLineSectionName(".debug_line");
+
+inline static size_t process_extended_line_op (FileShdrPair & aPair, Dwarf_Byte_Ptr data)
+{
+	size_t bytes_read;
+	size_t len = (size_t)ULEB128(data, bytes_read);
+
+	if (len == 0){
+		cerr << "badly formed extended line op encountered!\n";
+		// a length of 0 indicates a badly formed op and will force everything to be ignored until 'end_of_sequence'.
+		return 0;
+	}
+
+	len += bytes_read;
+	unsigned char op_code = *data++;
+  	switch (op_code){
+    case DW_LNE_end_sequence:
+      	break;
+    case DW_LNE_set_address: {
+    	size_t size = len - bytes_read - 1;
+		LinearAddr addr = GetValue(data, size);
+		LinearAddr relocatedAddress = aPair.iXIPFileDetails.Relocate(addr);
+		if (addr != relocatedAddress)
+			WriteValue(data, relocatedAddress, size);
+		break;
+    	}
+    case DW_LNE_define_file:
+      	ULEB128(data, bytes_read);
+      	ULEB128(data, bytes_read);
+      	ULEB128(data, bytes_read);
+      	break;     
+    default:
+
+    	break;
+    }
+
+  return len;
+}
+
+void DwarfLineManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr aStart, Dwarf_Byte_Ptr aEnd){
+	Dwarf_Byte_Ptr start = aStart;
+	Dwarf_Byte_Ptr end = aEnd;
+	size_t bytes_read = 0;
+	while (start < end){
+		Dwarf_Byte_Ptr hdrptr = start;		
+		size_t offset_size, initial_length_size;
+		
+		Dwarf_Word length = READ_UNALIGNED4(hdrptr); 
+		hdrptr += 4;
+
+		if (length >= 0xfffffff0u) {
+			cerr << "Error: 64 bit DWARF not supported\n";
+			exit(EXIT_FAILURE);
+		} else {	
+			offset_size = 4;
+			initial_length_size = 4;
+		}
+		
+		Dwarf_Byte_Ptr end_of_sequence = start + length + initial_length_size;
+
+		Dwarf_Half version = READ_UNALIGNED2(hdrptr);
+		hdrptr += 2;
+
+		if (version != 2 && version != 3){
+			static bool warned = false;
+			if (!warned){
+				cerr << "Only DWARF 2 and 3 aranges are currently supported\n";
+				warned = true;
+			}
+			return;
+		}
+		
+		hdrptr += offset_size;
+#if 0
+		// Don't need the next four fields 
+		Dwarf_Ubyte min_insn_length = *hdrptr++;   
+		Dwarf_Ubyte default_is_stmt = *hdrptr++;
+		Dwarf_Ubyte line_base = *hdrptr++;
+		Dwarf_Ubyte line_range = *hdrptr++;
+#endif
+		hdrptr +=4;
+		Dwarf_Ubyte opcode_base = *hdrptr++;
+
+	    /* Skip the contents of the Opcodes table.  */
+		Dwarf_Byte_Ptr standard_opcodes = hdrptr;
+		start = standard_opcodes + opcode_base - 1;
+
+		/* skip the contents of the Directory table.  */
+		while (*start != 0){
+			start += strlen ((char *) start) + 1;
+		}
+		/* Skip the NUL at the end of the table.  */
+		start++;
+
+		/* skip the contents of the File Name table.  */
+		while (*start != 0){
+			start += strlen ((char *) start) + 1;
+
+			ULEB128(start, bytes_read);
+			ULEB128(start, bytes_read);
+			ULEB128(start, bytes_read);
+		}
+		/* Skip the NUL at the end of the table.  */
+		start++;
+	   
+		while (start < end_of_sequence){
+			unsigned char op_code = *start++;
+
+			if (op_code >= opcode_base){
+				continue;
+			} else {
+				switch (op_code){
+// missing from dwarf.h - first byte of extended op codes is '0x0'
+#define DW_LNS_extended_op 0x0
+				case DW_LNS_extended_op:
+					size_t n = process_extended_line_op (aPair, start);
+					// if we don't understand the extended op skip to the end of the sequence :-(
+					if (n == 0)
+						start = end_of_sequence;
+					else 
+						start += n;
+					break;
+
+				case DW_LNS_copy:
+					break;
+
+				case DW_LNS_advance_pc:
+				case DW_LNS_advance_line:
+				case DW_LNS_set_file:
+				case DW_LNS_set_column:
+					ULEB128(start, bytes_read);
+					break;
+
+				case DW_LNS_negate_stmt:
+				case DW_LNS_set_basic_block:
+				case DW_LNS_const_add_pc:
+					break;
+
+				case DW_LNS_fixed_advance_pc:
+					start += 2;
+					break;
+
+				case DW_LNS_set_prologue_end:
+				case DW_LNS_set_epilogue_begin:
+					break;
+
+				case DW_LNS_set_isa:
+					ULEB128(start, bytes_read);
+					break;
+
+				default:
+					for (int i = standard_opcodes[op_code - 1]; i > 0 ; --i){
+						ULEB128(start, bytes_read);
+					}
+					break;
+				}
+			}
+		}
+		// !! eek ARM seems to require header word aligned - at least for Dwarf 2
+		if (aPair.iXIPFileDetails.iRVCTProduced && (version == 2))
+			start = (Dwarf_Byte_Ptr)(((unsigned long)start + 3) & ~3);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/dwarflocexpr.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,271 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <iostream>
+#include "dwarfmanager.h"
+
+void EditLocationExpression (Dwarf_Byte_Ptr data, unsigned int pointer_size, unsigned long length, FileShdrPair & aPair)
+{
+	unsigned op;
+	size_t bytes_read;
+	Dwarf_Byte_Ptr end = data + length;
+
+	while (data < end){
+		op = *data++;
+
+		switch (op){
+		case DW_OP_addr:
+			LinearAddr addr = READ_UNALIGNED4(data);
+			LinearAddr relocatedAddr = aPair.iXIPFileDetails.Relocate(addr);
+			WRITE_UNALIGNED4(data, relocatedAddr);
+			data += pointer_size;
+			break;
+		case DW_OP_deref:
+			break;
+		case DW_OP_const1u:
+		case DW_OP_const1s:
+			data++;
+			break;
+		case DW_OP_const2u:
+		case DW_OP_const2s:
+			data += 2;
+			break;
+		case DW_OP_const4u:
+		case DW_OP_const4s:
+			data += 4;
+			break;
+		case DW_OP_const8u:
+		case DW_OP_const8s:
+			data += 8;
+			break;
+		case DW_OP_constu:
+		case DW_OP_consts: 
+		{
+			ULEB128(data, bytes_read);
+			break;
+		}
+		case DW_OP_dup:
+		case DW_OP_drop:
+		case DW_OP_over:
+			break;
+		case DW_OP_pick:
+			data++;
+			break;
+		case DW_OP_swap:
+		case DW_OP_rot:
+		case DW_OP_xderef:
+		case DW_OP_abs:
+		case DW_OP_and:
+		case DW_OP_div:
+		case DW_OP_minus:
+		case DW_OP_mod:
+		case DW_OP_mul:
+		case DW_OP_neg:
+		case DW_OP_not:
+		case DW_OP_or:
+		case DW_OP_plus:
+			break;
+		case DW_OP_plus_uconst:
+		{
+			ULEB128(data, bytes_read);
+			break;
+		}
+		case DW_OP_shl:
+		case DW_OP_shr:
+		case DW_OP_shra:
+		case DW_OP_xor:
+			break;
+		case DW_OP_bra:
+			data += 2;
+			break;
+		case DW_OP_eq:
+		case DW_OP_ge:
+		case DW_OP_gt:
+		case DW_OP_le:
+		case DW_OP_lt:
+		case DW_OP_ne:
+			break;
+		case DW_OP_skip:
+			data += 2;
+			break;
+
+		case DW_OP_lit0:
+		case DW_OP_lit1:
+		case DW_OP_lit2:
+		case DW_OP_lit3:
+		case DW_OP_lit4:
+		case DW_OP_lit5:
+		case DW_OP_lit6:
+		case DW_OP_lit7:
+		case DW_OP_lit8:
+		case DW_OP_lit9:
+		case DW_OP_lit10:
+		case DW_OP_lit11:
+		case DW_OP_lit12:
+		case DW_OP_lit13:
+		case DW_OP_lit14:
+		case DW_OP_lit15:
+		case DW_OP_lit16:
+		case DW_OP_lit17:
+		case DW_OP_lit18:
+		case DW_OP_lit19:
+		case DW_OP_lit20:
+		case DW_OP_lit21:
+		case DW_OP_lit22:
+		case DW_OP_lit23:
+		case DW_OP_lit24:
+		case DW_OP_lit25:
+		case DW_OP_lit26:
+		case DW_OP_lit27:
+		case DW_OP_lit28:
+		case DW_OP_lit29:
+		case DW_OP_lit30:
+		case DW_OP_lit31:
+			break;
+
+		case DW_OP_reg0:
+		case DW_OP_reg1:
+		case DW_OP_reg2:
+		case DW_OP_reg3:
+		case DW_OP_reg4:
+		case DW_OP_reg5:
+		case DW_OP_reg6:
+		case DW_OP_reg7:
+		case DW_OP_reg8:
+		case DW_OP_reg9:
+		case DW_OP_reg10:
+		case DW_OP_reg11:
+		case DW_OP_reg12:
+		case DW_OP_reg13:
+		case DW_OP_reg14:
+		case DW_OP_reg15:
+		case DW_OP_reg16:
+		case DW_OP_reg17:
+		case DW_OP_reg18:
+		case DW_OP_reg19:
+		case DW_OP_reg20:
+		case DW_OP_reg21:
+		case DW_OP_reg22:
+		case DW_OP_reg23:
+		case DW_OP_reg24:
+		case DW_OP_reg25:
+		case DW_OP_reg26:
+		case DW_OP_reg27:
+		case DW_OP_reg28:
+		case DW_OP_reg29:
+		case DW_OP_reg30:
+		case DW_OP_reg31:
+			break;
+
+		case DW_OP_breg0:
+		case DW_OP_breg1:
+		case DW_OP_breg2:
+		case DW_OP_breg3:
+		case DW_OP_breg4:
+		case DW_OP_breg5:
+		case DW_OP_breg6:
+		case DW_OP_breg7:
+		case DW_OP_breg8:
+		case DW_OP_breg9:
+		case DW_OP_breg10:
+		case DW_OP_breg11:
+		case DW_OP_breg12:
+		case DW_OP_breg13:
+		case DW_OP_breg14:
+		case DW_OP_breg15:
+		case DW_OP_breg16:
+		case DW_OP_breg17:
+		case DW_OP_breg18:
+		case DW_OP_breg19:
+		case DW_OP_breg20:
+		case DW_OP_breg21:
+		case DW_OP_breg22:
+		case DW_OP_breg23:
+		case DW_OP_breg24:
+		case DW_OP_breg25:
+		case DW_OP_breg26:
+		case DW_OP_breg27:
+		case DW_OP_breg28:
+		case DW_OP_breg29:
+		case DW_OP_breg30:
+		case DW_OP_breg31:
+		case DW_OP_fbreg:
+		{
+			ULEB128(data, bytes_read);
+			break;
+		}
+		case DW_OP_bregx:
+		{
+			ULEB128(data, bytes_read);
+			ULEB128(data, bytes_read);
+			break;
+		}
+		case DW_OP_piece:
+		{
+			ULEB128(data, bytes_read);
+			break;
+		}
+		case DW_OP_deref_size:
+		case DW_OP_xderef_size:
+			data++;
+			break;
+		case DW_OP_nop:
+		  /* DWARF 3 extensions.  */
+		case DW_OP_push_object_address:
+		  break;
+		case DW_OP_call2:
+		  /* XXX: Strictly speaking for 64-bit DWARF3 files
+		     this ought to be an 8-byte wide computation.  */
+		  data += 2;
+		  break;
+		case DW_OP_call4:
+		  /* XXX: Strictly speaking for 64-bit DWARF3 files
+		     this ought to be an 8-byte wide computation.  */
+		  data += 4;
+		  break;
+		case DW_OP_call_ref:
+		  /* XXX: Strictly speaking for 64-bit DWARF3 files
+		     this ought to be an 8-byte wide computation.  */
+		  data += 4;
+		  break;
+		case DW_OP_form_tls_address:
+		case DW_OP_call_frame_cfa:
+		  break;
+		case DW_OP_bit_piece:
+		{
+			// Handily the spec doesn't describe the operands - but by analogy with
+			// DW_OP_piece we assume these are ULEB128 encoded.
+			ULEB128(data, bytes_read);
+			ULEB128(data, bytes_read);
+			break;
+		}
+	
+		/* GNU extensions.  */
+		case DW_OP_GNU_push_tls_address:
+		//case DW_OP_GNU_uninit:
+			/* FIXME: Is there data associated with this OP ?  */
+			break;
+
+		default:
+			// bail - can't do anything else sensible here
+			cerr << "Warning: Unrecognized opcode " << op << " in Dwarf expression.\n";
+		  return;
+		}
+
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/dwarflocmanager.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,66 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <iostream>
+#include "dwarfmanager.h"
+#include "inputfile.h"
+
+const string DwarfLocManager::iLocSectionName(".debug_loc");
+
+void DwarfLocManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr aStart, Dwarf_Byte_Ptr aEnd){
+	Dwarf_Byte_Ptr start = aStart;
+	Dwarf_Byte_Ptr end = aEnd;
+	size_t pointer_size = iDwarfInfoManager.GetPointerSize();
+	while (start < end){
+		// TODO: this doesn't deal with 64-bit Dwarf
+		Dwarf_Byte_Ptr lower = start;
+		Dwarf_Word w1 = GetValue(start, pointer_size);
+		start+= pointer_size;
+		Dwarf_Byte_Ptr upper = start;
+		Dwarf_Word w2  = GetValue(start, pointer_size);
+		start+= pointer_size;
+
+		if (w1 == 0 && w2 == 0){
+			continue;
+		}
+		if (w1 == 0xffffffff){
+			LinearAddr addr = w2;
+			LinearAddr relocatedAddress = aPair.iXIPFileDetails.Relocate(addr);
+			if (addr != relocatedAddress)
+				WriteValue(start - pointer_size, relocatedAddress, pointer_size);
+			continue;
+		}
+
+		if (aPair.iXIPFileDetails.iGCCProduced){
+			LinearAddr addr = w1;
+			LinearAddr relocatedAddress = aPair.iXIPFileDetails.Relocate(addr);
+			if (addr != relocatedAddress)
+				WriteValue(lower, relocatedAddress, pointer_size);			
+			addr = w2;
+			relocatedAddress = aPair.iXIPFileDetails.Relocate(addr);
+			if (addr != relocatedAddress)
+				WriteValue(upper, relocatedAddress, pointer_size);			
+		}
+		
+		Dwarf_Half length = GetValue(start, 2);
+		start += 2;
+		EditLocationExpression (start, pointer_size, length, aPair);		
+		start += length;
+
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/dwarfmanager.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,436 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <iostream>
+#include <iomanip>
+
+#include "dwarfmanager.h"
+#include "inputfile.h"
+#include "outputfile.h"
+#include "filefragment.h"
+
+void DwarfSectionManager::AddSection(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr){
+	if (iRomDetails->iTrace){
+		cout << "    " << GetSectionName() << " - DWARF\n";
+	}
+
+	FileShdrPair aFileShdrPair(aXIPFileDetails, aShdr);
+	iFileShdrList.push_back(aFileShdrPair);
+}
+
+void DwarfSectionManager::SetupSection(){
+	if (!iFileShdrList.empty()){
+		ElfSectionElfData * aDwarfSectionData = new ElfSectionElfData(*this);
+		Elf32_Shdr aDwarfShdr;
+		aDwarfShdr.sh_name = 0; // for now.
+		aDwarfShdr.sh_type = SHT_PROGBITS;
+		aDwarfShdr.sh_flags = 0;
+		aDwarfShdr.sh_addr = 0;
+		aDwarfShdr.sh_offset = 0; // for now
+		aDwarfShdr.sh_size = 0; // for now.
+		aDwarfShdr.sh_link = 0;
+		aDwarfShdr.sh_info = 0;
+		aDwarfShdr.sh_addralign = 4;
+		aDwarfShdr.sh_entsize = sizeof(Elf32_Sym);
+		
+		ElfSection aDwarfSection(aDwarfSectionData, GetSectionName().c_str(), aDwarfShdr);
+		iElfSectionManager.AddSection(aDwarfSection);
+	}
+}
+
+Dwarf_Unsigned DwarfSectionManager::DecodeUnsignedLeb128(Dwarf_Byte_Ptr leb128, size_t & leb128_length){
+	Dwarf_Ubyte byte;
+    Dwarf_Word word_number;
+    Dwarf_Unsigned number;
+    Dwarf_Sword shift;
+    Dwarf_Sword byte_length;
+
+    /* The following unrolls-the-loop for the first few bytes and
+       unpacks into 32 bits to make this as fast as possible.
+       word_number is assumed big enough that the shift has a defined
+       result. */
+    if ((*leb128 & 0x80) == 0) {
+    	leb128_length = 1;
+    	return *leb128;
+    } else if ((*(leb128 + 1) & 0x80) == 0) {
+    	leb128_length = 2;
+
+    	word_number = *leb128 & 0x7f;
+    	word_number |= (*(leb128 + 1) & 0x7f) << 7;
+    	return word_number;
+    } else if ((*(leb128 + 2) & 0x80) == 0) {
+    	leb128_length = 3;
+
+    	word_number = *leb128 & 0x7f;
+    	word_number |= (*(leb128 + 1) & 0x7f) << 7;
+    	word_number |= (*(leb128 + 2) & 0x7f) << 14;
+    	return word_number;
+    } else if ((*(leb128 + 3) & 0x80) == 0) {
+    	leb128_length = 4;
+
+    	word_number = *leb128 & 0x7f;
+    	word_number |= (*(leb128 + 1) & 0x7f) << 7;
+    	word_number |= (*(leb128 + 2) & 0x7f) << 14;
+    	word_number |= (*(leb128 + 3) & 0x7f) << 21;
+    	return word_number;
+    }
+
+    /* The rest handles long numbers Because the 'number' may be larger 
+       than the default int/unsigned, we must cast the 'byte' before
+       the shift for the shift to have a defined result. */
+    number = 0;
+    shift = 0;
+    byte_length = 1;
+    byte = *(leb128);
+    for (;;) {
+    	number |= ((Dwarf_Unsigned) (byte & 0x7f)) << shift;
+
+    	if ((byte & 0x80) == 0) {
+    		leb128_length = byte_length;
+    		return number;
+    	}
+    	shift += 7;
+
+    	byte_length++;
+    	++leb128;
+    	byte = *leb128;
+    }
+}
+
+#define BITSINBYTE 8
+Dwarf_Signed DwarfSectionManager::DecodeSignedLeb128(Dwarf_Byte_Ptr leb128, size_t & leb128_length){
+    Dwarf_Signed number = 0;
+    Dwarf_Bool sign = 0;
+    Dwarf_Word shift = 0;
+    Dwarf_Ubyte byte = *leb128;
+    Dwarf_Word byte_length = 1;
+
+    /* byte_length being the number of bytes of data absorbed so far in 
+       turning the leb into a Dwarf_Signed. */
+
+    for (;;) {
+    	sign = byte & 0x40;
+    	number |= ((Dwarf_Signed) ((byte & 0x7f))) << shift;
+    	shift += 7;
+
+    	if ((byte & 0x80) == 0) {
+    		break;
+    	}
+    	++leb128;
+    	byte = *leb128;
+    	byte_length++;
+    }
+
+    if ((shift < sizeof(Dwarf_Signed) * BITSINBYTE) && sign) {
+    	number |= -((Dwarf_Signed) 1 << shift);
+    }
+
+    leb128_length = byte_length;
+    return number;
+}
+
+Dwarf_Byte_Ptr DwarfSectionManager::GetSectionData(FileShdrPair & aPair){
+
+	InputFile in(aPair.iXIPFileDetails.iElfFile);
+	in.SetOffset(aPair.iShdr.sh_offset);
+	return (Dwarf_Byte_Ptr)in.GetData(aPair.iShdr.sh_size);
+}
+
+void DwarfConcatenatedSectionManager::GetFileFragmentData(FileFragmentData & aFileFragmentData ){
+	ConcatenateData();
+	if (iRomDetails->iTrace){
+		cout << "\nGenerating DWARF section " << GetSectionName() << " size = "
+		<< dec << Size() << " bytes\n";
+	} 
+	FileShdrList::iterator e = iFileShdrList.end();
+	for (FileShdrList::iterator i = iFileShdrList.begin(); i < e; i++){
+		if (iRomDetails->iTrace){
+			cout << "    " << i->iXIPFileDetails.iElfFile << " " << dec << i->iShdr.sh_size << " bytes\n" << flush;
+		}
+		ProcessSection(*i);
+	}	
+	SetFileFragmentData(aFileFragmentData, iSize, reinterpret_cast<char *>(iData));
+}
+
+void DwarfConcatenatedSectionManager::ConcatenateData(){
+	if (iData == NULL) {
+		size_t sectionSize = Size();
+		iData = new Dwarf_Ubyte[sectionSize];
+		Dwarf_Byte_Ptr p = iData;
+		FileShdrList::iterator e = iFileShdrList.end();
+		for (FileShdrList::iterator i = iFileShdrList.begin(); i < e; i++){
+			size_t off = p - iData;
+			size_t soff = GetSectionOffset(i->iXIPFileDetails.iElfFile);
+			if (off >= sectionSize)
+				assert(off < sectionSize);
+			if (off != soff)
+				assert(off == soff);
+			size_t n = i->iShdr.sh_size;
+			Dwarf_Byte_Ptr contrib = GetSectionData(*i);
+			memcpy(p, contrib, n);
+			p += n;
+			delete [] contrib;
+		}
+	}
+}
+
+size_t DwarfConcatenatedSectionManager::Size(){
+	if (iSizeValid)
+		return iSize;
+	//cerr << "Size for " << GetSectionName() << "\n";
+	size_t offset = 0;
+	FileShdrList::iterator e = iFileShdrList.end();
+	for (FileShdrList::iterator i = iFileShdrList.begin(); i != e; i++){
+		//cerr << "offset = 0x" << offset << "\t";
+		SetSectionOffset(i->iXIPFileDetails.iElfFile, offset);
+		size_t size = i->iShdr.sh_size;
+		//cerr << "section size for " << i->iXIPFileDetails.iElfFile << " 0x" << size << "\n";
+		SetSectionSize(i->iXIPFileDetails.iElfFile, size);
+		size_t newOffset = offset + size;
+		if (newOffset < offset){
+			cerr << "Error: The combined section " << GetSectionName() 
+				<< " requires translation from 32 to 64 bit Dwarf which is not currently supported.\n"
+				<< "Exclude the following files (or their equivalent in terms of their contribution to Dwarf):\n";
+			for (; i != e; i++){
+				cerr << i->iXIPFileDetails.iE32File << "\n";
+			}
+			exit(EXIT_FAILURE);
+		}
+		offset = newOffset;
+	}
+	//cerr << "Size = 0x" << offset << "\n";
+	iSizeValid = true;
+	return iSize = offset;
+}
+
+void DwarfConcatenatedSectionManager::ProcessSection(FileShdrPair & aPair){
+	Dwarf_Byte_Ptr start = GetSection(aPair.iXIPFileDetails.iElfFile);
+	Dwarf_Byte_Ptr end = start + aPair.iShdr.sh_size;
+	ProcessSection(aPair, start, end);
+}
+
+void DwarfConcatenatedSectionManager::SetSectionOffset(PathName & aPathName, size_t aOffset) {
+	iPathNameSectionOffsetMap[aPathName] = aOffset;
+}
+
+void DwarfConcatenatedSectionManager::InitOffsetMap(){ 
+	Size();  // forces the map to be set up if it hasn't been already
+}
+
+size_t DwarfConcatenatedSectionManager::GetSectionOffset(PathName & aPathName){
+	if (!iSizeValid) // if the size is valid then so must be the offsets.
+		InitOffsetMap(); 
+	return iPathNameSectionOffsetMap[aPathName];
+}
+
+void DwarfConcatenatedSectionManager::SetSectionSize(PathName & aPathName, size_t aSize) {
+		iPathNameSectionSizeMap[aPathName] = aSize;
+}
+
+size_t DwarfConcatenatedSectionManager::GetSectionSize(PathName & aPathName){
+	if (!iSizeValid) // if the size is valid then so must be the offsets.
+		InitOffsetMap(); 
+	return iPathNameSectionSizeMap[aPathName];
+}
+
+Dwarf_Byte_Ptr DwarfConcatenatedSectionManager::GetSection(PathName & aPathName){
+	ConcatenateData();
+	size_t offset = GetSectionOffset(aPathName);
+	return iData + offset;
+}
+
+class ElfSectionFragmentedDwarfData : public ElfSectionElfData {
+public:
+	ElfSectionFragmentedDwarfData(FileFragmentOwner & aSource) :
+		ElfSectionElfData(aSource)
+	{}
+	
+	ElfSectionFragmentedDwarfData(const ElfSectionElfData & aData) :
+		ElfSectionElfData(aData)
+	{}	
+	
+	// ElfSection protocol
+	virtual ElfSectionFragmentedDwarfData * Clone(){
+		return new ElfSectionFragmentedDwarfData(*this);
+	}
+	
+	virtual void AddData(OutputFile & aOutputFile){
+		return;
+	}
+};
+
+class DwarfSectionFragment : public FileFragmentOwner {
+public:
+	DwarfSectionFragment(DwarfFragmentedSectionManager & aSource,
+						 FileShdrPair & aPair):
+		iSource(aSource),
+		iPair(aPair),
+		iData(NULL)
+		{}
+	
+	// Bitwise copy is OK so don't need to write our own copy ctor etc.
+	
+	// The FileFragmentOwner protocol
+	virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData );
+	virtual size_t Size();
+	virtual void DeleteFileFragmentData();
+	
+private:
+	DwarfSectionFragment();
+	
+private:
+	DwarfFragmentedSectionManager & iSource;
+	FileShdrPair & iPair;
+	Dwarf_Byte_Ptr iData;
+};
+
+void DwarfSectionFragment::GetFileFragmentData(FileFragmentData & aFileFragmentData ){
+	iSource.ProcessSection(iPair, iData);	
+	SetFileFragmentData(aFileFragmentData, Size(), reinterpret_cast<char *>(iData));	
+}
+
+size_t DwarfSectionFragment::Size(){
+	return iPair.iShdr.sh_size;
+}
+
+void DwarfSectionFragment::DeleteFileFragmentData(){
+	delete [] iData;
+	// 
+	delete this;
+}
+
+void DwarfFragmentedSectionManager::SetupSection(){
+	if (!iFileShdrList.empty()){
+		ElfSectionFragmentedDwarfData * aDwarfSectionData = new ElfSectionFragmentedDwarfData(*this);
+		Elf32_Shdr aDwarfShdr;
+		aDwarfShdr.sh_name = 0; // for now.
+		aDwarfShdr.sh_type = SHT_PROGBITS;
+		aDwarfShdr.sh_flags = 0;
+		aDwarfShdr.sh_addr = 0;
+		aDwarfShdr.sh_offset = 0; // for now
+		aDwarfShdr.sh_size = 0; // for now.
+		aDwarfShdr.sh_link = 0;
+		aDwarfShdr.sh_info = 0;
+		aDwarfShdr.sh_addralign = 4;
+		aDwarfShdr.sh_entsize = sizeof(Elf32_Sym);
+		
+		// aDwarfSectionData will ask the secton manager (i.e. its source) for the offset of the section.
+		// So we better record it here. We assume that it is the current size of the output file.
+		// As long as we are single threaded and all the fragments get added consecutively as below
+		// this is a safe assumption.
+		SetOffset(iDwarfManager.GetOutputFile().Size());
+		
+		ElfSection aDwarfSection(aDwarfSectionData, GetSectionName().c_str(), aDwarfShdr);
+		iElfSectionManager.AddSection(aDwarfSection);
+		
+		for (FileShdrList::iterator i = iFileShdrList.begin(); i < iFileShdrList.end(); i++ ){
+			DwarfSectionFragment * aFrag = new DwarfSectionFragment(*this, *i);
+			aFrag->AddData(iDwarfManager.GetOutputFile());
+		}
+	}
+}
+
+// NB the section itself doesn't write any data
+// The FileFragmentOwner protocol
+
+void DwarfFragmentedSectionManager::GetFileFragmentData(FileFragmentData & aFileFragmentData ){	
+	SetFileFragmentData(aFileFragmentData, 0, reinterpret_cast<char *>(NULL));
+}
+
+// This should never get called
+void DwarfFragmentedSectionManager::ConcatenateData(){
+	assert(1 == 0);
+	return;
+}
+
+void DwarfFragmentedSectionManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr & aData){
+	if (iInitialTraceMessage & iRomDetails->iTrace){
+		cout << "\nGenerating DWARF section " << GetSectionName() << " size = "
+			<< dec << Size() << " bytes\n";
+		iInitialTraceMessage = false;
+	}
+	if (iRomDetails->iTrace){
+		cout << "    " << aPair.iXIPFileDetails.iElfFile << " size = " 
+		<< dec << aPair.iShdr.sh_size << "\n" << flush; 
+	}
+	Dwarf_Byte_Ptr start = GetSectionData(aPair);
+	aData = start;
+	Dwarf_Byte_Ptr end = start + aPair.iShdr.sh_size;
+	ProcessSection(aPair, start, end);
+}
+
+#if 0
+// This should never get called
+void DwarfFragmentedSectionManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end){
+	assert(1 == 0);
+	return;
+}
+#endif
+
+const string DwarfMacinfoManager::iMacinfoSectionName(".debug_macinfo");
+const string DwarfStrManager::iStrSectionName(".debug_str");
+
+
+void DwarfManager::AddSection(XIPFileDetails & aXIPFileDetails, string aSectionName, Elf32_Shdr * aShdr){
+	if (iDwarfAbbrevManager.GetSectionName() == aSectionName)
+		iDwarfAbbrevManager.AddSection(aXIPFileDetails, aShdr);
+	else if (iDwarfArangesManager.GetSectionName() == aSectionName)
+		iDwarfArangesManager.AddSection(aXIPFileDetails, aShdr);
+	else if (iDwarfFrameManager.GetSectionName() == aSectionName)
+		iDwarfFrameManager.AddSection(aXIPFileDetails, aShdr);
+	else if (iDwarfInfoManager.GetSectionName() == aSectionName)
+		iDwarfInfoManager.AddSection(aXIPFileDetails, aShdr);
+	else if (iDwarfLineManager.GetSectionName() == aSectionName)
+		iDwarfLineManager.AddSection(aXIPFileDetails, aShdr);
+	else if (iDwarfLocManager.GetSectionName() == aSectionName)
+		iDwarfLocManager.AddSection(aXIPFileDetails, aShdr);
+	else if (iDwarfMacinfoManager.GetSectionName() == aSectionName)
+		iDwarfMacinfoManager.AddSection(aXIPFileDetails, aShdr);
+	else if (iDwarfPubnamesManager.GetSectionName() == aSectionName)
+		iDwarfPubnamesManager.AddSection(aXIPFileDetails, aShdr);
+	else if (iDwarfPubtypesManager.GetSectionName() == aSectionName)
+		iDwarfPubtypesManager.AddSection(aXIPFileDetails, aShdr);
+	else if (iDwarfRangesManager.GetSectionName() == aSectionName)
+		iDwarfRangesManager.AddSection(aXIPFileDetails, aShdr);
+	else if (iDwarfStrManager.GetSectionName() == aSectionName)
+		iDwarfStrManager.AddSection(aXIPFileDetails, aShdr);
+#if 0
+	else
+		cerr << "Warning: unrecognised debug section name " << aSectionName << " ignored\n";
+#endif
+}
+
+void DwarfManager::SetupSections(){
+	// The order here is important for fix up
+	// first the purely concatenated 'leaf' sections
+	// See the diagram on p.182 of the Dwarf 3 spec
+	// to understand the 'dependenices'
+	iDwarfAbbrevManager.SetupSection();
+	iDwarfFrameManager.SetupSection();
+	iDwarfPubnamesManager.SetupSection();
+	iDwarfPubtypesManager.SetupSection();
+	iDwarfArangesManager.SetupSection();	
+	iDwarfMacinfoManager.SetupSection();
+	
+	iDwarfInfoManager.SetupSection();
+	iDwarfLineManager.SetupSection();
+	iDwarfLocManager.SetupSection();
+
+	iDwarfRangesManager.SetupSection();
+	iDwarfStrManager.SetupSection();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/dwarfmanager.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,699 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef DWARFMANAGER_H_
+#define DWARFMANAGER_H_
+
+#include <vector>
+#include <map>
+#include <string>
+#include <libelf.h>
+
+#include "dwarfdefs.h"
+#include "dwarf.h"
+#include "defs.h"
+#include "filefragment.h"
+#include "romdetails.h"
+#include "elfsectionmanager.h"
+
+using namespace std;
+
+class FileShdrPair {
+public:
+	FileShdrPair(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr):
+		iXIPFileDetails(aXIPFileDetails),
+		iShdr(*aShdr)
+	{}
+	FileShdrPair & FileShdrPair::operator=(const FileShdrPair & aFileShdrPair) {
+		iXIPFileDetails = aFileShdrPair.iXIPFileDetails;
+		iShdr = aFileShdrPair.iShdr;
+		return *this;
+	}
+
+	FileShdrPair::FileShdrPair(const FileShdrPair &aFileShdrPair):
+		iXIPFileDetails(aFileShdrPair.iXIPFileDetails),
+		iShdr(aFileShdrPair.iShdr)
+	{}
+	
+	XIPFileDetails & iXIPFileDetails;
+	Elf32_Shdr iShdr;
+};
+
+typedef std::vector<FileShdrPair> FileShdrList;
+
+void EditLocationExpression (Dwarf_Byte_Ptr data, 
+							 unsigned int pointer_size, 
+							 unsigned long length, 
+							 FileShdrPair & aPair);
+class DwarfManager;
+
+class DwarfSectionManager : public FileFragmentOwner {
+public:
+	DwarfSectionManager(ElfSectionManager & aElfSectionManager, 
+						DwarfManager & aDwarfManager, 
+						const string & aName, 
+						RomDetails * aRomDetails):
+		iElfSectionManager(aElfSectionManager),
+		iDwarfManager(aDwarfManager),
+		iSectionName(aName),
+		iSizeValid(false),
+		iSize(0),
+		iData(NULL),
+		iRomDetails(aRomDetails)
+	{}
+	
+	virtual ~DwarfSectionManager() {
+		iFileShdrList.clear();
+	}
+	
+	// The FileFragmentOwner protocol
+	virtual void DeleteFileFragmentData(){
+		if (iData) {
+			Dwarf_Byte_Ptr d = iData;
+			iData = NULL;
+			delete [] d;
+		}
+	}
+
+	virtual void AddSection(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr);
+	virtual void SetupSection();
+	const string & GetSectionName() { return iSectionName; }
+	virtual Dwarf_Byte_Ptr GetSectionData(FileShdrPair & aPair);
+		
+
+	
+	// LEB decoding
+	// Leb128 decoding used by all Dwarf section managers (potentially)
+	// TODO could get rid of LEB macros and define as inline functions.
+#define DECODE_ULEB128(v,p,n) \
+		Dwarf_Word v = DwarfSectionManager::DecodeUnsignedLeb128(p, n);\
+		p += n;
+#define ULEB128(p,n) \
+		DwarfSectionManager::DecodeUnsignedLeb128(p, n);\
+		p += n;
+	static Dwarf_Unsigned DecodeUnsignedLeb128(Dwarf_Byte_Ptr leb128, size_t & leb128_length);
+#define DECODE_SLEB128(v,p,n) \
+		Dwarf_Word v = DwarfSectionManager::DecodeSignedLeb128(p, n);\
+		p += n;
+#define SLEB128(p,n) \
+		DwarfSectionManager::DecodeSignedLeb128(p, n);\
+		p += n;
+	static Dwarf_Signed DecodeSignedLeb128(Dwarf_Byte_Ptr leb128, size_t & leb128_length);
+	
+private:
+	// Don't want one of these to be copied
+	DwarfSectionManager(const DwarfSectionManager & aDwarfSectionManager);
+	
+	DwarfSectionManager & operator=(const DwarfSectionManager & aDwarfSectionManager);
+protected:
+
+	virtual Dwarf_Byte_Ptr GetData(){ return iData; }
+	virtual void SetData(Dwarf_Byte_Ptr data) { iData = data; }
+	
+	size_t CheckNewOffset(size_t base, size_t offset){
+		const Dwarf_Off limit = 0xfffffff0ul;
+		Dwarf_Off newOffset = base + offset;
+		if (newOffset >= limit) {
+			cerr << "Error: cannot support transition from 32 to 64 bit offsets\n";
+			exit(EXIT_FAILURE);
+		}
+		return (size_t)newOffset;
+	}
+	
+protected:
+	ElfSectionManager & iElfSectionManager;
+	DwarfManager & iDwarfManager;
+	FileShdrList iFileShdrList;
+	const string iSectionName;
+	bool iSizeValid;
+	size_t iSize;
+	Dwarf_Byte_Ptr iData;
+	RomDetails * iRomDetails;
+};
+
+class DwarfConcatenatedSectionManager : public DwarfSectionManager {
+public:
+	DwarfConcatenatedSectionManager(ElfSectionManager & aElfSectionManager, 
+									DwarfManager & aDwarfManager, 
+									const string & aName, 
+									RomDetails * aRomDetails):
+		DwarfSectionManager(aElfSectionManager, 
+							aDwarfManager, 
+							aName, 
+							aRomDetails)
+	{}
+	
+	// The FileFragmentOwner protocol
+	virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData );
+	virtual size_t Size();
+	
+	virtual void ConcatenateData();
+	virtual void ProcessSection(FileShdrPair & aPair);
+	virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end){};
+	
+	// Concatenated section protocol
+	virtual void SetSectionOffset(PathName & aPathName, size_t aOffset);
+	virtual void InitOffsetMap();
+	virtual size_t GetSectionOffset(PathName & aPathName);
+	virtual void SetSectionSize(PathName & aPathName, size_t aSize);
+	virtual size_t GetSectionSize(PathName & aPathName);
+	
+	Dwarf_Byte_Ptr GetSection(PathName & aPathName);
+	
+protected:
+	typedef std::map<PathName, size_t> PathNameSectionOffsetMap;
+	PathNameSectionOffsetMap iPathNameSectionOffsetMap;
+	PathNameSectionOffsetMap iPathNameSectionSizeMap;
+
+
+};
+
+class DwarfFragmentedSectionManager : public DwarfConcatenatedSectionManager {
+public:
+	DwarfFragmentedSectionManager(ElfSectionManager & aElfSectionManager, 
+									DwarfManager & aDwarfManager, 
+									const string & aName, 
+									RomDetails * aRomDetails):
+		DwarfConcatenatedSectionManager(aElfSectionManager, 
+										aDwarfManager, 
+										aName, 
+										aRomDetails),
+		iInitialTraceMessage(true)
+	{}
+	
+	// Override the method of setting up the section
+	virtual void SetupSection();
+
+	// The FileFragmentOwner protocol
+	virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData );
+	//virtual size_t Size();
+	
+	virtual void ConcatenateData();
+	
+	void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr & aData);
+	virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end) = 0;
+	
+private:
+	bool iInitialTraceMessage;
+
+};
+
+class DebugAbbrevAttrForm {
+public:
+	DebugAbbrevAttrForm():
+			iAttr(0),
+			iForm(0)
+		{}
+	DebugAbbrevAttrForm(Dwarf_Half a, Dwarf_Half f):
+		iAttr(a),
+		iForm(f)
+	{}
+	Dwarf_Half iAttr;
+	Dwarf_Half iForm;
+};
+
+class DebugAbbrev {
+public:
+	DebugAbbrev():
+		iCode(0),
+		iTag(0),
+		iCount(0),
+		iRaw(NULL),
+		iParsed(NULL)
+		{}
+	DebugAbbrev(Dwarf_Unsigned c, Dwarf_Unsigned t, size_t n, Dwarf_Byte_Ptr r, DebugAbbrevAttrForm * p):
+			iCode(c),
+			iTag(t),
+			iCount(n),
+			iRaw(r),
+			iParsed(p)
+			{}
+	DebugAbbrev & operator=(const DebugAbbrev & aDebugAbbrev){
+		iCode = aDebugAbbrev.iCode;
+		iTag = aDebugAbbrev.iTag;
+		iCount = aDebugAbbrev.iCount;
+		iRaw = aDebugAbbrev.iRaw;
+		iParsed = aDebugAbbrev.iParsed;
+		return *this;
+	}
+	
+	DebugAbbrev(const DebugAbbrev & aDebugAbbrev){
+		*this = aDebugAbbrev;
+	}
+	
+	void Destroy(){
+		if (iParsed){
+			DebugAbbrevAttrForm * d = iParsed;
+			iParsed = NULL;
+			delete [] d;
+		}
+	}
+#if 0
+	// can't have default dtor do anything until and unless we prevent iParsed getting deleted
+	// whenever the class is copied in STL containers.
+	~DebugAbbrev(){
+		if (iParsed){
+			DebugAbbrevAttrForm * d = iParsed;
+			iParsed = NULL;
+			delete [] d;
+		}
+	}
+#endif
+	Dwarf_Unsigned iCode;
+	Dwarf_Unsigned iTag;
+	size_t iCount;
+	Dwarf_Byte_Ptr iRaw;
+	DebugAbbrevAttrForm * iParsed;
+};
+
+class InfoContext {
+private:
+	typedef std::map<Dwarf_Word, DebugAbbrev> AbbrevMap;
+	class AbbrevMapEntry {
+	public:
+		AbbrevMapEntry():
+					iCursor(NULL),
+					iMap(NULL)
+				{}
+		AbbrevMapEntry(Dwarf_Byte_Ptr c, AbbrevMap * m):
+			iCursor(c),
+			iMap(m)
+		{}
+		Dwarf_Byte_Ptr iCursor;
+		AbbrevMap * iMap;
+	};
+	typedef std::map<Uint32, AbbrevMapEntry> AbbrevOffsetMap;
+
+public:
+	InfoContext():
+		iContextValid(false),
+		iSectionStart(NULL),
+		iSectionEnd(NULL),
+		iSectionOffset(0),
+		// this is an invalid offset for 32 bit dwarf
+		// and will trigger the right behaviour in SetAbbrevOffset
+		// when called from Init
+		iAbbrevOffset(0xffffffff), 
+		
+		iAbbrevMapEntry(NULL, NULL)
+	{
+		//ClearMap();
+	}
+	~InfoContext(){
+		Reset();
+	}
+	void Init(Dwarf_Byte_Ptr s, Dwarf_Byte_Ptr e, size_t o){
+		iSectionStart = s;
+		iSectionEnd = e;
+		iSectionOffset = o;
+		//ClearMap();
+		iContextValid = true;
+		SetAbbrevOffset(0);
+	}
+	void Reset(){
+		iContextValid = false;
+		iSectionStart = iSectionEnd = NULL;
+		iSectionOffset = 0;
+		iAbbrevOffset = 0xffffffff;
+		ClearMap();
+	}
+	void ClearMap() {
+		for (AbbrevOffsetMap::iterator i = iMap.begin(); i != iMap.end(); i++){
+			AbbrevMap::iterator e = i->second.iMap->end();
+			for (AbbrevMap::iterator b = i->second.iMap->begin(); b != e; b++){
+				b->second.Destroy();
+			}
+			i->second.iMap->clear();
+		}
+		iMap.clear();
+	}
+	size_t GetSectionOffset(){ return iSectionOffset; }
+	
+	void SetAbbrevOffset(size_t offset);
+	
+	DebugAbbrev & GetAbbrev(Dwarf_Word aCode);
+	DebugAbbrev & FindAbbrev(Dwarf_Word aCode);
+
+	bool iContextValid;
+	Dwarf_Byte_Ptr iSectionStart;
+	Dwarf_Byte_Ptr iSectionEnd;
+	size_t iSectionOffset;
+	size_t iAbbrevOffset;
+	AbbrevMapEntry iAbbrevMapEntry;
+	AbbrevOffsetMap iMap;
+};
+
+class DwarfAbbrevManager : public DwarfConcatenatedSectionManager {
+public:
+	DwarfAbbrevManager(ElfSectionManager & aElfSectionManager, 
+					   DwarfManager & aDwarfManager, 
+					   RomDetails * aRomDetails):
+		DwarfConcatenatedSectionManager(aElfSectionManager, 
+										aDwarfManager, 
+										iAbbrevSectionName, 
+										aRomDetails)
+	{}
+	
+	// we might need to hang onto this after its been written to file
+	virtual void DeleteFileFragmentData(){}
+
+	void StartContext(PathName & aName);
+	void EndContext();
+	void SetContextAbbrevOffset(Uint32 offset);
+	size_t GetContextSectionOffset();
+	
+	DebugAbbrev & GetAbbrev(Dwarf_Word aCode);
+private:
+	static const string iAbbrevSectionName;
+	InfoContext iInfoContext;
+
+};
+
+class DwarfMacinfoManager : public DwarfFragmentedSectionManager {
+public:
+	DwarfMacinfoManager(ElfSectionManager & aElfSectionManager, 
+						DwarfManager & aDwarfManager, 
+						RomDetails * aRomDetails):
+		DwarfFragmentedSectionManager(aElfSectionManager, 
+									  aDwarfManager, 
+									  iMacinfoSectionName, 
+									  aRomDetails)
+	{}
+	virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end){};
+
+private:
+	
+	static const string iMacinfoSectionName;	
+};
+
+//class DwarfInfoManager : public DwarfConcatenatedSectionManager {
+class DwarfInfoManager : public DwarfFragmentedSectionManager {
+public:
+	DwarfInfoManager(ElfSectionManager & aElfSectionManager, 
+					 DwarfManager & aDwarfManager, 
+					 DwarfAbbrevManager & aDwarfAbbrevManager, 
+					 DwarfMacinfoManager & aDwarfMacinfoManager, 
+					 RomDetails * aRomDetails):
+		DwarfFragmentedSectionManager(aElfSectionManager, 
+										aDwarfManager, 
+										iInfoSectionName, 
+										aRomDetails),
+		iDwarfAbbrevManager(aDwarfAbbrevManager),
+		iDwarfMacinfoManager(aDwarfMacinfoManager),
+		iAddressSize(4),
+		iLocalLength(0)
+	{}
+	
+	virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end);
+	
+	size_t GetPointerSize() { return iAddressSize; }
+	
+private:
+	Dwarf_Byte_Ptr ProcessCU(FileShdrPair & aPair, Dwarf_Byte_Ptr s, Dwarf_Byte_Ptr e);
+	Dwarf_Byte_Ptr ProcessDIE(FileShdrPair & aPair, Dwarf_Byte_Ptr s, Dwarf_Byte_Ptr e);
+	
+	typedef Dwarf_Byte_Ptr (*InfoEditFn)(DwarfInfoManager&, Dwarf_Byte_Ptr, Dwarf_Half,FileShdrPair & aPair);
+	
+#define DECLARE_INFO_EDIT_FN(name)static Dwarf_Byte_Ptr name(DwarfInfoManager& aManager, \
+													Dwarf_Byte_Ptr aPtr, \
+													Dwarf_Half aForm, \
+													FileShdrPair & aPair)
+	DECLARE_INFO_EDIT_FN(DefaultInfoEditFn);
+	DECLARE_INFO_EDIT_FN(ErrorInfoEditFn);
+	DECLARE_INFO_EDIT_FN(InfoEditAddress);
+	DECLARE_INFO_EDIT_FN(InfoEditLinePtr);
+	DECLARE_INFO_EDIT_FN(InfoEditLocListPtr);
+	DECLARE_INFO_EDIT_FN(InfoEditLocExpr);
+	DECLARE_INFO_EDIT_FN(InfoEditMacInfoPtr);
+	DECLARE_INFO_EDIT_FN(InfoEditRangeListPtr);
+	DECLARE_INFO_EDIT_FN(InfoEditString);
+	DECLARE_INFO_EDIT_FN(InfoEditReference);
+	DECLARE_INFO_EDIT_FN(InfoEditTrampoline);
+	
+	size_t SizeOfDieValue(Dwarf_Half aForm, Dwarf_Byte_Ptr aPtr);	
+
+private:
+	static const string iInfoSectionName;
+	DwarfAbbrevManager & iDwarfAbbrevManager;
+	DwarfMacinfoManager & iDwarfMacinfoManager;
+	static InfoEditFn iInfoEditFn[];
+	
+	size_t iAddressSize;
+	size_t iLocalLength;
+};
+
+class DwarfFrameManager : public DwarfFragmentedSectionManager {
+public:
+	DwarfFrameManager(ElfSectionManager & aElfSectionManager, 
+					  DwarfManager & aDwarfManager, 
+					  RomDetails * aRomDetails):
+		DwarfFragmentedSectionManager(aElfSectionManager, 
+									  aDwarfManager, 
+									  iFrameSectionName, 
+									  aRomDetails)
+	{}
+
+	virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end);
+
+private:
+	typedef std::map<Dwarf_Byte_Ptr, Dwarf_Ubyte> CiePtrEncodingMap;
+	typedef std::map<Dwarf_Byte_Ptr, size_t> CieAugmentationMap;
+
+	static const string iFrameSectionName;	
+};
+
+class DwarfLineManager : public DwarfFragmentedSectionManager {
+public:
+	DwarfLineManager(ElfSectionManager & aElfSectionManager, 
+					 DwarfManager & aDwarfManager, 
+					 DwarfInfoManager & aDwarfInfoManager, 
+					 RomDetails * aRomDetails):
+		DwarfFragmentedSectionManager(aElfSectionManager, 
+									  aDwarfManager, 
+									  iLineSectionName, 
+									  aRomDetails),
+		iDwarfInfoManager(aDwarfInfoManager)
+	{}
+	
+	virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end);
+	
+private:
+	DwarfInfoManager & iDwarfInfoManager;
+
+	static const string iLineSectionName;	
+};
+
+class DwarfLocManager : public DwarfFragmentedSectionManager {
+public:
+	DwarfLocManager(ElfSectionManager & aElfSectionManager, 
+					DwarfManager & aDwarfManager, 
+					DwarfInfoManager & aDwarfInfoManager, 
+					RomDetails * aRomDetails):
+		DwarfFragmentedSectionManager(aElfSectionManager, 
+									  aDwarfManager, 
+									  iLocSectionName,
+									  aRomDetails),
+		iDwarfInfoManager(aDwarfInfoManager)
+	{}
+	
+	virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end);
+
+private:
+	DwarfInfoManager & iDwarfInfoManager;
+	
+	static const string iLocSectionName;
+};
+
+class DwarfNameManager : public DwarfFragmentedSectionManager {
+public:
+	DwarfNameManager(ElfSectionManager & aElfSectionManager, 
+					 DwarfManager & aDwarfManager, 
+					 const string & aName, 
+					 DwarfInfoManager & aDwarfInfoManager, 
+					 RomDetails * aRomDetails):
+		DwarfFragmentedSectionManager(aElfSectionManager, 
+									  aDwarfManager, 
+									  aName, 
+									  aRomDetails),
+		iDwarfInfoManager(aDwarfInfoManager)
+	{}
+	
+	virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end);
+
+protected:
+	DwarfInfoManager & iDwarfInfoManager;
+};
+
+class DwarfPubnamesManager : public DwarfNameManager {
+public:
+	DwarfPubnamesManager(ElfSectionManager & aElfSectionManager, 
+						 DwarfManager & aDwarfManager, 
+						 DwarfInfoManager & aDwarfInfoManager, 
+						 RomDetails * aRomDetails):
+		DwarfNameManager(aElfSectionManager, 
+						 aDwarfManager, 
+						 iPubnamesSectionName, 
+						 aDwarfInfoManager, 
+						 aRomDetails)
+	{}
+	
+private:
+	static const string iPubnamesSectionName;	
+};
+
+class DwarfPubtypesManager : public DwarfNameManager {
+public:
+	DwarfPubtypesManager(ElfSectionManager & aElfSectionManager, 
+						 DwarfManager & aDwarfManager, 
+						 DwarfInfoManager & aDwarfInfoManager, 
+						 RomDetails * aRomDetails):
+		DwarfNameManager(aElfSectionManager, 
+						 aDwarfManager, 
+						 iPubtypesSectionName, 
+						 aDwarfInfoManager, 
+						 aRomDetails)
+	{}
+	
+private:
+	static const string iPubtypesSectionName;	
+};
+
+class DwarfArangesManager : public DwarfFragmentedSectionManager {
+public:
+	DwarfArangesManager(ElfSectionManager & aElfSectionManager, 
+						DwarfManager & aDwarfManager, 
+						DwarfInfoManager & aDwarfInfoManager, 
+						RomDetails * aRomDetails):
+		DwarfFragmentedSectionManager(aElfSectionManager, 
+									  aDwarfManager, 
+									  iArangesSectionName, 
+									  aRomDetails),
+		iDwarfInfoManager(aDwarfInfoManager)
+	{}
+	
+	virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end);
+
+private:
+	DwarfInfoManager & iDwarfInfoManager;
+
+	static const string iArangesSectionName;	
+};
+
+
+class DwarfRangesManager : public DwarfFragmentedSectionManager {
+public:
+	DwarfRangesManager(ElfSectionManager & aElfSectionManager, 
+					   DwarfManager & aDwarfManager, 
+					   DwarfInfoManager & aDwarfInfoManager, 
+					   RomDetails * aRomDetails):
+		DwarfFragmentedSectionManager(aElfSectionManager, 
+									  aDwarfManager, 
+									  iRangesSectionName, 
+									  aRomDetails),
+		iDwarfInfoManager(aDwarfInfoManager)
+	{}
+
+	virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end);
+
+private:
+	DwarfInfoManager & iDwarfInfoManager;
+
+	static const string iRangesSectionName;	
+};
+
+class DwarfStrManager : public DwarfFragmentedSectionManager {
+public:
+	DwarfStrManager(ElfSectionManager & aElfSectionManager, 
+					DwarfManager & aDwarfManager, 
+					RomDetails * aRomDetails):
+		DwarfFragmentedSectionManager(aElfSectionManager, 
+									  aDwarfManager, 
+									  iStrSectionName, 
+									  aRomDetails)
+	{}
+	
+	virtual void ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr start, Dwarf_Byte_Ptr end){};
+
+private:
+	static const string iStrSectionName;	
+};
+
+class DwarfManager {
+public:
+	DwarfManager(ElfSectionManager & aElfSectionManager, 
+				RomDetails * aRomDetails, 
+				OutputFile & aOutputFile):
+		iDwarfAbbrevManager(aElfSectionManager, *this, aRomDetails),
+		iDwarfFrameManager(aElfSectionManager, *this, aRomDetails),
+		iDwarfMacinfoManager(aElfSectionManager, *this, aRomDetails),
+		iDwarfInfoManager(aElfSectionManager, *this, iDwarfAbbrevManager, iDwarfMacinfoManager, aRomDetails),
+		iDwarfLineManager(aElfSectionManager, *this, iDwarfInfoManager, aRomDetails),
+		iDwarfLocManager(aElfSectionManager, *this, iDwarfInfoManager, aRomDetails),
+		iDwarfPubnamesManager(aElfSectionManager, *this, iDwarfInfoManager, aRomDetails),
+		iDwarfPubtypesManager(aElfSectionManager, *this, iDwarfInfoManager, aRomDetails),
+		iDwarfArangesManager(aElfSectionManager, *this,iDwarfInfoManager, aRomDetails),
+		iDwarfRangesManager(aElfSectionManager, *this,iDwarfInfoManager, aRomDetails),
+		iDwarfStrManager(aElfSectionManager, *this, aRomDetails),
+		iRomDetails(aRomDetails),
+		iOutputFile(aOutputFile)
+	{}
+	
+	size_t GetLineSectionOffset(PathName & pname){
+		return iDwarfLineManager.GetSectionOffset(pname);
+	}
+	size_t GetLocListSectionOffset(PathName & pname){
+		return iDwarfLocManager.GetSectionOffset(pname);
+	}
+	size_t GetMacInfoSectionOffset(PathName & pname){
+		return iDwarfMacinfoManager.GetSectionOffset(pname);
+	}
+	size_t GetRangesSectionOffset(PathName & pname){
+		return iDwarfRangesManager.GetSectionOffset(pname);
+	}
+	size_t GetStrSectionOffset(PathName & pname){
+		return iDwarfStrManager.GetSectionOffset(pname);
+	}
+
+	OutputFile & GetOutputFile() { return iOutputFile; }
+	
+	void AddSection(XIPFileDetails & aXIPFileDetails, string aSectionName, Elf32_Shdr * aShdr);
+	void SetupSections();
+	
+private:
+	// Don't want one of these to be copied
+	DwarfManager(const DwarfManager & aDwarfManager);
+	
+	DwarfManager & operator=(const DwarfManager & aDwarfManager);
+	
+private:
+	DwarfAbbrevManager iDwarfAbbrevManager;
+	DwarfFrameManager iDwarfFrameManager;
+	DwarfMacinfoManager iDwarfMacinfoManager;
+	DwarfInfoManager iDwarfInfoManager;
+	DwarfLineManager iDwarfLineManager;
+	DwarfLocManager iDwarfLocManager;
+	DwarfPubnamesManager iDwarfPubnamesManager;
+	DwarfPubtypesManager iDwarfPubtypesManager;
+	DwarfArangesManager iDwarfArangesManager;
+	DwarfRangesManager iDwarfRangesManager;
+	DwarfStrManager iDwarfStrManager;
+	RomDetails * iRomDetails;
+	OutputFile & iOutputFile;
+};
+
+#endif /*DWARFMANAGER_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/dwarfnamemanager.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,81 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <iostream>
+#include "dwarfmanager.h"
+#include "inputfile.h"
+
+const string DwarfPubnamesManager::iPubnamesSectionName(".debug_pubnames");
+const string DwarfPubtypesManager::iPubtypesSectionName(".debug_pubtypes");
+
+void DwarfNameManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr aStart, Dwarf_Byte_Ptr aEnd){
+	Dwarf_Byte_Ptr start = aStart;
+	Dwarf_Byte_Ptr end = aEnd;
+	while (start < end){
+		Dwarf_Byte_Ptr data = start;
+		size_t offset_size, initial_length_size;
+
+		Dwarf_Word length = READ_UNALIGNED4(data); 
+		data += 4;
+
+		if (length >= 0xfffffff0u) {
+			cerr << "Error: 64 bit DWARF not supported\n";
+			exit(EXIT_FAILURE);
+		} else {	
+			offset_size = 4;
+			initial_length_size = 4;
+		}
+
+		Dwarf_Half version = READ_UNALIGNED2(data);
+		data += 2;
+
+		Dwarf_Word offset = GetValue(data, offset_size); 
+		Dwarf_Word newOffset = CheckNewOffset(iDwarfInfoManager.GetSectionOffset(aPair.iXIPFileDetails.iElfFile), offset);
+		if (offset != newOffset)
+			WriteValue(data, offset, offset_size);
+		data += offset_size;
+
+
+		//Dwarf_Word size = GetValue(data, offset_size);
+		// Don't need the length field
+		data += offset_size;
+
+		start += length + initial_length_size;
+
+		if (version != 2 && version != 3){
+			static bool warned = false;
+			if (!warned){
+				cerr << "Only DWARF 2 and 3 pubnames are currently supported\n";
+				warned = true;
+			}
+
+			continue;
+		}
+
+		do {
+			offset = GetValue(data, offset_size);
+
+			if (offset != 0)
+			{
+				data += offset_size;
+				data += strlen ((char *) data) + 1;
+			}
+		}
+		while (offset != 0);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/dwarfrangesmanager.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,41 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <iostream>
+#include "dwarfmanager.h"
+#include "inputfile.h"
+
+const string DwarfRangesManager::iRangesSectionName(".debug_ranges");
+
+void DwarfRangesManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr aStart, Dwarf_Byte_Ptr aEnd){
+	Dwarf_Byte_Ptr start = aStart;
+	Dwarf_Byte_Ptr end = aEnd;
+	size_t pointer_size = iDwarfInfoManager.GetPointerSize();
+	while (start < end){
+		// TODO: this doesn't deal with 64-bit Dwarf
+		Dwarf_Word w1 = GetValue(start, pointer_size);
+		start+= pointer_size;
+		if (w1 == 0xffffffff){
+			LinearAddr addr = GetValue(start, pointer_size);
+			LinearAddr relocatedAddress = aPair.iXIPFileDetails.Relocate(addr);
+			if (addr != relocatedAddress)
+				WriteValue(start, relocatedAddress, pointer_size);
+		} 
+		start += pointer_size;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/dwarfutils.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,208 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "dwarfdefs.h"
+#include "dwarf.h"
+
+char * GetDwarfTag(Dwarf_Unsigned aTag){
+	switch (aTag){
+	case DW_TAG_array_type: return "DW_TAG_array_type";
+	case DW_TAG_class_type: return "DW_TAG_class_type";
+	case DW_TAG_entry_point: return "DW_TAG_entry_point";
+	case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
+	case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
+	case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
+	case DW_TAG_label: return "DW_TAG_label";
+	case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
+	case DW_TAG_member: return "DW_TAG_member";
+	case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
+	case DW_TAG_reference_type: return "DW_TAG_reference_type";
+	case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
+	case DW_TAG_string_type: return "DW_TAG_string_type";
+	case DW_TAG_structure_type: return "DW_TAG_structure_type";
+	case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
+	case DW_TAG_typedef: return "DW_TAG_typedef";
+	case DW_TAG_union_type: return "DW_TAG_union_type";
+	case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
+	case DW_TAG_variant: return "DW_TAG_variant";
+	case DW_TAG_common_block: return "DW_TAG_common_block";
+	case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
+	case DW_TAG_inheritance: return "DW_TAG_inheritance";
+	case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
+	case DW_TAG_module: return "DW_TAG_module";
+	case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
+	case DW_TAG_set_type: return "DW_TAG_set_type";
+	case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
+	case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
+	case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
+	case DW_TAG_base_type: return "DW_TAG_base_type";
+	case DW_TAG_catch_block: return "DW_TAG_catch_block";
+	case DW_TAG_const_type: return "DW_TAG_const_type";
+	case DW_TAG_constant: return "DW_TAG_constant";
+	case DW_TAG_enumerator: return "DW_TAG_enumerator";
+	case DW_TAG_file_type: return "DW_TAG_file_type";
+	case DW_TAG_friend: return "DW_TAG_friend";
+	case DW_TAG_namelist: return "DW_TAG_namelist";
+	case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
+	case DW_TAG_packed_type: return "DW_TAG_packed_type";
+	case DW_TAG_subprogram: return "DW_TAG_subprogram";
+	case DW_TAG_template_type_parameter: return "DW_TAG_template_type_parameter";
+	case DW_TAG_template_value_parameter: return "DW_TAG_template_value_parameter";
+	case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
+	case DW_TAG_try_block: return "DW_TAG_try_block";
+	case DW_TAG_variant_part: return "DW_TAG_variant_part";
+	case DW_TAG_variable: return "DW_TAG_variable";
+	case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
+	case DW_TAG_dwarf_procedure: return "DW_TAG_dwarf_procedure";
+	case DW_TAG_restrict_type: return "DW_TAG_restrict_type";
+	case DW_TAG_interface_type: return "DW_TAG_interface_type";
+	case DW_TAG_namespace: return "DW_TAG_namespace";
+	case DW_TAG_imported_module: return "DW_TAG_imported_module";
+	case DW_TAG_unspecified_type: return "DW_TAG_unspecified_type";
+	case DW_TAG_partial_unit: return "DW_TAG_partial_unit";
+	case DW_TAG_imported_unit: return "DW_TAG_imported_unit";
+	case DW_TAG_mutable_type: return "DW_TAG_mutable_type";
+	case DW_TAG_condition: return "DW_TAG_condition";
+	case DW_TAG_shared_type: return "DW_TAG_shared_type";
+	default: return "Unrecognised TAG";
+	}
+}
+
+char * GetDwarfAttr(Dwarf_Half attr){
+	switch (attr){
+	case DW_AT_sibling: return "DW_AT_sibling";
+	case DW_AT_location: return "DW_AT_location";
+	case DW_AT_name: return "DW_AT_name";
+	case DW_AT_ordering: return "DW_AT_ordering";
+	case DW_AT_subscr_data: return "DW_AT_subscr_data";
+	case DW_AT_byte_size: return "DW_AT_byte_size";
+	case DW_AT_bit_offset: return "DW_AT_bit_offset";
+	case DW_AT_bit_size: return "DW_AT_bit_size";
+	case DW_AT_element_list: return "DW_AT_element_list";
+	case DW_AT_stmt_list: return "DW_AT_stmt_list";
+	case DW_AT_low_pc: return "DW_AT_low_pc";
+	case DW_AT_high_pc: return "DW_AT_high_pc";
+	case DW_AT_language: return "DW_AT_language";
+	case DW_AT_member: return "DW_AT_member";
+	case DW_AT_discr: return "DW_AT_discr";
+	case DW_AT_discr_value: return "DW_AT_discr_value";
+	case DW_AT_visibility: return "DW_AT_visibility";
+	case DW_AT_import: return "DW_AT_import";
+	case DW_AT_string_length: return "DW_AT_string_length";
+	case DW_AT_common_reference: return "DW_AT_common_reference";
+	case DW_AT_comp_dir: return "DW_AT_comp_dir";
+	case DW_AT_const_value: return "DW_AT_const_value";
+	case DW_AT_containing_type: return "DW_AT_containing_type";
+	case DW_AT_default_value: return "DW_AT_default_value";
+	case DW_AT_inline: return "DW_AT_inline";
+	case DW_AT_is_optional: return "DW_AT_is_optional";
+	case DW_AT_lower_bound: return "DW_AT_lower_bound";
+	case DW_AT_producer: return "DW_AT_producer";
+	case DW_AT_prototyped: return "DW_AT_prototyped";
+	case DW_AT_return_addr: return "DW_AT_return_addr";
+	case DW_AT_start_scope: return "DW_AT_start_scope";
+	case DW_AT_bit_stride: return "DW_AT_bit_stride";
+	case DW_AT_upper_bound: return "DW_AT_upper_bound";
+	case DW_AT_abstract_origin: return "DW_AT_abstract_origin";
+	case DW_AT_accessibility: return "DW_AT_accessibility";
+	case DW_AT_address_class: return "DW_AT_address_class";
+	case DW_AT_artificial: return "DW_AT_artificial";
+	case DW_AT_base_types: return "DW_AT_base_types";
+	case DW_AT_calling_convention: return "DW_AT_calling_convention";
+	case DW_AT_count: return "DW_AT_count";
+	case DW_AT_data_member_location: return "DW_AT_data_member_location";
+	case DW_AT_decl_column: return "DW_AT_decl_column";
+	case DW_AT_decl_file: return "DW_AT_decl_file";
+	case DW_AT_decl_line: return "DW_AT_decl_line";
+	case DW_AT_declaration: return "DW_AT_declaration";
+	case DW_AT_discr_list: return "DW_AT_discr_list";
+	case DW_AT_encoding: return "DW_AT_encoding";
+	case DW_AT_external: return "DW_AT_external";
+	case DW_AT_frame_base: return "DW_AT_frame_base";
+	case DW_AT_friend: return "DW_AT_friend";
+	case DW_AT_identifier_case: return "DW_AT_identifier_case";
+	case DW_AT_macro_info: return "DW_AT_macro_info";
+	case DW_AT_namelist_item: return "DW_AT_namelist_item";
+	case DW_AT_priority: return "DW_AT_priority";
+	case DW_AT_segment: return "DW_AT_segment";
+	case DW_AT_specification: return "DW_AT_specification";
+	case DW_AT_static_link: return "DW_AT_static_link";
+	case DW_AT_type: return "DW_AT_type";
+	case DW_AT_use_location: return "DW_AT_use_location";
+	case DW_AT_variable_parameter: return "DW_AT_variable_parameter";
+	case DW_AT_virtuality: return "DW_AT_virtuality";
+	case DW_AT_vtable_elem_location: return "DW_AT_vtable_elem_location";
+	case DW_AT_allocated: return "DW_AT_allocated";
+	case DW_AT_associated: return "DW_AT_associated";
+	case DW_AT_data_location: return "DW_AT_data_location";
+	case DW_AT_byte_stride: return "DW_AT_byte_stride";
+	case DW_AT_entry_pc: return "DW_AT_entry_pc";
+	case DW_AT_use_UTF8: return "DW_AT_use_UTF8";
+	case DW_AT_extension: return "DW_AT_extension";
+	case DW_AT_ranges: return "DW_AT_ranges";
+	case DW_AT_trampoline: return "DW_AT_trampoline";
+	case DW_AT_call_column: return "DW_AT_call_column";
+	case DW_AT_call_file: return "DW_AT_call_file";
+	case DW_AT_call_line: return "DW_AT_call_line";
+	case DW_AT_description: return "DW_AT_description";
+	case DW_AT_binary_scale: return "DW_AT_binary_scale";
+	case DW_AT_decimal_scale: return "DW_AT_decimal_scale";
+	case DW_AT_small: return "DW_AT_small";
+	case DW_AT_decimal_sign: return "DW_AT_decimal_sign";
+	case DW_AT_digit_count: return "DW_AT_digit_count";
+	case DW_AT_picture_string: return "DW_AT_picture_string";
+	case DW_AT_mutable: return "DW_AT_mutable";
+	case DW_AT_threads_scaled: return "DW_AT_threads_scaled";
+	case DW_AT_explicit: return "DW_AT_explicit";
+	case DW_AT_object_pointer: return "DW_AT_object_pointer";
+	case DW_AT_endianity: return "DW_AT_endianity";
+	case DW_AT_elemental: return "DW_AT_elemental";
+	case DW_AT_pure: return "DW_AT_pure";
+	case DW_AT_recursive: return "DW_AT_recursive";
+
+	default: return "Unrecognised ATTR";
+	}
+	
+}
+
+char * GetDwarfForm(Dwarf_Half form){
+	switch (form){
+	case DW_FORM_addr: return "DW_FORM_addr";
+	case DW_FORM_block2: return "DW_FORM_block2";
+	case DW_FORM_block4: return "DW_FORM_block4";
+	case DW_FORM_data2: return "DW_FORM_data2";
+	case DW_FORM_data4: return "DW_FORM_data4";
+	case DW_FORM_data8: return "DW_FORM_data8";
+	case DW_FORM_string: return "DW_FORM_string";
+	case DW_FORM_block: return "DW_FORM_block";
+	case DW_FORM_block1: return "DW_FORM_block1";
+	case DW_FORM_data1: return "DW_FORM_data1";
+	case DW_FORM_flag: return "DW_FORM_flag";
+	case DW_FORM_sdata: return "DW_FORM_sdata";
+	case DW_FORM_strp: return "DW_FORM_strp";
+	case DW_FORM_udata: return "DW_FORM_udata";
+	case DW_FORM_ref_addr: return "DW_FORM_ref_addr";
+	case DW_FORM_ref1: return "DW_FORM_ref1";
+	case DW_FORM_ref2: return "DW_FORM_ref2";
+	case DW_FORM_ref4: return "DW_FORM_ref4";
+	case DW_FORM_ref8: return "DW_FORM_ref8";
+	case DW_FORM_ref_udata: return "DW_FORM_ref_udata";
+	case DW_FORM_indirect: return "DW_FORM_indirect";
+	default: return "Unrecognised FORM";
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/e32romimage.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,58 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <fcntl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <cstring>
+
+#include "elfromerror.h"
+#include "e32romimage.h"
+
+
+void E32RomImage::SetupRomData(){
+	// see if there's a header on the image.
+	iRomFile.GetData(&iE32RomHeader, sizeof(iE32RomHeader));
+	
+	// In general the 'name' is of the form EPOC*ROM.
+	// We are looking for ARM roms for the moment so check for EPOCARM and error on anything
+	// else which matches EPOC*ROM
+    bool isEPOCHeader = !strncmp((const char *)&iE32RomHeader.name[0], "EPOC", 4) && 
+    				(strstr((const char *)&iE32RomHeader.name[0], "ROM") != NULL);
+    bool isARMHeader = !strncmp((const char *)&iE32RomHeader.name[0], "EPOCARM", 7);
+
+    if(isARMHeader)
+    	iRomFile.SetOffset(sizeof(iE32RomHeader));
+    else if (isEPOCHeader) 
+    	errx(EX_NOINPUT, "unsupported rom type: %s\n", (const char *)&iE32RomHeader.name[0]);
+}
+
+void E32RomImage::GetFileFragmentData(FileFragmentData & aFileFragmentData ){
+	assert(iRomFile.Size() > 0);
+	if (!iData)
+		iData = iRomFile.GetData();
+	SetFileFragmentData(aFileFragmentData, Size(), reinterpret_cast<char *>(iData));
+}
+
+void E32RomImage::DeleteFileFragmentData(){ 
+	if (iData) {
+		char * d = iData;
+		iData = NULL;
+		delete [] d; 
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/e32romimage.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,68 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef E32ROMIMAGE_H_
+#define E32ROMIMAGE_H_
+
+#include <cassert>
+
+#include "defs.h"
+#include "filefragment.h"
+#include "inputfile.h"
+
+class E32RomImage : public FileFragmentOwner {
+public:
+	typedef struct // this is the structure of an EPOC rom header
+	{
+		char name[16];
+	    unsigned char versionStr[4];
+	    unsigned char buildNumStr[4];
+	    unsigned long romSize;
+	    unsigned long wrapSize;
+	} E32RomHeader;
+public:
+		
+	E32RomImage(PathName aPath):
+		iRomFile(aPath), iData(NULL)
+		{};	
+	
+	void SetupRomData();
+
+	// The FileFragmentOwner protocol
+	virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData );
+	virtual size_t Size() { 
+		assert(iRomFile.Size() - iRomFile.GetOffset()); 
+		return iRomFile.Size() - iRomFile.GetOffset(); 
+	};
+	virtual void DeleteFileFragmentData();
+	
+private:
+
+	void Open();
+	void Close();
+	void SetSize();
+	
+private:	
+	InputFile iRomFile;
+	char * iData;
+	E32RomHeader iE32RomHeader;
+
+	
+};
+
+#endif /*E32ROMIMAGE_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/elfdefs.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,24 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef ELFDEFS_H_
+#define ELFDEFS_H_
+
+#include <libelf.h>
+
+#endif /*ELFDEFS_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/elfheader.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,35 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "elfheader.h"
+
+Elf32Header::Elf32Header(Elf32_Ehdr & aHdr){
+	iHdr = aHdr;
+	iHdr.e_entry = 0x0;
+	iHdr.e_phoff = iHdr.e_shoff = iHdr.e_shoff = 0;
+	iHdr.e_phnum = iHdr.e_shnum = iHdr.e_shstrndx = 0;
+	iHdr.e_ehsize = sizeof(Elf32_Ehdr);
+	// Let's say this is an executable rather than a shared object.
+	iHdr.e_type = ET_EXEC;
+}
+
+void Elf32Header::GetFileFragmentData(FileFragmentData & aFileFragmentData ){
+	SetFileFragmentData(aFileFragmentData, Size(), reinterpret_cast<char *>(&iHdr));
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/elfheader.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,47 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef ELFHEADER_H_
+#define ELFHEADER_H_
+
+#include "elfdefs.h"
+#include "filefragment.h"
+//#include "outputfile.h"
+
+class Elf32Header : public FileFragmentOwner {
+public:
+	Elf32Header(){};
+	Elf32Header(Elf32_Ehdr & aHeader);
+	
+	void SetEntryPoint(Elf32_Addr addr) { iHdr.e_entry = addr; }
+	void SetProgramHdrOffset(Elf32_Off aOff) { iHdr.e_phoff = aOff; };
+	void SetSectionHdrOffset(Elf32_Off aOff) { iHdr.e_shoff = aOff; };
+	void AddProgramHdr() { iHdr.e_phnum++; };
+	void AddSectionHdr() { iHdr.e_shnum++; };
+	void SetSectionStringNdx(Elf32_Half ndx) { iHdr.e_shstrndx = ndx; };
+
+	// FileFragmentOwner protocol
+	virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData );
+	virtual size_t Size() { return sizeof(iHdr); };
+	virtual void DeleteFileFragmentData() {};
+
+private:
+	Elf32_Ehdr iHdr;
+};
+
+#endif /*ELFHEADER_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/elfphdr.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,46 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "elfphdr.h"
+
+ElfPHdr & ElfPHdr::operator=(const ElfPHdr & aPHdr){
+	iOffset = aPHdr.iOffset;
+	iElf32Phdr = aPHdr.iElf32Phdr;
+	return *this;
+}
+
+ElfPHdr::ElfPHdr(const ElfPHdr & aPHdr){
+	*this = aPHdr;
+}
+
+#if 0
+void ElfPHdr::InitRom(RomDetails * aRomDetails, size_t aOffset){
+	iElf32Phdr.p_type = PT_LOAD;
+	iElf32Phdr.p_offset = aOffset;
+	iElf32Phdr.p_vaddr = aRomDetails->iRomBaseLinearAddr;
+	iElf32Phdr.p_paddr = aRomDetails->iRomPhysAddr;
+	iElf32Phdr.p_align = 4;
+	iElf32Phdr.p_flags = PF_X + PF_R;
+	iElf32Phdr.p_filesz = iElf32Phdr.p_memsz = iRomImage.Size();
+}
+#endif
+
+void ElfPHdr::GetFileFragmentData(FileFragmentData & aFileFragmentData ){
+	SetFileFragmentData(aFileFragmentData, Size(), reinterpret_cast<char *>(&iElf32Phdr));
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/elfphdr.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,73 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef ELFPHDR_H_
+#define ELFPHDR_H_
+#include <libelf.h>
+
+#include "romdetails.h"
+#include "elfheader.h"
+#include "e32romimage.h"
+#include "filefragment.h"
+#include "outputfile.h"
+
+class ElfPHdr : public FileFragmentOwner {
+public:
+	ElfPHdr(){}
+	
+	ElfPHdr(const ElfPHdr & aPHdr);
+	
+	ElfPHdr & operator=(const ElfPHdr & aPHdr);
+	
+	Elf32_Word GetPhdrFilesz(){ return iElf32Phdr.p_filesz; }
+	Elf32_Word GetPhdrOffset(){ return iElf32Phdr.p_offset; }
+	Elf32_Addr GetPhdrPaddr(){ return iElf32Phdr.p_paddr; }
+
+	void SetPhdrType(Elf32_Word x) { iElf32Phdr.p_type = x; }
+	void SetPhdrOffset(Elf32_Off x) { iElf32Phdr.p_offset = x; }
+	void SetPhdrVaddr(Elf32_Addr x) { iElf32Phdr.p_vaddr = x; }
+	void SetPhdrPaddr(Elf32_Addr x) { iElf32Phdr.p_paddr = x; }
+	void SetPhdrFilesz(Elf32_Word x) { iElf32Phdr.p_filesz = x; }
+	void SetPhdrMemsz(Elf32_Word x) { iElf32Phdr.p_memsz = x; }
+	void SetPhdrFlags(Elf32_Word x) { iElf32Phdr.p_flags = x; }
+	void SetPhdrAlign(Elf32_Word x) { iElf32Phdr.p_align = x; }
+	
+	void InitRom(RomDetails * aRomDetails, size_t aOffset);
+	
+	virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData );
+	virtual size_t Size() { return sizeof(Elf32_Phdr); };
+	virtual void DeleteFileFragmentData() {};
+
+private:
+
+#if 0
+	typedef struct {
+	    Elf32_Word		p_type;
+	    Elf32_Off		p_offset;
+	    Elf32_Addr		p_vaddr;
+	    Elf32_Addr		p_paddr;
+	    Elf32_Word		p_filesz;
+	    Elf32_Word		p_memsz;
+	    Elf32_Word		p_flags;
+	    Elf32_Word		p_align;
+	} Elf32_Phdr;
+#endif
+	Elf32_Phdr	iElf32Phdr;
+};
+
+#endif /*ELFPHDR_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/elfrom.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,567 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <fcntl.h>
+#include <string.h>
+#include <iostream>
+#include <sstream>
+#include <iomanip>
+
+using namespace std;
+
+#include "elfromerror.h"
+#include "elfrom.h"
+#include "inputfile.h"
+
+#define NO_GAPS
+
+void ElfRom::SetupE32RomData() {
+	SetupRomElf32_EHdr();
+	SetupRomImage();
+}
+
+// TODO: don't use primary file - fill header in by hand.
+void ElfRom::SetupRomElf32_EHdr() {
+	//create ELF header
+
+	unsigned char c[EI_NIDENT] = {ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3, ELFCLASS32, ELFDATA2LSB, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; 
+	Elf32_Ehdr elf32_ehdr;
+
+	for (int i=0; i <EI_NIDENT;i++)
+		elf32_ehdr.e_ident[i] = c[i];
+
+	elf32_ehdr.e_type		= ET_EXEC;
+	elf32_ehdr.e_machine	= EM_ARM;
+	elf32_ehdr.e_version	= EV_CURRENT;
+	elf32_ehdr.e_entry		= iRomDetails->iRomPhysAddr;
+	elf32_ehdr.e_shoff		= sizeof(Elf32_Ehdr);
+	
+// ARM specific flags 
+// e_entry contains a program-loader entry point
+#define EF_ARM_HASENTRY 0x02
+// Each subsection of the symbol table is sorted by symbol value
+#define EF_ARM_SYMSARESORTED 0x04
+// Symbols in dynamic symbol tables that are defined in sections
+// included in program segment n have st_shndx = n+ 1. 
+#define EF_ARM_DYNSYMSUSESEGIDX 0x8
+// Mapping symbols precede other local symbols in the symbol table
+#define EF_ARM_MAPSYMSFIRST 0x10
+// This masks an 8-bit version number, the version of the ARM EABI to
+// which this ELF file conforms. This EABI is version 2. A value of 0
+// denotes unknown conformance. (current version is 0x02000000)
+#define EF_ARM_EABIMASK 0xFF000000
+
+#define EF_ARM_EABI_VERSION 0x02000000
+#define EF_ARM_BPABI_VERSION 0x04000000
+
+	elf32_ehdr.e_flags		= EF_ARM_BPABI_VERSION | EF_ARM_HASENTRY;
+	elf32_ehdr.e_ehsize		= sizeof(Elf32_Ehdr);
+	elf32_ehdr.e_phentsize 	= sizeof(Elf32_Phdr);
+	elf32_ehdr.e_shentsize 	= sizeof(Elf32_Shdr);
+	elf32_ehdr.e_shnum		= 0;
+	elf32_ehdr.e_shstrndx	= 0;
+	elf32_ehdr.e_phnum		= 02;
+	new (&iElf32Header) Elf32Header(elf32_ehdr);
+#if 0
+	iElf32Header.SetEntryPoint(iRomDetails->iRomPhysAddr);
+	elf_end(e);
+	close(fd);
+#endif
+	iElf32Header.SetEntryPoint(iRomDetails->iRomPhysAddr);
+	iElf32Header.AddData(iOutputFile);
+	assert(iElf32Header.GetOffset() == 0);
+	if (iRomDetails->iTrace){
+		cout << "\nElf header added.\n";
+	}
+
+}
+
+
+void ElfRom::SetupRomImage(){
+	// ensure image size is known and we know how to get hold of it
+	iE32RomImage.SetupRomData();
+	iE32RomImage.AddData(iOutputFile);
+	assert(iE32RomImage.GetOffset() == iElf32Header.Size());
+	if (iRomDetails->iTrace){
+		size_t offset = iE32RomImage.GetOffset();
+		size_t size = iE32RomImage.Size();
+		cout << "\nAdded ROM image " << iRomDetails->iRomFile << "\n";
+		cout.fill('0');
+		cout << hex << "      offset 0x" << setw(8)
+			<< offset << " size = 0x" << setw(8) << size << "\n" ;
+	}
+}
+
+void ElfRom::SetupProgramHeaderTable(){
+	size_t offsetx = AddBootStrapProgramHeader();
+	RomDetails::XIPFileList::iterator aXIPFile = iRomDetails->iXIPFiles.begin();
+	RomDetails::XIPFileList::iterator end = iRomDetails->iXIPFiles.end();
+	unsigned int p = iRomDetails->iRomPhysAddr;
+	unsigned int v = iRomDetails->iRomBaseLinearAddr;
+	int addend = v > p ? -(v - p) : p - v;
+	
+	if (iRomDetails->iTrace){
+		cout << "\nAdding program headers for e32images\n";
+	}
+	
+	while (aXIPFile != end) {
+		offsetx = SetupProgramHeaders(*aXIPFile, offsetx, addend);
+		aXIPFile++;
+	}
+	AddFinalHeader(offsetx);
+
+#ifdef NO_GAPS
+	// check there are no gaps or overlaps in the phdrs
+	Elf32_Word bsz = iBootStrapPHdr.GetPhdrFilesz();
+	Elf32_Word coffset = iBootStrapPHdr.GetPhdrOffset() + bsz;
+	Elf32_Addr phys_addr = iBootStrapPHdr.GetPhdrPaddr() + bsz;
+	ElfPHdrList::iterator aCheckHdr = iElfPHdrList.begin();
+	ElfPHdrList::iterator endCheckHdr = iElfPHdrList.end();
+	while(aCheckHdr != endCheckHdr) {
+		Elf32_Word o = aCheckHdr->GetPhdrOffset();
+		if (coffset != o){
+			cerr << "Error: Phdr table broken - offsets incorrect\n";
+			assert(coffset == o);
+		}
+		Elf32_Addr addr = aCheckHdr->GetPhdrPaddr();
+		if (phys_addr > addr){
+			cerr << "Error: Phdr table broken - physical addresses incorrect\n";
+			assert(phys_addr <= addr);
+		}
+		size_t sz = aCheckHdr->GetPhdrFilesz();
+		coffset = o + sz;
+		phys_addr = addr + sz;
+		aCheckHdr++;
+	}
+#endif
+	
+	ElfPHdrList::iterator aHdr = iElfPHdrList.begin();
+	ElfPHdrList::iterator endHdr = iElfPHdrList.end();
+	while (aHdr != endHdr) {
+		aHdr->AddData(iOutputFile);
+		aHdr++;
+	}
+}
+
+size_t ElfRom::AddBootStrapProgramHeader(){
+	iBootStrapPHdr.SetPhdrType(PT_LOAD);
+	iBootStrapPHdr.SetPhdrOffset(iE32RomImage.GetOffset());
+	iBootStrapPHdr.SetPhdrVaddr(iRomDetails->iRomPhysAddr);
+	iBootStrapPHdr.SetPhdrPaddr(iRomDetails->iRomPhysAddr);
+	iBootStrapPHdr.SetPhdrAlign(4);
+	iBootStrapPHdr.SetPhdrFlags(PF_X + PF_R);
+	size_t bootstrapsize = iRomDetails->iXIPFiles[0].iLoadAddr - iRomDetails->iRomBaseLinearAddr;
+	iBootStrapPHdr.SetPhdrFilesz(bootstrapsize);
+	iBootStrapPHdr.SetPhdrMemsz(bootstrapsize);
+		
+	iBootStrapPHdr.AddData(iOutputFile);
+	assert((iElf32Header.Size() + iE32RomImage.Size()) == iBootStrapPHdr.GetOffset());
+	iElf32Header.AddProgramHdr();
+	iElf32Header.SetProgramHdrOffset(iBootStrapPHdr.GetOffset());
+	if (iRomDetails->iTrace){
+		size_t offset = iBootStrapPHdr.GetOffset();
+		cout << "\nAdded PHdr for bootstrap\n";
+		cout.fill('0');
+		cout << hex << "      offset 0x" << setw(8) << offset 
+			 << " size = 0x" << setw(8) << bootstrapsize << "\n";
+	}
+
+	return iE32RomImage.GetOffset() + bootstrapsize;
+}
+
+static inline size_t InitE32HdrPHdr(ElfPHdr & hdr, size_t offset, Elf32_Word vaddr, Elf32_Word paddr, Elf32_Word size){
+	hdr.SetPhdrType(PT_LOAD);
+	hdr.SetPhdrOffset(offset);
+	hdr.SetPhdrVaddr(vaddr);
+	hdr.SetPhdrPaddr(paddr);
+	hdr.SetPhdrAlign(0);
+	hdr.SetPhdrFlags(PF_R);
+	hdr.SetPhdrFilesz(size);
+	hdr.SetPhdrMemsz(size);
+		
+	return offset + size;	
+	
+}
+static inline size_t InitROPHdr(ElfPHdr & hdr, size_t offset, Elf32_Word vaddr, Elf32_Word paddr, Elf32_Word size){
+	hdr.SetPhdrType(PT_LOAD);
+	hdr.SetPhdrOffset(offset);
+	hdr.SetPhdrVaddr(vaddr);
+	hdr.SetPhdrPaddr(paddr);
+	hdr.SetPhdrAlign(4);
+	hdr.SetPhdrFlags(PF_X + PF_R);
+	hdr.SetPhdrFilesz(size);
+	hdr.SetPhdrMemsz(size);
+		
+	return offset + size;	
+	
+}
+
+static inline size_t InitRWPHdr(ElfPHdr & hdr, size_t offset, Elf32_Word vaddr, Elf32_Word paddr, Elf32_Word fsize, Elf32_Word msize){
+	hdr.SetPhdrType(PT_LOAD);
+	hdr.SetPhdrOffset(offset);
+	hdr.SetPhdrVaddr(vaddr);
+	hdr.SetPhdrPaddr(paddr);
+	hdr.SetPhdrAlign(4);
+	hdr.SetPhdrFlags(PF_X + PF_R);
+	hdr.SetPhdrFilesz(fsize);
+	hdr.SetPhdrMemsz(msize);
+		
+	return offset + fsize;	
+	
+}
+
+size_t ElfRom::SetupProgramHeaders(XIPFileDetails & aXIPFileDetails, size_t offset, int addend){
+	ElfPHdr e32hdr;
+	Elf32_Word e32hdrVaddr = aXIPFileDetails.iLoadAddr;
+	Elf32_Word e32hdrPaddr = aXIPFileDetails.iLoadAddr + addend;
+	Elf32_Word e32hdrSize = aXIPFileDetails.iROAddr - aXIPFileDetails.iLoadAddr ;
+	size_t e32hdrOffsetInRom = aXIPFileDetails.iLoadAddr - iRomDetails->iRomBaseLinearAddr;
+	size_t e32hdrOffsetInElf = iE32RomImage.GetOffset() + e32hdrOffsetInRom;
+#ifdef NO_GAPS
+	// But actually the offset we'll use is the one we were given as an argument.
+	// This means we need to adjust the size, vaddr and paddr by the difference
+	size_t diff = e32hdrOffsetInElf - offset;
+	e32hdrSize += diff;
+	e32hdrVaddr -= diff;
+	e32hdrPaddr -= diff;
+	offset = InitE32HdrPHdr(e32hdr, offset, e32hdrVaddr, e32hdrPaddr, e32hdrSize);
+#else
+	offset = InitE32HdrPHdr(e32hdr, e32hdrOffsetInElf, e32hdrVaddr, e32hdrPaddr, e32hdrSize);
+#endif
+	iElf32Header.AddProgramHdr();
+	iElfPHdrList.push_back(e32hdr);
+	ElfPHdr thdr;
+	Elf32_Word textVaddr = aXIPFileDetails.iROAddr;
+	Elf32_Word textPaddr = aXIPFileDetails.iROAddr + addend;
+	Elf32_Word textSize = aXIPFileDetails.iROSize;
+	size_t textOffsetInRom = aXIPFileDetails.iROAddr - iRomDetails->iRomBaseLinearAddr;
+	size_t textOffsetInElf = iE32RomImage.GetOffset() + textOffsetInRom;
+	offset = InitROPHdr(thdr, textOffsetInElf, textVaddr, textPaddr, textSize);
+	iElf32Header.AddProgramHdr();
+	iElfPHdrList.push_back(thdr);
+
+	if (iRomDetails->iTrace){
+		cout << "  " << aXIPFileDetails.iE32File << "\n";
+		cout.fill(' ');
+		cout << left << "    .text\n";
+		cout.fill('0');
+		cout << "      paddr = 0x" << right << setw(8) << textPaddr << " vaddr = 0x" << right << setw(8)<< textVaddr
+		     << " offset = 0x" << right << setw(8) << textOffsetInElf 
+			 << " size = 0x" << setw(8) << textSize << "\n" << flush;
+	}
+	
+	if (aXIPFileDetails.iRWSize > 0){
+		ElfPHdr dhdr;
+		Elf32_Word dataVaddr = aXIPFileDetails.iRWAddr;
+		Elf32_Word dataPaddr = aXIPFileDetails.iROMDataAddr + addend;
+		Elf32_Word fsize = aXIPFileDetails.iRWSize;
+		Elf32_Word msize = aXIPFileDetails.iBSSDataSize;
+		size_t dataOffsetInRom = aXIPFileDetails.iROMDataAddr - iRomDetails->iRomBaseLinearAddr;
+		size_t dataOffsetInElf = iE32RomImage.GetOffset() + dataOffsetInRom;
+		offset = InitRWPHdr(dhdr, dataOffsetInElf, dataVaddr, dataPaddr, fsize, msize);
+		iElf32Header.AddProgramHdr();
+		iElfPHdrList.push_back(dhdr);
+		
+		if (iRomDetails->iTrace){
+			cout.fill(' ');
+			cout << left << "    .data\n";
+			cout.fill('0');
+			cout << "      paddr = 0x" << right << setw(8) << dataPaddr << " vaddr = 0x" << right << setw(8)<< dataVaddr  
+				 << " offset = 0x" << right << setw(8)<< dataOffsetInElf
+				 << " size = 0x" << right << setw(8) << fsize << "\n" << flush;
+		}
+		
+	}
+	return offset;
+}
+
+// This adds a header for the remainder of the ROM image after the last XIP file
+size_t ElfRom::AddFinalHeader(size_t offset){
+	ElfPHdr & lastHdr = iElfPHdrList.back();
+	Elf32_Word startAddr = lastHdr.GetPhdrPaddr() + lastHdr.GetPhdrFilesz();
+	ElfPHdr e32hdr;
+	Elf32_Word e32hdrVaddr = startAddr;
+	Elf32_Word e32hdrPaddr = startAddr;
+	Elf32_Word e32hdrSize = iE32RomImage.Size() - offset + iE32RomImage.GetOffset();
+
+	offset = InitE32HdrPHdr(e32hdr, offset, e32hdrVaddr, e32hdrPaddr, e32hdrSize);
+
+	iElf32Header.AddProgramHdr();
+	iElfPHdrList.push_back(e32hdr);	
+	
+	if (iRomDetails->iTrace){
+		cout << "\nAdded final PHdr\n" << "      offset 0x" << hex << right << setw(8) << offset 
+			<< " size = 0x" << setw(8) << e32hdrSize << "\n";
+	}
+	return offset;
+}
+
+void ElfRom::SetupAuxilarySections(){
+	SetupLogFile();
+}
+
+void ElfRom::SetupLogFile(){
+	if (!iRomDetails->iLogFile.size()) return;
+	InputFile * aLogFile = new InputFile(iRomDetails->iLogFile);
+	ElfSectionFileData * aLogFileData = new ElfSectionFileData(aLogFile);
+	Elf32_Shdr shdr;
+	shdr.sh_name = 0; // for now.
+	shdr.sh_offset = 0; // for now
+	shdr.sh_info = 0;
+	shdr.sh_link = SHN_UNDEF;
+	shdr.sh_addr = 0;
+	shdr.sh_addralign = 0;
+	shdr.sh_type = SHT_PROGBITS;
+	shdr.sh_size = 0; // for now.
+	shdr.sh_flags = 0;
+	shdr.sh_entsize = 0;
+
+	ElfSection aLogFileSection(aLogFileData, "ROMLogFile", shdr);
+	iElfSectionManager.AddSection(aLogFileSection);
+
+}
+
+void ElfRom::SetupELFRomData() {
+	SetupProgramHeaderTable();
+	SetupAuxilarySections();
+	if (!iRomDetails->iStrip){
+		SetupSectionHeaderTable();
+		SetupSymbolTable();
+		if (!iRomDetails->iNoDwarf){
+			SetupDwarfSections();
+		}
+	}
+}
+
+void ElfRom::SetupSectionHeaderTable(){
+	RomDetails::XIPFileList::iterator aXIPFile = iRomDetails->iXIPFiles.begin();
+	RomDetails::XIPFileList::iterator end = iRomDetails->iXIPFiles.end();
+
+	if (iRomDetails->iTrace && aXIPFile != end){
+		cout << "\nAdding Section headers from associated ELF files\n";
+	}
+
+	while (aXIPFile != end) {
+		SetupSectionHeaders(*aXIPFile);
+		aXIPFile++;
+	}
+}
+
+void ElfRom::SetupSectionHeaders(XIPFileDetails & aXIPFileDetails) {
+	// Open ELF file
+	PathName aPath = aXIPFileDetails.iElfFile;
+	
+	if (aPath.size() == 0) return;
+	
+	int fd;
+	Elf * e;
+	size_t shstrndx;
+	bool hasSectionStringTable = true;
+
+
+	if ((fd = open(aPath.c_str(), O_RDONLY|O_BINARY, 0)) < 0){
+		warnx(EX_NOINPUT, "open \"%s\" failed\n", aPath.c_str());
+		goto finish;
+	}
+	if ((e = elf_begin(fd, ELF_C_READ , NULL)) == NULL)
+		errx(EX_SOFTWARE, "elf_begin() failed: %s.\n", elf_errmsg(-1));
+	if (elf_kind(e) != ELF_K_ELF)
+		errx(EX_SOFTWARE, "file not of kind ELF_K_ELF: %s.\n", aPath.c_str());
+	if (elf_getshstrndx(e, &shstrndx) == 0) {
+		hasSectionStringTable = false;
+		warnx(EX_SOFTWARE, "getshstrndx() failed for \"%s\"\n", aPath.c_str());
+	}
+	if (hasSectionStringTable){
+		SetUpSegmentInfo(aXIPFileDetails, e);
+		SetupSectionHeaders(aXIPFileDetails, e, shstrndx);
+	}
+
+	elf_end(e);
+	close(fd);	
+finish:
+	return;
+}
+
+void ElfRom::SetupSectionHeaders(XIPFileDetails & aXIPFileDetails, Elf * e, size_t shstrndx){
+	// Iterate through sections looking for the ones we're after. Namely:
+	// text, data, bss/zi, symtab, strtable,  and .debug*
+	Elf_Scn * scn = NULL; 
+	Elf32_Shdr * shdr;
+	SectionNumberMap aSectionNumberMap;
+	SectionVaddrAddendMap aSectionVaddrAddendMap;
+
+	String aPath(aXIPFileDetails.iElfFile);
+	
+	const char * debugName = ".debug";
+	const size_t debugNameLength = strlen(debugName);
+	const char * staticStrTab = ".strtab";
+	
+	if (iRomDetails->iTrace){
+		cout << "  " << aXIPFileDetails.iElfFile << "\n";
+	}
+	
+	while ((scn = elf_nextscn(e, scn)) != NULL) {
+
+    	if ((shdr = elf32_getshdr(scn)) == NULL)
+    		errx(EX_SOFTWARE, "getshdr() failed: %s.\n", elf_errmsg(-1));
+    	
+		size_t aOldNdx = elf_ndxscn(scn);
+    	char * name = elf_strptr(e, shstrndx, shdr->sh_name);
+    	VirtualAddr sectionAddr = shdr->sh_addr;
+
+    	switch (shdr->sh_type) {
+    	case SHT_NOBITS:
+    		// Check for BSS or ZI
+    		if ((shdr->sh_flags & SHF_WRITE) && (shdr->sh_flags & SHF_ALLOC)) {
+    			// set up section number mapping
+    			size_t aNew = AddBssSectionHeader(aXIPFileDetails, shdr, name);
+    			aSectionNumberMap.push_back(SectionNumberMapping(aOldNdx, aNew));
+    			// set up address adjustment for relocation of e.g. symbols
+    			int addend = aXIPFileDetails.iBSSAddr - sectionAddr;
+    			aSectionVaddrAddendMap.push_back(SectionVaddrAddendMapping(aOldNdx, addend));
+    		}
+    		break;
+#define ARM_EXIDX	(SHT_LOPROC + 1)
+    	case ARM_EXIDX:    		
+    	case SHT_PROGBITS:
+    		// text/ro or data/rw will have SHF_ALLOC set
+    		if (shdr->sh_flags & SHF_ALLOC) {
+    			size_t aNew = 0;
+    		    int addend = 0;
+    		    if (shdr->sh_flags & SHF_WRITE) {
+    				aNew = AddRwSectionHeader(aXIPFileDetails, shdr, name);
+    				addend = aXIPFileDetails.iRWAddr - sectionAddr;
+    		    } else {
+    				aNew = AddRoSectionHeader(aXIPFileDetails, shdr, name);
+    				addend = aXIPFileDetails.iROAddr - sectionAddr;
+    		    }
+    			// set up section number mapping
+    		    aSectionNumberMap.push_back(SectionNumberMapping(aOldNdx, aNew)); 
+    			// set up address adjustment for relocation of e.g. symbols
+    		    aSectionVaddrAddendMap.push_back(SectionVaddrAddendMapping(aOldNdx, addend));     	
+    		} else if (!iRomDetails->iNoDwarf && !strncmp(debugName, name, debugNameLength)) {
+    			iDwarfFound = true;
+    			iDwarfManager.AddSection(aXIPFileDetails, name, shdr);
+    		}
+    		break;
+    	case SHT_SYMTAB:
+    		iElfSymbolTableManager.AddSymbolTable(aPath, shdr->sh_offset, shdr->sh_size, shdr->sh_info);
+    		break;
+    	case SHT_STRTAB:
+    		if (!strcmp(staticStrTab, name))
+    			iElfSymbolTableManager.AddStringTable(aPath, shdr->sh_offset, shdr->sh_size);
+    		break;
+    	}
+    }
+	iElfSymbolTableManager.Finalize(aSectionNumberMap, aSectionVaddrAddendMap);
+}
+
+size_t ElfRom::AddRoSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName){
+	size_t delta = aShdr->sh_addr - aXIPFileDetails.iElfTextBase;
+	VirtualAddr vaddr = aXIPFileDetails.iROAddr + delta;
+	size_t offsetInRom = vaddr - iRomDetails->iRomBaseLinearAddr;
+	size_t offsetInElf = iE32RomImage.GetOffset() + offsetInRom;
+	aShdr->sh_addr = vaddr;
+	return AddROMSectionHeader(aXIPFileDetails, aShdr, aName, offsetInElf );
+}
+
+size_t ElfRom::AddRwSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName){		
+	size_t delta = aShdr->sh_addr - aXIPFileDetails.iElfDataBase;
+	VirtualAddr vaddr = aXIPFileDetails.iROMDataAddr + delta;
+	size_t offsetInRom = vaddr - iRomDetails->iRomBaseLinearAddr;
+	size_t offsetInElf = iE32RomImage.GetOffset() + offsetInRom;	
+	aShdr->sh_addr = aXIPFileDetails.iRWAddr;
+	return AddROMSectionHeader(aXIPFileDetails, aShdr, aName, offsetInElf);
+}
+
+size_t ElfRom::AddBssSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName){	
+	size_t delta = aShdr->sh_addr - aXIPFileDetails.iElfDataBase;
+	VirtualAddr vaddr = aXIPFileDetails.iROMDataAddr + delta;
+	size_t offsetInRom = vaddr - iRomDetails->iRomBaseLinearAddr;
+	size_t offsetInElf = iE32RomImage.GetOffset() + offsetInRom;	
+	aShdr->sh_addr = aXIPFileDetails.iBSSAddr;
+	return AddROMSectionHeader(aXIPFileDetails, aShdr, aName, offsetInElf);
+}
+
+size_t ElfRom::AddROMSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName, size_t aOffset){	
+	ElfSectionData * romData = aOffset ? 
+								(ElfSectionData *)new ElfSectionRomData(aOffset, aShdr->sh_size) 
+								: (ElfSectionData *)new ElfSectionNoData();
+	ElfSection aSection(romData, aName, *aShdr);
+	iElfSectionManager.AddSection(aSection);
+	
+	if (iRomDetails->iTrace){
+		cout.fill(' ');
+		cout << "    " << left << setw(22) << aName << "\n";
+		cout.fill('0');
+		cout << "      vaddr = 0x" << right << hex << setw(8) << aShdr->sh_addr << " offset = 0x" 
+			 << right << hex << setw(8) << aOffset 
+			 << " size = 0x" << right << hex << setw(8) << aShdr->sh_size << "\n";
+	}
+	return aSection.GetIndex();
+}
+
+void ElfRom::SetUpSegmentInfo(XIPFileDetails & aXIPFileDetails, Elf * e){
+	Elf32_Ehdr * ehdr = elf32_getehdr(e);
+	if (ehdr == NULL)
+		errx(EX_SOFTWARE, "elf32_getehdr() failed: %s.", elf_errmsg(-1));
+	size_t n = ehdr->e_phnum;
+	Elf32_Phdr * phdr = elf32_getphdr(e);
+	if (phdr == NULL)
+		errx(EX_SOFTWARE, "elf32_getphdr() failed: %s.", elf_errmsg(-1));
+
+	for (size_t i = 0; i < n; i++) {
+		if (phdr[i].p_flags & PF_X){
+			VirtualAddr segmentAddr = phdr[i].p_vaddr;
+	    	aXIPFileDetails.iElfTextBase = segmentAddr;
+	    	aXIPFileDetails.iElfTextLimit = segmentAddr + phdr[i].p_memsz;
+			
+		} else if (phdr[i].p_flags & PF_W){
+	    	aXIPFileDetails.iElfDataBase = phdr[i].p_vaddr;
+		}
+	}	
+}
+
+void ElfRom::SetupSymbolTable(){
+	iElfSymbolTableManager.AddSymbolTable();
+	if (iRomDetails->iTrace){
+		cout << "\nAdded section headers for combined symbol table and symbol string table\n";
+	}
+}
+
+void ElfRom::SetupDwarfSections(){
+	if (iRomDetails->iTrace && iDwarfFound){
+		cout << "\nSetting up Dwarf Sections\n";
+	} else if (iRomDetails->iTrace && !iDwarfFound && !iRomDetails->iNoDwarf){
+		cout << "\nWarning: No Dwarf information found\n";
+		return;
+	}
+	iDwarfManager.SetupSections();
+}
+
+void ElfRom::AddData() {
+	iElfSectionManager.AddData();
+	iElf32Header.SetSectionHdrOffset(iElfSectionManager.GetOffset());
+}
+
+void ElfRom::Dump(){
+	iOutputFile.Dump();
+	if (iRomDetails->iTrace){
+		cout << "\nWrote " << iRomDetails->iElfRomFile << " " << dec << iOutputFile.Size() << " bytes\n";
+	}	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/elfrom.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,95 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef ELFROM_H_
+#define ELFROM_H_
+
+#include <vector>
+//
+// Copyright (c) 2008 Symbian Software Ltd. All rights reserved.
+//
+
+#include <libelf.h>
+
+#include "romdetails.h"
+#include "outputfile.h"
+#include "elfheader.h"
+#include "e32romimage.h"
+#include "elfphdr.h"
+#include "elfsectionmanager.h"
+#include "elfsymboltablemanager.h"
+#include "dwarfmanager.h"
+
+class ElfRom {
+public:
+	ElfRom(RomDetails * aRomDetails) :
+		iRomDetails(aRomDetails), iOutputFile(aRomDetails->iElfRomFile),
+		iE32RomImage(aRomDetails->iRomFile),
+		iElfSectionManager(iElf32Header, iE32RomImage, iOutputFile),
+		iElfSymbolTableManager(iElf32Header, iE32RomImage, iOutputFile, iElfSectionManager),
+		iDwarfManager(iElfSectionManager, aRomDetails, iOutputFile),
+		iDwarfFound(false)
+		{}
+	void SetupE32RomData();
+	void SetupELFRomData();
+	void AddData();
+	void Dump();
+
+private:
+	typedef std::vector< Elf32_Shdr * > Elf32_Shdr_List;
+	
+private:
+	void SetupRomElf32_EHdr();
+	void SetupRomImage();
+	void SetupProgramHeaderTable();
+	size_t AddBootStrapProgramHeader();
+	size_t SetupProgramHeaders(XIPFileDetails & aXIPFileDetails, size_t offset, int addend);
+	void SetupAuxilarySections();
+	void SetupLogFile();
+	void SetupSectionHeaderTable();
+	void SetupSectionHeaders(XIPFileDetails & aXIPFileDetails);
+	void SetupSectionHeaders(XIPFileDetails & aXIPFileDetails, Elf * e, size_t shstrndx);
+	void SetUpSegmentInfo(XIPFileDetails & aXIPFileDetails, Elf * e);
+	size_t AddRoSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName);
+	size_t AddRwSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName);
+	size_t AddBssSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName);
+	size_t AddROMSectionHeader(XIPFileDetails & aXIPFileDetails, Elf32_Shdr * aShdr, char * aName, size_t aOffset);
+	size_t AddFinalHeader(size_t offset);
+	void SetupSymbolTable();
+	void SetupDwarfSections();
+	
+private:
+	RomDetails * iRomDetails;
+	OutputFile iOutputFile;
+	
+	Elf32Header iElf32Header;
+	E32RomImage iE32RomImage;
+
+	ElfPHdr	iBootStrapPHdr;
+
+	typedef std::vector<ElfPHdr> ElfPHdrList;
+	ElfPHdrList iElfPHdrList;
+	
+	ElfSectionManager iElfSectionManager;
+	ElfSymbolTableManager iElfSymbolTableManager;
+	DwarfManager iDwarfManager;
+	
+	bool iDwarfFound;
+
+};
+#endif /*ELFROM_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/elfromerror.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,33 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void errx(int errortype, const char * format, const char * msg) {
+	(void)errortype;
+	printf("ERROR: ");
+	printf(format, msg);
+	exit(EXIT_FAILURE);
+}
+
+void warnx(int errortype, const char * format, const char * msg) {
+	(void)errortype;
+	printf("WARNING: ");
+	printf(format, msg);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/elfromerror.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,27 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef ELFROMERROR_H_
+#define ELFROMERROR_H_
+
+#define EX_SOFTWARE 1
+#define EX_NOINPUT  2
+void errx(int errortype, const char * format, const char * msg);
+void warnx(int errortype, const char * format, const char * msg);
+
+#endif /*ELFROMERROR_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/elfsection.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,123 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "outputfile.h"
+#include "inputfile.h"
+#include "filefragment.h"
+#include "elfsection.h"
+
+
+ElfSection & ElfSection::operator=(const ElfSection & aSection) {
+	iSectionName = aSection.iSectionName;
+	iSectionHdr = aSection.iSectionHdr;
+	iSectionData = aSection.iSectionData->Clone();
+	iIndex = aSection.iIndex;
+	return *this;
+}
+
+ElfSection::ElfSection(const ElfSection & aSection){
+	*this = aSection;
+}
+
+ElfSectionRomData::ElfSectionRomData(const ElfSectionRomData & aData) {
+	iOffset = aData.iOffset;
+	iSize = aData.iSize;
+}
+
+ElfSectionRomData * ElfSectionRomData::Clone(){
+	return new ElfSectionRomData(*this);
+}
+
+ElfSectionElfData::ElfSectionElfData(const ElfSectionElfData & aData) :
+	iSource(aData.iSource)
+{
+	iOffset = aData.iOffset;
+}
+
+ElfSectionElfData * ElfSectionElfData::Clone(){
+	return new ElfSectionElfData(*this);
+}
+
+void ElfSectionElfData::AddData(OutputFile & aOutputFile){
+	iSource.AddData(aOutputFile);
+}
+
+void ElfSectionElfData::GetFileFragmentData(FileFragmentData & aFileFragmentData ){
+	iSource.GetFileFragmentData(aFileFragmentData);
+}
+
+void ElfSectionElfData::DeleteFileFragmentData(){
+	iSource.DeleteFileFragmentData();	
+}
+
+size_t ElfSectionElfData::Size(){
+	return iSource.Size();
+}
+
+size_t ElfSectionElfData::GetOffset(){
+	return iSource.GetOffset();
+}
+
+ElfSectionFileData::ElfSectionFileData(const ElfSectionFileData & aData) {
+	iOffset = aData.iOffset;
+	iInputFile = aData.iInputFile;
+	iData = aData.iData;
+}
+
+ElfSectionFileData * ElfSectionFileData::Clone(){
+	return new ElfSectionFileData(*this);
+}
+
+void ElfSectionFileData::GetFileFragmentData(FileFragmentData & aFileFragmentData ){
+	iData = iInputFile->GetData();
+	SetFileFragmentData(aFileFragmentData, iInputFile->Size(), (char *)iData);
+}
+
+void ElfSectionFileData::DeleteFileFragmentData(){
+	if (iData) {
+		char * d = iData;
+		iData = NULL;
+		delete [] d;
+	}
+}
+
+size_t ElfSectionFileData::Size(){
+	return iInputFile->Size();
+}
+
+ElfSectionNoData::ElfSectionNoData(const ElfSectionNoData & aData) {
+	iOffset = aData.iOffset;
+}
+
+ElfSectionNoData * ElfSectionNoData::Clone(){
+	return new ElfSectionNoData(*this);
+}
+
+void ElfSectionNoData::GetFileFragmentData(FileFragmentData & aFileFragmentData ){
+	SetFileFragmentData(aFileFragmentData, 0u, reinterpret_cast<char *>(NULL));
+}
+
+ElfSection::~ElfSection(){
+	delete iSectionData;
+}
+
+void ElfSection::AddData(OutputFile & aOutputFile){
+	iSectionData->AddData(aOutputFile);
+	SetSize(iSectionData->Size());
+	SetOffset(iSectionData->GetOffset());
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/elfsection.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,182 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef ELFSECTION_H_
+#define ELFSECTION_H_
+
+#include <libelf.h>
+
+#include "defs.h" // for String
+
+#include "filefragment.h"
+#include "inputfile.h"
+
+class ElfSectionHeader {
+public:
+	ElfSectionHeader()
+		{}
+	
+	ElfSectionHeader(Elf32_Shdr & aShdr) :
+		iElf32Shdr(aShdr)
+		{}
+	
+	Elf32_Shdr iElf32Shdr;
+};
+
+class ElfSectionData  : public FileFragmentOwner {
+public:
+	ElfSectionData()
+		{}
+	ElfSectionData(size_t aOffset):
+		FileFragmentOwner(aOffset)
+		{}
+	virtual ElfSectionData * Clone() = 0;
+	
+	// The FileFragmentOwner protocol
+	virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData ) = 0;
+	virtual size_t Size() = 0;
+	virtual void DeleteFileFragmentData() = 0;
+
+
+};
+
+class ElfSectionRomData : public ElfSectionData {
+public:
+	ElfSectionRomData(size_t aOffset, size_t aSize) :
+		ElfSectionData(aOffset), 
+		iSize(aSize)
+		{}
+	
+	ElfSectionRomData(const ElfSectionRomData & aData);
+
+	// ElfSection protocol
+	virtual ElfSectionRomData * Clone();
+
+	// The FileFragmentOwner protocol
+	virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData ){}
+	virtual size_t Size(){ return iSize; }
+	// Nothing to delete
+	virtual void DeleteFileFragmentData(){};
+	// Dont add data;
+	virtual void AddData(OutputFile & aOutputFile) {};
+	
+private:
+	size_t iSize;
+};
+
+class ElfSectionElfData : public ElfSectionData {
+public:
+	ElfSectionElfData(FileFragmentOwner & aSource) :
+		iSource(aSource)
+		{}
+	
+	ElfSectionElfData(const ElfSectionElfData & aData);
+	
+	// ElfSection protocol
+	virtual ElfSectionElfData * Clone();
+
+	// The FileFragmentOwner protocol
+	virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData );
+	virtual size_t Size();
+	virtual void DeleteFileFragmentData();
+	virtual void AddData(OutputFile & aOutputFile);
+	virtual size_t GetOffset();
+	
+private:
+	FileFragmentOwner & iSource;
+};
+
+class ElfSectionFileData : public ElfSectionData {
+public:
+	ElfSectionFileData(InputFile * aInputFile) :
+		iInputFile(aInputFile), iData(NULL)
+		{}
+	ElfSectionFileData(const ElfSectionFileData & aData);
+	
+	// ElfSection protocol
+	virtual ElfSectionFileData * Clone();
+
+	// The FileFragmentOwner protocol
+	virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData );
+	virtual size_t Size();
+	virtual void DeleteFileFragmentData();
+
+private:
+	InputFile * iInputFile;
+	char * iData;
+};
+
+class ElfSectionNoData : public ElfSectionData {
+public:
+	ElfSectionNoData(){}
+	
+	ElfSectionNoData(const ElfSectionNoData & aData);
+	
+	// ElfSection protocol
+	virtual ElfSectionNoData * Clone();
+
+	// The FileFragmentOwner protocol
+	virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData );
+	virtual size_t Size() { return 0; }
+	// Nothing to delete
+	virtual void DeleteFileFragmentData(){};
+	// Dont add data;
+	virtual void AddData(OutputFile & aOutputFile) {};
+
+
+
+private:
+	InputFile * iInputFile;
+};
+
+class ElfSection {
+public:
+	ElfSection(ElfSectionData *  aData) :
+		iSectionName(""), iSectionData(aData), iIndex(0)
+		{}
+	
+	ElfSection(ElfSectionData *  aData, String aName, Elf32_Shdr & aShdr) :
+		iSectionName(aName), iSectionHdr(aShdr), iSectionData(aData)
+		{}
+	
+	ElfSection(const ElfSection & aData);
+	
+	ElfSection & operator=(const ElfSection & aSection);
+	
+	virtual ~ElfSection();
+	
+	String & GetName() { return iSectionName ; }
+	void SetNameOffset(size_t nameOffset) { iSectionHdr.iElf32Shdr.sh_name = nameOffset; }
+	
+	ElfSectionHeader & GetSectionHeader() { return iSectionHdr; }
+	
+	void SetSize(size_t aSize) { iSectionHdr.iElf32Shdr.sh_size = aSize; }
+	void SetOffset(size_t aOffset) { iSectionHdr.iElf32Shdr.sh_offset = aOffset; }
+	
+	virtual void AddData(OutputFile & aOutputFile);
+	unsigned int GetIndex() { return iIndex; };
+	void SetIndex(unsigned int aIndex) { iIndex = aIndex; };
+	
+private:
+	String iSectionName;
+	ElfSectionHeader iSectionHdr;
+	ElfSectionData * iSectionData;
+	unsigned int	iIndex;
+};
+
+#endif /*ELFSECTION_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/elfsectionmanager.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,155 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <string.h>
+
+#include "elfsectionmanager.h"
+
+void ElfSectionManager::GetFileFragmentData(FileFragmentData & aFileFragmentData ){
+	int nSections = iSections.size();
+	if (nSections > 0){
+		iData = new Elf32_Shdr[nSections];
+		Elf32_Shdr * p = iData;
+		SectionList::iterator aSection = iSections.begin();
+		SectionList::iterator end = iSections.end();
+		while (aSection != end) {
+			*p = aSection->GetSectionHeader().iElf32Shdr;
+			p++;
+			aSection++;
+		}
+		SetFileFragmentData(aFileFragmentData, Size(), reinterpret_cast<char *>(iData));
+	}
+}
+
+size_t ElfSectionManager::Size(){
+	return SectionHeaderSize();
+}
+
+void ElfSectionManager::DeleteFileFragmentData(){
+	if (iData) {
+		Elf32_Shdr * d = iData;
+		iData = NULL;
+		delete[] d;
+	}
+}
+
+void ElfSectionManager::AddData(){
+	AddData(iOutputFile);
+}
+
+void ElfSectionManager::AddData(OutputFile & aOutputFile){
+	if (iSections.size() > 0) {
+		SectionList::iterator aSection = iSections.begin();
+		SectionList::iterator end = iSections.end();
+		while (aSection != end) {
+			aSection->AddData(aOutputFile);
+			aSection++;
+		}
+		AddSectionTable();
+	}
+}
+
+void ElfSectionManager::EnsureSectionStringTableSectionAdded(){
+	if (iSectionStringTableSectionAdded) return;
+	
+	// set iSectionStringTableSectionAdded true now so we don't do the next bit twice;
+	iSectionStringTableSectionAdded = true;
+
+	// first create the UNDEF section
+	ElfSectionNoData * aUndefData = new ElfSectionNoData();
+	
+	Elf32_Shdr undef;
+	undef.sh_name = 0; 
+	undef.sh_type = SHT_NULL;
+	undef.sh_flags = 0;
+	undef.sh_addr = 0;
+	undef.sh_offset = 0; 
+	undef.sh_size = 0; 
+	undef.sh_link = 0;
+	undef.sh_info = 0;
+	undef.sh_addralign = 0;
+	undef.sh_entsize = 0;
+	
+	ElfSection aUndefSection(aUndefData, "", undef);
+	AddSection(aUndefSection);
+	
+	ElfSectionElfData * aSectionStringTableSectionData = new ElfSectionElfData(iStringTable);
+	Elf32_Shdr shdr;
+	shdr.sh_name = 0; // for now.
+	shdr.sh_type = SHT_STRTAB;
+	shdr.sh_flags = 0;
+	shdr.sh_addr = 0;
+	shdr.sh_offset = 0; // for now
+	shdr.sh_size = 0; // for now.
+	shdr.sh_link = SHN_UNDEF;
+	shdr.sh_info = 0;
+	shdr.sh_addralign = 0;
+	shdr.sh_entsize = 0;
+
+	ElfSection aSectionStringTableSection(aSectionStringTableSectionData, ".shstrtab", shdr);
+	AddSection(aSectionStringTableSection);
+	iElf32Header.SetSectionStringNdx(iSections.size() - 1);
+}
+void ElfSectionManager::AddSection(ElfSection & aSection){
+	EnsureSectionStringTableSectionAdded();
+	if (aSection.GetName().size() > 0){
+		// rename sections for GDB (yuk!)
+		String sectionName(aSection.GetName());
+		String ro("ER_RO");
+		String text(".text");
+		if (sectionName == ro){
+			sectionName = text;
+		} else {
+			String rw("ER_RW");
+			String data(".data");
+			if (sectionName == rw){
+				sectionName = data;
+			} else {
+				String zi("ER_ZI");
+				String bss(".bss");
+				if (sectionName == zi)
+					sectionName = bss;
+			}
+		}
+		size_t nameOffset = iStringTable.AddName(sectionName);
+		aSection.SetNameOffset(nameOffset);
+	} else {
+		// use the initial Null String.
+		size_t nameOffset = iStringTable.AllocateInitialNullString();
+		aSection.SetNameOffset(nameOffset);
+	}
+	aSection.SetIndex(iSections.size());
+	iSections.push_back(aSection);
+	iElf32Header.AddSectionHdr();
+}
+	
+size_t ElfSectionManager::SectionHeaderSize(){
+	return iSections.size() * sizeof(Elf32_Shdr);
+}
+
+void ElfSectionManager::AddSectionStringTable(){
+	// Assume the section header already setup and we've got hold of it. We need to say where the strings ended up.
+	const FileFragment & aSectionTableFrag = iOutputFile.GetFileFragment(this);	
+	SetOffset(aSectionTableFrag.GetOffset());
+}
+
+void ElfSectionManager::AddSectionTable(){
+	const FileFragment & aSectionTableFrag = iOutputFile.GetFileFragment(this);	
+	SetOffset(aSectionTableFrag.GetOffset());
+	iElf32Header.SetSectionHdrOffset(GetOffset());
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/elfsectionmanager.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,89 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef ELFSECTIONMANAGER_H_
+#define ELFSECTIONMANAGER_H_
+
+#include <vector>
+
+#include "filefragment.h"
+//
+// Copyright (c) 2008 Symbian Software Ltd. All rights reserved.
+//
+
+#include "elfstringtable.h"
+#include "outputfile.h"
+#include "elfheader.h"
+#include "e32romimage.h"
+#include "elfsection.h"
+#include "defs.h" // String
+
+
+class ElfSectionHeaderStringTable : public ElfStringTable {
+public:
+	size_t AddName(String aName) {
+		return AddString(aName);
+	}
+
+};
+
+class ElfSectionManager : public FileFragmentOwner {
+public:
+	ElfSectionManager(Elf32Header & aElf32Header, E32RomImage & aRomImage, OutputFile & aOutputFile) :
+		iElf32Header(aElf32Header), iRomImage(aRomImage), 
+		iOutputFile(aOutputFile), iOffset(0), iData(NULL),
+		iSectionStringTableSectionAdded(false)
+		{}
+	
+	// The FileFragmentOwner protocol
+	virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData );
+	virtual size_t Size();
+	virtual void DeleteFileFragmentData();
+	virtual void AddData(OutputFile & aOutputFile);
+	
+	void AddData();
+	void AddSection(ElfSection & aSection);
+	
+	int NumSections() { return iSections.size(); }
+	
+private:
+	// Don't want one of these to be copied
+	ElfSectionManager(const ElfSectionManager & aElfSectionManager);
+	
+	ElfSectionManager & operator=(const ElfSectionManager & aElfSectionManager);
+	
+private:
+	size_t SectionHeaderSize();
+	void AddSectionStringTable();
+	void AddSectionTable();
+	void EnsureSectionStringTableSectionAdded();
+	
+private:
+	typedef std::vector<ElfSection> SectionList;
+	Elf32Header & iElf32Header;
+	E32RomImage & iRomImage;
+	OutputFile & iOutputFile;
+	SectionList iSections;
+	size_t iOffset;
+	ElfSectionHeaderStringTable iStringTable;
+	Elf32_Shdr * iData;
+	bool iSectionStringTableSectionAdded;
+	
+};
+
+#endif /*ELFSECTIONMANAGER_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/elfstringtable.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,57 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <string.h>
+
+#include "elfstringtable.h"
+
+void ElfStringTable::GetFileFragmentData(FileFragmentData & aFileFragmentData ){
+	size_t nbytes = Size();
+	iData = new char[nbytes];
+	memset(iData, 0, nbytes);
+	if (iStrings.size() > 0) {
+		StringList::iterator aString = iStrings.begin();
+		StringList::iterator end = iStrings.end();
+		while (aString != end) {
+			memcpy(iData + aString->iOffset, aString->iName.data(), aString->iName.size()); 
+			aString++;
+		}
+	}
+	SetFileFragmentData(aFileFragmentData, nbytes, reinterpret_cast<char *>(iData));
+}
+
+size_t ElfStringTable::Size() {
+	return iSize;
+}
+
+void ElfStringTable::DeleteFileFragmentData(){
+	if (iData) {
+		char * d = iData;
+		iData = NULL;
+		delete [] d;
+	}
+}
+
+size_t ElfStringTable::AddString(String aString){
+	size_t offset = iSize;
+	StringTableEntry sn(aString, offset);
+	iStrings.push_back(sn);
+	size_t ss = aString.size();
+	iSize += (ss + 1);
+	return offset;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/elfstringtable.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,83 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef ELFSTRINGTABLE_H_
+#define ELFSTRINGTABLE_H_
+
+//
+// Copyright (c) 2008 Symbian Software Ltd. All rights reserved.
+//
+
+#include <vector>
+
+#include "defs.h"
+#include "filefragment.h"
+#include "outputfile.h"
+
+class ElfStringTable : public FileFragmentOwner {
+public:
+	ElfStringTable() :
+		iSize(0), iData(NULL)
+		{}
+	
+	~ElfStringTable(){
+		iStrings.clear();
+		if (iData) {
+			char * d = iData;
+			iData = NULL;
+			delete d;
+		}
+	}
+	
+	// The FileFragmentOwner protocol
+	virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData );
+	virtual size_t Size();
+	virtual void SetSize(size_t aSize) 
+		{ iSize = aSize; }
+	virtual void DeleteFileFragmentData();
+	
+	size_t AddString(String aName);
+	size_t AllocateInitialNullString() {
+		if (iSize == 0) {
+			StringTableEntry sn("", 0);
+			iStrings.push_back(sn);
+			iSize = 1;
+		}
+		// The initial string is always at offset 0 in the section.
+		return 0;
+	}
+	
+private:
+	class StringTableEntry {
+	public:
+		StringTableEntry(String aName, size_t aOffset):
+			iName(aName), iOffset(aOffset)
+			{}
+
+		String iName;
+		size_t iOffset;
+	};
+
+	typedef std::vector<StringTableEntry> StringList;
+	
+	StringList iStrings;
+	size_t iSize;
+	char * iData;
+};
+
+#endif /*ELFSTRINGTABLE_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/elfsymboltablemanager.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,259 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <libelf.h>
+#include <map>
+
+#include "elfsymboltablemanager.h"
+
+void ElfFileSymbolFragments::AddSymbolTable(String & aPath, size_t aOffset, size_t aSize, size_t aFirstGlobal){
+	iPath = aPath;
+	// drop the inital 'undefined' symbol
+	iSymbolTableOffset = aOffset + sizeof(Elf32_Sym);
+	iSymbolTableSize = aSize - sizeof(Elf32_Sym);
+	iFirstGlobal = aFirstGlobal - 1;
+}
+
+void ElfFileSymbolFragments::AddStringTable(String & aPath, size_t aOffset, size_t aSize){
+	iPath = aPath;
+	// drop the inital "\0"
+	iStringTableOffset = aOffset + 1;
+	iStringTableSize = aSize - 1;
+}
+
+size_t ElfFileSymbolFragments::LookupSection(size_t ndx){
+	SectionNumberMap::iterator aMapping = iSectionNumberMap.begin();
+	SectionNumberMap::iterator end = iSectionNumberMap.end();
+	while (aMapping != end) {
+		if (aMapping->iOld == ndx) 
+			return aMapping->iNew;
+		aMapping++;
+	}
+	return ndx;
+}
+
+int ElfFileSymbolFragments::LookupVaddrAddend(size_t ndx){
+	SectionVaddrAddendMap::iterator aMapping = iSectionVaddrAddendMap.begin();
+	SectionVaddrAddendMap::iterator end = iSectionVaddrAddendMap.end();
+	while (aMapping != end) {
+		if (aMapping->iSectionNumber == ndx) 
+			return aMapping->iAddend;
+		aMapping++;
+	}
+	return 0;
+}
+
+size_t ElfSymTabStringTable::Size(){
+	return iElfSymbolTableManager.GetSymTabStringsSectionSize();
+}
+
+void ElfSymbolTableManager::Finalize(SectionNumberMap & aSectionNumberMap, SectionVaddrAddendMap & aSectionVaddrAddendMap ){
+	iCurrentFragment.SetSectionNumberMap(aSectionNumberMap);
+	iCurrentFragment.SetSectionVaddrAddendMap(aSectionVaddrAddendMap);
+	iCurrentFragment.Validate();
+	iSymbolFragments.push_back(iCurrentFragment);
+	iCurrentFragment.Reset();
+}
+
+// TODO: This could be done more efficiently and with out the use of the ElfStringTable object.
+void ElfSymbolTableManager::GetFileFragmentData(FileFragmentData & aFileFragmentData ){
+	size_t symTabSize = GetSymTabSectionSize(); 
+	iData = new char[symTabSize];
+	Elf32_Sym * syms = (Elf32_Sym *)iData;
+
+	
+	// set up UNDEF symbol
+	syms[0].st_info = 0;
+	syms[0].st_name = 0;
+	syms[0].st_other = 0;
+	syms[0].st_shndx = 0;
+	syms[0].st_size = 0;
+	syms[0].st_value = 0;
+
+	// set up 'cursors' into final symbol table so we put locals first 
+	// and globals at the end
+	Elf32_Sym * lsym = &syms[1];
+	size_t firstGlobal = GetFirstNonLocalIndex();
+	Elf32_Sym * gsym = &syms[firstGlobal];
+	Elf32_Sym * lsymLim = gsym;
+	iStringTable.AllocateInitialNullString();
+	
+	SymbolFragmentList::iterator aFrag = iSymbolFragments.begin();
+	SymbolFragmentList::iterator end = iSymbolFragments.end();
+	while (aFrag != end) {
+		//InputFile aFile((char *)(aFrag->GetPath().c_str()));
+		InputFile aFile(aFrag->GetPath());
+		aFile.SetOffset(aFrag->GetSymbolTableOffset());
+		size_t symSize = aFrag->GetSymbolTableSize();
+		size_t limit = symSize / sizeof(Elf32_Sym);
+		char * symtabData = aFile.GetData(symSize);
+		Elf32_Sym * symtab = (Elf32_Sym *)symtabData;
+		aFile.SetOffset(aFrag->GetStringTableOffset());
+		char * strtabx = aFile.GetData(aFrag->GetStringTableSize());
+		// set strtab back one to 'add' "\0" back in so indexs works with addition.
+		char * strtab = strtabx - 1;
+		size_t firstNonLocal = aFrag->GetFirstGlobal();
+		
+		typedef std::map<size_t, size_t> SymbolNdxMap;
+		SymbolNdxMap symNdxMap;
+		
+		for (size_t i = 0; i < limit; i++){
+			size_t strndx = symtab[i].st_name;
+			
+			if (strndx != 0) {
+				// see if we've already seen this index
+				SymbolNdxMap::iterator res = symNdxMap.find(strndx);
+				size_t newndx;
+				if (res != symNdxMap.end()){
+					newndx = res->second;
+					symtab[i].st_name = newndx;	
+				} else {
+					char * name = &strtab[strndx];
+					newndx = iStringTable.AddString(name);
+					symNdxMap[strndx] = symtab[i].st_name = newndx;
+				}
+			}
+			
+			if (!(symtab[i].st_value || symtab[i].st_size)){
+				symtab[i].st_shndx = SHN_UNDEF;
+			} else {
+				size_t oldNdx = symtab[i].st_shndx;
+				
+				// retrieve new section index
+				size_t newscnndx = aFrag->LookupSection(oldNdx);
+				// retrieve the vaddr adjustment to add to the symbol's value
+				int addend = aFrag->LookupVaddrAddend(oldNdx);
+				symtab[i].st_shndx = newscnndx;
+				symtab[i].st_value += addend;
+			}
+			if (i < firstNonLocal){
+				assert(lsym < lsymLim);
+				*(lsym++) = symtab[i];
+			} else {
+				*(gsym++) = symtab[i];
+			}
+		}
+		
+		delete [] symtabData;
+		delete strtabx;
+		
+		aFrag++;
+	}
+	SetFileFragmentData(aFileFragmentData, symTabSize, reinterpret_cast<char *>(iData));
+}
+
+
+size_t ElfSymbolTableManager::Size(){
+	return GetSymTabSectionSize();
+}
+
+void ElfSymbolTableManager::DeleteFileFragmentData(){
+	char * d = iData;
+	iData = NULL;
+	delete [] d;
+}
+
+void ElfSymbolTableManager::AddData(OutputFile & aOutputFile){
+	const FileFragment & aSectionFrag = iOutputFile.GetFileFragment(this);	
+	SetOffset(aSectionFrag.GetOffset());
+}
+
+void ElfSymbolTableManager::AddSymbolTable(){
+	// The sym table section needs to record the index of its associated
+	// string table in its link field and record the index of the first non-local
+	// symbol in its info field
+	int symTabSize = GetSymTabSectionSize(); 
+	size_t firstNonLocal = GetFirstNonLocalIndex();
+	size_t nextSectionIndex = iElfSectionManager.NumSections();
+	
+	ElfSectionElfData * aSymTabSectionData = new ElfSectionElfData(*this);
+	Elf32_Shdr symTabShdr;
+	symTabShdr.sh_name = 0; // for now.
+	symTabShdr.sh_type = SHT_SYMTAB;
+	symTabShdr.sh_flags = 0;
+	symTabShdr.sh_addr = 0;
+	symTabShdr.sh_offset = 0; // for now
+	symTabShdr.sh_size = symTabSize; // for now.
+	// symTabShdr will be @ index nextSectionIndex so the .strtab will 
+	// be @ nextSectionIndex +1
+	symTabShdr.sh_link = nextSectionIndex + 1;
+	symTabShdr.sh_info = firstNonLocal;
+	symTabShdr.sh_addralign = 4;
+	symTabShdr.sh_entsize = sizeof(Elf32_Sym);
+	
+	ElfSection aSymTabSection(aSymTabSectionData, ".symtab", symTabShdr);
+	iElfSectionManager.AddSection(aSymTabSection);
+
+
+	ElfSectionElfData * aStringTableSectionData = new ElfSectionElfData(iStringTable);
+	Elf32_Shdr shdr;
+	shdr.sh_name = 0; // for now.
+	shdr.sh_type = SHT_STRTAB;
+	shdr.sh_flags = 0;
+	shdr.sh_addr = 0;
+	shdr.sh_offset = 0; // for now
+	shdr.sh_size = GetSymTabStringsSectionSize();
+	shdr.sh_link = 0;
+	shdr.sh_info = 0;
+	shdr.sh_addralign = 0;
+	shdr.sh_entsize = 0;
+	ElfSection aStringTableSection(aStringTableSectionData, ".strtab", shdr);
+	iElfSectionManager.AddSection(aStringTableSection);
+
+}
+
+size_t ElfSymbolTableManager::GetSymTabSectionSize(){
+	int symTabSize = sizeof(Elf32_Sym); // add the 'undefined' symbols
+	
+	SymbolFragmentList::iterator aFrag = iSymbolFragments.begin();
+	SymbolFragmentList::iterator end = iSymbolFragments.end();
+	while (aFrag != end) {
+		symTabSize += aFrag->GetSymbolTableSize();
+		aFrag++;
+	}
+	return symTabSize;
+}
+
+size_t ElfSymbolTableManager::GetSymTabStringsSectionSize(){
+	
+	if (iSymbolStringTableSizeValid)
+		return iSymbolStringTableSize;
+	
+	int stringsSize = 1; // add the leading "\0"
+	
+	SymbolFragmentList::iterator aFrag = iSymbolFragments.begin();
+	SymbolFragmentList::iterator end = iSymbolFragments.end();
+	while (aFrag != end) {
+		stringsSize += aFrag->GetStringTableSize();
+		aFrag++;
+	}
+	iSymbolStringTableSizeValid = true;
+	return iSymbolStringTableSize = stringsSize;
+}
+
+size_t ElfSymbolTableManager::GetFirstNonLocalIndex(){
+	int ndx = 1; // add the 'undefined' symbols
+	
+	SymbolFragmentList::iterator aFrag = iSymbolFragments.begin();
+	SymbolFragmentList::iterator end = iSymbolFragments.end();
+	while (aFrag != end) {
+		ndx += aFrag->GetFirstGlobal();
+		aFrag++;
+	}
+	return ndx;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/elfsymboltablemanager.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,233 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef ELFSYMBOLTABLEMANAGER_H_
+#define ELFSYMBOLTABLEMANAGER_H_
+
+#include <vector>
+#include <cassert>
+
+#include "filefragment.h"
+#include "elfstringtable.h"
+#include "outputfile.h"
+#include "elfheader.h"
+#include "e32romimage.h"
+#include "elfsection.h"
+#include "elfsectionmanager.h"
+#include "defs.h" // String
+
+class ElfSymbolTableManager;
+
+class SectionNumberMapping {
+public:
+	SectionNumberMapping(size_t aOld, size_t aNew):
+		iOld(aOld), iNew(aNew)
+		{}
+	
+	SectionNumberMapping & operator=(const SectionNumberMapping & aSectionNumberMapping){
+		iOld = aSectionNumberMapping.iOld;
+		iNew = aSectionNumberMapping.iNew;
+		return *this;
+	}
+	
+	SectionNumberMapping(const SectionNumberMapping & aSectionNumberMapping){
+		*this = aSectionNumberMapping;
+	}
+
+	size_t iOld;
+	size_t iNew;
+};
+
+typedef std::vector< SectionNumberMapping > SectionNumberMap;
+
+class SectionVaddrAddendMapping {
+public:
+	SectionVaddrAddendMapping(size_t aSectionNumber, signed int aAddend):
+		iSectionNumber(aSectionNumber), iAddend(aAddend)
+		{}
+	
+	SectionVaddrAddendMapping & operator=(const SectionVaddrAddendMapping & aSectionVaddrAddendMapping){
+		iSectionNumber = aSectionVaddrAddendMapping.iSectionNumber;
+		iAddend = aSectionVaddrAddendMapping.iAddend;
+		return *this;
+	}
+	
+	SectionVaddrAddendMapping(const SectionVaddrAddendMapping & SectionVaddrAddendMapping){
+		*this = SectionVaddrAddendMapping;
+	}
+
+	size_t iSectionNumber;
+	signed int iAddend;
+};
+
+typedef std::vector< SectionVaddrAddendMapping > SectionVaddrAddendMap;
+
+class ElfFileSymbolFragments {
+public:
+	ElfFileSymbolFragments(ElfSymbolTableManager * aElfSymbolTableManager):
+		iPath(""), 
+		iSymbolTableOffset(0), iSymbolTableSize(0),
+		iFirstGlobal(0),
+		iStringTableOffset(0), iStringTableSize(0),
+		iElfSymbolTableManager(aElfSymbolTableManager)
+		{
+		iSectionNumberMap.clear();
+		iSectionVaddrAddendMap.clear();
+		}
+	
+	ElfFileSymbolFragments & operator=(const ElfFileSymbolFragments & aElfFileSymbolFragments){
+		iPath = aElfFileSymbolFragments.iPath;
+		iSymbolTableOffset = aElfFileSymbolFragments.iSymbolTableOffset;
+		iSymbolTableSize = aElfFileSymbolFragments.iSymbolTableSize;
+		iFirstGlobal = aElfFileSymbolFragments.iFirstGlobal;
+		iStringTableOffset = aElfFileSymbolFragments.iStringTableOffset;
+		iStringTableSize = aElfFileSymbolFragments.iStringTableSize;
+		iSectionNumberMap = aElfFileSymbolFragments.iSectionNumberMap;
+		iSectionVaddrAddendMap = aElfFileSymbolFragments.iSectionVaddrAddendMap;
+		iElfSymbolTableManager = aElfFileSymbolFragments.iElfSymbolTableManager;
+		return *this;
+	}
+	
+	ElfFileSymbolFragments(const ElfFileSymbolFragments & aElfFileSymbolFragments){
+		*this = aElfFileSymbolFragments;
+	}
+	
+	
+
+	void AddSymbolTable(String & aPath, size_t aOffset, size_t aSize, size_t aFirstGlobal);
+	
+	void AddStringTable(String & aPath, size_t aOffset, size_t aSize);
+	String & GetPath() { return iPath; }
+	size_t GetSymbolTableOffset() { return iSymbolTableOffset; }
+	size_t GetSymbolTableSize() { return iSymbolTableSize; }
+	size_t GetFirstGlobal() { return iFirstGlobal; }
+	size_t GetStringTableOffset() { return iStringTableOffset; }
+	size_t GetStringTableSize() { return iStringTableSize; }
+	
+	void SetSectionNumberMap(SectionNumberMap & aSectionNumberMap){
+		iSectionNumberMap = aSectionNumberMap;
+	}
+	
+	size_t LookupSection(size_t ndx);
+	
+	void SetSectionVaddrAddendMap(SectionVaddrAddendMap & aSectionVaddrAddendMap){
+		iSectionVaddrAddendMap = aSectionVaddrAddendMap;
+	}
+	
+	int LookupVaddrAddend(size_t ndx);
+	
+	void Validate() {
+		assert(iPath.size() != 0);
+		assert(iSymbolTableOffset != 0);
+		assert(iSymbolTableSize != 0);
+		assert(iStringTableOffset != 0);
+		assert(iStringTableSize != 0);
+		assert(!iSectionNumberMap.empty());
+		assert(!iSectionVaddrAddendMap.empty());
+	}
+	
+	void Reset(){
+		new (this) ElfFileSymbolFragments(iElfSymbolTableManager);
+	}
+	
+private:
+	String iPath;
+	size_t iSymbolTableOffset;
+	size_t iSymbolTableSize;
+	size_t iFirstGlobal;
+	size_t iStringTableOffset;
+	size_t iStringTableSize;
+	SectionNumberMap iSectionNumberMap;
+	SectionVaddrAddendMap iSectionVaddrAddendMap;
+	ElfSymbolTableManager * iElfSymbolTableManager;
+	
+};
+
+class ElfSymTabStringTable : public ElfStringTable {
+public:
+	ElfSymTabStringTable(ElfSymbolTableManager & aElfSymbolTableManager):
+		iElfSymbolTableManager(aElfSymbolTableManager)
+		{}
+	
+	virtual size_t Size();
+	
+private:
+	ElfSymbolTableManager & iElfSymbolTableManager;
+};
+
+class ElfSymbolTableManager : public FileFragmentOwner {
+public:
+	ElfSymbolTableManager(Elf32Header & aElf32Header, E32RomImage & aRomImage, 
+					      OutputFile & aOutputFile, ElfSectionManager & aElfSectionManager) :
+		iElf32Header(aElf32Header), iRomImage(aRomImage), 
+		iOutputFile(aOutputFile), iElfSectionManager(aElfSectionManager),
+		iData(NULL),
+		iSymbolStringTableSizeValid(false),
+		iSymbolStringTableSize(0),
+		iCurrentFragment(this),
+		iStringTable(*this)
+		{}
+	
+	// The FileFragmentOwner protocol
+	virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData );
+	virtual size_t Size();
+	virtual void DeleteFileFragmentData();
+	virtual void AddData(OutputFile & aOutputFile);
+	
+	void AddSymbolTable(String & aPath, size_t aOffset, size_t aSize, size_t aFirstGlobal){
+		iCurrentFragment.AddSymbolTable(aPath, aOffset, aSize, aFirstGlobal);
+	}
+	void AddStringTable(String & aPath, size_t aOffset, size_t aSize){
+		iCurrentFragment.AddStringTable(aPath, aOffset, aSize);
+
+	}
+	virtual void AddSymbolFragment(){
+		iSymbolFragments.push_back(iCurrentFragment);
+	}
+	virtual void AddSymbolTable();
+	
+	size_t GetSymTabStringsSectionSize();
+
+	virtual void Finalize(SectionNumberMap & aSectionNumberMap, SectionVaddrAddendMap & aSectionVaddrAddendMap);
+	
+private:
+	// Don't want one of these to be copied
+	ElfSymbolTableManager(const ElfSymbolTableManager & aElfSymbolTableManager);
+	
+	ElfSymbolTableManager & operator=(const ElfSymbolTableManager & aElfSymbolTableManager);
+	
+	size_t GetSymTabSectionSize();
+	size_t GetFirstNonLocalIndex();
+
+private:
+	typedef std::vector<ElfFileSymbolFragments> SymbolFragmentList;
+private:
+	Elf32Header & iElf32Header;
+	E32RomImage & iRomImage;
+	OutputFile & iOutputFile;
+	ElfSectionManager & iElfSectionManager;
+	
+	char * iData;
+	bool iSymbolStringTableSizeValid;
+	size_t iSymbolStringTableSize;
+	ElfFileSymbolFragments iCurrentFragment;
+	SymbolFragmentList iSymbolFragments;
+	ElfSymTabStringTable iStringTable;
+};
+
+#endif /*ELFSYMBOLTABLEMANAGER_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/filefragment.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,48 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <cassert>
+
+#include "filefragment.h"
+#include "outputfile.h"
+
+
+FileFragmentData::~FileFragmentData(){
+
+}
+
+FileFragmentOwner::~FileFragmentOwner(){
+
+}
+
+FileFragment::~FileFragment(){
+
+}
+
+void FileFragment::Write(OutputFile * aFile){
+	FileFragmentData aData;
+	iOwner->GetFileFragmentData(aData);
+	assert(aData.GetSize() == iSize);
+	aFile->Write(iOffset, iSize, aData.GetData());
+	iOwner->DeleteFileFragmentData();
+}
+
+void FileFragmentOwner::AddData(OutputFile & aOutputFile){
+	const FileFragment & aFileFrag = aOutputFile.GetFileFragment(this);
+	SetOffset(aFileFrag.GetOffset());
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/filefragment.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,116 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef FILEFRAGMENT_H_
+#define FILEFRAGMENT_H_
+
+#include <stddef.h>
+
+class OutputFile;
+
+class FileFragmentData
+{
+
+public:
+	FileFragmentData() :
+		iSize(0), iData(0)
+		{};
+	FileFragmentData(size_t aSize, char * aData) :
+		iSize(aSize), iData(aData)
+		{};
+	virtual ~FileFragmentData();
+	inline char* GetData() { return iData; };
+	inline size_t GetSize() { return iSize; };
+	inline void SetData(char * newVal) { iData = newVal; };
+	inline void SetSize(size_t newVal) { iSize = newVal; };
+
+private:
+	size_t iSize;
+	char* iData;
+};
+
+/**
+ * Defines the interface for owners of FileFragments
+ */
+class FileFragmentOwner
+{
+public:
+	FileFragmentOwner() :
+		iOffset(0)
+		{};
+		
+	FileFragmentOwner(size_t aOffset) :
+		iOffset(aOffset)
+		{};	
+		
+	virtual ~FileFragmentOwner();
+
+	virtual void GetFileFragmentData(FileFragmentData & aFileFragmentData ) =0;
+	virtual size_t Size() = 0;
+	virtual void DeleteFileFragmentData() = 0;
+	
+	virtual void AddData(OutputFile & aFile);
+	virtual size_t GetOffset() { return iOffset; }
+	virtual void SetOffset(size_t aOffset) { iOffset = aOffset; }
+	
+//protected:
+	void SetFileFragmentData(FileFragmentData & aFileFragmentData, size_t aSize, char * aData){
+		aFileFragmentData.SetSize(aSize);
+		aFileFragmentData.SetData(aData);
+	}		
+	
+protected:
+	size_t iOffset;
+};
+
+
+/**
+ * Represents a fragment of file of a given size (in bytes) at a given offset (in
+ * bytes).
+ */
+class FileFragment
+{
+
+public:
+	FileFragment(size_t aOffset, size_t aSize, FileFragmentOwner * aOwner) :
+		iOffset(aOffset), iSize(aSize), iOwner(aOwner)
+		{};
+	virtual ~FileFragment();
+	
+	inline size_t GetOffset() const { return iOffset; };
+	inline size_t GetSize() const { return iSize; };
+	inline void SetOffset(size_t newVal) { iOffset = newVal; };
+	inline void SetSize(size_t newVal) { iSize = newVal; };
+	void Write(OutputFile * aFile);
+
+private:
+	/**
+	 * offset in bytes at which the fragment occurs in the file
+	 */
+	size_t iOffset;
+	/**
+	 * size in bytes of the file fragment
+	 */
+	size_t iSize;
+	/**
+	 * the owner of the file fragment
+	 */
+	FileFragmentOwner * iOwner;
+};
+
+#endif /*FILEFRAGMENT_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/inputfile.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,112 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <fcntl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <cassert>
+
+#include "elfromerror.h"
+#include "inputfile.h"
+
+InputFile & InputFile::operator=(const InputFile & aInputFile) {
+	// Don't copy fd. Force a new to be got.
+	iOpened = false;
+	// Force size to be re-computed
+	iSizeValid = false;
+	iOffset = aInputFile.iOffset;
+	iPathName = aInputFile.iPathName;
+	return *this;
+}
+
+InputFile::InputFile(const InputFile & aInputFile){
+	*this = aInputFile;
+}
+
+InputFile::~InputFile(){
+	Close();
+}
+
+void InputFile::Open(){
+	if (iOpened) return;
+	if ((iFd = open(iPathName.c_str(), O_RDONLY|O_BINARY, 0)) < 0)
+		errx(EX_NOINPUT, "open \"%s\" failed\n", iPathName.c_str());
+	else
+		iOpened = true;
+}
+
+void InputFile::Close(){
+	if (!iOpened) return;
+	close(iFd);
+	iOpened = false;
+	iSizeValid = false;
+}
+
+size_t InputFile::Size(){
+	if (iSizeValid) return iSize - iOffset;
+	SetSize();
+	return iSize - iOffset;
+}
+
+void InputFile::SetSize(){
+	Open();
+	if ((iSize = lseek(iFd, (size_t)0, SEEK_END)) == (size_t)-1)
+		errx(EX_NOINPUT, "failed to get size of \"%s\"", iPathName.c_str());
+	if (lseek(iFd, (size_t)0, SEEK_SET) != 0)
+		errx(EX_NOINPUT, "failed to get size of \"%s\"", iPathName.c_str());
+	Close();
+	iSizeValid = true;
+}
+
+char * InputFile::GetData(){
+	size_t nbytes = Size();
+	return GetData(nbytes);
+}
+
+char * InputFile::GetData(size_t nbytes) {
+	char * data = new char[nbytes];
+	GetData(data, nbytes);
+	return data;
+}
+
+void InputFile::GetData(void * data, size_t nbytes){
+	char * d = (char *)data;
+	size_t done = 0;
+	ssize_t n;
+	
+	Open();
+	
+	if (iOffset > 0)
+		if ((size_t)lseek(iFd, iOffset, SEEK_SET) != iOffset) {
+			Close();
+			errx(EX_NOINPUT, "failed to read from \"%s\"", iPathName.c_str());
+		}
+	
+	while (nbytes){
+		n = read(iFd, d+done,nbytes);
+		// n must be greater than 0
+		if (n <= 0){
+			Close();
+			errx(EX_NOINPUT, "failed to read from \"%s\"", iPathName.c_str());
+		}
+		done += n;
+		nbytes -= n;
+	}
+	
+	Close();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/inputfile.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,59 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef INPUTFILE_H_
+#define INPUTFILE_H_
+
+#include <cassert>
+
+#include "defs.h"
+
+class InputFile {
+public:
+	InputFile(PathName & aPath) :
+		iPathName(aPath), iFd(0), iOpened(false), iSize(0), iSizeValid(false), iOffset(0)
+		{
+			assert(iPathName.size() != 0);
+		}
+	~InputFile();
+	void Open();
+	void Close();
+	size_t Size();
+	char * GetData();
+	char * GetData(size_t nbytes);
+	void GetData(void * data, size_t nbytes);
+	void SetOffset(size_t aOffset) { iOffset = aOffset; }
+	size_t GetOffset() { return iOffset; }
+	
+	InputFile & operator=(const InputFile & aInputFile);
+	InputFile(const InputFile & aInputFile);
+	
+
+private:
+	
+	void SetSize();
+private:
+	PathName iPathName;
+	int iFd;
+	bool iOpened;
+	size_t iSize;
+	bool iSizeValid;
+	size_t iOffset;
+};
+
+#endif /*INPUTFILE_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/main.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,55 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <fcntl.h>
+#include <libelf.h> 
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string>
+#include "romdetails.h"
+#include "processoptions.h"
+
+#include "elfromerror.h"
+#include "elfrom.h"
+
+
+void InitLibElf() {
+	if (elf_version(EV_CURRENT) == EV_NONE) 
+		errx(EX_SOFTWARE, "ELF library initialization failed: %s\n",
+				elf_errmsg(-1));
+}
+
+RomDetails * Init(int argc, char * argv[]){
+	RomDetails * details = ProcessOptions(argc, argv);
+	return ProcessRomDetails(details);
+}
+
+int main(int argc, char * argv[]){
+//TODO: print banner if trace on
+	InitLibElf();
+	RomDetails * romDetails = Init(argc, argv);
+	ElfRom aElfRom(romDetails);
+	aElfRom.SetupE32RomData();
+	aElfRom.SetupELFRomData();
+	aElfRom.AddData();
+	
+	aElfRom.Dump();
+	
+	return EXIT_SUCCESS;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/outputfile.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,125 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <cstdio>
+#include <cstdlib>
+#include <unistd.h>
+#include <cassert>
+
+#include "outputfile.h"
+
+static const size_t NumReservedFileFragments = 100;
+
+OutputFile::OutputFile(PathName aFileName) :
+	iFileName(aFileName), iOpened(false), iFd(-1), iCurrentOffset(0)
+{
+	assert(iFileName.size() != 0);
+	// reserve space for file fragments
+	iFileFragments.reserve(NumReservedFileFragments);
+}
+
+OutputFile::~OutputFile(){
+	iFileFragments.clear();
+	if (iOpened)
+		Close();
+}
+
+
+void OutputFile::Close(){
+	if (iOpened) {
+		close(iFd);
+		iOpened = false;
+	}
+}
+
+void OutputFile::Flush(){
+	if (!iOpened)
+		Open();
+	if (iFileFragments.size() > 0) {
+		FragmentList::iterator aFrag = iFileFragments.begin();
+		FragmentList::iterator end = iFileFragments.end();
+		while (aFrag != end) {
+			aFrag->Write(this);
+			aFrag++;
+		}
+		iFileFragments.clear();
+	}	
+}
+
+void OutputFile::Dump(){
+	Flush();
+	Close();
+}
+
+const FileFragment & OutputFile::GetFileFragment(FileFragmentOwner * aOwner){
+	size_t aSize = aOwner->Size();
+	FileFragment aFragment(iCurrentOffset, aSize, aOwner);
+	iFileFragments.push_back(aFragment);
+	iCurrentOffset += ALIGN4(aSize);
+	return  iFileFragments.back();
+}
+
+void OutputFile::Open(){
+	if (!iOpened) {
+		if ((iFd = open(iFileName.c_str(), O_WRONLY | O_CREAT | O_BINARY | O_TRUNC, S_IRUSR | S_IWUSR)) == -1) {
+			char msg[1000];
+			sprintf(msg, "Output file %s", iFileName.c_str());
+			perror(msg);
+			exit(EXIT_FAILURE);
+		}
+		iOpened = true;
+	}
+}
+
+void OutputFile::Write(size_t aOffset, size_t aSize, char * aData){
+	assert(((aSize==0) && (aData==NULL)) || ((aSize>0) && (aData!=NULL)));
+	if (aSize == 0) return;
+	char msg[1000];
+#ifndef USE_PWRITE
+	if (lseek(iFd, aOffset, SEEK_SET) != (int)aOffset) {
+		sprintf(msg, "Failed to seek to offset %d in output file %s", aOffset, iFileName.c_str());
+		goto error;
+	}
+	for (size_t n = 0; n < aSize;) {
+		if ((int)(n += write(iFd, aData+n, aSize - n)) == -1) {
+			sprintf(msg, "Failed to write to output file %s", iFileName.c_str());
+			goto error;			
+		}
+	}
+#else
+	for (size_t n = 0; n < aSize;) {
+		if ((n += pwrite(iFd, aData+n, aSize - n, aOffset + n)) == -1) {
+			sprintf(msg, "Failed to write to output file %s", iFileName.c_str());
+			goto error;			
+		}
+	}	
+#endif
+	return;
+	
+error:
+		perror(msg);
+// should we close the file and delete it??		
+#ifdef DELETE_OUTPUT_ON_ERROR
+		Close();
+		unlink(iFileName);
+#endif
+		exit(EXIT_FAILURE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/outputfile.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,65 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef OUTPUTFILE_H_
+#define OUTPUTFILE_H_
+
+#include <vector>
+
+#include "defs.h"
+#include "filefragment.h"
+
+// uncomment this is output file should be deleted on error
+//#define DELETE_OUTPUT_ON_ERROR
+// uncomment to use pwrite (this should be more efficient) but results in different
+// file pointer behaviour. NB not defined by MINGW in unistd.h 
+//#define USE_PWRITE
+
+// TODO: NB currently this can only deal with 4gb files. Need to upgrade for larger files
+class OutputFile
+{
+public:
+	OutputFile(PathName aFileName);
+	virtual ~OutputFile();
+
+	virtual void Close();
+	virtual void Flush();
+	virtual void Dump();
+	virtual const FileFragment & GetFileFragment(FileFragmentOwner * aOwner);
+	virtual void Open();
+	virtual void Write(size_t aOffset, size_t aSize, char * aData);
+	virtual size_t Size(){ return iCurrentOffset; }
+
+private:
+	// Don't want one of these to be copied
+	OutputFile(const OutputFile & aOutputFile);
+	
+	OutputFile & operator=(const OutputFile & aOutputFile);
+	
+private:
+	typedef std::vector<FileFragment> FragmentList;
+	
+	PathName iFileName;
+	FragmentList iFileFragments;
+	bool iOpened;
+	int iFd;
+	size_t iCurrentOffset;
+
+};
+
+#endif /*OUTPUTFILE_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/processoptions.cpp	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,609 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <boost/program_options.hpp>
+namespace po = boost::program_options;
+#include <boost/regex.hpp>
+#include <boost/filesystem.hpp>
+namespace fs = boost::filesystem;
+
+#include <iostream>
+
+#include <iterator>
+#include <string>
+#include <map>
+#include <set>
+
+#include <ctype.h>
+#include <cstdlib>
+
+using namespace std;
+
+#include "defs.h"
+#include "romdetails.h"
+#include "inputfile.h"
+#include "elfromerror.h"
+
+static inline void downcase(std::string & s){
+	for (std::string::iterator i = s.begin(); i != s.end(); i++)
+		*i = tolower(*i);
+}
+
+static int required_option(const po::variables_map& vm, const char* option){
+	if (vm.count(option) == 0 || vm[option].defaulted()) {
+		cerr << "Error: option \'" << option << "\' required.\n";
+		return 1;
+	} 
+	return 0;
+}
+
+static int either_or_required(const po::variables_map& vm, const char* option1, const char* option2){
+	if ((vm.count(option1) == 0 || vm[option1].defaulted()) &&
+		(vm.count(option2) == 0 || vm[option2].defaulted())) {
+		cerr << "Error: either option \'" << option1 << "\' or option \'" << option2 <<"\' required.\n";
+		return 1;
+	} 
+	return 0;
+}
+
+RomDetails * ProcessOptions(int ac, char* av[]) {
+	RomDetails * details = new RomDetails;
+	int errors = 0;
+	
+    try {
+
+    	string phys_addr;
+        po::options_description desc("  Command Line Only");
+        desc.add_options()
+            ("help,h", "produce help message")
+            ("config-file,c", po::value<string>(), 	"pathname of config file "
+            													  	"(overrides default of elf4rom.cfg and value "
+            														"of ELF4ROM_CFG_FILE environment variable)")
+        ;
+
+        po::options_description config("  Command Line and Configuration File");
+        config.add_options()
+            ("board-name,b", po::value<string>(&details->iBoardName), 	"name of board targeted e.g. versatilepb")
+            ("debug,d", po::value< vector<string> >(&details->iTargetFiles)->multitoken()->composing(), 
+																		"collect ELF and DWARF data from the listed files")
+			("drive,D", po::value<string>(&details->iDrive), 			"drive on which to find ELF files")
+			("exclude,e", po::value< vector<string> >(&details->iExcludeFiles)->multitoken()->composing(), 
+																		"exclude collection of ELF and DWARF data from the listed files")
+            ("input,i", po::value<string>(&details->iRomFile), 			"pathname of ROM image")
+            ("logfile,l", po::value<string>(&details->iLogFile), 		"pathname of ROMBUILD log file")
+            ("no-dwarf,n", po::bool_switch(&details->iNoDwarf), 		"suppress generatation of DWARF in output"
+																		" (prevents source level debugging but saves time and space)")
+            ("output,o", po::value<string>(&details->iElfRomFile), 		"pathname of output file")
+            // lexical_cast doesn't understand <LinearAddress> even though its just a typedef
+            // for unsigned int
+            ("physical-address,p", po::value<string>(&phys_addr), 		"physical address of ROM on device. Overrides board-name")
+            ("search,s", po::bool_switch(&details->iSearch), 			"search for ELF files in build directory if .sym file not "
+            															"found in release directory")
+            ("strip,S", po::bool_switch(&details->iStrip), 				"suppress generation of symbol table and DWARF in output"
+																		" (useful to produce a 'loadable' ELF image for e.g. a simulator)")
+			("trace,t", po::bool_switch(&details->iTrace), 				"switch on trace")
+			;
+            
+        po::options_description cmdline_options;
+        cmdline_options.add(desc).add(config);
+
+        po::options_description config_file_options;
+        config_file_options.add(config);
+        
+        po::variables_map vm; 
+        //po::store(po::parse_command_line(ac, av, desc), vm);
+        po::store(po::command_line_parser(ac, av).options(cmdline_options).run(), vm);
+        
+        char * cfgFile = "elf4rom.cfg";
+        if (vm.count("config-file")) {
+        	char * xcfgFile = (char *)(vm["config-file"].as<string>().c_str());
+        	fs::path cfgpath(xcfgFile);
+
+        	if (fs::exists(cfgpath)) {
+        		cfgFile = xcfgFile;
+        	} else {
+        		cerr << "Warning: specified config file " << xcfgFile << " not found: will not attempt to use default.\n";
+        	}
+        } else {
+        	char * envCfgFile = getenv("ELF4ROM_CFG_FILE");
+        	if (envCfgFile != NULL) 
+        		cfgFile = envCfgFile;
+        }
+        
+        ifstream ifs(cfgFile);
+        store(parse_config_file(ifs, config_file_options), vm);
+
+       	po::notify(vm); 
+ 
+        if (vm.count("help")) {
+        	cout << "elf4rom [option]";
+            cout << cmdline_options << "\n";
+            delete details;
+            exit(EXIT_SUCCESS) ;
+        }
+
+        
+        errors += required_option(vm, "input");
+        errors += required_option(vm, "logfile");
+        errors += required_option(vm, "output");
+        
+        errors += either_or_required(vm, "board-name", "physical-address");
+
+        if (vm.count("physical-address")){
+        	char *f;
+        	const char * p = phys_addr.c_str();
+        	details->iRomPhysAddr = strtoul(p ,&f , 16);
+        	if (f == p){
+        		cerr << "Error: invalid arg to --physical-address: " << phys_addr.c_str() << "\n";
+        		exit(EXIT_FAILURE);
+        	}
+        } else if (vm.count("board-name")){
+        	// TODO: figure out address frmo board name
+        	cerr << "Error: --board-name option not implemented yet\n";
+            exit(EXIT_FAILURE) ;
+        }
+        
+        if (errors) {
+        	cerr << "elf4rom [option]";
+            cerr << cmdline_options << "\n";
+            delete details;
+            exit(EXIT_FAILURE) ;
+        }
+    }
+    catch(exception& e) {
+        cerr << "error: " << e.what() << "\n";
+        exit(EXIT_FAILURE) ;
+    }
+    catch(...) {
+        cerr << "Exception of unknown type!\n";
+        exit(EXIT_FAILURE) ;
+    }
+
+    return details;
+}
+
+
+static bool VerifyLogFile(string::const_iterator & start, string::const_iterator & end, string::const_iterator & rest){
+#if 0 
+// Look for somthing like the following
+ROMBUILD - Rom builder V2.08 (Build 593)
+Copyright (c) 1996-2007 Symbian Software Ltd.
+or
+ROMBUILD - Rom builder V2.08 (Build 596)
+Copyright (c) 1996-2009 Nokia Corporation.
+#endif	
+
+	const char * banner  = "ROMBUILD.*Rom builder.*Copyright.*";
+	boost::regex e(banner);
+	boost::match_results<string::const_iterator> what;
+	if (boost::regex_search(start, end, what, e)){ 
+		rest = what[0].second;
+		return true;
+	}
+	return false;
+}
+
+static void OffenceWarning (string & offender){
+	cerr << "Warning: The following section of the ROM Log appears corrupt:\n" << offender << "\n";	
+}
+
+static inline unsigned int ConvertToUnsignedLong(string & s, string & offender){
+	char * endp;
+	const char * ss = s.c_str();
+	unsigned int res = strtoul(ss, &endp,16);
+	if (endp == ss)
+		OffenceWarning(offender);
+	return res;
+}
+
+static bool ProcessXIPFile(string::const_iterator & start, string::const_iterator & end, 
+		string::const_iterator & rest, RomDetails * details){
+	const char * f  = 
+		"Processing file (\\S+)\\s*" 		// 1
+		"(\\[Primary\\]\\s*)?"				// 2
+		"(\\[Secondary\\]\\s*)?"			// 3		
+		"(ELF File:\\s*\\S+\\s*)?" 			// 4
+		"(ELF MD5:\\s*\\S+\\s*)?"			// 5
+		"Load Address:\\s+(\\S+)\\s*"		// 6
+		"Size:\\s+\\S+\\s*"
+		"Uids:\\s+\\S+\\s+\\S+\\s+\\S+\\s+\\S+\\s*"
+		"Entry point:\\s+\\S+\\s*"
+		"Code start addr:\\s+(\\S+)\\s*"	// 7
+		"Data start addr:\\s+(\\S+)\\s*"	// 8
+		"DataBssLinearBase:\\s+(\\S+)\\s*"	// 9
+		"Text size:\\s+\\S+\\s*"
+		"Code size:\\s+(\\S+)\\s*"			// 10
+		"Data size:\\s+(\\S+)\\s*"			// 11
+		"BssSize:\\s+(\\S+)\\s*"			// 12
+		;
+	boost::regex e(f);
+	boost::match_results<string::const_iterator> what;
+	if (boost::regex_search(start, end, what, e)){
+		string filename(what[1].first, what[1].second);
+		string offender(what[0].first, what[0].second);
+		if (filename.size() == 0)
+			OffenceWarning(offender);
+		bool primary = what[2].matched;
+		if (what[2].matched){
+			primary = true;
+		}
+		
+		const int kla = 6;
+		string ls(what[kla].first, what[kla].second);
+		LinearAddr load = ConvertToUnsignedLong(ls, offender);
+
+		const int kta = kla + 1;
+		string ts(what[kta].first, what[kta].second);
+		LinearAddr text = ConvertToUnsignedLong(ts, offender);
+
+		const int kda = kta + 1;
+		string ds(what[kda].first, what[kda].second);
+		LinearAddr data = ConvertToUnsignedLong(ds, offender);
+
+		const int kva = kda + 1;
+		string vds(what[kva].first, what[kva].second);
+		VirtualAddr vdata = ConvertToUnsignedLong(vds, offender);
+
+		const int kts = kva + 1;
+		string tss(what[kts].first, what[kts].second);
+		size_t textSize = ConvertToUnsignedLong(tss, offender);		
+
+		const int kds = kts + 1;
+		string dss(what[kds].first, what[kds].second);
+		size_t fileDataSize = ConvertToUnsignedLong(dss, offender);
+
+		const int kbs = kds + 1;
+		string bsss(what[kbs].first, what[kbs].second);
+		size_t bssSize = ConvertToUnsignedLong(bsss, offender);		
+		VirtualAddr bss = vdata + fileDataSize;
+		size_t memDataSize = fileDataSize + bssSize;
+		
+		string elffile("");
+		details->iXIPFiles.push_back(XIPFileDetails(filename, 
+													elffile, 
+													load, 
+													text, 
+													textSize,
+													vdata, 
+													fileDataSize, 
+													data, 
+													bss, 
+													memDataSize));
+		if (primary)
+			new(&details->iPrimary)XIPFileDetails(filename, 
+												  elffile, 
+												  load, 
+												  text, 
+												  textSize,
+												  vdata, 
+												  fileDataSize, 
+												  data, 
+												  bss, 
+												  memDataSize);
+		
+		rest = what[0].second;
+		return true;
+	}
+	rest = start;
+	return false;
+
+}
+
+static void CheckXIPFiles(RomDetails * details, std::vector<string> & list){
+	for (std::vector<string>::iterator i = list.begin(); i != list.end(); i++) {
+		bool found = false;
+		for (RomDetails::XIPFileList::iterator j = details->iXIPFiles.begin(); j != details->iXIPFiles.end(); j++){
+			fs::path e32filePath(j->iE32File);
+			String e32FileName(e32filePath.leaf());
+			if ((*i) == e32FileName){
+				found = true;
+				break;
+			}
+
+		}
+		if (!found){
+			cerr << "WARNING: " << (*i) << " not found in ROM\n";
+		}
+	}
+}
+
+static void CheckDebugXIPFiles(RomDetails * details){
+	CheckXIPFiles(details, details->iTargetFiles);
+}
+
+static void CheckExcludeXIPFile(RomDetails * details){
+	CheckXIPFiles(details, details->iExcludeFiles);
+}
+
+static void ProcessXIPFiles(string::const_iterator & start, string::const_iterator & end, 
+		string::const_iterator & rest, RomDetails * details){
+	while (ProcessXIPFile(start,end,rest,details)){
+		start = rest;
+	}
+	CheckDebugXIPFiles(details);
+	CheckExcludeXIPFile(details);
+}
+
+
+static void ProcessRomDetails(string::const_iterator & start, string::const_iterator & end, 
+								string::const_iterator & rest, RomDetails * details){
+	const char * align  = "Linear base address:\\s*([\\S]+)$";
+	boost::regex e(align);
+	boost::match_results<string::const_iterator> what;
+	if (boost::regex_search(start, end, what, e)){ 
+		string offender(what[0].first, what[0].second);
+		string lbas(what[1].first, what[1].second);
+		details->iRomBaseLinearAddr = ConvertToUnsignedLong(lbas, offender);
+	} else {
+        cerr << "Error: " << details->iLogFile << " not a valid ROM log file. Could not find Linear base address." << "\n";
+        exit(EXIT_FAILURE) ;		
+	}
+}
+
+static fs::path FindBuildPath(RomDetails * details){
+	const string epoc32("epoc32");
+	const string builddir("build");
+	const string epocRoot(getenv("EPOCROOT"));
+	if (details->iDrive.size() > 0) {
+		string drive(details->iDrive);
+		if (drive.size() == 1){
+			drive += ":";
+		} else if (((drive.size() == 2) && (drive[drive.size()-1] != ':')) || (drive.size() > 2)){
+	        cerr << "Error: Invalid drive specification: " << drive << "\n";
+	        exit(EXIT_FAILURE) ;			
+		}
+		fs::path buildpath(drive);
+
+		buildpath /= epocRoot;
+		buildpath /= epoc32;
+		buildpath /= builddir;
+		return buildpath;
+	}
+	fs::path primary_path(details->iPrimary.iE32File);
+	fs::path buildpath;
+	for (fs::path::iterator i = primary_path.begin(); i != primary_path.end(); i++){
+		string item(*i);
+		downcase(item);
+		buildpath /= item;
+		if (item == epoc32) {
+			buildpath /= builddir;
+			break;
+		}
+	}
+	return buildpath;
+}
+
+class PathCache {
+public:
+	typedef std::map<string, string> PathMap;
+
+	PathCache(fs::path & apath):
+		iBuildPath(apath)
+		{
+			if (fs::exists(apath)){
+				fs::recursive_directory_iterator i(apath);
+				iCurrent = i;
+			}
+		}
+	bool FindPath(string & pattern, string & result);
+	fs::path & GetBuildPath() { return iBuildPath; }
+	
+private:
+	bool GetNextPath(string & path);
+	bool Filtered(fs::path & path);
+
+private:
+	
+	fs::path iBuildPath;
+	fs::recursive_directory_iterator iCurrent;
+	fs::recursive_directory_iterator iEnd;
+	PathMap iPathMap;
+	static const std::string filters;
+};
+
+
+
+bool PathCache::Filtered(fs::path & apath){
+	std::string ext(fs::extension(apath));
+	downcase(ext);
+	if (ext.size() > 0){
+		if (filters.find(ext) != std::string::npos)
+			return true;
+	} 
+	return false;
+}
+
+bool PathCache::GetNextPath(string & path){
+	 for (; iCurrent != iEnd; ++iCurrent ){
+		 if (fs::is_directory(iCurrent->status()))
+			 continue;
+		 fs::path candidate(iCurrent->path());
+		 if (!Filtered(candidate)) {
+			 path = candidate.string();
+			 ++iCurrent;
+			 return true;
+		 }
+	 }
+	 return false;
+}
+
+static void GetTarget(string & source, string & target){
+	fs::path t1(source);
+	fs::path::iterator s = t1.begin();
+	fs::path::iterator start = t1.end();
+	int n = 0;
+	for (; n < 3 && s != start; n++, start--){}
+	if (n < 3) {
+		warnx(0, "%s does not have 3 elements\n", source.c_str());
+	}
+
+	fs::path q;
+	for (; start != t1.end(); start++){
+		q /= fs::path(*start);
+	}
+	target = q.string();
+	downcase(target);
+}
+
+bool PathCache::FindPath(string & source, string & result){
+	string ss;
+	if (source.size() == 0) return false;
+	GetTarget(source, ss);
+	
+	// now check the cache
+	PathMap::iterator res = iPathMap.find(ss);
+	if (res != iPathMap.end()){
+		result = res->second;
+		return true;
+	}
+	
+	// otherwise iterate until we find a match
+	string candidate;
+	while (GetNextPath(candidate)){
+		downcase(candidate);
+		size_t n = candidate.rfind(ss);
+		if (n != string::npos){
+			size_t csize = candidate.size();
+			size_t sssize = ss.size();
+			if ((csize - sssize) == n){
+				// put it in cache anyway just in case its the primary
+				iPathMap[ss] = candidate;
+				result = candidate;
+				return true;
+			}
+		}
+		string x;
+		GetTarget(candidate, x);
+		iPathMap[x] = candidate;
+	}
+	return false;
+}
+
+const std::string PathCache::filters(
+		".cpp"
+		".h"
+		".mk"
+		".o"
+		".in"
+		".via"
+		".mbg"
+		".rsg"
+		".bat"
+		".make"
+		".def"
+		".armv5"
+	);
+
+static bool FindSymFile(XIPFileDetails & detail, string & rootname){
+	fs::path buildpath(rootname);
+	fs::path e32path(detail.iE32File);
+	buildpath /= e32path;
+	// check for pre-RAPTOR .sym file
+	fs::path elfpath = fs::change_extension(buildpath, ".sym");
+	if (fs::exists(elfpath)) {
+		detail.iElfFile = elfpath.string();
+		return true;
+	}
+	// check for RAPTOR .sym file
+	fs::path symPath(buildpath.string() + ".sym");
+	if (fs::exists(symPath)) {
+		detail.iElfFile = symPath.string();
+		return true;
+	}	
+	return false;
+}
+
+static void FindElfFile(XIPFileDetails & detail, PathCache & cache, bool search){
+	// see if there's a .sym file
+	string root(cache.GetBuildPath().root_name());
+	if (FindSymFile(detail, root)) return;
+	if (!search) {
+		cerr << "Warning: could not find ELF file for " << detail.iE32File << ".\n";
+		return;
+	}
+	string s(detail.iE32File);
+	string res;
+	if (s.size() == 0) return;
+	if (cache.GetBuildPath().string().empty()) return;
+	
+	if (cache.FindPath(s, res)){
+		detail.iElfFile = res;
+	} else
+		cerr << "Warning: could not find ELF file for " << detail.iE32File << ".\n";
+}
+
+
+static void FindElfFiles(RomDetails * details){
+	fs::path buildroot = FindBuildPath(details);
+	PathCache cache(buildroot);
+	bool search = details->iSearch;
+	FindElfFile(details->iPrimary, cache, search);
+	for(RomDetails::XIPFileList::iterator i = details->iXIPFiles.begin(); i != details->iXIPFiles.end(); i++){
+		fs::path e32filePath(i->iE32File);
+		String e32FileName(e32filePath.leaf());
+		if (details->iTargetFiles.empty()) {
+			bool find = true;
+			for (std::vector<String>::iterator ef = details->iExcludeFiles.begin(); ef != details->iExcludeFiles.end(); ef++) {
+				fs::path excludePath(*ef);
+				String excludeFile(excludePath.leaf());
+				if (e32FileName == excludeFile) {
+					find = false;
+					break;
+				}
+			}
+			if (find)
+				FindElfFile(*i, cache, search);
+		} else {
+			for (std::vector<String>::iterator tf = details->iTargetFiles.begin(); tf != details->iTargetFiles.end(); tf++) {
+				fs::path targetPath(*tf);
+				String targetFile(targetPath.leaf());				
+				if (e32FileName == targetFile) {
+					FindElfFile(*i, cache, search);
+					break;
+				}
+			}
+		}
+	}
+	
+}
+
+RomDetails * ProcessRomDetails(RomDetails * details){
+	InputFile in(details->iLogFile);
+	char * data = in.GetData();
+	string logfile(data);
+	string::const_iterator  start = logfile.begin();
+	string::const_iterator  end = logfile.end();
+	string::const_iterator  rest;
+
+	if (!VerifyLogFile(start, end , rest)) {
+        cerr << "error: " << details->iLogFile << " not a valid ROM log file." << "\n";
+        exit(EXIT_FAILURE) ;
+	}
+	
+	ProcessXIPFiles(start,end,rest,details);
+	
+	ProcessRomDetails(rest, end, rest, details);
+	
+	FindElfFiles(details);
+	
+	// TODO: make sure functions that return data allocated with new [] 
+	// have an appropriate return value so that delete [] can be used
+	delete [] data;
+	
+	return details;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/processoptions.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,25 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef PROCESSOPTIONS_H_
+#define PROCESSOPTIONS_H_
+
+RomDetails * ProcessOptions(int ac, char* av[]);
+RomDetails * ProcessRomDetails(RomDetails *);
+
+#endif /*PROCESSOPTIONS_H_*/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/elf4rom/src/romdetails.h	Tue Jan 26 13:28:08 2010 +0000
@@ -0,0 +1,151 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program 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 Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public License
+* along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef ROMDETAILS_H_
+#define ROMDETAILS_H_
+
+#include <vector>
+
+#include "defs.h"
+
+class XIPFileDetails {
+public:
+	XIPFileDetails():
+		iE32File(""), 
+		iElfFile(""), 
+		iLoadAddr(0x0),
+		iROAddr(0x0), 
+		iROSize(0),
+		iRWAddr(0x0),
+		iRWSize(0),
+		iROMDataAddr(0), 
+		iBSSAddr(0),
+		iBSSDataSize(0),
+		iElfTextBase(0),
+		iElfTextLimit(0),
+		iElfDataBase(0),
+		iRVCTProduced(false),
+		iGCCProduced(false)
+		{};
+	XIPFileDetails(PathName & aE32File,PathName & aELFFile, LinearAddr load, LinearAddr text, size_t textSize,
+			VirtualAddr data, size_t dataSize, LinearAddr aRomData, VirtualAddr bss,
+			size_t bssDataSize):
+		iE32File(aE32File), 
+		iElfFile(aELFFile),
+		iLoadAddr(load),
+		iROAddr(text),
+		iROSize(textSize),
+		iRWAddr(data),
+		iRWSize(dataSize),
+		iROMDataAddr(aRomData), 
+		iBSSAddr(bss),
+		iBSSDataSize(bssDataSize),
+		iElfTextBase(0),
+		iElfTextLimit(0),
+		iElfDataBase(0),
+		iRVCTProduced(false),
+		iGCCProduced(false)
+		{};	
+	XIPFileDetails(char * aE32File,char * aELFFile, LinearAddr load, LinearAddr text, size_t textSize,
+			VirtualAddr data, size_t dataSize, LinearAddr aRomData, VirtualAddr bss, 
+			size_t bssDataSize):
+		iE32File(aE32File), 
+		iElfFile(aELFFile), 
+		iLoadAddr(load),
+		iROAddr(text),
+		iROSize(textSize),
+		iRWAddr(data),
+		iRWSize(dataSize),
+		iROMDataAddr(aRomData), 
+		iBSSAddr(bss),
+		iBSSDataSize(bssDataSize),
+		iElfTextBase(0),
+		iElfTextLimit(0),
+		iElfDataBase(0),
+		iRVCTProduced(false),
+		iGCCProduced(false)
+		{};	
+		
+	LinearAddr Relocate(LinearAddr addr){
+		if ((addr >= iElfTextBase) && (addr < iElfTextLimit)){
+			size_t offset = addr - iElfTextBase;
+			return iROAddr + offset;
+		} else if ((addr >= iElfDataBase) && (addr < (iElfDataBase + iBSSDataSize))) {
+			size_t offset = addr - iElfDataBase;
+			return iRWAddr + offset;
+		} else {
+			return addr;
+		}
+	}
+	PathName iE32File;
+	PathName iElfFile;
+	LinearAddr iLoadAddr;
+	LinearAddr iROAddr;
+	size_t iROSize;
+	VirtualAddr iRWAddr;
+	size_t iRWSize;
+	LinearAddr iROMDataAddr;
+	VirtualAddr iBSSAddr;
+	size_t iBSSDataSize;
+	VirtualAddr iElfTextBase;
+	VirtualAddr iElfTextLimit;
+	VirtualAddr iElfDataBase;
+	// This is dodgy. We probably need a better way of coping with 'oddities'
+	bool iRVCTProduced;
+	bool iGCCProduced;
+};
+
+class RomDetails {
+public:
+	RomDetails():
+		iBoardName(""),
+		iRomFile(""),
+		iElfRomFile(""),
+		iLogFile(""),
+		iDrive(""),
+		iRomPhysAddr(0),
+		iRomBaseLinearAddr(0),
+		iKernelDataVirtualAddr(0),
+		iNoDwarf(false),
+		iSearch(false),
+		iStrip(false),
+		iTrace(false),
+		iVerbosity(0)
+		{}
+		
+	typedef std::vector<XIPFileDetails> XIPFileList;
+	String iBoardName;
+	PathName iRomFile;
+	PathName iElfRomFile;
+	PathName iLogFile;
+	PathName iDrive;
+	LinearAddr iRomPhysAddr;
+	LinearAddr iRomBaseLinearAddr;
+	VirtualAddr iKernelDataVirtualAddr;
+	XIPFileDetails iPrimary;
+	XIPFileList	iXIPFiles;
+	bool iNoDwarf;
+	bool iSearch;
+	bool iStrip;
+	bool iTrace;
+	unsigned int iVerbosity;
+	std::vector<std::string> iTargetFiles;
+	std::vector<std::string> iExcludeFiles;
+
+};
+#endif /*ROMDETAILS_H_*/