# HG changeset patch # User cdavies@GUAR # Date 1264512488 0 # Node ID 2925e6e5efd7cc47c5c5c14512383b431c5a2f6f # Parent a587897e3bb2a285b944d97cbf4b604a7ac24b3d# Parent bfd7df5b9067f0c764c948abafa43b0495411248 catch up phonesim-integ to tip diff -r a587897e3bb2 -r 2925e6e5efd7 .hgtags --- 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 diff -r a587897e3bb2 -r 2925e6e5efd7 README.txt --- 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 diff -r a587897e3bb2 -r 2925e6e5efd7 baseport/syborg/bld.inf --- 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 diff -r a587897e3bb2 -r 2925e6e5efd7 baseport/syborg/soundsc/shared_sound.h --- 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); diff -r a587897e3bb2 -r 2925e6e5efd7 baseport/syborg/soundsc/shared_txsound.cpp --- 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 { diff -r a587897e3bb2 -r 2925e6e5efd7 tools/e32test-driver/COPYING --- /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. + 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. + + + Copyright (C) + + 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 . + +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: + + Copyright (C) + 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 +. + + 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 +. diff -r a587897e3bb2 -r 2925e6e5efd7 tools/e32test-driver/COPYING.LESSER --- /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. + 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. diff -r a587897e3bb2 -r 2925e6e5efd7 tools/e32test-driver/qemuruntest.py --- /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 . + +# 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" diff -r a587897e3bb2 -r 2925e6e5efd7 tools/e32test-driver/rtest.py --- /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 . + +# 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() diff -r a587897e3bb2 -r 2925e6e5efd7 tools/e32test-driver/rtestreport.py --- /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 . + +# 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 + + diff -r a587897e3bb2 -r 2925e6e5efd7 tools/e32test-driver/runtests.py --- /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 . + +# 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() diff -r a587897e3bb2 -r 2925e6e5efd7 tools/e32test-driver/setup.py --- /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 . + +# 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']) diff -r a587897e3bb2 -r 2925e6e5efd7 tools/e32test-driver/watchdog.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 . + +# 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() + diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/README.txt --- /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. diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/COPYING --- /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 $ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/ChangeLog --- /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 + * 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 + * 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 + * 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 + * 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 + * 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 + * 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 + * 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 + * dwarfdump.1: Corrected spelling error. +2007-05-25 DavidAnderson + * 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 + * 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 + * 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 + * print_reloc.c dwarfdump.c print_frames.c: Unified + copyright to the SGI form. No copyright change. + +2007-04-06 David Anderson + * 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 + * 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 + * 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. diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/ChangeLog2006 --- /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 + * 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 + * tag_tree.list: add tags to make allowed list more complete. + Omission noticed by Marcel Mettes. +2006-06-14 David Anderson + * print_frames.c: Clean up printing of augmentation data by + eliminating dangling 0x (for eh_frame). +2006-04-28 David Anderson + * 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 + * *.c: Ran indent so all now follow a standard look. + * dwconf.c: Added fclose(conf_stream). +2006-04-18 David Anderson + * 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 + * 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 used in install rule and creating + places to search for dwarfdump.conf +2006-04-16 David Anderson + * 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 + * 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 + * 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 + * 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 + * 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 + * print_sections.c: Add 'break;' at line 710. + Thanks to Richard Stuckey for noticing. +2005-12-01 David Anderson + * dwarf_names.awk: use snprintf instead of sprintf for safety. +2005-12-01 David Anderson + * 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 + * 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 + * makename.c: remove non-standard malloc.h include, + stdlib.h suffices and is already included. + +2005-10-24 David Anderson + * tag_attr.c tag_tree.c: added DWARF3 TAGs to string array. + +2005-08-01 David Anderson + * 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 + * 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 + * print_sections.c (print_line_numbers_this_cu): Use new + dwarf_srclines_dealloc() for deallocation after + dwarf_srclines() called. + +2005-04-13 David Anderson + * 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 + * 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 + * print_sections.c: Correct macro section printing. + +2004-10-28 David Anderson + * 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 + * 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 + + * print_die.c (print_die_and_children): Change to iteration + on siblings (still recursing on children). + + +2004-03-30 David Anderson + * dwarfdump.c (main): getopt() string should contain k:g + not kg: Thanks to Peter Seiderer for pointing this out. + +2003-12-31 David Anderson + * 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 + * 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 + * 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 + + * 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 + * 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 + * print_sections.c: macro printing now supported. + * dwarfdump.c: removed erroneous dwarf_dealloc() + of string returned by dwarf_errmsg(). + +2002-11-22 David Anderson + * 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 + * tag_attr.list dwarf.h: DW_AT_namelist_items is + wrong, changed to DW_AT_namelist_item + +2002-04-29 Stephen Clarke + * dwarfdump.c (main): #ifdef for __CYGWIN__ on open(). + +2001-06-14 David Anderson + + * 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 + + * 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 + + * 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 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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/DWARFDUMPCOPYRIGHT --- /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 + diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/GPL.txt --- /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. + + + Copyright (C) + + 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. + + , 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. diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/Makefile.in --- /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 $@ + 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 $@ + 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" diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/NEWS --- /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= -x abi= 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. diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/README --- /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 $ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/at_list.awk --- /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" +} + diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/config.guess --- /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 . +# Please send patches to . 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 ." + +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 /* 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 + + 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 + #include + + 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 + 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 + #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' /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 + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # 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 < +# include +#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 + 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 +# 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 < 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: diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/config.h.in --- /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 header file. */ +#undef HAVE_ELF_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_GETOPT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBELF_H + +/* Define to 1 if you have the 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 header file. */ +#undef HAVE_MEMORY_H + +/* Define 1 if plain libelf builds. */ +#undef HAVE_RAW_LIBELF_OK + +/* Define to 1 if you have the header file. */ +#undef HAVE_SGIDEFS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the 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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/config.sub --- /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 . 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 ." + +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: diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/configure --- /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 +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#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 if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + 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 &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &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 +#include +#include +#include +/* 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 +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 to if __STDC__ is defined, since + # 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 +#else +# include +#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 +_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 to if __STDC__ is defined, since + # 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 +#else +# include +#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 +_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 +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 +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 +#include +#include +#include + +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 + +_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 + +_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 +#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 +_ACEOF + +elif test "$ac_cv_header_libelf_h" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define LOCATION_OF_LIBELFHEADER +_ACEOF + +elif test "$ac_cv_header_libelf_libelf_h" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define LOCATION_OF_LIBELFHEADER +_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 +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 + +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 + +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 ." +_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 <>$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 <>$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 + diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/configure.in --- /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,[], [Define to header that first defines elf]) +elif test "$ac_cv_header_libelf_h" = yes; then + AC_DEFINE(LOCATION_OF_LIBELFHEADER, [], + [Define to header that first defines elf.]) +elif test "$ac_cv_header_libelf_libelf_h" = yes; then + AC_DEFINE(LOCATION_OF_LIBELFHEADER,[], + [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 ],[ __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 +],[ int p; p = 0; ] , + AC_DEFINE(HAVE_RAW_LIBELF_OK,1, + [Define 1 if plain libelf builds.])) +AC_TRY_COMPILE([ +#define _GNU_SOURCE +#include +],[ 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) diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwarfdump.1 --- /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=' +flavors below describe how to name an abi and use that to guide +the -f or -F processing. +Without '-R' or '-x abi='/ dwarfdump ignores +the dwarfdump.conf file and uses compiled-in MIPS/IRIX +conventions). +If no '-x name=' is given, dwarfdump +looks for "./dwarfdump.conf", "$HOME/.dwarfdump.conf", "/lib/dwarfdump.conf" and takes the first it finds. +If one or more '-x name=' 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= +where abi=names an abi in dwarfdump.conf (see the +abiname: command in dwarfdump.conf). +.TP +.B \-x name= +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 +/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. diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwarfdump.c --- /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 +#include +#include +#ifdef HAVE_GETOPT_H +#include +#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, " \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= meaning name dwarfdump.conf file -x + 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= \n"); + fprintf(stderr, " and \n"); + fprintf(stderr, "-x abi= \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 \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 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=\tname dwarfdump.conf\n"); + fprintf(stderr, "\t\t-x 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); + +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwarfdump.conf --- /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: +# reg: +# frame_interface: +# cfa_reg: +# initial_reg_value: +# reg_table_size: +# endabi: +# +# Symbolic names do not work here, use literal numbers +# where applicable (in C standard decimal, octal (leading 0) or +# hexadecimal ). +# +# 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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwconf.c --- /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 +#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, ®num); + 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, ®num, &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: + reg: + frame_interface: + cfa_reg: + initial_reg_value: + reg_table_size: + endabi: + + 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= + 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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/dwconf.h --- /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); diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/esb.c --- /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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/esb.h --- /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); + diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/globals.h --- /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 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 +/* 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 +#include +#include +#ifdef HAVE_ELF_H +#include +#endif +#ifdef HAVE_LIBELF_H +#include +#else +#ifdef HAVE_LIBELF_LIBELF_H +#include +#endif +#endif +#include +#include + +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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/install.sh --- /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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/makename.c --- /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 +#include +#include +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/makename.h --- /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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_die.c --- /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 = ""; + char *ptagname = ""; + + 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:\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 /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 = ""; + + 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,""); + } + 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), "", + (unsigned long long) llbuf->ld_lopc); + esb_append(string_out, small_buf); + + + snprintf(small_buf, sizeof(small_buf), "", + (unsigned long long) llbuf->ld_hipc); + esb_append(string_out, small_buf); + if (verbose) { + snprintf(small_buf, sizeof(small_buf), + "", + 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), + "", + (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), + "", + (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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_frames.c --- /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>", + 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("\n", "none"); + } else if (eh_table_offset == DW_DLX_EH_OFFSET_UNAVAILABLE) { + printf("\n", "unknown"); + } else { + printf("\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(""); + } /* 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, + ®, + &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, + ®, + &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, + ®, + &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("",esb_get_string(&exprstring)); + esb_destructor(&exprstring); + } + } + break; + default: + printf("Internal error in libdwarf, value type %d\n", + value_type); + exit(1); + } + return; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_frames.h --- /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); diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_reloc.c --- /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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/print_sections.c --- /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] + */ + + +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 + ("\t[row,column]\t\t//= (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, + ¤t_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 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 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> %-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> %-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); + + } +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/tag_attr.c --- /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 +#include +#include /* For exit() declaration etc. */ +#include /* 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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/tag_attr.list --- /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 + +/* + 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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/tag_tree.c --- /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 +#include +#include /* For exit() declaration etc. */ +#include /* 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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/tag_tree.list --- /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 + +/* + 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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/dwarfdump/testesb.c --- /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 +#include +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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/CHANGES --- /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 +------------------------------------------------------------- diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/COPYING --- /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 $ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/ChangeLog --- /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 + * 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 + * 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 + * dwarf_frame2.c (gnu_aug_encodings): Now allows 'S' augmentation + character in eh_frame. +2007-10-16 David Anderson + * 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 + * 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 + * 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 + * pro_frame.c: Added commentary about some missing DWARF3 support. + * dwarf_srclines_dealloc.c: File unused, now deleted. +2007-07-04 David Anderson + * 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 + * 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 + * 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 + * 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 + * 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 + * 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 + * 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 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 + * 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 + * 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 + * 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 + * libdwarf2.1.mm (dwarf_loclist_n): Minor refinement + of the description. + * libdwarf2.1.ps: regenerated +2006-08-31 David Anderson + * 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 + * 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 + * dwarf_frame.c: Changed local variable type to + avoid compiler warning. +2006-04-21 David Anderson + * dwarf_frame.c: Initialized local to 0, wrong value. + Thanks to Cristi Vlasceanu for noticing. +2006-04-18 David Anderson + * All *.c: Ran indent so all c files follow a standard look. +2006-04-16 David Anderson + * 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 + * 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 + * 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 + * 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 + * 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 + * 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 + * 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 + * dwarf_frame2.c: ensure local variables initialized + to avoid coredump. +2006-03-08 David Anderson + * dwarf_die_deliv.c: Remove Richard Stukey's -1 and + replace with a simpler more complete fix. +2006-03-07 David Anderson + * 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 + * 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 + * 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 + * dwarf.h: Now matches 2005 DWARF3 public review document. + +2005-11-08 David Anderson + * 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 + * dwarf.h: Updated to match DWARF3 public review document. + +2005-10-03 David Anderson + * 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 + * malloc_check.c: Moved the #ifdef WANT_LIBBDWARF_MALLOC_CHECK + down after #includes so the test is meaningful. +2005-07-15 David Anderson + * 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 + * 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 + * 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 + * 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 + * 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 + * mips_extensions.mm: Documented the libexc/.debug_funcnames + dependency and the 64bit-offset DWARF extension. + * mips_extensions.ps: Regenerated. + +2005-03-21 David Anderson + * 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 + * 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 + * pro_incl.h: Added #elif defined(HAVE_LIBELF_H) + enabling build on a platform missing normal elf.h. + +2005-02-11 David Anderson + * 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 + * 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 + * 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 + * 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 + * 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 + * dwarf_frame.c (_dwarf_exec_frame_instr): + DW_CFA_def_cfa_register case, was setting offset, which + is incorrect. Thanks to Tom Hughes + for pointing this out. + +2004-02-03 David Anderson + * 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 + * 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 + * 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 + * 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 + * dwarf_line.h: reference in comment to li_dbg meant to + refer to li_offset. Corrected and amplified comment. + +2003-10-06 David Anderson + * dwarf_abbrev.c dwarf_die_deliv.c dwarf_form.c dwarf_loc.c + dwarf_util.c: applied indent(1). + +2003-10-02 David Anderson + * 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 + * 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 + * 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 + * 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 + * dwarf_loc.c: Made comment at head of dwarf_loclist() + a bit clearer. + +2002-11-22 Tom Hughes + * dwarf_macro.c: Corrected bugs in macro-info functions. + +2002-10-29 David Anderson + * 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 + * 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 + for pointing out the 4 places this was wrong. + Used cu_context local pointer to avoid numerous + double indirections. + +2002-08-14 David Anderson + * 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 + * pro_types.c (_dwarf_transform_simplename_to_disk): correct + generation of .debug_info size field. + Thanks to Kelly O'Hair for pointing out + the bug. + +2002-05-23 Daniel Gohman + * 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 + * 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 + * 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 + * libdwarf.h: added struct Elf declaration + to reduce dependency on header include ordering. + +2002-02-11 David Anderson + * 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 + * 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 + * 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" + * 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" + * 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 + * dwarf_loc.c DW_OP_bregx operands are unsigned + reg num followed by signed offset. + +2001-04-11 David Anderson + * 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 + + * pro_die.c: set ar_reloc_len field + in all cases. + +2000-12-14 David Anderson + + * dwarf_frame.h: clarified some comments. + +2000-12-14 Ulrich Drepper + + * 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 + 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 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. +------------------------------------------------------------- diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/LGPL.txt --- /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. + + + Copyright (C) + + 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. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/LIBDWARFCOPYRIGHT --- /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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/Makefile.in --- /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" diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/NEWS --- /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. diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/README --- /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 $ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/bldDWindex.sh --- /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' . +# Please send patches to . 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 ." + +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 /* 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 + + 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 + #include + + 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 + 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 + #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' /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 + echo i586-unisys-sysv4 + exit ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # 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 < +# include +#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 + 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 +# 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 < 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: diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/config.h.in --- /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 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 header file. */ +#undef HAVE_ELFACCESS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_ELF_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_INTTYPES_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_LIBELF_H + +/* Define to 1 if you have the 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 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 header file. */ +#undef HAVE_STDINT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STDLIB_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_STRING_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_IA64_ELF_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_STAT_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SYS_TYPES_H + +/* Define to 1 if you have the 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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/config.sub --- /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 . 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 ." + +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: diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/configure --- /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 +#if HAVE_SYS_TYPES_H +# include +#endif +#if HAVE_SYS_STAT_H +# include +#endif +#if STDC_HEADERS +# include +# include +#else +# if HAVE_STDLIB_H +# include +# endif +#endif +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H +# include +# endif +# include +#endif +#if HAVE_STRINGS_H +# include +#endif +#if HAVE_INTTYPES_H +# include +#else +# if HAVE_STDINT_H +# include +# endif +#endif +#if HAVE_UNISTD_H +# include +#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 if you have libraries in a + nonstandard directory + CPPFLAGS C/C++ preprocessor flags, e.g. -I if you have + headers in a nonstandard directory + 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 &5\"") >&5 + (eval $ac_compiler --version &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v &5\"") >&5 + (eval $ac_compiler -v &5) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V &5\"") >&5 + (eval $ac_compiler -V &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 +#include +#include +#include +/* 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 +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 +#include + +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 +#include + +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 to if __STDC__ is defined, since + # 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 +#else +# include +#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 +_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 to if __STDC__ is defined, since + # 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 +#else +# include +#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 +_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 +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 +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 +#include +#include +#include + +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 + +_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 + +_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 +#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 +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 +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 +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 + +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 + +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 +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 +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 +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 +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 ." +_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 <>$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 <>$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 + diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/configure.in --- /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 ],[ __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 ],[ __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 ],[ 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 +],[ int p; p = 0; ] , + AC_DEFINE(HAVE_RAW_LIBELF_OK,1, + [Define 1 if plain libelf builds.])) +AC_TRY_COMPILE([ +#define _GNU_SOURCE +#include +],[ 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 ],[ __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 ],[ __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 ],[ __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 ],[ 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) diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf.h --- /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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf.v2.mm --- /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 == 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 == 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 + +.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, ; Allocate frame +foo+4 store R1, R7, (-4) ; Save the return address +foo+8 store R6, R7, (-8) ; Save R6 +foo+12 add R6, R7, 0 ; R6 is now the Frame ptr +foo+16 store R4, R6, (-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, (-12) ; Restore R4 +foo+68 load R6, R7, (-8) ; Restore R6 +foo+72 load R1, R7, (-4) ; Restore return address +foo+76 add R7, R7, ; 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(/4) ; assuming < 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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf.v2.pdf Binary file tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf.v2.pdf has changed diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_abbrev.c --- /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 +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_abbrev.h --- /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; +}; diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_addr_finder.c --- /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 +#endif +#include +#include +#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 +#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, <ag, &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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_alloc.c --- /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 + +#include +#include +#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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_alloc.h --- /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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_arange.c --- /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 +#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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_arange.h --- /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); diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_base_types.h --- /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; diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_die_deliv.c --- /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 +#endif +#include +#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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_die_deliv.h --- /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; +}; diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_error.c --- /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 +#endif + +#include +#include +#include +#include + +/* 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]); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_error.h --- /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; +}; diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_form.c --- /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; i0; 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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_frame.c --- /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 +#include +#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 = ®_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 = ®_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 = ®_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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_frame.h --- /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 *); diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_frame2.c --- /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 +#include +#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); + +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_frame3.c --- /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 +#include +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_funcs.c --- /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 +#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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_funcs.h --- /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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_global.c --- /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 +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_global.h --- /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 + diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_incl.h --- /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 + +#ifdef HAVE_ELF_H +#include +#endif + +#include +#include +#include + +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_init_finish.c --- /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 +#endif +#ifdef __SGI_FAST_LIBELF +#include +#else +#ifdef HAVE_LIBELF_H +#include +#else +#ifdef HAVE_LIBELF_LIBELF_H +#include +#endif +#endif +#endif /* !defined(__SGI_FAST_LIBELF) */ + +#include +#include +#include +#include +#include + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_leb.c --- /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 + + +/* + 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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_line.c --- /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 +#include +#include "dwarf_line.h" +#ifdef HAVE_ALLOCA_H +#include +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_line.h --- /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); diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_line2.c --- /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 +#include "dwarf_line.h" +#ifdef HAVE_ALLOCA_H +#include +#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. +*/ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_loc.c --- /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; + + + +} + + diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_loc.h --- /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; +}; diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_macro.c --- /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 +#include +#ifdef HAVE_STDLIB_H +#include +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_macro.h --- /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 $ + +*/ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_opaque.h --- /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 + + +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 *); diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_print_lines.c --- /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 +#include +#include "dwarf_line.h" +#ifdef HAVE_ALLOCA_H +#include +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_pubtypes.c --- /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 +#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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_query.c --- /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 +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_sort_line.c --- /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 +#include +#include "dwarf_line.h" +#ifdef HAVE_ALLOCA_H +#include +#endif +#ifdef HAVE_STRING_H +#include +#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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_string.c --- /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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_stubs.c --- /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 + + + + /*ARGSUSED*/ int +dwarf_nextglob(Dwarf_Debug dbg, + Dwarf_Global glob, + Dwarf_Global * returned_nextglob, Dwarf_Error * error) +{ + return (DW_DLV_NO_ENTRY); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_types.c --- /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 +#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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_types.h --- /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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_util.c --- /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 +#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; + +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_util.h --- /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); diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_vars.c --- /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 +#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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_vars.h --- /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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_weaks.c --- /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 +#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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_weaks.h --- /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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/index.v2.pdf Binary file tools/elf4rom/libs/dwarf-20071209/libdwarf/index.v2.pdf has changed diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/install.sh --- /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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf.h --- /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 */ + diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf2.1.mm --- /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 +\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 value" or "name(args)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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf2.1.pdf Binary file tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf2.1.pdf has changed diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf2p.1.mm --- /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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf2p.1.pdf Binary file tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarf2p.1.pdf has changed diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/libdwarfdefs.h --- /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 defines them */ +#define HAVE___UINT32_T 1 +#endif + +#if (!defined(HAVE___UINT64_T)) && defined(HAVE___UINT64_T_IN_SGIDEFS_H) +#include /* 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 +#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 +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/malloc_check.c --- /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 +#include /* 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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/malloc_check.h --- /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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/mips_extensions.mm --- /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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/mips_extensions.pdf Binary file tools/elf4rom/libs/dwarf-20071209/libdwarf/mips_extensions.pdf has changed diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_alloc.c --- /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 +#endif /* HAVE_STDLIB_H */ +#ifdef HAVE_STRING_H +#include +#endif /* HAVE_STRING_H */ +#include + +/* + 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); +} + diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_alloc.h --- /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); diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_arange.c --- /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 +#include +#ifdef HAVE_ELFACCESS_H +#include +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_arange.h --- /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 */ + +}; diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_die.c --- /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 +#include +#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; + } +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_die.h --- /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); diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_encode_nm.c --- /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 +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_encode_nm.h --- /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); diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_error.c --- /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 +#endif + +#include +#include +#include +#include +#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(); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_error.h --- /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); diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_expr.c --- /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 +#include +#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])); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_expr.h --- /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; +}; diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_finish.c --- /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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_forms.c --- /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 +#include +#include +#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; ide_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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_frame.c --- /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 +#include +#include +#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)); + } +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_frame.h --- /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; +}; diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_funcs.c --- /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 +#include +#ifdef HAVE_ELFACCESS_H +#include +#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); + +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_incl.h --- /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 +#elif defined(HAVE_LIBELF_H) +/* On one platform without elf.h this gets Elf32_Rel + type defined (a required type). */ +#include +#endif + +#if defined(sun) +#include +#include +#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" diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_init.c --- /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 +#include +#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; + +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_line.c --- /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 +#include +#ifdef HAVE_ELF_H +#include +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_line.h --- /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); diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_macinfo.c --- /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 +#include +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_macinfo.h --- /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); diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_opaque.h --- /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 + +/* + 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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_pubnames.c --- /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 +#include +#ifdef HAVE_ELFACCESS_H +#include +#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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc.c --- /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 +#include +/*#include */ +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc.h --- /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); diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc_stream.c --- /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 +#include +#ifdef HAVE_ELFACCESS_H +#include +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc_stream.h --- /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); diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc_symbolic.c --- /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 +#include +/*#include */ +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_reloc_symbolic.h --- /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); diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_section.c --- /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 +#include +#ifdef HAVE_ELFACCESS_H +#include +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_section.h --- /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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_types.c --- /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 +#include +#ifdef HAVE_ELFACCESS_H +#include +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_types.h --- /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); diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_util.h --- /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 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 */ + + diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_vars.c --- /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 +#include +#ifdef HAVE_ELFACCESS_H +#include +#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); + + +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_weaks.c --- /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 +#include +#ifdef HAVE_ELFACCESS_H +#include +#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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/COPYING.LIB --- /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. + + + Copyright (C) + + 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. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/ChangeLog --- /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 + + * 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 + + * lib/Makefile.in: + improved make -jX patch. + +Wed Jun 20 08:04:30 CEST 2007, Michael Riepe + + * lib/Makefile.in: + add "make -jX install" patch by Joel Martin. + +Tue Nov 21 21:21:12 CET 2006, Michael Riepe + + * lib/Makefile.w32: + fix Windows compilation bug. + +Thu Sep 7 17:55:42 CEST 2006, Michael Riepe + + * 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 + + * Makefile.in: + add trackinstall target. + +Mon Aug 21 20:26:47 CEST 2006, Michael Riepe + + * 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 + + * 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 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 + + * 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 + + * w32/libelf.def: + add missing functions. + +Sat Jul 8 00:50:00 CEST 2006, Michael Riepe + + * VERSION: + bump up to 0.8.9. + +Sat Jul 8 00:17:00 CEST 2006, Michael Riepe + + * 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 + + * VERSION: + bump up to 0.8.8. + +Fri Jul 7 18:27:25 CEST 2006, Michael Riepe + + * 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 + + * 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 + + * po/de.po: + update. + +Fri Apr 21 19:17:46 CEST 2006, Michael Riepe + + * 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 + + * lib/input.c: + * lib/update.c: + handle partial reads and writes. + +Tue Aug 16 01:48:17 CEST 2005, Michael Riepe + + * 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 + + * README: + * w32/build.bat: + update. + * w32/libelf.def: + fix syntax. + +Tue Jun 28 00:31:24 CEST 2005, Michael Riepe + + * Makefile.in: + remove superfluous slash. + +Tue Jun 21 03:58:47 CEST 2005, Michael Riepe + + * lib/Makefile.in: + get rid of lib/pic subdir. + +Sat May 21 17:39:28 CEST 2005, Michael Riepe + + * (global): + remove my e-mail address from all copyright clauses. + +Sun May 15 23:08:30 CEST 2005, Michael Riepe + + * configure.in: + check if $CC can copile . + * lib/private.h: + #include before (fixes glibc bug). + +Sun May 8 23:40:35 CEST 2005, Michael Riepe + + * Makefile.in: + add instroot variable. + install libelf.pc. + * configure.in: + create libelf.pc. + +Sun Mar 20 15:41:22 CET 2005, Michael Riepe + + * (global): + change my e-mail address. + +Fri Jan 28 23:09:57 CET 2005, Michael Riepe + + * po/Makefile.in: + use modified gmo2msg. + * po/gmo2msg.c: + make gmo2msg output more portable. + +Thu Oct 7 11:37:09 CEST 2004, Michael Riepe + + * lib/cook.c: + only use Elf64_Shdr if __LIBELF64 is true. + +Fri Sep 17 02:55:47 CEST 2004, Michael Riepe + + * 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 + + * 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 + + * 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 + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + * lib/Makefile.in: + give up on . + * lib/getarsym.c: + +Wed Jun 23 01:07:46 CEST 2004, Michael Riepe + + * config.guess: + * config.sub: + update from FSF. + +Tue May 4 22:02:01 CEST 2004, Michael Riepe + + * config.guess: + * config.sub: + update from FSF. + +Tue Mar 30 15:09:00 CEST 2004, Michael Riepe + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + * lib/Makefile.in: + use to work around W32 compiler problems. + +Mon Feb 16 06:19:11 CET 2004, Michael Riepe + + * Makefile.in: + generate old-format tar file. + +Sat Jan 24 03:42:39 CET 2004, Michael Riepe + + * 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 + + * lib/update.c: + #undef max before #define. + +Wed Jan 21 18:15:50 CET 2004, Michael Riepe + + * lib/begin.c: + better support for Cygwin .lib archive files. + +Mon Jan 19 15:36:21 CET 2004, Michael Riepe + + * lib/libelf.h: + * lib/memset.c: + include unconditionally. + +Fri Jan 16 23:13:25 CET 2004, Michael Riepe + + * 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 + + * 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 for size_t. + * lib/nlist.c: + declare open() on W32 systems. + +Tue Dec 16 20:02:30 CET 2003, Michael Riepe + + * Makefile.in: + let disttest target make dist again. + +Sat Dec 13 16:14:31 CET 2003, Michael Riepe + + * lib/update.c: + call lseek before ftruncate. + +Fri Dec 5 16:25:16 CET 2003, Michael Riepe + + * 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 + + * 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 + + * lib/elf_repl.h: + add EM_SPARC64 + +Thu Oct 9 23:08:56 CEST 2003, Michael Riepe + + * 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 + + * config.guess: + * config.sub: + latest versions from FSF + +Sat May 24 18:55:14 CEST 2003, Michael Riepe + + * 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 + + * aclocal.m4: + provide name suffixes only + * lib/Makefile.in: + use name suffixes + +Fri May 23 01:24:26 CEST 2003, Michael Riepe + + * 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 + + * 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 + + * lib/update.c: + improved fix for elf_update `null buffer' bug + +Mon May 12 00:34:44 CEST 2003, Michael Riepe + + * config.guess: + * config.sub: + latest versions from FSF + +Sun May 11 01:44:06 CEST 2003, Michael Riepe + + * 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 + + * 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 + + * VERSION: + bump up to 0.8.4 + +Sun Mar 23 16:06:43 CET 2003, Michael Riepe + + * configure.in: + fix --enable-compat + +Thu Feb 27 14:35:12 CET 2003, Michael Riepe + + * 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 + + * config.guess: + * config.sub: + latest versions from FSF + +Wed Jan 15 22:50:53 CET 2003, Michael Riepe + + * lib/begin.c: + fix overflow check + +Sun Jan 12 04:27:31 CET 2003, Michael Riepe + + * configure.in: + prefer int for __libelf_i32_t (if int has 32 bits) + +Thu Jan 2 17:40:22 CET 2003, Michael Riepe + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * VERSION: + set version to 0.8.0. + * README: + update version. + +Tue Oct 30 17:05:03 CET 2001, Michael Riepe + + * Makefile.in: + use uid/gid=0 when creating the distribution tar file. + +Mon Oct 15 23:47:10 CEST 2001, Michael Riepe + + * configure.in: + check for and . + create ./pic when configuring. + * lib/Makefile.in: + move .o to ../pic/$@, not ../pic. + * lib/begin.c: + define struct ar_hdr and friends if is missing. + use lseek(..., SEEK_END). + * lib/input.c: + use lseek(..., SEEK_SET). + * lib/nlist.c: + include 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 + + * aclocal.m4: + remove superfluous case. + +Mon Oct 8 17:56:04 CEST 2001, Michael Riepe + + * lib/opt.delscn.c: + handle versioning sections properly. + +Mon Oct 8 17:02:43 CEST 2001, Michael Riepe + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * lib/32.xlatetof.c: + * lib/64.xlatetof.c: + remove `const' when compiling with -fPIC. + +Fri Sep 28 20:14:42 CEST 2001, Michael Riepe + + * README: + add pointers to documentation. + * lib/64.xlatetof.c: + fixed conversion thinko. + (Jakub Jelinek 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 + + * 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 + + * Makefile.in: + * configure.in: + * lib/Makefile.in: + * po/Makefile.in: + add maintainer mode. + +Sat Sep 1 15:11:42 CEST 2001, Michael Riepe + + * lib/sys_elf.h.in: add more fixes for broken files. + +Sat Sep 1 05:01:16 CEST 2001, Michael Riepe + + * 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 + + * 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 + + * 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 + + * lib/strptr.c: rename `sd' variable. + +Fri Mar 31 20:11:14 CEST 2000, Michael Riepe + + * Makefile.in: also pass CPPFLAGS and LDFLAGS to config.status. + +Fri Mar 31 20:02:55 CEST 2000, Michael Riepe + + * 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 + + * 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 + + * lib/gelfshdr.c: remove ELF class check. + +Mon Mar 27 01:24:50 CEST 2000, Michael Riepe + + * lib/gelf.h: #include when compiling libelf. + +Sun Mar 26 15:02:54 CEST 2000, Michael Riepe + + * lib/private.h: #include 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 include. + +Sun Mar 26 06:22:20 CEST 2000, Michael Riepe + + * 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 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 + + * configure.in: + add check for existing 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * VERSION: set version to 0.7.1. + + * po/de.po: new file. + +Fri Nov 27 22:24:00 MET 1998, Michael Riepe + + * lib/memset.c: rename and rewrite. + * lib/private.h: rename __memset. + +Tue Aug 25 17:17:18 MEST 1998, Michael Riepe + + * 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 + + * 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 + + * 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 + + * 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 + + * lib/*.c: move rcsid[] after . + + * 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 + + * README: update for 0.7.0 release. + +Sun Jun 4 15:26:49 MEST 1998, Michael Riepe + + * 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 + + * 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 + + * 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 + + * (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 . + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * VERSION: change version to 0.5.9. + + * aclocal.m4: rewrite NLS check. + +Tue Jul 23 18:59:05 MET DST 1996, Michael Riepe + + * 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 + + * 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 + + * 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 + + * 32.xlatetof.c: change `char' to `unsigned char'. + +Tue May 28 19:00:30 MET DST 1996, Michael Riepe + + * 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 + + * 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 + + * 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 + + * update.c (elf_update): mmap(MAP_SHARED) wants non-empty file. + +Tue May 21 15:33:07 MET DST 1996, Michael Riepe + + * 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 + + * 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 + + * 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 + + * 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 + + * 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 + + * 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. + diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/INSTALL --- /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. + diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/MANIFEST --- /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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/Makefile.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: diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/README --- /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 ''. 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 , or . + +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 . +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 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 + diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/VERSION --- /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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/acconfig.h --- /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 or */ +#undef HAVE_STRUCT_NLIST_DECLARATION + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_LINK_H + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_SYS_LINK_H + +/* Define to `' or `' 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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/aclocal.m4 --- /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 ], + [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 ], + [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 +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 : diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/config.guess --- /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 . +# Please send patches to . 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 ." + +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 /* 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 + + 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 + #include + + 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 + 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 + #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 + #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' /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 + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # 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 < +# include +#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 + 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 +# 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 < 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: diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/config.h.in --- /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 doesn't define. */ +#undef off_t + +/* Define to `unsigned' if 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 or */ +#undef HAVE_STRUCT_NLIST_DECLARATION + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_LINK_H + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_SYS_LINK_H + +/* Define to `' or `' 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 header file. */ +#undef HAVE_AR_H + +/* Define if you have the header file. */ +#undef HAVE_ELF_H + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_GELF_H + +/* Define if you have the header file. */ +#undef HAVE_LIBELF_H + +/* Define if you have the header file. */ +#undef HAVE_LINK_H + +/* Define if you have the header file. */ +#undef HAVE_NLIST_H + +/* Define if you have the header file. */ +#undef HAVE_STDINT_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_ELF_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_LINK_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/config.sub --- /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 . 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 ." + +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: diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/configure --- /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 , and (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 <&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 < +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 < +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 < +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 < +#include +#include +#include +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 +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 +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 < +#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 +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 <&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 +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 <&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 < + #elif HAVE_SYS_ELF_H + #include + #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 +EOF + +elif test "$ac_cv_header_sys_elf_h" = yes; then + cat >> confdefs.h <<\EOF +#define __LIBELF_HEADER_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 +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 <&6 +fi +done + +echo $ac_n "checking whether to install , and ""... $ac_c" 1>&6 +echo "configure:1319: checking whether to install , and " >&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 <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 < +#if STDC_HEADERS +#include +#include +#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 < +#if STDC_HEADERS +#include +#include +#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 < +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 <&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 < +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 <&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 < +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 <&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 < +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 <&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 < +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 <. + # QNX declares Elf32_Dyn in . + 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 <&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 < +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 < +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 . + 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 <&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 <&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 <&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 <&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 <&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 < /* 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 < /* 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 <&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 <&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 <> confdefs.h <&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 <> confdefs.h <&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 <> confdefs.h <&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 +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 <&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 < +/* 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 <&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 < +#include +#include + +/* This mess was copied from the GNU getpagesize.h. */ +#ifndef HAVE_GETPAGESIZE +# ifdef HAVE_UNISTD_H +# include +# 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 +# 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 < +/* 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 <&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 < +/* 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 <&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 <&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 < +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 <&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 <&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 <&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 < +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 <&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 < +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 < +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 </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 < 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 <> $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 <> $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 <> $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 <> $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 : diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/configure.in --- /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 + #elif HAVE_SYS_ELF_H + #include + #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, []) +elif test "$ac_cv_header_sys_elf_h" = yes; then + AC_DEFINE(__LIBELF_HEADER_ELF_H, []) +fi + +AC_CHECK_HEADERS(ar.h libelf.h nlist.h gelf.h) +AC_MSG_CHECKING([whether to install , and ]) +AC_ARG_ENABLE(compat, + [ --enable-compat install , and (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 . + # QNX declares Elf32_Dyn in . + 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 ], [Elf32_Dyn x], + [libelf_cv_struct_elf32_dyn=link.h], + AC_TRY_COMPILE([#include ], [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 . + 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 /* 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 /* 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 : diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/install-sh --- /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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/32.fsize.c --- /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 +#include + +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/32.getehdr.c --- /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 + +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/32.getphdr.c --- /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 + +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/32.getshdr.c --- /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 + +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/32.newehdr.c --- /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 + +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/32.newphdr.c --- /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 + +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/32.xlatetof.c --- /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 +#include +#include + +#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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/64.xlatetof.c --- /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 +#include +#include + +#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__ */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/Makefile.in --- /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 " > $(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 \$$" $(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) diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/Makefile.w32 --- /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) diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/assert.c --- /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 + +#ifndef lint +static const char rcsid[] = "@(#) $Id: assert.c,v 1.4 2005/05/21 15:39:20 michael Exp $"; +#endif /* lint */ + +#include + +void +__elf_assert(const char *file, unsigned line, const char *cond) { + fprintf(stderr, "%s:%u: libelf assertion failure: %s\n", + file, line, cond); + abort(); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/begin.c --- /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 + +#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 +#else /* HAVE_AR_H */ + +#define ARMAG "!\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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/build.bat --- /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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/byteswap.h --- /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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/checksum.c --- /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 + +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/cntl.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/config.h.w32 --- /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 doesn't define. */ +#undef off_t + +/* Define to `unsigned' if 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 or */ +#undef HAVE_STRUCT_NLIST_DECLARATION + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_LINK_H + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_SYS_LINK_H + +/* Define to `' or `' 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 header file. */ +#undef HAVE_AR_H + +/* Define if you have the header file. */ +#undef HAVE_ELF_H + +/* Define if you have the header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_GELF_H + +/* Define if you have the header file. */ +#undef HAVE_LIBELF_H + +/* Define if you have the header file. */ +#undef HAVE_LINK_H + +/* Define if you have the header file. */ +#undef HAVE_NLIST_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_ELF_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_LINK_H + +/* Define if you have the header file. */ +#undef HAVE_UNISTD_H diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/cook.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/data.c --- /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 + +#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; diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/elf_repl.h --- /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 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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/end.c --- /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 + +#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 +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/errmsg.c --- /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 + +#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 +#else /* HAVE_DGETTEXT */ +# define dgettext(dom, str) str +#endif /* HAVE_DGETTEXT */ + +#if HAVE_CATGETS +# include +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 /* 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]); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/errno.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/errors.h --- /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")) diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/ext_types.h --- /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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/fill.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/flag.c --- /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 + +#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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/gelf.h --- /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 +#else /* __LIBELF_INTERNAL__ */ +#include +#endif /* __LIBELF_INTERNAL__ */ + +#if __LIBELF_NEED_LINK_H +#include +#elif __LIBELF_NEED_SYS_LINK_H +#include +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/gelfehdr.c --- /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 + +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/gelfphdr.c --- /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 + +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/gelfshdr.c --- /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 + +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/gelftrans.c --- /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 + +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/getarhdr.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/getarsym.c --- /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 +#include + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/getbase.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/getdata.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/getident.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/getscn.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/hash.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/input.c --- /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 + +#ifndef lint +static const char rcsid[] = "@(#) $Id: input.c,v 1.10 2005/10/20 21:08:02 michael Exp $"; +#endif /* lint */ + +#include + +#if HAVE_MMAP +#include +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/kind.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/libelf.def --- /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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/libelf.h --- /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 /* for size_t */ +#include + +#if __LIBELF_INTERNAL__ +#include +#else /* __LIBELF_INTERNAL__ */ +#include +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/memset.c --- /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 +#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 /* for size_t */ +#include + +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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/ndxscn.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/newdata.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/newscn.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/next.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/nextscn.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/nlist.c --- /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 +#include + +#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 +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/nlist.h --- /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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/opt.delscn.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/private.h --- /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 +#endif /* HAVE_CONFIG_H */ + +/* + * Workaround for GLIBC bug: + * include before + */ +#if HAVE_STDINT_H +#include +#endif +#include + +#if STDC_HEADERS +# include +# include +#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 +#else +#if HAVE_UNISTD_H +# include +#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 +#elif __LIBELF_NEED_SYS_LINK_H +# include +#endif /* __LIBELF_NEED_LINK_H */ + +#include + +#if HAVE_STRUCT_NLIST_DECLARATION +# undef nlist +#endif /* HAVE_STRUCT_NLIST_DECLARATION */ + +#if __LIBELF64 +#include +#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 /* 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 , 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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/rand.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/rawdata.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/rawfile.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/strptr.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/swap64.c --- /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 +#include + +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/sys_elf.h.in --- /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 INSTEAD! + */ + +/* Define to `' or `' if one of them is present */ +#undef __LIBELF_HEADER_ELF_H + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_LINK_H + +/* Define if Elf32_Dyn is declared in */ +#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 +# else /* __LIBELF_INTERNAL__ */ +# include +# endif /* __LIBELF_INTERNAL__ */ +#endif /* __LIBELF_HEADER_ELF_H */ + +/* + * On some systems, 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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/sys_elf.h.w32 --- /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 INSTEAD! + */ + +/* Define to `' or `' if one of them is present */ +#undef __LIBELF_HEADER_ELF_H + +/* Define if Elf32_Dyn is declared in */ +#undef __LIBELF_NEED_LINK_H + +/* Define if Elf32_Dyn is declared in */ +#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 +# else /* __LIBELF_INTERNAL__ */ +# include +# endif /* __LIBELF_INTERNAL__ */ +#endif /* __LIBELF_HEADER_ELF_H */ + +/* + * On some systems, 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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/update.c --- /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 + +#ifndef lint +static const char rcsid[] = "@(#) $Id: update.c,v 1.32 2006/07/07 22:15:50 michael Exp $"; +#endif /* lint */ + +#include + +#if HAVE_MMAP +#include +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/verdef.h --- /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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/verdef_32_tof.c --- /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 +#include +#include + +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/verdef_32_tom.c --- /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 +#include +#include + +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/verdef_64_tof.c --- /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 +#include +#include + +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/verdef_64_tom.c --- /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 +#include +#include + +#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 */ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/verneed.h --- /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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/version.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/x.elfext.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/x.movscn.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/lib/x.remscn.c --- /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 + +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/libelf.pc.in --- /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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/mkinstalldirs --- /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 +# 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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/po/Makefile.in --- /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: diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/po/de.gmo Binary file tools/elf4rom/libs/libelf-0.8.10/po/de.gmo has changed diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/po/de.msg --- /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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/po/de.po --- /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 \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" diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/po/gmo2msg.c --- /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 +#include +#include +#include +#include + +#define DOMAIN "libelf" + +static const char *msgs[] = { +#define __err__(a,b) b, +#include +#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 \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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/po/libelf.pot --- /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 , 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 \n" +"Language-Team: LANGUAGE \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 "" diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/po/stamp-po --- /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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/libs/libelf-0.8.10/stamp-h.in --- /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 diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/COPYING --- /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. + 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. + + + Copyright (C) + + 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 . + +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: + + Copyright (C) + 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 +. + + 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 +. diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/COPYING.LESSER --- /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. + 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. diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/Makefile --- /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 . + +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) diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/defs.h --- /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 . +*/ + +#ifndef DEFS_H_ +#define DEFS_H_ + +#include +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_*/ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/dwarfabbrevmanager.cpp --- /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 . +*/ + +#include +#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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/dwarfarangesmanager.cpp --- /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 . +*/ + +#include +#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; + } + } +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/dwarfdefs.h --- /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 . +*/ + +#ifndef DWARFDEFS_H_ +#define DWARFDEFS_H_ + +//#include +/* 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 +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_*/ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/dwarfframemanager.cpp --- /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 . +*/ + +#include +#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; + } + } + } + +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/dwarfinfomanager.cpp --- /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 . +*/ + +#include +#include +#include + +#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 */ +}; diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/dwarflinemanager.cpp --- /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 . +*/ + +#include +#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); + } +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/dwarflocexpr.cpp --- /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 . +*/ + +#include +#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; + } + + } +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/dwarflocmanager.cpp --- /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 . +*/ + +#include +#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; + + } +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/dwarfmanager.cpp --- /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 . +*/ + +#include +#include + +#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(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(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(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(); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/dwarfmanager.h --- /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 . +*/ + +#ifndef DWARFMANAGER_H_ +#define DWARFMANAGER_H_ + +#include +#include +#include +#include + +#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 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 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 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 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 CiePtrEncodingMap; + typedef std::map 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_*/ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/dwarfnamemanager.cpp --- /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 . +*/ + +#include +#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); + } +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/dwarfrangesmanager.cpp --- /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 . +*/ + +#include +#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; + } +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/dwarfutils.cpp --- /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 . +*/ + +#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"; + } +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/e32romimage.cpp --- /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 . +*/ + +#include +#include +#include +#include + +#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(iData)); +} + +void E32RomImage::DeleteFileFragmentData(){ + if (iData) { + char * d = iData; + iData = NULL; + delete [] d; + } +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/e32romimage.h --- /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 . +*/ + +#ifndef E32ROMIMAGE_H_ +#define E32ROMIMAGE_H_ + +#include + +#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_*/ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/elfdefs.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 . +*/ + +#ifndef ELFDEFS_H_ +#define ELFDEFS_H_ + +#include + +#endif /*ELFDEFS_H_*/ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/elfheader.cpp --- /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 . +*/ + +#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(&iHdr)); +} + + diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/elfheader.h --- /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 . +*/ + +#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_*/ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/elfphdr.cpp --- /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 . +*/ + +#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(&iElf32Phdr)); +} + diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/elfphdr.h --- /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 . +*/ + +#ifndef ELFPHDR_H_ +#define ELFPHDR_H_ +#include + +#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_*/ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/elfrom.cpp --- /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 . +*/ + +#include +#include +#include +#include +#include + +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 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"; + } +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/elfrom.h --- /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 . +*/ + +#ifndef ELFROM_H_ +#define ELFROM_H_ + +#include +// +// Copyright (c) 2008 Symbian Software Ltd. All rights reserved. +// + +#include + +#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 ElfPHdrList; + ElfPHdrList iElfPHdrList; + + ElfSectionManager iElfSectionManager; + ElfSymbolTableManager iElfSymbolTableManager; + DwarfManager iDwarfManager; + + bool iDwarfFound; + +}; +#endif /*ELFROM_H_*/ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/elfromerror.cpp --- /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 . +*/ + +#include +#include + +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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/elfromerror.h --- /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 . +*/ + +#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_*/ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/elfsection.cpp --- /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 . +*/ + +#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(NULL)); +} + +ElfSection::~ElfSection(){ + delete iSectionData; +} + +void ElfSection::AddData(OutputFile & aOutputFile){ + iSectionData->AddData(aOutputFile); + SetSize(iSectionData->Size()); + SetOffset(iSectionData->GetOffset()); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/elfsection.h --- /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 . +*/ + +#ifndef ELFSECTION_H_ +#define ELFSECTION_H_ + +#include + +#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_*/ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/elfsectionmanager.cpp --- /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 . +*/ + +#include + +#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(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()); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/elfsectionmanager.h --- /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 . +*/ + +#ifndef ELFSECTIONMANAGER_H_ +#define ELFSECTIONMANAGER_H_ + +#include + +#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 SectionList; + Elf32Header & iElf32Header; + E32RomImage & iRomImage; + OutputFile & iOutputFile; + SectionList iSections; + size_t iOffset; + ElfSectionHeaderStringTable iStringTable; + Elf32_Shdr * iData; + bool iSectionStringTableSectionAdded; + +}; + +#endif /*ELFSECTIONMANAGER_H_*/ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/elfstringtable.cpp --- /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 . +*/ + +#include + +#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(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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/elfstringtable.h --- /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 . +*/ + +#ifndef ELFSTRINGTABLE_H_ +#define ELFSTRINGTABLE_H_ + +// +// Copyright (c) 2008 Symbian Software Ltd. All rights reserved. +// + +#include + +#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 StringList; + + StringList iStrings; + size_t iSize; + char * iData; +}; + +#endif /*ELFSTRINGTABLE_H_*/ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/elfsymboltablemanager.cpp --- /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 . +*/ + +#include +#include + +#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 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(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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/elfsymboltablemanager.h --- /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 . +*/ + +#ifndef ELFSYMBOLTABLEMANAGER_H_ +#define ELFSYMBOLTABLEMANAGER_H_ + +#include +#include + +#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 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_*/ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/filefragment.cpp --- /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 . +*/ + +#include + +#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()); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/filefragment.h --- /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 . +*/ + +#ifndef FILEFRAGMENT_H_ +#define FILEFRAGMENT_H_ + +#include + +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_*/ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/inputfile.cpp --- /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 . +*/ + +#include +#include +#include +#include + +#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(); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/inputfile.h --- /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 . +*/ + +#ifndef INPUTFILE_H_ +#define INPUTFILE_H_ + +#include + +#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_*/ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/main.cpp --- /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 . +*/ + +#include +#include +#include +#include +#include +#include +#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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/outputfile.cpp --- /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 . +*/ + +#include +#include +#include +#include +#include +#include +#include + +#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); +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/outputfile.h --- /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 . +*/ + +#ifndef OUTPUTFILE_H_ +#define OUTPUTFILE_H_ + +#include + +#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 FragmentList; + + PathName iFileName; + FragmentList iFileFragments; + bool iOpened; + int iFd; + size_t iCurrentOffset; + +}; + +#endif /*OUTPUTFILE_H_*/ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/processoptions.cpp --- /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 . +*/ + +#include +namespace po = boost::program_options; +#include +#include +namespace fs = boost::filesystem; + +#include + +#include +#include +#include +#include + +#include +#include + +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(), "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(&details->iBoardName), "name of board targeted e.g. versatilepb") + ("debug,d", po::value< vector >(&details->iTargetFiles)->multitoken()->composing(), + "collect ELF and DWARF data from the listed files") + ("drive,D", po::value(&details->iDrive), "drive on which to find ELF files") + ("exclude,e", po::value< vector >(&details->iExcludeFiles)->multitoken()->composing(), + "exclude collection of ELF and DWARF data from the listed files") + ("input,i", po::value(&details->iRomFile), "pathname of ROM image") + ("logfile,l", po::value(&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(&details->iElfRomFile), "pathname of output file") + // lexical_cast doesn't understand even though its just a typedef + // for unsigned int + ("physical-address,p", po::value(&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().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 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 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 & list){ + for (std::vector::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 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 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::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::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; +} diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/processoptions.h --- /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 . +*/ + +#ifndef PROCESSOPTIONS_H_ +#define PROCESSOPTIONS_H_ + +RomDetails * ProcessOptions(int ac, char* av[]); +RomDetails * ProcessRomDetails(RomDetails *); + +#endif /*PROCESSOPTIONS_H_*/ diff -r a587897e3bb2 -r 2925e6e5efd7 tools/elf4rom/src/romdetails.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 . +*/ + +#ifndef ROMDETAILS_H_ +#define ROMDETAILS_H_ + +#include + +#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 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 iTargetFiles; + std::vector iExcludeFiles; + +}; +#endif /*ROMDETAILS_H_*/